(Fexpand_file_name): Copy argument `name' into local storage on all platforms,
[bpt/emacs.git] / src / fileio.c
CommitLineData
570d7624 1/* File IO for GNU Emacs.
0b5538bd
TTN
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
8cabe764 4 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
570d7624
JB
5
6This file is part of GNU Emacs.
7
8GNU Emacs is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
684d6f5b 10the Free Software Foundation; either version 3, or (at your option)
570d7624
JB
11any later version.
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
20the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21Boston, MA 02110-1301, USA. */
570d7624 22
18160b98 23#include <config.h>
570d7624 24
612221ab 25#ifdef HAVE_FCNTL_H
bb369dc6
RS
26#include <fcntl.h>
27#endif
28
1b335d29 29#include <stdio.h>
570d7624
JB
30#include <sys/types.h>
31#include <sys/stat.h>
bfb61299 32
29beb080
RS
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
36
f73b0ada
BF
37#if !defined (S_ISLNK) && defined (S_IFLNK)
38# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
39#endif
40
bb369dc6
RS
41#if !defined (S_ISFIFO) && defined (S_IFIFO)
42# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
43#endif
44
f73b0ada
BF
45#if !defined (S_ISREG) && defined (S_IFREG)
46# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
47#endif
48
5b9c0a1d 49#ifdef HAVE_PWD_H
570d7624 50#include <pwd.h>
bfb61299
JB
51#endif
52
570d7624 53#include <ctype.h>
bfb61299
JB
54
55#ifdef VMS
3d9f5ce2 56#include "vmsdir.h"
bfb61299
JB
57#include <perror.h>
58#include <stddef.h>
59#include <string.h>
bfb61299
JB
60#endif
61
570d7624
JB
62#include <errno.h>
63
bfb61299 64#ifndef vax11c
f12ef5eb 65#ifndef USE_CRT_DLL
570d7624 66extern int errno;
570d7624 67#endif
f12ef5eb 68#endif
570d7624 69
570d7624
JB
70#ifdef APOLLO
71#include <sys/time.h>
72#endif
73
570d7624 74#include "lisp.h"
8d4e077b 75#include "intervals.h"
570d7624 76#include "buffer.h"
6fdaa9a0
KH
77#include "charset.h"
78#include "coding.h"
570d7624 79#include "window.h"
67c08d6c 80#include "blockinput.h"
570d7624 81
5e570b75
RS
82#ifdef WINDOWSNT
83#define NOMINMAX 1
84#include <windows.h>
85#include <stdlib.h>
86#include <fcntl.h>
87#endif /* not WINDOWSNT */
88
7990d02a
EZ
89#ifdef MSDOS
90#include "msdos.h"
91#include <sys/param.h>
92#if __DJGPP__ >= 2
93#include <fcntl.h>
94#include <string.h>
95#endif
96#endif
97
199607e4
RS
98#ifdef DOS_NT
99#define CORRECT_DIR_SEPS(s) \
100 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
101 else unixtodos_filename (s); \
102 } while (0)
103/* On Windows, drive letters must be alphabetic - on DOS, the Netware
104 redirector allows the six letters between 'Z' and 'a' as well. */
105#ifdef MSDOS
106#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
107#endif
108#ifdef WINDOWSNT
109#define IS_DRIVE(x) isalpha (x)
110#endif
f54b565c
MB
111/* Need to lower-case the drive letter, or else expanded
112 filenames will sometimes compare inequal, because
113 `expand-file-name' doesn't always down-case the drive letter. */
114#define DRIVE_LETTER(x) (tolower (x))
199607e4
RS
115#endif
116
570d7624 117#ifdef VMS
570d7624
JB
118#include <file.h>
119#include <rmsdef.h>
120#include <fab.h>
121#include <nam.h>
122#endif
123
de5bf5d3 124#include "systime.h"
570d7624
JB
125
126#ifdef HPUX
127#include <netio.h>
9b7828a5 128#ifndef HPUX8
47e7b9e5 129#ifndef HPUX9
570d7624
JB
130#include <errnet.h>
131#endif
9b7828a5 132#endif
47e7b9e5 133#endif
570d7624 134
9c856db9
GM
135#include "commands.h"
136extern int use_dialog_box;
03d6484e 137extern int use_file_dialog;
9c856db9 138
570d7624
JB
139#ifndef O_WRONLY
140#define O_WRONLY 1
141#endif
142
4018b5ef
RS
143#ifndef O_RDONLY
144#define O_RDONLY 0
145#endif
146
8f6df9b5
EZ
147#ifndef S_ISLNK
148# define lstat stat
149#endif
150
c1558952
TTN
151#ifndef FILE_SYSTEM_CASE
152#define FILE_SYSTEM_CASE(filename) (filename)
153#endif
154
570d7624
JB
155/* Nonzero during writing of auto-save files */
156int auto_saving;
157
158/* Set by auto_save_1 to mode of original file so Fwrite_region will create
159 a new file with the same mode as the original */
160int auto_save_mode_bits;
161
31e31a15
CY
162/* Set by auto_save_1 if an error occurred during the last auto-save. */
163int auto_save_error_occurred;
164
356a6224
KH
165/* The symbol bound to coding-system-for-read when
166 insert-file-contents is called for recovering a file. This is not
167 an actual coding system name, but just an indicator to tell
168 insert-file-contents to use `emacs-mule' with a special flag for
169 auto saving and recovering a file. */
170Lisp_Object Qauto_save_coding;
171
b1d1b865
RS
172/* Coding system for file names, or nil if none. */
173Lisp_Object Vfile_name_coding_system;
174
cd913586
KH
175/* Coding system for file names used only when
176 Vfile_name_coding_system is nil. */
177Lisp_Object Vdefault_file_name_coding_system;
178
199607e4 179/* Alist of elements (REGEXP . HANDLER) for file names
32f4334d
RS
180 whose I/O is done with a special handler. */
181Lisp_Object Vfile_name_handler_alist;
182
f6c9b683
RS
183/* Property name of a file name handler,
184 which gives a list of operations it handles.. */
185Lisp_Object Qoperations;
186
0d420e88
BG
187/* Lisp functions for translating file formats */
188Lisp_Object Qformat_decode, Qformat_annotate_function;
189
c9e82392 190/* Function to be called to decide a coding system of a reading file. */
0414b394 191Lisp_Object Vset_auto_coding_function;
c9e82392 192
d6a3cc15
RS
193/* Functions to be called to process text properties in inserted file. */
194Lisp_Object Vafter_insert_file_functions;
195
2080470e 196/* Lisp function for setting buffer-file-coding-system and the
b6426b03 197 multibyteness of the current buffer after inserting a file. */
2080470e 198Lisp_Object Qafter_insert_file_set_coding;
b6426b03 199
d6a3cc15
RS
200/* Functions to be called to create text property annotations for file. */
201Lisp_Object Vwrite_region_annotate_functions;
bd235610 202Lisp_Object Qwrite_region_annotate_functions;
d6a3cc15 203
6fc6f94b
RS
204/* During build_annotations, each time an annotation function is called,
205 this holds the annotations made by the previous functions. */
206Lisp_Object Vwrite_region_annotations_so_far;
207
e54d3b5d
RS
208/* File name in which we write a list of all our auto save files. */
209Lisp_Object Vauto_save_list_file_name;
210
f8a12fae
CY
211/* Whether or not files are auto-saved into themselves. */
212Lisp_Object Vauto_save_visited_file_name;
213
59ffe07d 214/* Function to call to read a file name. */
efdc16c9 215Lisp_Object Vread_file_name_function;
59ffe07d
KS
216
217/* Current predicate used by read_file_name_internal. */
218Lisp_Object Vread_file_name_predicate;
219
316ef0dc
JPW
220/* Nonzero means completion ignores case when reading file name. */
221int read_file_name_completion_ignore_case;
222
570d7624
JB
223/* Nonzero means, when reading a filename in the minibuffer,
224 start out by inserting the default directory into the minibuffer. */
225int insert_default_directory;
226
227/* On VMS, nonzero means write new files with record format stmlf.
228 Zero means use var format. */
229int vms_stmlf_recfm;
230
199607e4
RS
231/* On NT, specifies the directory separator character, used (eg.) when
232 expanding file names. This can be bound to / or \. */
233Lisp_Object Vdirectory_sep_char;
234
ccf61795
RF
235#ifdef HAVE_FSYNC
236/* Nonzero means skip the call to fsync in Fwrite-region. */
237int write_region_inhibit_fsync;
238#endif
239
84f6296a
RS
240extern Lisp_Object Vuser_login_name;
241
c1c4693e
RS
242#ifdef WINDOWSNT
243extern Lisp_Object Vw32_get_true_file_attributes;
244#endif
245
84f6296a
RS
246extern int minibuf_level;
247
a8c828be
RS
248extern int minibuffer_auto_raise;
249
75fa7206
RS
250extern int history_delete_duplicates;
251
a65970a0
RS
252/* These variables describe handlers that have "already" had a chance
253 to handle the current operation.
254
255 Vinhibit_file_name_handlers is a list of file name handlers.
256 Vinhibit_file_name_operation is the operation being handled.
257 If we try to handle that operation, we ignore those handlers. */
258
82c2d839 259static Lisp_Object Vinhibit_file_name_handlers;
a65970a0 260static Lisp_Object Vinhibit_file_name_operation;
82c2d839 261
c0b7b21c 262Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
505ab9bc 263Lisp_Object Qexcl;
15c65264
RS
264Lisp_Object Qfile_name_history;
265
d6a3cc15
RS
266Lisp_Object Qcar_less_than_car;
267
ce51c54c 268static int a_write P_ ((int, Lisp_Object, int, int,
b9013200 269 Lisp_Object *, struct coding_system *));
ce51c54c
KH
270static int e_write P_ ((int, Lisp_Object, int, int, struct coding_system *));
271
ec7adf26 272\f
5d01d666 273void
570d7624 274report_file_error (string, data)
19290c65 275 const char *string;
570d7624
JB
276 Lisp_Object data;
277{
278 Lisp_Object errstring;
505ab9bc 279 int errorno = errno;
570d7624 280
ca9c0567 281 synchronize_system_messages_locale ();
68c45bf0
PE
282 errstring = code_convert_string_norecord (build_string (strerror (errorno)),
283 Vlocale_coding_system, 0);
284
570d7624 285 while (1)
505ab9bc
RS
286 switch (errorno)
287 {
288 case EEXIST:
24b1ddad 289 xsignal (Qfile_already_exists, Fcons (errstring, data));
505ab9bc
RS
290 break;
291 default:
292 /* System error messages are capitalized. Downcase the initial
293 unless it is followed by a slash. */
d5db4077 294 if (SREF (errstring, 1) != '/')
942dc838 295 SSET (errstring, 0, DOWNCASE (SREF (errstring, 0)));
505ab9bc 296
24b1ddad 297 xsignal (Qfile_error,
505ab9bc
RS
298 Fcons (build_string (string), Fcons (errstring, data)));
299 }
570d7624 300}
b5148e85 301
b27a1703 302Lisp_Object
b5148e85
RS
303close_file_unwind (fd)
304 Lisp_Object fd;
305{
68c45bf0 306 emacs_close (XFASTINT (fd));
b27a1703 307 return Qnil;
b5148e85 308}
a1d2b64a
RS
309
310/* Restore point, having saved it as a marker. */
311
ec7adf26 312static Lisp_Object
a1d2b64a 313restore_point_unwind (location)
199607e4 314 Lisp_Object location;
a1d2b64a 315{
ec7adf26 316 Fgoto_char (location);
a1d2b64a 317 Fset_marker (location, Qnil, Qnil);
b27a1703 318 return Qnil;
a1d2b64a 319}
570d7624 320\f
0bf2eed2 321Lisp_Object Qexpand_file_name;
273e0829 322Lisp_Object Qsubstitute_in_file_name;
0bf2eed2
RS
323Lisp_Object Qdirectory_file_name;
324Lisp_Object Qfile_name_directory;
325Lisp_Object Qfile_name_nondirectory;
642ef245 326Lisp_Object Qunhandled_file_name_directory;
0bf2eed2 327Lisp_Object Qfile_name_as_directory;
32f4334d 328Lisp_Object Qcopy_file;
a6e6e718 329Lisp_Object Qmake_directory_internal;
b272d624 330Lisp_Object Qmake_directory;
32f4334d
RS
331Lisp_Object Qdelete_directory;
332Lisp_Object Qdelete_file;
333Lisp_Object Qrename_file;
334Lisp_Object Qadd_name_to_file;
335Lisp_Object Qmake_symbolic_link;
336Lisp_Object Qfile_exists_p;
337Lisp_Object Qfile_executable_p;
338Lisp_Object Qfile_readable_p;
32f4334d 339Lisp_Object Qfile_writable_p;
1f8653eb
RS
340Lisp_Object Qfile_symlink_p;
341Lisp_Object Qaccess_file;
32f4334d 342Lisp_Object Qfile_directory_p;
adedc71d 343Lisp_Object Qfile_regular_p;
32f4334d
RS
344Lisp_Object Qfile_accessible_directory_p;
345Lisp_Object Qfile_modes;
346Lisp_Object Qset_file_modes;
819da85b 347Lisp_Object Qset_file_times;
32f4334d
RS
348Lisp_Object Qfile_newer_than_file_p;
349Lisp_Object Qinsert_file_contents;
350Lisp_Object Qwrite_region;
351Lisp_Object Qverify_visited_file_modtime;
3ec46acd 352Lisp_Object Qset_visited_file_modtime;
32f4334d 353
49307295 354DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
8c1a1077
PJ
355 doc: /* Return FILENAME's handler function for OPERATION, if it has one.
356Otherwise, return nil.
357A file name is handled if one of the regular expressions in
358`file-name-handler-alist' matches it.
359
360If OPERATION equals `inhibit-file-name-operation', then we ignore
361any handlers that are members of `inhibit-file-name-handlers',
362but we still do run any other handlers. This lets handlers
363use the standard functions without calling themselves recursively. */)
364 (filename, operation)
365 Lisp_Object filename, operation;
32f4334d 366{
642ef245 367 /* This function must not munge the match data. */
204ee271 368 Lisp_Object chain, inhibited_handlers, result;
8d2ced53 369 int pos = -1;
642ef245 370
204ee271 371 result = Qnil;
b7826503 372 CHECK_STRING (filename);
e4432095 373
a65970a0
RS
374 if (EQ (operation, Vinhibit_file_name_operation))
375 inhibited_handlers = Vinhibit_file_name_handlers;
376 else
377 inhibited_handlers = Qnil;
82c2d839 378
93c30b5f 379 for (chain = Vfile_name_handler_alist; CONSP (chain);
03699b14 380 chain = XCDR (chain))
32f4334d
RS
381 {
382 Lisp_Object elt;
03699b14 383 elt = XCAR (chain);
93c30b5f 384 if (CONSP (elt))
32f4334d 385 {
f6c9b683 386 Lisp_Object string = XCAR (elt);
8d2ced53 387 int match_pos;
f6c9b683 388 Lisp_Object handler = XCDR (elt);
68780e2a
RS
389 Lisp_Object operations = Qnil;
390
391 if (SYMBOLP (handler))
392 operations = Fget (handler, Qoperations);
f6c9b683 393
8d2ced53 394 if (STRINGP (string)
f6c9b683
RS
395 && (match_pos = fast_string_match (string, filename)) > pos
396 && (NILP (operations) || ! NILP (Fmemq (operation, operations))))
a65970a0 397 {
f6c9b683 398 Lisp_Object tem;
a65970a0 399
03699b14 400 handler = XCDR (elt);
a65970a0
RS
401 tem = Fmemq (handler, inhibited_handlers);
402 if (NILP (tem))
8d2ced53
SM
403 {
404 result = handler;
405 pos = match_pos;
406 }
a65970a0 407 }
32f4334d 408 }
642ef245
JB
409
410 QUIT;
32f4334d 411 }
8d2ced53 412 return result;
32f4334d
RS
413}
414\f
570d7624 415DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
8c1a1077
PJ
416 1, 1, 0,
417 doc: /* Return the directory component in file name FILENAME.
418Return nil if FILENAME does not include a directory.
78379264 419Otherwise return a directory name.
8c1a1077
PJ
420Given a Unix syntax file name, returns a string ending in slash;
421on VMS, perhaps instead a string ending in `:', `]' or `>'. */)
422 (filename)
3b7f6e60 423 Lisp_Object filename;
570d7624 424{
100c44b7 425#ifndef DOS_NT
19290c65 426 register const unsigned char *beg;
100c44b7
EZ
427#else
428 register unsigned char *beg;
429#endif
19290c65 430 register const unsigned char *p;
0bf2eed2 431 Lisp_Object handler;
570d7624 432
b7826503 433 CHECK_STRING (filename);
570d7624 434
0bf2eed2
RS
435 /* If the file name has special constructs in it,
436 call the corresponding file handler. */
3b7f6e60 437 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
0bf2eed2 438 if (!NILP (handler))
3b7f6e60 439 return call2 (handler, Qfile_name_directory, filename);
0bf2eed2 440
3b7f6e60 441 filename = FILE_SYSTEM_CASE (filename);
d5db4077 442 beg = SDATA (filename);
199607e4
RS
443#ifdef DOS_NT
444 beg = strcpy (alloca (strlen (beg) + 1), beg);
445#endif
d5db4077 446 p = beg + SBYTES (filename);
570d7624 447
199607e4 448 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
570d7624
JB
449#ifdef VMS
450 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
451#endif /* VMS */
199607e4 452#ifdef DOS_NT
ba14e174
RS
453 /* only recognise drive specifier at the beginning */
454 && !(p[-1] == ':'
455 /* handle the "/:d:foo" and "/:foo" cases correctly */
456 && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
457 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
199607e4 458#endif
570d7624
JB
459 ) p--;
460
461 if (p == beg)
462 return Qnil;
5e570b75 463#ifdef DOS_NT
4c3c22f3 464 /* Expansion of "c:" to drive and default directory. */
ba14e174 465 if (p[-1] == ':')
4c3c22f3 466 {
4c3c22f3 467 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
199607e4 468 unsigned char *res = alloca (MAXPATHLEN + 1);
ba14e174
RS
469 unsigned char *r = res;
470
471 if (p == beg + 4 && IS_DIRECTORY_SEP (*beg) && beg[1] == ':')
472 {
473 strncpy (res, beg, 2);
474 beg += 2;
475 r += 2;
476 }
477
478 if (getdefdir (toupper (*beg) - 'A' + 1, r))
4c3c22f3 479 {
199607e4 480 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
4c3c22f3
RS
481 strcat (res, "/");
482 beg = res;
483 p = beg + strlen (beg);
484 }
485 }
199607e4 486 CORRECT_DIR_SEPS (beg);
5e570b75 487#endif /* DOS_NT */
60d67b83 488
d7231f93 489 return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename));
570d7624
JB
490}
491
60d67b83
RS
492DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
493 Sfile_name_nondirectory, 1, 1, 0,
8c1a1077
PJ
494 doc: /* Return file name FILENAME sans its directory.
495For example, in a Unix-syntax file name,
496this is everything after the last slash,
497or the entire name if it contains no slash. */)
498 (filename)
3b7f6e60 499 Lisp_Object filename;
570d7624 500{
19290c65 501 register const unsigned char *beg, *p, *end;
0bf2eed2 502 Lisp_Object handler;
570d7624 503
b7826503 504 CHECK_STRING (filename);
570d7624 505
0bf2eed2
RS
506 /* If the file name has special constructs in it,
507 call the corresponding file handler. */
3b7f6e60 508 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
0bf2eed2 509 if (!NILP (handler))
3b7f6e60 510 return call2 (handler, Qfile_name_nondirectory, filename);
0bf2eed2 511
d5db4077
KR
512 beg = SDATA (filename);
513 end = p = beg + SBYTES (filename);
570d7624 514
199607e4 515 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
570d7624
JB
516#ifdef VMS
517 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
518#endif /* VMS */
199607e4
RS
519#ifdef DOS_NT
520 /* only recognise drive specifier at beginning */
ba14e174
RS
521 && !(p[-1] == ':'
522 /* handle the "/:d:foo" case correctly */
523 && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
199607e4 524#endif
60d67b83
RS
525 )
526 p--;
570d7624 527
d7231f93 528 return make_specified_string (p, -1, end - p, STRING_MULTIBYTE (filename));
570d7624 529}
642ef245 530
60d67b83
RS
531DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory,
532 Sunhandled_file_name_directory, 1, 1, 0,
8c1a1077
PJ
533 doc: /* Return a directly usable directory name somehow associated with FILENAME.
534A `directly usable' directory name is one that may be used without the
535intervention of any file handler.
536If FILENAME is a directly usable file itself, return
537\(file-name-directory FILENAME).
538The `call-process' and `start-process' functions use this function to
539get a current directory to run processes in. */)
540 (filename)
541 Lisp_Object filename;
642ef245
JB
542{
543 Lisp_Object handler;
544
545 /* If the file name has special constructs in it,
546 call the corresponding file handler. */
49307295 547 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
642ef245
JB
548 if (!NILP (handler))
549 return call2 (handler, Qunhandled_file_name_directory, filename);
550
551 return Ffile_name_directory (filename);
552}
553
570d7624
JB
554\f
555char *
556file_name_as_directory (out, in)
557 char *out, *in;
558{
559 int size = strlen (in) - 1;
560
561 strcpy (out, in);
562
8aa3a244
RS
563 if (size < 0)
564 {
154a307d
KH
565 out[0] = '.';
566 out[1] = '/';
567 out[2] = 0;
8aa3a244
RS
568 return out;
569 }
570
570d7624
JB
571#ifdef VMS
572 /* Is it already a directory string? */
573 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
574 return out;
575 /* Is it a VMS directory file name? If so, hack VMS syntax. */
576 else if (! index (in, '/')
577 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
578 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
579 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
580 || ! strncmp (&in[size - 5], ".dir", 4))
581 && (in[size - 1] == '.' || in[size - 1] == ';')
582 && in[size] == '1')))
583 {
584 register char *p, *dot;
585 char brack;
586
587 /* x.dir -> [.x]
588 dir:x.dir --> dir:[x]
589 dir:[x]y.dir --> dir:[x.y] */
590 p = in + size;
591 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
592 if (p != in)
593 {
594 strncpy (out, in, p - in);
595 out[p - in] = '\0';
596 if (*p == ':')
597 {
598 brack = ']';
599 strcat (out, ":[");
600 }
601 else
602 {
603 brack = *p;
604 strcat (out, ".");
605 }
606 p++;
607 }
608 else
609 {
610 brack = ']';
611 strcpy (out, "[.");
612 }
bfb61299
JB
613 dot = index (p, '.');
614 if (dot)
570d7624
JB
615 {
616 /* blindly remove any extension */
617 size = strlen (out) + (dot - p);
618 strncat (out, p, dot - p);
619 }
620 else
621 {
622 strcat (out, p);
623 size = strlen (out);
624 }
625 out[size++] = brack;
626 out[size] = '\0';
627 }
628#else /* not VMS */
629 /* For Unix syntax, Append a slash if necessary */
199607e4 630 if (!IS_DIRECTORY_SEP (out[size]))
5e570b75 631 {
8cfd6446
JB
632 /* Cannot use DIRECTORY_SEP, which could have any value */
633 out[size + 1] = '/';
5e570b75
RS
634 out[size + 2] = '\0';
635 }
199607e4
RS
636#ifdef DOS_NT
637 CORRECT_DIR_SEPS (out);
638#endif
570d7624
JB
639#endif /* not VMS */
640 return out;
641}
642
643DEFUN ("file-name-as-directory", Ffile_name_as_directory,
644 Sfile_name_as_directory, 1, 1, 0,
0dac4f85 645 doc: /* Return a string representing the file name FILE interpreted as a directory.
8c1a1077
PJ
646This operation exists because a directory is also a file, but its name as
647a directory is different from its name as a file.
648The result can be used as the value of `default-directory'
649or passed as second argument to `expand-file-name'.
650For a Unix-syntax file name, just appends a slash.
651On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc. */)
652 (file)
570d7624
JB
653 Lisp_Object file;
654{
655 char *buf;
0bf2eed2 656 Lisp_Object handler;
570d7624 657
b7826503 658 CHECK_STRING (file);
265a9e55 659 if (NILP (file))
570d7624 660 return Qnil;
0bf2eed2
RS
661
662 /* If the file name has special constructs in it,
663 call the corresponding file handler. */
49307295 664 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
0bf2eed2
RS
665 if (!NILP (handler))
666 return call2 (handler, Qfile_name_as_directory, file);
667
d5db4077 668 buf = (char *) alloca (SBYTES (file) + 10);
d7231f93
KH
669 file_name_as_directory (buf, SDATA (file));
670 return make_specified_string (buf, -1, strlen (buf),
671 STRING_MULTIBYTE (file));
570d7624
JB
672}
673\f
674/*
675 * Convert from directory name to filename.
676 * On VMS:
677 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
678 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
199607e4 679 * On UNIX, it's simple: just make sure there isn't a terminating /
570d7624
JB
680
681 * Value is nonzero if the string output is different from the input.
682 */
683
dfcf069d 684int
570d7624
JB
685directory_file_name (src, dst)
686 char *src, *dst;
687{
688 long slen;
689#ifdef VMS
690 long rlen;
691 char * ptr, * rptr;
692 char bracket;
693 struct FAB fab = cc$rms_fab;
694 struct NAM nam = cc$rms_nam;
695 char esa[NAM$C_MAXRSS];
696#endif /* VMS */
697
698 slen = strlen (src);
699#ifdef VMS
700 if (! index (src, '/')
701 && (src[slen - 1] == ']'
702 || src[slen - 1] == ':'
703 || src[slen - 1] == '>'))
704 {
705 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
706 fab.fab$l_fna = src;
707 fab.fab$b_fns = slen;
708 fab.fab$l_nam = &nam;
709 fab.fab$l_fop = FAB$M_NAM;
710
711 nam.nam$l_esa = esa;
712 nam.nam$b_ess = sizeof esa;
713 nam.nam$b_nop |= NAM$M_SYNCHK;
714
715 /* We call SYS$PARSE to handle such things as [--] for us. */
199607e4 716 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
570d7624
JB
717 {
718 slen = nam.nam$b_esl;
719 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
720 slen -= 2;
721 esa[slen] = '\0';
722 src = esa;
723 }
724 if (src[slen - 1] != ']' && src[slen - 1] != '>')
725 {
726 /* what about when we have logical_name:???? */
727 if (src[slen - 1] == ':')
5e570b75 728 { /* Xlate logical name and see what we get */
570d7624
JB
729 ptr = strcpy (dst, src); /* upper case for getenv */
730 while (*ptr)
731 {
732 if ('a' <= *ptr && *ptr <= 'z')
733 *ptr -= 040;
734 ptr++;
735 }
5e570b75 736 dst[slen - 1] = 0; /* remove colon */
570d7624
JB
737 if (!(src = egetenv (dst)))
738 return 0;
739 /* should we jump to the beginning of this procedure?
740 Good points: allows us to use logical names that xlate
741 to Unix names,
742 Bad points: can be a problem if we just translated to a device
743 name...
744 For now, I'll punt and always expect VMS names, and hope for
745 the best! */
746 slen = strlen (src);
747 if (src[slen - 1] != ']' && src[slen - 1] != '>')
748 { /* no recursion here! */
749 strcpy (dst, src);
750 return 0;
751 }
752 }
753 else
5e570b75 754 { /* not a directory spec */
570d7624
JB
755 strcpy (dst, src);
756 return 0;
757 }
758 }
759 bracket = src[slen - 1];
760
761 /* If bracket is ']' or '>', bracket - 2 is the corresponding
762 opening bracket. */
bfb61299
JB
763 ptr = index (src, bracket - 2);
764 if (ptr == 0)
570d7624
JB
765 { /* no opening bracket */
766 strcpy (dst, src);
767 return 0;
768 }
769 if (!(rptr = rindex (src, '.')))
770 rptr = ptr;
771 slen = rptr - src;
772 strncpy (dst, src, slen);
773 dst[slen] = '\0';
774 if (*rptr == '.')
775 {
776 dst[slen++] = bracket;
777 dst[slen] = '\0';
778 }
779 else
780 {
781 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
782 then translate the device and recurse. */
783 if (dst[slen - 1] == ':'
5e570b75 784 && dst[slen - 2] != ':' /* skip decnet nodes */
199607e4 785 && strcmp (src + slen, "[000000]") == 0)
570d7624
JB
786 {
787 dst[slen - 1] = '\0';
788 if ((ptr = egetenv (dst))
789 && (rlen = strlen (ptr) - 1) > 0
790 && (ptr[rlen] == ']' || ptr[rlen] == '>')
791 && ptr[rlen - 1] == '.')
792 {
72b21817
RS
793 char * buf = (char *) alloca (strlen (ptr) + 1);
794 strcpy (buf, ptr);
795 buf[rlen - 1] = ']';
796 buf[rlen] = '\0';
797 return directory_file_name (buf, dst);
570d7624
JB
798 }
799 else
800 dst[slen - 1] = ':';
801 }
802 strcat (dst, "[000000]");
803 slen += 8;
804 }
805 rptr++;
806 rlen = strlen (rptr) - 1;
807 strncat (dst, rptr, rlen);
808 dst[slen + rlen] = '\0';
809 strcat (dst, ".DIR.1");
810 return 1;
811 }
812#endif /* VMS */
813 /* Process as Unix format: just remove any final slash.
814 But leave "/" unchanged; do not change it to "". */
815 strcpy (dst, src);
125feee8
RS
816#ifdef APOLLO
817 /* Handle // as root for apollo's. */
818 if ((slen > 2 && dst[slen - 1] == '/')
819 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
820 dst[slen - 1] = 0;
821#else
199607e4 822 if (slen > 1
5e570b75 823 && IS_DIRECTORY_SEP (dst[slen - 1])
4592782e
RS
824#ifdef DOS_NT
825 && !IS_ANY_SEP (dst[slen - 2])
826#endif
827 )
570d7624 828 dst[slen - 1] = 0;
199607e4
RS
829#endif
830#ifdef DOS_NT
831 CORRECT_DIR_SEPS (dst);
125feee8 832#endif
570d7624
JB
833 return 1;
834}
835
836DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
8c1a1077
PJ
837 1, 1, 0,
838 doc: /* Returns the file name of the directory named DIRECTORY.
839This is the name of the file that holds the data for the directory DIRECTORY.
840This operation exists because a directory is also a file, but its name as
841a directory is different from its name as a file.
842In Unix-syntax, this function just removes the final slash.
843On VMS, given a VMS-syntax directory name such as \"[X.Y]\",
844it returns a file name such as \"[X]Y.DIR.1\". */)
845 (directory)
570d7624
JB
846 Lisp_Object directory;
847{
848 char *buf;
0bf2eed2 849 Lisp_Object handler;
570d7624 850
b7826503 851 CHECK_STRING (directory);
570d7624 852
265a9e55 853 if (NILP (directory))
570d7624 854 return Qnil;
0bf2eed2
RS
855
856 /* If the file name has special constructs in it,
857 call the corresponding file handler. */
49307295 858 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
0bf2eed2
RS
859 if (!NILP (handler))
860 return call2 (handler, Qdirectory_file_name, directory);
861
570d7624
JB
862#ifdef VMS
863 /* 20 extra chars is insufficient for VMS, since we might perform a
864 logical name translation. an equivalence string can be up to 255
865 chars long, so grab that much extra space... - sss */
d5db4077 866 buf = (char *) alloca (SBYTES (directory) + 20 + 255);
570d7624 867#else
d5db4077 868 buf = (char *) alloca (SBYTES (directory) + 20);
570d7624 869#endif
d5db4077 870 directory_file_name (SDATA (directory), buf);
d7231f93
KH
871 return make_specified_string (buf, -1, strlen (buf),
872 STRING_MULTIBYTE (directory));
570d7624
JB
873}
874
3ce839e4
RS
875static char make_temp_name_tbl[64] =
876{
877 'A','B','C','D','E','F','G','H',
878 'I','J','K','L','M','N','O','P',
879 'Q','R','S','T','U','V','W','X',
880 'Y','Z','a','b','c','d','e','f',
881 'g','h','i','j','k','l','m','n',
882 'o','p','q','r','s','t','u','v',
883 'w','x','y','z','0','1','2','3',
884 '4','5','6','7','8','9','-','_'
885};
cb613bb8 886
3ce839e4
RS
887static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
888
cb613bb8 889/* Value is a temporary file name starting with PREFIX, a string.
efdc16c9 890
cb613bb8
GM
891 The Emacs process number forms part of the result, so there is
892 no danger of generating a name being used by another process.
893 In addition, this function makes an attempt to choose a name
894 which has no existing file. To make this work, PREFIX should be
895 an absolute file name.
efdc16c9 896
cb613bb8
GM
897 BASE64_P non-zero means add the pid as 3 characters in base64
898 encoding. In this case, 6 characters will be added to PREFIX to
899 form the file name. Otherwise, if Emacs is running on a system
900 with long file names, add the pid as a decimal number.
901
902 This function signals an error if no unique file name could be
903 generated. */
904
905Lisp_Object
906make_temp_name (prefix, base64_p)
570d7624 907 Lisp_Object prefix;
cb613bb8 908 int base64_p;
570d7624
JB
909{
910 Lisp_Object val;
0cedd530 911 int len, clen;
3ce839e4
RS
912 int pid;
913 unsigned char *p, *data;
914 char pidbuf[20];
915 int pidlen;
efdc16c9 916
b7826503 917 CHECK_STRING (prefix);
3ce839e4
RS
918
919 /* VAL is created by adding 6 characters to PREFIX. The first
920 three are the PID of this process, in base 64, and the second
921 three are incremented if the file already exists. This ensures
922 262144 unique file names per PID per PREFIX. */
923
924 pid = (int) getpid ();
925
cb613bb8
GM
926 if (base64_p)
927 {
928 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
929 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
930 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
931 pidlen = 3;
932 }
933 else
934 {
3ce839e4 935#ifdef HAVE_LONG_FILE_NAMES
cb613bb8
GM
936 sprintf (pidbuf, "%d", pid);
937 pidlen = strlen (pidbuf);
3a3bfb18 938#else
cb613bb8
GM
939 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
940 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
941 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
942 pidlen = 3;
3ce839e4 943#endif
cb613bb8 944 }
efdc16c9 945
0cedd530
SM
946 len = SBYTES (prefix); clen = SCHARS (prefix);
947 val = make_uninit_multibyte_string (clen + 3 + pidlen, len + 3 + pidlen);
948 if (!STRING_MULTIBYTE (prefix))
949 STRING_SET_UNIBYTE (val);
d5db4077
KR
950 data = SDATA (val);
951 bcopy(SDATA (prefix), data, len);
3ce839e4
RS
952 p = data + len;
953
954 bcopy (pidbuf, p, pidlen);
955 p += pidlen;
956
957 /* Here we try to minimize useless stat'ing when this function is
958 invoked many times successively with the same PREFIX. We achieve
959 this by initializing count to a random value, and incrementing it
f6a492a9
RS
960 afterwards.
961
962 We don't want make-temp-name to be called while dumping,
963 because then make_temp_name_count_initialized_p would get set
964 and then make_temp_name_count would not be set when Emacs starts. */
965
3ce839e4
RS
966 if (!make_temp_name_count_initialized_p)
967 {
968 make_temp_name_count = (unsigned) time (NULL);
969 make_temp_name_count_initialized_p = 1;
970 }
971
972 while (1)
973 {
974 struct stat ignored;
8a7777fc 975 unsigned num = make_temp_name_count;
3ce839e4
RS
976
977 p[0] = make_temp_name_tbl[num & 63], num >>= 6;
978 p[1] = make_temp_name_tbl[num & 63], num >>= 6;
979 p[2] = make_temp_name_tbl[num & 63], num >>= 6;
980
8a7777fc
RS
981 /* Poor man's congruential RN generator. Replace with
982 ++make_temp_name_count for debugging. */
983 make_temp_name_count += 25229;
984 make_temp_name_count %= 225307;
985
3ce839e4
RS
986 if (stat (data, &ignored) < 0)
987 {
988 /* We want to return only if errno is ENOENT. */
989 if (errno == ENOENT)
990 return val;
991 else
992 /* The error here is dubious, but there is little else we
993 can do. The alternatives are to return nil, which is
994 as bad as (and in many cases worse than) throwing the
995 error, or to ignore the error, which will likely result
8a7777fc
RS
996 in looping through 225307 stat's, which is not only
997 dog-slow, but also useless since it will fallback to
998 the errow below, anyway. */
9869bb0b 999 report_file_error ("Cannot create temporary name for prefix",
3ce839e4
RS
1000 Fcons (prefix, Qnil));
1001 /* not reached */
1002 }
1003 }
1004
1005 error ("Cannot create temporary name for prefix `%s'",
d5db4077 1006 SDATA (prefix));
3ce839e4 1007 return Qnil;
570d7624 1008}
3ce839e4 1009
cb613bb8
GM
1010
1011DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
8c1a1077
PJ
1012 doc: /* Generate temporary file name (string) starting with PREFIX (a string).
1013The Emacs process number forms part of the result,
1014so there is no danger of generating a name being used by another process.
1015
1016In addition, this function makes an attempt to choose a name
1017which has no existing file. To make this work,
1018PREFIX should be an absolute file name.
1019
1020There is a race condition between calling `make-temp-name' and creating the
1021file which opens all kinds of security holes. For that reason, you should
f9e6f049
RS
1022probably use `make-temp-file' instead, except in three circumstances:
1023
1024* If you are creating the file in the user's home directory.
1025* If you are creating a directory rather than an ordinary file.
1026* If you are taking special precautions as `make-temp-file' does. */)
8c1a1077 1027 (prefix)
cb613bb8
GM
1028 Lisp_Object prefix;
1029{
1030 return make_temp_name (prefix, 0);
1031}
1032
1033
570d7624
JB
1034\f
1035DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
8c1a1077
PJ
1036 doc: /* Convert filename NAME to absolute, and canonicalize it.
1037Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
78379264 1038\(does not start with slash or tilde); if DEFAULT-DIRECTORY is nil or missing,
a4e03fe5 1039the current buffer's value of `default-directory' is used.
8c1a1077
PJ
1040File name components that are `.' are removed, and
1041so are file name components followed by `..', along with the `..' itself;
1042note that these simplifications are done without checking the resulting
1043file names in the file system.
1044An initial `~/' expands to your home directory.
1045An initial `~USER/' expands to USER's home directory.
1046See also the function `substitute-in-file-name'. */)
1047 (name, default_directory)
3b7f6e60 1048 Lisp_Object name, default_directory;
570d7624
JB
1049{
1050 unsigned char *nm;
199607e4 1051
570d7624
JB
1052 register unsigned char *newdir, *p, *o;
1053 int tlen;
1054 unsigned char *target;
1055 struct passwd *pw;
570d7624
JB
1056#ifdef VMS
1057 unsigned char * colon = 0;
1058 unsigned char * close = 0;
1059 unsigned char * slash = 0;
1060 unsigned char * brack = 0;
1061 int lbrack = 0, rbrack = 0;
1062 int dots = 0;
1063#endif /* VMS */
5e570b75 1064#ifdef DOS_NT
199607e4 1065 int drive = 0;
9a1dc3be 1066 int collapse_newdir = 1;
f0f95d31 1067 int is_escaped = 0;
5e570b75 1068#endif /* DOS_NT */
199607e4 1069 int length;
beb402de 1070 Lisp_Object handler, result;
2b046a72 1071 int multibyte;
8fe2123e 1072 Lisp_Object hdir;
199607e4 1073
b7826503 1074 CHECK_STRING (name);
570d7624 1075
0bf2eed2
RS
1076 /* If the file name has special constructs in it,
1077 call the corresponding file handler. */
49307295 1078 handler = Ffind_file_name_handler (name, Qexpand_file_name);
0bf2eed2 1079 if (!NILP (handler))
3b7f6e60 1080 return call3 (handler, Qexpand_file_name, name, default_directory);
58fc9587 1081
3b7f6e60
EN
1082 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
1083 if (NILP (default_directory))
1084 default_directory = current_buffer->directory;
82330e7f 1085 if (! STRINGP (default_directory))
dd693537
EZ
1086 {
1087#ifdef DOS_NT
1088 /* "/" is not considered a root directory on DOS_NT, so using "/"
1089 here causes an infinite recursion in, e.g., the following:
1090
1091 (let (default-directory)
1092 (expand-file-name "a"))
1093
1094 To avoid this, we set default_directory to the root of the
1095 current drive. */
1096 extern char *emacs_root_dir (void);
1097
1098 default_directory = build_string (emacs_root_dir ());
1099#else
1100 default_directory = build_string ("/");
1101#endif
1102 }
58fc9587 1103
3b7f6e60 1104 if (!NILP (default_directory))
273e0829 1105 {
3b7f6e60 1106 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
273e0829 1107 if (!NILP (handler))
3b7f6e60 1108 return call3 (handler, Qexpand_file_name, name, default_directory);
273e0829 1109 }
0bf2eed2 1110
d5db4077 1111 o = SDATA (default_directory);
5e570b75 1112
3b7f6e60 1113 /* Make sure DEFAULT_DIRECTORY is properly expanded.
f14b1c68 1114 It would be better to do this down below where we actually use
3b7f6e60 1115 default_directory. Unfortunately, calling Fexpand_file_name recursively
f14b1c68
JB
1116 could invoke GC, and the strings might be relocated. This would
1117 be annoying because we have pointers into strings lying around
1118 that would need adjusting, and people would add new pointers to
1119 the code and forget to adjust them, resulting in intermittent bugs.
4ad827c5
RS
1120 Putting this call here avoids all that crud.
1121
1122 The EQ test avoids infinite recursion. */
3b7f6e60 1123 if (! NILP (default_directory) && !EQ (default_directory, name)
199607e4
RS
1124 /* Save time in some common cases - as long as default_directory
1125 is not relative, it can be canonicalized with name below (if it
1126 is needed at all) without requiring it to be expanded now. */
01937013 1127#ifdef DOS_NT
199607e4 1128 /* Detect MSDOS file names with drive specifiers. */
f0f95d31 1129 && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))
199607e4
RS
1130#ifdef WINDOWSNT
1131 /* Detect Windows file names in UNC format. */
1132 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
01937013 1133#endif
199607e4
RS
1134#else /* not DOS_NT */
1135 /* Detect Unix absolute file names (/... alone is not absolute on
1136 DOS or Windows). */
1137 && ! (IS_DIRECTORY_SEP (o[0]))
1138#endif /* not DOS_NT */
1139 )
f14b1c68
JB
1140 {
1141 struct gcpro gcpro1;
1142
1143 GCPRO1 (name);
3b7f6e60 1144 default_directory = Fexpand_file_name (default_directory, Qnil);
f14b1c68
JB
1145 UNGCPRO;
1146 }
1147
4c3c22f3 1148 name = FILE_SYSTEM_CASE (name);
d5db4077 1149 nm = SDATA (name);
2b046a72 1150 multibyte = STRING_MULTIBYTE (name);
a5a1cc06 1151
565f0b98 1152 /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */
199607e4
RS
1153 nm = strcpy (alloca (strlen (nm) + 1), nm);
1154
565f0b98 1155#ifdef DOS_NT
f0f95d31
RS
1156 /* Note if special escape prefix is present, but remove for now. */
1157 if (nm[0] == '/' && nm[1] == ':')
1158 {
1159 is_escaped = 1;
1160 nm += 2;
1161 }
1162
199607e4 1163 /* Find and remove drive specifier if present; this makes nm absolute
f0f95d31
RS
1164 even if the rest of the name appears to be relative. Only look for
1165 drive specifier at the beginning. */
1166 if (IS_DRIVE (nm[0]) && IS_DEVICE_SEP (nm[1]))
1167 {
1168 drive = nm[0];
1169 nm += 2;
1170 }
bb1ff1f4
GV
1171
1172#ifdef WINDOWSNT
1173 /* If we see "c://somedir", we want to strip the first slash after the
1174 colon when stripping the drive letter. Otherwise, this expands to
1175 "//somedir". */
1176 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1177 nm++;
1178#endif /* WINDOWSNT */
5e570b75 1179#endif /* DOS_NT */
4c3c22f3 1180
199607e4
RS
1181#ifdef WINDOWSNT
1182 /* Discard any previous drive specifier if nm is now in UNC format. */
1183 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1184 {
1185 drive = 0;
1186 }
1187#endif
1188
214378ec
GM
1189 /* If nm is absolute, look for `/./' or `/../' or `//''sequences; if
1190 none are found, we can probably return right away. We will avoid
1191 allocating a new string if name is already fully expanded. */
570d7624 1192 if (
5e570b75 1193 IS_DIRECTORY_SEP (nm[0])
199607e4 1194#ifdef MSDOS
f0f95d31 1195 && drive && !is_escaped
199607e4
RS
1196#endif
1197#ifdef WINDOWSNT
f0f95d31 1198 && (drive || IS_DIRECTORY_SEP (nm[1])) && !is_escaped
199607e4 1199#endif
570d7624
JB
1200#ifdef VMS
1201 || index (nm, ':')
1202#endif /* VMS */
1203 )
1204 {
f14b1c68
JB
1205 /* If it turns out that the filename we want to return is just a
1206 suffix of FILENAME, we don't need to go through and edit
1207 things; we just need to construct a new string using data
1208 starting at the middle of FILENAME. If we set lose to a
1209 non-zero value, that means we've discovered that we can't do
1210 that cool trick. */
1211 int lose = 0;
1212
570d7624 1213 p = nm;
570d7624
JB
1214 while (*p)
1215 {
199607e4 1216 /* Since we know the name is absolute, we can assume that each
c77d647e
JB
1217 element starts with a "/". */
1218
c77d647e 1219 /* "." and ".." are hairy. */
5e570b75 1220 if (IS_DIRECTORY_SEP (p[0])
c77d647e 1221 && p[1] == '.'
5e570b75 1222 && (IS_DIRECTORY_SEP (p[2])
c77d647e 1223 || p[2] == 0
5e570b75 1224 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
c77d647e 1225 || p[3] == 0))))
570d7624 1226 lose = 1;
214378ec
GM
1227 /* We want to replace multiple `/' in a row with a single
1228 slash. */
1229 else if (p > nm
1230 && IS_DIRECTORY_SEP (p[0])
1231 && IS_DIRECTORY_SEP (p[1]))
1232 lose = 1;
efdc16c9 1233
570d7624
JB
1234#ifdef VMS
1235 if (p[0] == '\\')
1236 lose = 1;
1237 if (p[0] == '/') {
1238 /* if dev:[dir]/, move nm to / */
1239 if (!slash && p > nm && (brack || colon)) {
1240 nm = (brack ? brack + 1 : colon + 1);
1241 lbrack = rbrack = 0;
1242 brack = 0;
1243 colon = 0;
1244 }
1245 slash = p;
1246 }
1247 if (p[0] == '-')
ad204e95 1248#ifdef NO_HYPHENS_IN_FILENAMES
570d7624
JB
1249 if (lbrack == rbrack)
1250 {
ad204e95
TTN
1251 /* Avoid clobbering negative version numbers. */
1252 if (dots < 2)
570d7624
JB
1253 p[0] = '_';
1254 }
1255 else
ad204e95 1256#endif /* NO_HYPHENS_IN_FILENAMES */
994a7262
RS
1257 if (lbrack > rbrack
1258 && ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<')
1259 && (p[1] == '.' || p[1] == ']' || p[1] == '>')))
570d7624 1260 lose = 1;
ad204e95 1261#ifdef NO_HYPHENS_IN_FILENAMES
570d7624
JB
1262 else
1263 p[0] = '_';
ad204e95 1264#endif /* NO_HYPHENS_IN_FILENAMES */
570d7624
JB
1265 /* count open brackets, reset close bracket pointer */
1266 if (p[0] == '[' || p[0] == '<')
1267 lbrack++, brack = 0;
1268 /* count close brackets, set close bracket pointer */
1269 if (p[0] == ']' || p[0] == '>')
1270 rbrack++, brack = p;
1271 /* detect ][ or >< */
1272 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1273 lose = 1;
1274 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1275 nm = p + 1, lose = 1;
1276 if (p[0] == ':' && (colon || slash))
1277 /* if dev1:[dir]dev2:, move nm to dev2: */
1278 if (brack)
1279 {
1280 nm = brack + 1;
1281 brack = 0;
1282 }
199607e4 1283 /* if /name/dev:, move nm to dev: */
570d7624
JB
1284 else if (slash)
1285 nm = slash + 1;
1286 /* if node::dev:, move colon following dev */
1287 else if (colon && colon[-1] == ':')
1288 colon = p;
1289 /* if dev1:dev2:, move nm to dev2: */
1290 else if (colon && colon[-1] != ':')
1291 {
1292 nm = colon + 1;
1293 colon = 0;
1294 }
1295 if (p[0] == ':' && !colon)
1296 {
1297 if (p[1] == ':')
1298 p++;
1299 colon = p;
1300 }
1301 if (lbrack == rbrack)
1302 if (p[0] == ';')
1303 dots = 2;
1304 else if (p[0] == '.')
1305 dots++;
1306#endif /* VMS */
1307 p++;
1308 }
1309 if (!lose)
1310 {
1311#ifdef VMS
1312 if (index (nm, '/'))
d7231f93
KH
1313 {
1314 nm = sys_translate_unix (nm);
2b046a72 1315 return make_specified_string (nm, -1, strlen (nm), multibyte);
d7231f93 1316 }
570d7624 1317#endif /* VMS */
199607e4
RS
1318#ifdef DOS_NT
1319 /* Make sure directories are all separated with / or \ as
1320 desired, but avoid allocation of a new string when not
1321 required. */
1322 CORRECT_DIR_SEPS (nm);
1323#ifdef WINDOWSNT
1324 if (IS_DIRECTORY_SEP (nm[1]))
1325 {
d5db4077 1326 if (strcmp (nm, SDATA (name)) != 0)
2b046a72 1327 name = make_specified_string (nm, -1, strlen (nm), multibyte);
199607e4
RS
1328 }
1329 else
1330#endif
1331 /* drive must be set, so this is okay */
d5db4077 1332 if (strcmp (nm - 2, SDATA (name)) != 0)
199607e4 1333 {
3f817c73
KH
1334 char temp[] = " :";
1335
2b046a72 1336 name = make_specified_string (nm, -1, p - nm, multibyte);
3f817c73
KH
1337 temp[0] = DRIVE_LETTER (drive);
1338 name = concat2 (build_string (temp), name);
199607e4
RS
1339 }
1340 return name;
1341#else /* not DOS_NT */
565f0b98 1342 if (strcmp (nm, SDATA (name)) == 0)
570d7624 1343 return name;
2b046a72 1344 return make_specified_string (nm, -1, strlen (nm), multibyte);
5e570b75 1345#endif /* not DOS_NT */
570d7624
JB
1346 }
1347 }
1348
199607e4
RS
1349 /* At this point, nm might or might not be an absolute file name. We
1350 need to expand ~ or ~user if present, otherwise prefix nm with
1351 default_directory if nm is not absolute, and finally collapse /./
1352 and /foo/../ sequences.
1353
1354 We set newdir to be the appropriate prefix if one is needed:
1355 - the relevant user directory if nm starts with ~ or ~user
1356 - the specified drive's working dir (DOS/NT only) if nm does not
1357 start with /
1358 - the value of default_directory.
1359
1360 Note that these prefixes are not guaranteed to be absolute (except
1361 for the working dir of a drive). Therefore, to ensure we always
1362 return an absolute name, if the final prefix is not absolute we
1363 append it to the current working directory. */
570d7624
JB
1364
1365 newdir = 0;
1366
1367 if (nm[0] == '~') /* prefix ~ */
c77d647e 1368 {
5e570b75 1369 if (IS_DIRECTORY_SEP (nm[1])
570d7624 1370#ifdef VMS
c77d647e 1371 || nm[1] == ':'
5e570b75 1372#endif /* VMS */
c77d647e
JB
1373 || nm[1] == 0) /* ~ by itself */
1374 {
8fe2123e
EZ
1375 Lisp_Object tem;
1376
c77d647e
JB
1377 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1378 newdir = (unsigned char *) "";
199607e4 1379 nm++;
8fe2123e
EZ
1380 /* egetenv may return a unibyte string, which will bite us since
1381 we expect the directory to be multibyte. */
1382 tem = build_string (newdir);
1383 if (!STRING_MULTIBYTE (tem))
1384 {
1385 hdir = DECODE_FILE (tem);
1386 newdir = SDATA (hdir);
1387 }
5e570b75 1388#ifdef DOS_NT
9a1dc3be 1389 collapse_newdir = 0;
4c3c22f3 1390#endif
570d7624 1391#ifdef VMS
c77d647e 1392 nm++; /* Don't leave the slash in nm. */
5e570b75 1393#endif /* VMS */
c77d647e
JB
1394 }
1395 else /* ~user/filename */
1396 {
5e570b75 1397 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
570d7624 1398#ifdef VMS
c77d647e 1399 && *p != ':'
5e570b75 1400#endif /* VMS */
c77d647e
JB
1401 ); p++);
1402 o = (unsigned char *) alloca (p - nm + 1);
1403 bcopy ((char *) nm, o, p - nm);
1404 o [p - nm] = 0;
1405
67c08d6c 1406 BLOCK_INPUT;
c77d647e 1407 pw = (struct passwd *) getpwnam (o + 1);
67c08d6c 1408 UNBLOCK_INPUT;
c77d647e
JB
1409 if (pw)
1410 {
1411 newdir = (unsigned char *) pw -> pw_dir;
570d7624 1412#ifdef VMS
c77d647e 1413 nm = p + 1; /* skip the terminator */
570d7624 1414#else
c77d647e 1415 nm = p;
199607e4 1416#ifdef DOS_NT
9a1dc3be 1417 collapse_newdir = 0;
199607e4 1418#endif
5e570b75 1419#endif /* VMS */
c77d647e 1420 }
e5d77022 1421
c77d647e
JB
1422 /* If we don't find a user of that name, leave the name
1423 unchanged; don't move nm forward to p. */
1424 }
1425 }
570d7624 1426
5e570b75 1427#ifdef DOS_NT
199607e4
RS
1428 /* On DOS and Windows, nm is absolute if a drive name was specified;
1429 use the drive's current directory as the prefix if needed. */
1430 if (!newdir && drive)
1431 {
1432 /* Get default directory if needed to make nm absolute. */
1433 if (!IS_DIRECTORY_SEP (nm[0]))
1434 {
1435 newdir = alloca (MAXPATHLEN + 1);
1436 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1437 newdir = NULL;
1438 }
1439 if (!newdir)
1440 {
1441 /* Either nm starts with /, or drive isn't mounted. */
1442 newdir = alloca (4);
f94988a7 1443 newdir[0] = DRIVE_LETTER (drive);
199607e4
RS
1444 newdir[1] = ':';
1445 newdir[2] = '/';
1446 newdir[3] = 0;
1447 }
1448 }
5e570b75 1449#endif /* DOS_NT */
199607e4
RS
1450
1451 /* Finally, if no prefix has been specified and nm is not absolute,
1452 then it must be expanded relative to default_directory. */
1453
34097368 1454 if (1
199607e4
RS
1455#ifndef DOS_NT
1456 /* /... alone is not absolute on DOS and Windows. */
34097368 1457 && !IS_DIRECTORY_SEP (nm[0])
199607e4
RS
1458#endif
1459#ifdef WINDOWSNT
34097368 1460 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
199607e4
RS
1461#endif
1462#ifdef VMS
1463 && !index (nm, ':')
1464#endif
570d7624
JB
1465 && !newdir)
1466 {
d5db4077 1467 newdir = SDATA (default_directory);
2b046a72 1468 multibyte |= STRING_MULTIBYTE (default_directory);
f0f95d31
RS
1469#ifdef DOS_NT
1470 /* Note if special escape prefix is present, but remove for now. */
1471 if (newdir[0] == '/' && newdir[1] == ':')
1472 {
1473 is_escaped = 1;
1474 newdir += 2;
1475 }
1476#endif
570d7624
JB
1477 }
1478
5e570b75 1479#ifdef DOS_NT
199607e4
RS
1480 if (newdir)
1481 {
1482 /* First ensure newdir is an absolute name. */
1483 if (
1484 /* Detect MSDOS file names with drive specifiers. */
1485 ! (IS_DRIVE (newdir[0])
1486 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1487#ifdef WINDOWSNT
1488 /* Detect Windows file names in UNC format. */
1489 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1490#endif
1491 )
1492 {
1493 /* Effectively, let newdir be (expand-file-name newdir cwd).
1494 Because of the admonition against calling expand-file-name
1495 when we have pointers into lisp strings, we accomplish this
1496 indirectly by prepending newdir to nm if necessary, and using
1497 cwd (or the wd of newdir's drive) as the new newdir. */
1498
c70a4df6 1499 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
199607e4
RS
1500 {
1501 drive = newdir[0];
1502 newdir += 2;
1503 }
1504 if (!IS_DIRECTORY_SEP (nm[0]))
1505 {
1506 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1507 file_name_as_directory (tmp, newdir);
1508 strcat (tmp, nm);
1509 nm = tmp;
1510 }
1511 newdir = alloca (MAXPATHLEN + 1);
1512 if (drive)
1513 {
1514 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1515 newdir = "/";
1516 }
1517 else
1518 getwd (newdir);
1519 }
1520
1521 /* Strip off drive name from prefix, if present. */
c70a4df6 1522 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
199607e4
RS
1523 {
1524 drive = newdir[0];
1525 newdir += 2;
1526 }
1527
1528 /* Keep only a prefix from newdir if nm starts with slash
82330e7f 1529 (//server/share for UNC, nothing otherwise). */
9a1dc3be 1530 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
199607e4
RS
1531 {
1532#ifdef WINDOWSNT
1533 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1534 {
1535 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1536 p = newdir + 2;
1537 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1538 p++;
1539 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1540 *p = 0;
1541 }
1542 else
1543#endif
1544 newdir = "";
1545 }
1546 }
5e570b75 1547#endif /* DOS_NT */
199607e4
RS
1548
1549 if (newdir)
bfb61299 1550 {
57676091 1551 /* Get rid of any slash at the end of newdir, unless newdir is
f0f95d31 1552 just / or // (an incomplete UNC name). */
199607e4 1553 length = strlen (newdir);
f0f95d31 1554 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
57676091
RS
1555#ifdef WINDOWSNT
1556 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1557#endif
1558 )
bfb61299
JB
1559 {
1560 unsigned char *temp = (unsigned char *) alloca (length);
1561 bcopy (newdir, temp, length - 1);
1562 temp[length - 1] = 0;
1563 newdir = temp;
1564 }
1565 tlen = length + 1;
1566 }
1567 else
1568 tlen = 0;
570d7624 1569
bfb61299
JB
1570 /* Now concatenate the directory and name to new space in the stack frame */
1571 tlen += strlen (nm) + 1;
5e570b75 1572#ifdef DOS_NT
f0f95d31
RS
1573 /* Reserve space for drive specifier and escape prefix, since either
1574 or both may need to be inserted. (The Microsoft x86 compiler
5e570b75 1575 produces incorrect code if the following two lines are combined.) */
f0f95d31
RS
1576 target = (unsigned char *) alloca (tlen + 4);
1577 target += 4;
5e570b75 1578#else /* not DOS_NT */
570d7624 1579 target = (unsigned char *) alloca (tlen);
5e570b75 1580#endif /* not DOS_NT */
570d7624
JB
1581 *target = 0;
1582
1583 if (newdir)
1584 {
1585#ifndef VMS
5e570b75 1586 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
f5321b5c 1587 {
3ea2d8b2 1588#ifdef DOS_NT
f5321b5c
RS
1589 /* If newdir is effectively "C:/", then the drive letter will have
1590 been stripped and newdir will be "/". Concatenating with an
1591 absolute directory in nm produces "//", which will then be
1592 incorrectly treated as a network share. Ignore newdir in
1593 this case (keeping the drive letter). */
efdc16c9 1594 if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0])
f5321b5c
RS
1595 && newdir[1] == '\0'))
1596#endif
1597 strcpy (target, newdir);
1598 }
570d7624
JB
1599 else
1600#endif
c77d647e 1601 file_name_as_directory (target, newdir);
570d7624
JB
1602 }
1603
1604 strcat (target, nm);
1605#ifdef VMS
1606 if (index (target, '/'))
1607 strcpy (target, sys_translate_unix (target));
1608#endif /* VMS */
1609
199607e4
RS
1610 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1611
214378ec
GM
1612 /* Now canonicalize by removing `//', `/.' and `/foo/..' if they
1613 appear. */
570d7624
JB
1614
1615 p = target;
1616 o = target;
1617
1618 while (*p)
1619 {
1620#ifdef VMS
1621 if (*p != ']' && *p != '>' && *p != '-')
1622 {
1623 if (*p == '\\')
1624 p++;
1625 *o++ = *p++;
1626 }
1627 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1628 /* brackets are offset from each other by 2 */
1629 {
1630 p += 2;
1631 if (*p != '.' && *p != '-' && o[-1] != '.')
1632 /* convert [foo][bar] to [bar] */
1633 while (o[-1] != '[' && o[-1] != '<')
1634 o--;
1635 else if (*p == '-' && *o != '.')
1636 *--p = '.';
1637 }
994a7262
RS
1638 else if (p[0] == '-' && o[-1] == '.'
1639 && (p[1] == '.' || p[1] == ']' || p[1] == '>'))
570d7624
JB
1640 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1641 {
1642 do
1643 o--;
1644 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
5e570b75 1645 if (p[1] == '.') /* foo.-.bar ==> bar. */
570d7624
JB
1646 p += 2;
1647 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1648 p++, o--;
1649 /* else [foo.-] ==> [-] */
1650 }
1651 else
1652 {
ad204e95 1653#ifdef NO_HYPHENS_IN_FILENAMES
994a7262
RS
1654 if (*p == '-'
1655 && o[-1] != '[' && o[-1] != '<' && o[-1] != '.'
1656 && p[1] != ']' && p[1] != '>' && p[1] != '.')
570d7624 1657 *p = '_';
ad204e95 1658#endif /* NO_HYPHENS_IN_FILENAMES */
570d7624
JB
1659 *o++ = *p++;
1660 }
1661#else /* not VMS */
5e570b75
RS
1662 if (!IS_DIRECTORY_SEP (*p))
1663 {
570d7624
JB
1664 *o++ = *p++;
1665 }
b8f7f3be 1666 else if (p[1] == '.'
5e570b75 1667 && (IS_DIRECTORY_SEP (p[2])
c77d647e
JB
1668 || p[2] == 0))
1669 {
1670 /* If "/." is the entire filename, keep the "/". Otherwise,
1671 just delete the whole "/.". */
1672 if (o == target && p[2] == '\0')
1673 *o++ = *p;
1674 p += 2;
1675 }
b8f7f3be 1676 else if (p[1] == '.' && p[2] == '.'
aa4060b9
EZ
1677 /* `/../' is the "superroot" on certain file systems.
1678 Turned off on DOS_NT systems because they have no
1679 "superroot" and because this causes us to produce
1680 file names like "d:/../foo" which fail file-related
1681 functions of the underlying OS. (To reproduce, try a
1682 long series of "../../" in default_directory, longer
1683 than the number of levels from the root.) */
1684#ifndef DOS_NT
570d7624 1685 && o != target
aa4060b9 1686#endif
5e570b75 1687 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
570d7624 1688 {
5e570b75 1689 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
570d7624 1690 ;
795de720
RS
1691 /* Keep initial / only if this is the whole name. */
1692 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
51b1d12e 1693 ++o;
570d7624
JB
1694 p += 3;
1695 }
b8f7f3be
SM
1696 else if (p > target && IS_DIRECTORY_SEP (p[1]))
1697 /* Collapse multiple `/' in a row. */
1698 p++;
570d7624 1699 else
5e570b75 1700 {
570d7624
JB
1701 *o++ = *p++;
1702 }
1703#endif /* not VMS */
1704 }
1705
5e570b75 1706#ifdef DOS_NT
199607e4 1707 /* At last, set drive name. */
5e570b75 1708#ifdef WINDOWSNT
199607e4
RS
1709 /* Except for network file name. */
1710 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
5e570b75 1711#endif /* WINDOWSNT */
4c3c22f3 1712 {
199607e4 1713 if (!drive) abort ();
4c3c22f3 1714 target -= 2;
f94988a7 1715 target[0] = DRIVE_LETTER (drive);
4c3c22f3
RS
1716 target[1] = ':';
1717 }
f0f95d31
RS
1718 /* Reinsert the escape prefix if required. */
1719 if (is_escaped)
1720 {
1721 target -= 2;
1722 target[0] = '/';
1723 target[1] = ':';
1724 }
199607e4 1725 CORRECT_DIR_SEPS (target);
5e570b75 1726#endif /* DOS_NT */
4c3c22f3 1727
2b046a72 1728 result = make_specified_string (target, -1, o - target, multibyte);
beb402de
KG
1729
1730 /* Again look to see if the file name has special constructs in it
1731 and perhaps call the corresponding file handler. This is needed
1732 for filenames such as "/foo/../user@host:/bar/../baz". Expanding
1733 the ".." component gives us "/user@host:/bar/../baz" which needs
1734 to be expanded again. */
1735 handler = Ffind_file_name_handler (result, Qexpand_file_name);
1736 if (!NILP (handler))
1737 return call3 (handler, Qexpand_file_name, result, default_directory);
1738
1739 return result;
570d7624 1740}
5e570b75 1741
4887597a
EZ
1742#if 0
1743/* PLEASE DO NOT DELETE THIS COMMENTED-OUT VERSION!
1744 This is the old version of expand-file-name, before it was thoroughly
1745 rewritten for Emacs 10.31. We leave this version here commented-out,
1746 because the code is very complex and likely to have subtle bugs. If
1747 bugs _are_ found, it might be of interest to look at the old code and
1748 see what did it do in the relevant situation.
1749
1750 Don't remove this code: it's true that it will be accessible via CVS,
1751 but a few years from deletion, people will forget it is there. */
1752
1753/* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1754DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1755 "Convert FILENAME to absolute, and canonicalize it.\n\
1756Second arg DEFAULT is directory to start with if FILENAME is relative\n\
c70a4df6 1757\(does not start with slash); if DEFAULT is nil or missing,\n\
4887597a
EZ
1758the current buffer's value of default-directory is used.\n\
1759Filenames containing `.' or `..' as components are simplified;\n\
1760initial `~/' expands to your home directory.\n\
1761See also the function `substitute-in-file-name'.")
1762 (name, defalt)
1763 Lisp_Object name, defalt;
1764{
1765 unsigned char *nm;
1766
1767 register unsigned char *newdir, *p, *o;
1768 int tlen;
1769 unsigned char *target;
1770 struct passwd *pw;
1771 int lose;
1772#ifdef VMS
1773 unsigned char * colon = 0;
1774 unsigned char * close = 0;
1775 unsigned char * slash = 0;
1776 unsigned char * brack = 0;
1777 int lbrack = 0, rbrack = 0;
1778 int dots = 0;
1779#endif /* VMS */
1780
b7826503 1781 CHECK_STRING (name);
4887597a
EZ
1782
1783#ifdef VMS
1784 /* Filenames on VMS are always upper case. */
1785 name = Fupcase (name);
1786#endif
1787
d5db4077 1788 nm = SDATA (name);
4887597a
EZ
1789
1790 /* If nm is absolute, flush ...// and detect /./ and /../.
1791 If no /./ or /../ we can return right away. */
1792 if (
1793 nm[0] == '/'
1794#ifdef VMS
1795 || index (nm, ':')
1796#endif /* VMS */
1797 )
1798 {
1799 p = nm;
1800 lose = 0;
1801 while (*p)
1802 {
1803 if (p[0] == '/' && p[1] == '/'
1804#ifdef APOLLO
1805 /* // at start of filename is meaningful on Apollo system. */
1806 && nm != p
1807#endif /* APOLLO */
1808 )
1809 nm = p + 1;
1810 if (p[0] == '/' && p[1] == '~')
1811 nm = p + 1, lose = 1;
1812 if (p[0] == '/' && p[1] == '.'
1813 && (p[2] == '/' || p[2] == 0
1814 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1815 lose = 1;
1816#ifdef VMS
1817 if (p[0] == '\\')
1818 lose = 1;
1819 if (p[0] == '/') {
1820 /* if dev:[dir]/, move nm to / */
1821 if (!slash && p > nm && (brack || colon)) {
1822 nm = (brack ? brack + 1 : colon + 1);
1823 lbrack = rbrack = 0;
1824 brack = 0;
1825 colon = 0;
1826 }
1827 slash = p;
1828 }
1829 if (p[0] == '-')
1830#ifndef VMS4_4
1831 /* VMS pre V4.4,convert '-'s in filenames. */
1832 if (lbrack == rbrack)
1833 {
1834 if (dots < 2) /* this is to allow negative version numbers */
1835 p[0] = '_';
1836 }
1837 else
1838#endif /* VMS4_4 */
994a7262
RS
1839 if (lbrack > rbrack
1840 && ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<')
1841 && (p[1] == '.' || p[1] == ']' || p[1] == '>')))
4887597a
EZ
1842 lose = 1;
1843#ifndef VMS4_4
1844 else
1845 p[0] = '_';
1846#endif /* VMS4_4 */
1847 /* count open brackets, reset close bracket pointer */
1848 if (p[0] == '[' || p[0] == '<')
1849 lbrack++, brack = 0;
1850 /* count close brackets, set close bracket pointer */
1851 if (p[0] == ']' || p[0] == '>')
1852 rbrack++, brack = p;
1853 /* detect ][ or >< */
1854 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1855 lose = 1;
1856 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1857 nm = p + 1, lose = 1;
1858 if (p[0] == ':' && (colon || slash))
1859 /* if dev1:[dir]dev2:, move nm to dev2: */
1860 if (brack)
1861 {
1862 nm = brack + 1;
1863 brack = 0;
1864 }
1865 /* If /name/dev:, move nm to dev: */
1866 else if (slash)
1867 nm = slash + 1;
1868 /* If node::dev:, move colon following dev */
1869 else if (colon && colon[-1] == ':')
1870 colon = p;
1871 /* If dev1:dev2:, move nm to dev2: */
1872 else if (colon && colon[-1] != ':')
1873 {
1874 nm = colon + 1;
1875 colon = 0;
1876 }
1877 if (p[0] == ':' && !colon)
1878 {
1879 if (p[1] == ':')
1880 p++;
1881 colon = p;
1882 }
1883 if (lbrack == rbrack)
1884 if (p[0] == ';')
1885 dots = 2;
1886 else if (p[0] == '.')
1887 dots++;
1888#endif /* VMS */
1889 p++;
1890 }
1891 if (!lose)
1892 {
1893#ifdef VMS
1894 if (index (nm, '/'))
1895 return build_string (sys_translate_unix (nm));
1896#endif /* VMS */
d5db4077 1897 if (nm == SDATA (name))
4887597a
EZ
1898 return name;
1899 return build_string (nm);
1900 }
1901 }
1902
1903 /* Now determine directory to start with and put it in NEWDIR */
1904
1905 newdir = 0;
1906
1907 if (nm[0] == '~') /* prefix ~ */
1908 if (nm[1] == '/'
1909#ifdef VMS
1910 || nm[1] == ':'
1911#endif /* VMS */
1912 || nm[1] == 0)/* ~/filename */
1913 {
1914 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1915 newdir = (unsigned char *) "";
1916 nm++;
1917#ifdef VMS
1918 nm++; /* Don't leave the slash in nm. */
1919#endif /* VMS */
1920 }
1921 else /* ~user/filename */
1922 {
1923 /* Get past ~ to user */
1924 unsigned char *user = nm + 1;
1925 /* Find end of name. */
1926 unsigned char *ptr = (unsigned char *) index (user, '/');
1927 int len = ptr ? ptr - user : strlen (user);
1928#ifdef VMS
1929 unsigned char *ptr1 = index (user, ':');
1930 if (ptr1 != 0 && ptr1 - user < len)
1931 len = ptr1 - user;
1932#endif /* VMS */
1933 /* Copy the user name into temp storage. */
1934 o = (unsigned char *) alloca (len + 1);
1935 bcopy ((char *) user, o, len);
1936 o[len] = 0;
1937
1938 /* Look up the user name. */
67c08d6c 1939 BLOCK_INPUT;
4887597a 1940 pw = (struct passwd *) getpwnam (o + 1);
67c08d6c 1941 UNBLOCK_INPUT;
4887597a
EZ
1942 if (!pw)
1943 error ("\"%s\" isn't a registered user", o + 1);
1944
1945 newdir = (unsigned char *) pw->pw_dir;
1946
1947 /* Discard the user name from NM. */
1948 nm += len;
1949 }
1950
1951 if (nm[0] != '/'
1952#ifdef VMS
1953 && !index (nm, ':')
1954#endif /* not VMS */
1955 && !newdir)
1956 {
1957 if (NILP (defalt))
1958 defalt = current_buffer->directory;
b7826503 1959 CHECK_STRING (defalt);
d5db4077 1960 newdir = SDATA (defalt);
4887597a
EZ
1961 }
1962
1963 /* Now concatenate the directory and name to new space in the stack frame */
1964
1965 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1966 target = (unsigned char *) alloca (tlen);
1967 *target = 0;
1968
1969 if (newdir)
1970 {
1971#ifndef VMS
1972 if (nm[0] == 0 || nm[0] == '/')
1973 strcpy (target, newdir);
1974 else
1975#endif
1976 file_name_as_directory (target, newdir);
1977 }
1978
1979 strcat (target, nm);
1980#ifdef VMS
1981 if (index (target, '/'))
1982 strcpy (target, sys_translate_unix (target));
1983#endif /* VMS */
1984
1985 /* Now canonicalize by removing /. and /foo/.. if they appear */
1986
1987 p = target;
1988 o = target;
1989
1990 while (*p)
1991 {
1992#ifdef VMS
1993 if (*p != ']' && *p != '>' && *p != '-')
1994 {
1995 if (*p == '\\')
1996 p++;
1997 *o++ = *p++;
1998 }
1999 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
2000 /* brackets are offset from each other by 2 */
2001 {
2002 p += 2;
2003 if (*p != '.' && *p != '-' && o[-1] != '.')
2004 /* convert [foo][bar] to [bar] */
2005 while (o[-1] != '[' && o[-1] != '<')
2006 o--;
2007 else if (*p == '-' && *o != '.')
2008 *--p = '.';
2009 }
994a7262
RS
2010 else if (p[0] == '-' && o[-1] == '.'
2011 && (p[1] == '.' || p[1] == ']' || p[1] == '>'))
4887597a
EZ
2012 /* flush .foo.- ; leave - if stopped by '[' or '<' */
2013 {
2014 do
2015 o--;
2016 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
2017 if (p[1] == '.') /* foo.-.bar ==> bar. */
2018 p += 2;
2019 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
2020 p++, o--;
2021 /* else [foo.-] ==> [-] */
2022 }
2023 else
2024 {
2025#ifndef VMS4_4
994a7262
RS
2026 if (*p == '-'
2027 && o[-1] != '[' && o[-1] != '<' && o[-1] != '.'
2028 && p[1] != ']' && p[1] != '>' && p[1] != '.')
4887597a
EZ
2029 *p = '_';
2030#endif /* VMS4_4 */
2031 *o++ = *p++;
2032 }
2033#else /* not VMS */
2034 if (*p != '/')
2035 {
2036 *o++ = *p++;
2037 }
2038 else if (!strncmp (p, "//", 2)
2039#ifdef APOLLO
2040 /* // at start of filename is meaningful in Apollo system. */
2041 && o != target
2042#endif /* APOLLO */
2043 )
2044 {
2045 o = target;
2046 p++;
2047 }
994a7262
RS
2048 else if (p[0] == '/' && p[1] == '.'
2049 && (p[2] == '/' || p[2] == 0))
4887597a
EZ
2050 p += 2;
2051 else if (!strncmp (p, "/..", 3)
2052 /* `/../' is the "superroot" on certain file systems. */
2053 && o != target
2054 && (p[3] == '/' || p[3] == 0))
2055 {
2056 while (o != target && *--o != '/')
2057 ;
2058#ifdef APOLLO
2059 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
2060 ++o;
2061 else
2062#endif /* APOLLO */
2063 if (o == target && *o == '/')
2064 ++o;
2065 p += 3;
2066 }
2067 else
2068 {
2069 *o++ = *p++;
2070 }
2071#endif /* not VMS */
2072 }
2073
2074 return make_string (target, o - target);
2075}
2076#endif
570d7624 2077\f
c70a4df6
SM
2078/* If /~ or // appears, discard everything through first slash. */
2079static int
2080file_name_absolute_p (filename)
2081 const unsigned char *filename;
2082{
2083 return
2084 (IS_DIRECTORY_SEP (*filename) || *filename == '~'
2085#ifdef VMS
2086 /* ??? This criterion is probably wrong for '<'. */
2087 || index (filename, ':') || index (filename, '<')
2088 || (*filename == '[' && (filename[1] != '-'
2089 || (filename[2] != '.' && filename[2] != ']'))
2090 && filename[1] != '.')
2091#endif /* VMS */
2092#ifdef DOS_NT
2093 || (IS_DRIVE (*filename) && IS_DEVICE_SEP (filename[1])
2094 && IS_DIRECTORY_SEP (filename[2]))
2095#endif
2096 );
2097}
2098
2099static unsigned char *
2100search_embedded_absfilename (nm, endp)
2101 unsigned char *nm, *endp;
2102{
2103 unsigned char *p, *s;
2104
2105 for (p = nm + 1; p < endp; p++)
2106 {
2107 if ((0
2108#ifdef VMS
2109 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
2110#endif /* VMS */
2111 || IS_DIRECTORY_SEP (p[-1]))
2112 && file_name_absolute_p (p)
2113#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
2114 /* // at start of file name is meaningful in Apollo,
2115 WindowsNT and Cygwin systems. */
f34574c6 2116 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm)
c70a4df6
SM
2117#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
2118 )
2119 {
2120 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
2121#ifdef VMS
2122 && *s != ':'
2123#endif /* VMS */
2124 ); s++);
2125 if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
2126 {
2127 unsigned char *o = alloca (s - p + 1);
2128 struct passwd *pw;
2129 bcopy (p, o, s - p);
2130 o [s - p] = 0;
2131
2132 /* If we have ~user and `user' exists, discard
2133 everything up to ~. But if `user' does not exist, leave
2134 ~user alone, it might be a literal file name. */
67c08d6c
YM
2135 BLOCK_INPUT;
2136 pw = getpwnam (o + 1);
2137 UNBLOCK_INPUT;
2138 if (pw)
c70a4df6 2139 return p;
c70a4df6
SM
2140 }
2141 else
2142 return p;
2143 }
2144 }
2145 return NULL;
2146}
2147
570d7624 2148DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
8c1a1077
PJ
2149 Ssubstitute_in_file_name, 1, 1, 0,
2150 doc: /* Substitute environment variables referred to in FILENAME.
2151`$FOO' where FOO is an environment variable name means to substitute
2152the value of that variable. The variable name should be terminated
2153with a character not a letter, digit or underscore; otherwise, enclose
2154the entire variable name in braces.
2155If `/~' appears, all of FILENAME through that `/' is discarded.
2156
2157On VMS, `$' substitution is not done; this function does little and only
2158duplicates what `expand-file-name' does. */)
2159 (filename)
3b7f6e60 2160 Lisp_Object filename;
570d7624
JB
2161{
2162 unsigned char *nm;
2163
2164 register unsigned char *s, *p, *o, *x, *endp;
6bbd7a29 2165 unsigned char *target = NULL;
570d7624
JB
2166 int total = 0;
2167 int substituted = 0;
2168 unsigned char *xnm;
8ce069f5 2169 Lisp_Object handler;
570d7624 2170
b7826503 2171 CHECK_STRING (filename);
570d7624 2172
8ce069f5
RS
2173 /* If the file name has special constructs in it,
2174 call the corresponding file handler. */
3b7f6e60 2175 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
8ce069f5 2176 if (!NILP (handler))
3b7f6e60 2177 return call2 (handler, Qsubstitute_in_file_name, filename);
8ce069f5 2178
d5db4077 2179 nm = SDATA (filename);
199607e4
RS
2180#ifdef DOS_NT
2181 nm = strcpy (alloca (strlen (nm) + 1), nm);
2182 CORRECT_DIR_SEPS (nm);
d5db4077 2183 substituted = (strcmp (nm, SDATA (filename)) != 0);
a5a1cc06 2184#endif
d5db4077 2185 endp = nm + SBYTES (filename);
570d7624 2186
82330e7f 2187 /* If /~ or // appears, discard everything through first slash. */
c70a4df6
SM
2188 p = search_embedded_absfilename (nm, endp);
2189 if (p)
2190 /* Start over with the new string, so we check the file-name-handler
2191 again. Important with filenames like "/home/foo//:/hello///there"
2192 which whould substitute to "/:/hello///there" rather than "/there". */
2193 return Fsubstitute_in_file_name
da5b5435
JR
2194 (make_specified_string (p, -1, endp - p,
2195 STRING_MULTIBYTE (filename)));
570d7624 2196
570d7624 2197#ifdef VMS
c70a4df6 2198 return filename;
570d7624
JB
2199#else
2200
2201 /* See if any variables are substituted into the string
2202 and find the total length of their values in `total' */
2203
2204 for (p = nm; p != endp;)
2205 if (*p != '$')
2206 p++;
2207 else
2208 {
2209 p++;
2210 if (p == endp)
2211 goto badsubst;
2212 else if (*p == '$')
2213 {
2214 /* "$$" means a single "$" */
2215 p++;
2216 total -= 1;
2217 substituted = 1;
2218 continue;
2219 }
2220 else if (*p == '{')
2221 {
2222 o = ++p;
2223 while (p != endp && *p != '}') p++;
2224 if (*p != '}') goto missingclose;
2225 s = p;
2226 }
2227 else
2228 {
2229 o = p;
2230 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2231 s = p;
2232 }
2233
2234 /* Copy out the variable name */
2235 target = (unsigned char *) alloca (s - o + 1);
2236 strncpy (target, o, s - o);
2237 target[s - o] = 0;
5e570b75 2238#ifdef DOS_NT
4c3c22f3 2239 strupr (target); /* $home == $HOME etc. */
5e570b75 2240#endif /* DOS_NT */
570d7624
JB
2241
2242 /* Get variable value */
2243 o = (unsigned char *) egetenv (target);
8d2ced53 2244 if (o)
3efaadb7
SM
2245 { /* Eight-bit chars occupy upto 2 bytes in multibyte. */
2246 total += strlen (o) * (STRING_MULTIBYTE (filename) ? 2 : 1);
8d2ced53
SM
2247 substituted = 1;
2248 }
2249 else if (*p == '}')
2250 goto badvar;
570d7624
JB
2251 }
2252
2253 if (!substituted)
3b7f6e60 2254 return filename;
570d7624
JB
2255
2256 /* If substitution required, recopy the string and do it */
2257 /* Make space in stack frame for the new copy */
d5db4077 2258 xnm = (unsigned char *) alloca (SBYTES (filename) + total + 1);
570d7624
JB
2259 x = xnm;
2260
2261 /* Copy the rest of the name through, replacing $ constructs with values */
2262 for (p = nm; *p;)
2263 if (*p != '$')
2264 *x++ = *p++;
2265 else
2266 {
2267 p++;
2268 if (p == endp)
2269 goto badsubst;
2270 else if (*p == '$')
2271 {
2272 *x++ = *p++;
2273 continue;
2274 }
2275 else if (*p == '{')
2276 {
2277 o = ++p;
2278 while (p != endp && *p != '}') p++;
2279 if (*p != '}') goto missingclose;
2280 s = p++;
2281 }
2282 else
2283 {
2284 o = p;
2285 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2286 s = p;
2287 }
2288
2289 /* Copy out the variable name */
2290 target = (unsigned char *) alloca (s - o + 1);
2291 strncpy (target, o, s - o);
2292 target[s - o] = 0;
5e570b75 2293#ifdef DOS_NT
4c3c22f3 2294 strupr (target); /* $home == $HOME etc. */
5e570b75 2295#endif /* DOS_NT */
570d7624
JB
2296
2297 /* Get variable value */
2298 o = (unsigned char *) egetenv (target);
570d7624 2299 if (!o)
8d2ced53
SM
2300 {
2301 *x++ = '$';
2302 strcpy (x, target); x+= strlen (target);
2303 }
da5b5435 2304 else if (STRING_MULTIBYTE (filename))
60d67b83 2305 {
da5b5435
JR
2306 /* If the original string is multibyte,
2307 convert what we substitute into multibyte. */
2308 while (*o)
2309 {
2310 int c = unibyte_char_to_multibyte (*o++);
2311 x += CHAR_STRING (c, x);
2312 }
60d67b83
RS
2313 }
2314 else
2315 {
2316 strcpy (x, o);
2317 x += strlen (o);
2318 }
570d7624
JB
2319 }
2320
2321 *x = 0;
2322
82330e7f 2323 /* If /~ or // appears, discard everything through first slash. */
c70a4df6
SM
2324 while ((p = search_embedded_absfilename (xnm, x)))
2325 /* This time we do not start over because we've already expanded envvars
2326 and replaced $$ with $. Maybe we should start over as well, but we'd
2327 need to quote some $ to $$ first. */
2328 xnm = p;
570d7624 2329
da5b5435 2330 return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename));
570d7624
JB
2331
2332 badsubst:
2333 error ("Bad format environment-variable substitution");
2334 missingclose:
2335 error ("Missing \"}\" in environment-variable substitution");
2336 badvar:
2337 error ("Substituting nonexistent environment variable \"%s\"", target);
2338
2339 /* NOTREACHED */
2340#endif /* not VMS */
6bbd7a29 2341 return Qnil;
570d7624
JB
2342}
2343\f
067ffa38 2344/* A slightly faster and more convenient way to get
298b760e 2345 (directory-file-name (expand-file-name FOO)). */
067ffa38 2346
570d7624
JB
2347Lisp_Object
2348expand_and_dir_to_file (filename, defdir)
2349 Lisp_Object filename, defdir;
2350{
199607e4 2351 register Lisp_Object absname;
570d7624 2352
199607e4 2353 absname = Fexpand_file_name (filename, defdir);
570d7624
JB
2354#ifdef VMS
2355 {
d5db4077 2356 register int c = SREF (absname, SBYTES (absname) - 1);
570d7624 2357 if (c == ':' || c == ']' || c == '>')
199607e4 2358 absname = Fdirectory_file_name (absname);
570d7624
JB
2359 }
2360#else
199607e4 2361 /* Remove final slash, if any (unless this is the root dir).
570d7624 2362 stat behaves differently depending! */
d5db4077
KR
2363 if (SCHARS (absname) > 1
2364 && IS_DIRECTORY_SEP (SREF (absname, SBYTES (absname) - 1))
2365 && !IS_DEVICE_SEP (SREF (absname, SBYTES (absname)-2)))
ddc61f46 2366 /* We cannot take shortcuts; they might be wrong for magic file names. */
199607e4 2367 absname = Fdirectory_file_name (absname);
570d7624 2368#endif
199607e4 2369 return absname;
570d7624
JB
2370}
2371\f
3ed15d97
RS
2372/* Signal an error if the file ABSNAME already exists.
2373 If INTERACTIVE is nonzero, ask the user whether to proceed,
2374 and bypass the error if the user says to go ahead.
2375 QUERYSTRING is a name for the action that is being considered
2376 to alter the file.
de1d0127 2377
3ed15d97 2378 *STATPTR is used to store the stat information if the file exists.
de1d0127 2379 If the file does not exist, STATPTR->st_mode is set to 0.
b8b29dc9
RS
2380 If STATPTR is null, we don't store into it.
2381
2382 If QUICK is nonzero, we ask for y or n, not yes or no. */
3ed15d97 2383
c4df73f9 2384void
b8b29dc9 2385barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
570d7624
JB
2386 Lisp_Object absname;
2387 unsigned char *querystring;
2388 int interactive;
3ed15d97 2389 struct stat *statptr;
b8b29dc9 2390 int quick;
570d7624 2391{
643c73b9 2392 register Lisp_Object tem, encoded_filename;
4018b5ef 2393 struct stat statbuf;
570d7624
JB
2394 struct gcpro gcpro1;
2395
643c73b9
RS
2396 encoded_filename = ENCODE_FILE (absname);
2397
4018b5ef
RS
2398 /* stat is a good way to tell whether the file exists,
2399 regardless of what access permissions it has. */
f72b5416 2400 if (lstat (SDATA (encoded_filename), &statbuf) >= 0)
570d7624
JB
2401 {
2402 if (! interactive)
24b1ddad
KS
2403 xsignal2 (Qfile_already_exists,
2404 build_string ("File already exists"), absname);
570d7624 2405 GCPRO1 (absname);
67e8e2b8
RS
2406 tem = format2 ("File %s already exists; %s anyway? ",
2407 absname, build_string (querystring));
b8b29dc9
RS
2408 if (quick)
2409 tem = Fy_or_n_p (tem);
2410 else
2411 tem = do_yes_or_no_p (tem);
570d7624 2412 UNGCPRO;
265a9e55 2413 if (NILP (tem))
24b1ddad
KS
2414 xsignal2 (Qfile_already_exists,
2415 build_string ("File already exists"), absname);
3ed15d97
RS
2416 if (statptr)
2417 *statptr = statbuf;
2418 }
2419 else
2420 {
2421 if (statptr)
2422 statptr->st_mode = 0;
570d7624
JB
2423 }
2424 return;
2425}
2426
795c20df 2427DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5,
7c0f6118 2428 "fCopy file: \nGCopy %s to file: \np\nP",
8c1a1077
PJ
2429 doc: /* Copy FILE to NEWNAME. Both args must be strings.
2430If NEWNAME names a directory, copy FILE there.
795c20df
CY
2431
2432This function always sets the file modes of the output file to match
2433the input file.
2434
2435The optional third argument OK-IF-ALREADY-EXISTS specifies what to do
2436if file NEWNAME already exists. If OK-IF-ALREADY-EXISTS is nil, we
2437signal a `file-already-exists' error without overwriting. If
2438OK-IF-ALREADY-EXISTS is a number, we request confirmation from the user
2439about overwriting; this is what happens in interactive use with M-x.
2440Any other value for OK-IF-ALREADY-EXISTS means to overwrite the
2441existing file.
c50f15d0 2442
7f08b80e 2443Fourth arg KEEP-TIME non-nil means give the output file the same
8c1a1077 2444last-modified time as the old one. (This works on only some systems.)
c50f15d0 2445
7fce7dfe
EZ
2446A prefix arg makes KEEP-TIME non-nil.
2447
586702ce
RS
2448If PRESERVE-UID-GID is non-nil, we try to transfer the
2449uid and gid of FILE to NEWNAME. */)
795c20df
CY
2450 (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid)
2451 Lisp_Object file, newname, ok_if_already_exists, keep_time;
586702ce 2452 Lisp_Object preserve_uid_gid;
570d7624
JB
2453{
2454 int ifd, ofd, n;
2455 char buf[16 * 1024];
3ed15d97 2456 struct stat st, out_st;
32f4334d 2457 Lisp_Object handler;
b1d1b865 2458 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
aed13378 2459 int count = SPECPDL_INDEX ();
f73b0ada 2460 int input_file_statable_p;
b1d1b865 2461 Lisp_Object encoded_file, encoded_newname;
570d7624 2462
b1d1b865
RS
2463 encoded_file = encoded_newname = Qnil;
2464 GCPRO4 (file, newname, encoded_file, encoded_newname);
b7826503
PJ
2465 CHECK_STRING (file);
2466 CHECK_STRING (newname);
b1d1b865 2467
a9d14e54 2468 if (!NILP (Ffile_directory_p (newname)))
dcdbbb5d 2469 newname = Fexpand_file_name (Ffile_name_nondirectory (file), newname);
a9d14e54
GM
2470 else
2471 newname = Fexpand_file_name (newname, Qnil);
2472
3b7f6e60 2473 file = Fexpand_file_name (file, Qnil);
32f4334d 2474
0bf2eed2 2475 /* If the input file name has special constructs in it,
32f4334d 2476 call the corresponding file handler. */
3b7f6e60 2477 handler = Ffind_file_name_handler (file, Qcopy_file);
0bf2eed2 2478 /* Likewise for output file name. */
51cf6d37 2479 if (NILP (handler))
49307295 2480 handler = Ffind_file_name_handler (newname, Qcopy_file);
32f4334d 2481 if (!NILP (handler))
3b7f6e60 2482 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
8ca6602c 2483 ok_if_already_exists, keep_time));
32f4334d 2484
b1d1b865
RS
2485 encoded_file = ENCODE_FILE (file);
2486 encoded_newname = ENCODE_FILE (newname);
2487
265a9e55 2488 if (NILP (ok_if_already_exists)
93c30b5f 2489 || INTEGERP (ok_if_already_exists))
2f868094 2490 barf_or_query_if_file_exists (newname, "copy to it",
b8b29dc9 2491 INTEGERP (ok_if_already_exists), &out_st, 0);
d5db4077 2492 else if (stat (SDATA (encoded_newname), &out_st) < 0)
3ed15d97 2493 out_st.st_mode = 0;
570d7624 2494
e8691c59 2495#ifdef WINDOWSNT
d5db4077 2496 if (!CopyFile (SDATA (encoded_file),
efdc16c9 2497 SDATA (encoded_newname),
e8691c59
GM
2498 FALSE))
2499 report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
8b53dc06
JR
2500 /* CopyFile retains the timestamp by default. */
2501 else if (NILP (keep_time))
e8691c59
GM
2502 {
2503 EMACS_TIME now;
ad497129
JR
2504 DWORD attributes;
2505 char * filename;
2506
e8691c59 2507 EMACS_GET_TIME (now);
d5db4077 2508 filename = SDATA (encoded_newname);
ad497129
JR
2509
2510 /* Ensure file is writable while its modified time is set. */
2511 attributes = GetFileAttributes (filename);
02cca86b 2512 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
ad497129
JR
2513 if (set_file_times (filename, now, now))
2514 {
2515 /* Restore original attributes. */
2516 SetFileAttributes (filename, attributes);
24b1ddad
KS
2517 xsignal2 (Qfile_date_error,
2518 build_string ("Cannot set file date"), newname);
ad497129
JR
2519 }
2520 /* Restore original attributes. */
2521 SetFileAttributes (filename, attributes);
e8691c59
GM
2522 }
2523#else /* not WINDOWSNT */
13336908 2524 immediate_quit = 1;
d5db4077 2525 ifd = emacs_open (SDATA (encoded_file), O_RDONLY, 0);
13336908
RS
2526 immediate_quit = 0;
2527
570d7624 2528 if (ifd < 0)
3b7f6e60 2529 report_file_error ("Opening input file", Fcons (file, Qnil));
570d7624 2530
b5148e85
RS
2531 record_unwind_protect (close_file_unwind, make_number (ifd));
2532
f73b0ada
BF
2533 /* We can only copy regular files and symbolic links. Other files are not
2534 copyable by us. */
2535 input_file_statable_p = (fstat (ifd, &st) >= 0);
2536
b016179b 2537#if !defined (MSDOS) || __DJGPP__ > 1
3ed15d97
RS
2538 if (out_st.st_mode != 0
2539 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2540 {
2541 errno = 0;
2542 report_file_error ("Input and output files are the same",
3b7f6e60 2543 Fcons (file, Fcons (newname, Qnil)));
3ed15d97
RS
2544 }
2545#endif
2546
f73b0ada
BF
2547#if defined (S_ISREG) && defined (S_ISLNK)
2548 if (input_file_statable_p)
2549 {
2550 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2551 {
2552#if defined (EISDIR)
2553 /* Get a better looking error message. */
2554 errno = EISDIR;
2555#endif /* EISDIR */
3b7f6e60 2556 report_file_error ("Non-regular file", Fcons (file, Qnil));
f73b0ada
BF
2557 }
2558 }
2559#endif /* S_ISREG && S_ISLNK */
2560
570d7624
JB
2561#ifdef VMS
2562 /* Create the copy file with the same record format as the input file */
d5db4077 2563 ofd = sys_creat (SDATA (encoded_newname), 0666, ifd);
570d7624 2564#else
4c3c22f3
RS
2565#ifdef MSDOS
2566 /* System's default file type was set to binary by _fmode in emacs.c. */
c50f15d0 2567 ofd = emacs_open (SDATA (encoded_newname),
7fce7dfe 2568 O_WRONLY | O_TRUNC | O_CREAT
795c20df 2569 | (NILP (ok_if_already_exists) ? O_EXCL : 0),
c50f15d0
RS
2570 S_IREAD | S_IWRITE);
2571#else /* not MSDOS */
2572 ofd = emacs_open (SDATA (encoded_newname),
2573 O_WRONLY | O_TRUNC | O_CREAT
795c20df 2574 | (NILP (ok_if_already_exists) ? O_EXCL : 0),
c50f15d0 2575 0666);
4c3c22f3 2576#endif /* not MSDOS */
570d7624
JB
2577#endif /* VMS */
2578 if (ofd < 0)
3ed15d97 2579 report_file_error ("Opening output file", Fcons (newname, Qnil));
b5148e85
RS
2580
2581 record_unwind_protect (close_file_unwind, make_number (ofd));
570d7624 2582
b5148e85
RS
2583 immediate_quit = 1;
2584 QUIT;
68c45bf0
PE
2585 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2586 if (emacs_write (ofd, buf, n) != n)
3ed15d97 2587 report_file_error ("I/O error", Fcons (newname, Qnil));
b5148e85 2588 immediate_quit = 0;
570d7624 2589
b016179b
EZ
2590#ifndef MSDOS
2591 /* Preserve the original file modes, and if requested, also its
2592 owner and group. */
586702ce
RS
2593 if (input_file_statable_p)
2594 {
b016179b
EZ
2595 if (! NILP (preserve_uid_gid))
2596 fchown (ofd, st.st_uid, st.st_gid);
586702ce 2597 fchmod (ofd, st.st_mode & 07777);
586702ce 2598 }
b016179b 2599#endif /* not MSDOS */
586702ce 2600
5acac34e 2601 /* Closing the output clobbers the file times on some systems. */
68c45bf0 2602 if (emacs_close (ofd) < 0)
5acac34e
RS
2603 report_file_error ("I/O error", Fcons (newname, Qnil));
2604
f73b0ada 2605 if (input_file_statable_p)
570d7624 2606 {
8ca6602c 2607 if (!NILP (keep_time))
570d7624 2608 {
de5bf5d3
JB
2609 EMACS_TIME atime, mtime;
2610 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2611 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
d5db4077 2612 if (set_file_times (SDATA (encoded_newname),
b1d1b865 2613 atime, mtime))
24b1ddad
KS
2614 xsignal2 (Qfile_date_error,
2615 build_string ("Cannot set file date"), newname);
570d7624 2616 }
570d7624
JB
2617 }
2618
68c45bf0 2619 emacs_close (ifd);
b016179b
EZ
2620
2621#if defined (__DJGPP__) && __DJGPP__ > 1
2622 if (input_file_statable_p)
2623 {
2624 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2625 and if it can't, it tells so. Otherwise, under MSDOS we usually
2626 get only the READ bit, which will make the copied file read-only,
2627 so it's better not to chmod at all. */
2628 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2629 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2630 }
2631#endif /* DJGPP version 2 or newer */
2632#endif /* not WINDOWSNT */
5acac34e 2633
b5148e85
RS
2634 /* Discard the unwind protects. */
2635 specpdl_ptr = specpdl + count;
2636
570d7624
JB
2637 UNGCPRO;
2638 return Qnil;
2639}
385b6cc7 2640\f
9bbe01fb 2641DEFUN ("make-directory-internal", Fmake_directory_internal,
353cfc19 2642 Smake_directory_internal, 1, 1, 0,
8c1a1077
PJ
2643 doc: /* Create a new directory named DIRECTORY. */)
2644 (directory)
3b7f6e60 2645 Lisp_Object directory;
570d7624 2646{
19290c65 2647 const unsigned char *dir;
32f4334d 2648 Lisp_Object handler;
b1d1b865 2649 Lisp_Object encoded_dir;
570d7624 2650
b7826503 2651 CHECK_STRING (directory);
3b7f6e60 2652 directory = Fexpand_file_name (directory, Qnil);
32f4334d 2653
3b7f6e60 2654 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
32f4334d 2655 if (!NILP (handler))
3b7f6e60 2656 return call2 (handler, Qmake_directory_internal, directory);
9bbe01fb 2657
b1d1b865
RS
2658 encoded_dir = ENCODE_FILE (directory);
2659
d5db4077 2660 dir = SDATA (encoded_dir);
570d7624 2661
5e570b75
RS
2662#ifdef WINDOWSNT
2663 if (mkdir (dir) != 0)
2664#else
570d7624 2665 if (mkdir (dir, 0777) != 0)
5e570b75 2666#endif
a9f2aeae 2667 report_file_error ("Creating directory", list1 (directory));
570d7624 2668
32f4334d 2669 return Qnil;
570d7624
JB
2670}
2671
aa734e17 2672DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
efdc16c9 2673 doc: /* Delete the directory named DIRECTORY. Does not follow symlinks. */)
8c1a1077 2674 (directory)
3b7f6e60 2675 Lisp_Object directory;
570d7624 2676{
19290c65 2677 const unsigned char *dir;
32f4334d 2678 Lisp_Object handler;
b1d1b865 2679 Lisp_Object encoded_dir;
570d7624 2680
b7826503 2681 CHECK_STRING (directory);
3b7f6e60 2682 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
570d7624 2683
3b7f6e60 2684 handler = Ffind_file_name_handler (directory, Qdelete_directory);
32f4334d 2685 if (!NILP (handler))
3b7f6e60 2686 return call2 (handler, Qdelete_directory, directory);
32f4334d 2687
b1d1b865
RS
2688 encoded_dir = ENCODE_FILE (directory);
2689
d5db4077 2690 dir = SDATA (encoded_dir);
b1d1b865 2691
570d7624 2692 if (rmdir (dir) != 0)
a9f2aeae 2693 report_file_error ("Removing directory", list1 (directory));
570d7624
JB
2694
2695 return Qnil;
2696}
2697
2698DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
efdc16c9 2699 doc: /* Delete file named FILENAME. If it is a symlink, remove the symlink.
8c1a1077
PJ
2700If file has multiple names, it continues to exist with the other names. */)
2701 (filename)
570d7624
JB
2702 Lisp_Object filename;
2703{
32f4334d 2704 Lisp_Object handler;
b1d1b865 2705 Lisp_Object encoded_file;
efdc16c9 2706 struct gcpro gcpro1;
b1d1b865 2707
efdc16c9 2708 GCPRO1 (filename);
b4bd27c5
RS
2709 if (!NILP (Ffile_directory_p (filename))
2710 && NILP (Ffile_symlink_p (filename)))
24b1ddad
KS
2711 xsignal2 (Qfile_error,
2712 build_string ("Removing old name: is a directory"),
2713 filename);
efdc16c9 2714 UNGCPRO;
570d7624 2715 filename = Fexpand_file_name (filename, Qnil);
32f4334d 2716
49307295 2717 handler = Ffind_file_name_handler (filename, Qdelete_file);
32f4334d 2718 if (!NILP (handler))
8a9b0da9 2719 return call2 (handler, Qdelete_file, filename);
32f4334d 2720
b1d1b865
RS
2721 encoded_file = ENCODE_FILE (filename);
2722
d5db4077 2723 if (0 > unlink (SDATA (encoded_file)))
a9f2aeae 2724 report_file_error ("Removing old name", list1 (filename));
8a9b0da9 2725 return Qnil;
570d7624
JB
2726}
2727
385b6cc7
RS
2728static Lisp_Object
2729internal_delete_file_1 (ignore)
2730 Lisp_Object ignore;
2731{
2732 return Qt;
2733}
2734
2735/* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2736
2737int
2738internal_delete_file (filename)
2739 Lisp_Object filename;
2740{
a3911e8c
KR
2741 Lisp_Object tem;
2742 tem = internal_condition_case_1 (Fdelete_file, filename,
2743 Qt, internal_delete_file_1);
2744 return NILP (tem);
385b6cc7
RS
2745}
2746\f
570d7624 2747DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
7c0f6118 2748 "fRename file: \nGRename %s to file: \np",
a4e03fe5 2749 doc: /* Rename FILE as NEWNAME. Both args must be strings.
8c1a1077
PJ
2750If file has names other than FILE, it continues to have those names.
2751Signals a `file-already-exists' error if a file NEWNAME already exists
2752unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2753A number as third arg means request confirmation if NEWNAME already exists.
2754This is what happens in interactive use with M-x. */)
2755 (file, newname, ok_if_already_exists)
3b7f6e60 2756 Lisp_Object file, newname, ok_if_already_exists;
570d7624 2757{
32f4334d 2758 Lisp_Object handler;
f72b5416
JD
2759 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
2760 Lisp_Object encoded_file, encoded_newname, symlink_target;
570d7624 2761
f72b5416
JD
2762 symlink_target = encoded_file = encoded_newname = Qnil;
2763 GCPRO5 (file, newname, encoded_file, encoded_newname, symlink_target);
b7826503
PJ
2764 CHECK_STRING (file);
2765 CHECK_STRING (newname);
3b7f6e60 2766 file = Fexpand_file_name (file, Qnil);
1ffc5c90 2767
f83caf70
EZ
2768 if ((!NILP (Ffile_directory_p (newname)))
2769#ifdef DOS_NT
2770 /* If the file names are identical but for the case,
2771 don't attempt to move directory to itself. */
2772 && (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))
2773#endif
2774 )
1ffc5c90
RS
2775 newname = Fexpand_file_name (Ffile_name_nondirectory (file), newname);
2776 else
2777 newname = Fexpand_file_name (newname, Qnil);
32f4334d
RS
2778
2779 /* If the file name has special constructs in it,
2780 call the corresponding file handler. */
3b7f6e60 2781 handler = Ffind_file_name_handler (file, Qrename_file);
51cf6d37 2782 if (NILP (handler))
49307295 2783 handler = Ffind_file_name_handler (newname, Qrename_file);
32f4334d 2784 if (!NILP (handler))
36712b0a 2785 RETURN_UNGCPRO (call4 (handler, Qrename_file,
3b7f6e60 2786 file, newname, ok_if_already_exists));
32f4334d 2787
b1d1b865
RS
2788 encoded_file = ENCODE_FILE (file);
2789 encoded_newname = ENCODE_FILE (newname);
2790
bc77278f
EZ
2791#ifdef DOS_NT
2792 /* If the file names are identical but for the case, don't ask for
2793 confirmation: they simply want to change the letter-case of the
2794 file name. */
2795 if (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))
2796#endif
265a9e55 2797 if (NILP (ok_if_already_exists)
93c30b5f 2798 || INTEGERP (ok_if_already_exists))
2f868094 2799 barf_or_query_if_file_exists (newname, "rename to it",
b8b29dc9 2800 INTEGERP (ok_if_already_exists), 0, 0);
570d7624 2801#ifndef BSD4_1
d5db4077 2802 if (0 > rename (SDATA (encoded_file), SDATA (encoded_newname)))
570d7624 2803#else
d5db4077
KR
2804 if (0 > link (SDATA (encoded_file), SDATA (encoded_newname))
2805 || 0 > unlink (SDATA (encoded_file)))
570d7624
JB
2806#endif
2807 {
2808 if (errno == EXDEV)
2809 {
440c7d00 2810#ifdef S_IFLNK
f72b5416 2811 symlink_target = Ffile_symlink_p (file);
440c7d00
JD
2812 if (! NILP (symlink_target))
2813 Fmake_symbolic_link (symlink_target, newname,
f59abab9 2814 NILP (ok_if_already_exists) ? Qnil : Qt);
440c7d00
JD
2815 else
2816#endif
586702ce
RS
2817 Fcopy_file (file, newname,
2818 /* We have already prompted if it was an integer,
2819 so don't have copy-file prompt again. */
2820 NILP (ok_if_already_exists) ? Qnil : Qt,
795c20df 2821 Qt, Qt);
d550c425 2822
3b7f6e60 2823 Fdelete_file (file);
570d7624
JB
2824 }
2825 else
a9f2aeae 2826 report_file_error ("Renaming", list2 (file, newname));
570d7624
JB
2827 }
2828 UNGCPRO;
2829 return Qnil;
2830}
2831
2832DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
7c0f6118 2833 "fAdd name to file: \nGName to add to %s: \np",
a4e03fe5 2834 doc: /* Give FILE additional name NEWNAME. Both args must be strings.
8c1a1077
PJ
2835Signals a `file-already-exists' error if a file NEWNAME already exists
2836unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2837A number as third arg means request confirmation if NEWNAME already exists.
2838This is what happens in interactive use with M-x. */)
2839 (file, newname, ok_if_already_exists)
3b7f6e60 2840 Lisp_Object file, newname, ok_if_already_exists;
570d7624 2841{
32f4334d 2842 Lisp_Object handler;
b1d1b865
RS
2843 Lisp_Object encoded_file, encoded_newname;
2844 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
570d7624 2845
b1d1b865
RS
2846 GCPRO4 (file, newname, encoded_file, encoded_newname);
2847 encoded_file = encoded_newname = Qnil;
b7826503
PJ
2848 CHECK_STRING (file);
2849 CHECK_STRING (newname);
3b7f6e60 2850 file = Fexpand_file_name (file, Qnil);
1ffc5c90
RS
2851
2852 if (!NILP (Ffile_directory_p (newname)))
2853 newname = Fexpand_file_name (Ffile_name_nondirectory (file), newname);
2854 else
2855 newname = Fexpand_file_name (newname, Qnil);
32f4334d
RS
2856
2857 /* If the file name has special constructs in it,
2858 call the corresponding file handler. */
3b7f6e60 2859 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
32f4334d 2860 if (!NILP (handler))
3b7f6e60 2861 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
36712b0a 2862 newname, ok_if_already_exists));
32f4334d 2863
adc6741c
RS
2864 /* If the new name has special constructs in it,
2865 call the corresponding file handler. */
2866 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2867 if (!NILP (handler))
3b7f6e60 2868 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
adc6741c
RS
2869 newname, ok_if_already_exists));
2870
b1d1b865
RS
2871 encoded_file = ENCODE_FILE (file);
2872 encoded_newname = ENCODE_FILE (newname);
2873
265a9e55 2874 if (NILP (ok_if_already_exists)
93c30b5f 2875 || INTEGERP (ok_if_already_exists))
2f868094 2876 barf_or_query_if_file_exists (newname, "make it a new name",
b8b29dc9 2877 INTEGERP (ok_if_already_exists), 0, 0);
5e570b75 2878
d5db4077
KR
2879 unlink (SDATA (newname));
2880 if (0 > link (SDATA (encoded_file), SDATA (encoded_newname)))
a9f2aeae 2881 report_file_error ("Adding new name", list2 (file, newname));
570d7624
JB
2882
2883 UNGCPRO;
2884 return Qnil;
2885}
2886
570d7624 2887DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
7c0f6118 2888 "FMake symbolic link to file: \nGMake symbolic link to file %s: \np",
68780e2a
RS
2889 doc: /* Make a symbolic link to FILENAME, named LINKNAME.
2890Both args must be strings.
8c1a1077
PJ
2891Signals a `file-already-exists' error if a file LINKNAME already exists
2892unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2893A number as third arg means request confirmation if LINKNAME already exists.
2894This happens for interactive use with M-x. */)
2895 (filename, linkname, ok_if_already_exists)
e5d77022 2896 Lisp_Object filename, linkname, ok_if_already_exists;
570d7624 2897{
32f4334d 2898 Lisp_Object handler;
b1d1b865
RS
2899 Lisp_Object encoded_filename, encoded_linkname;
2900 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
570d7624 2901
b1d1b865
RS
2902 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2903 encoded_filename = encoded_linkname = Qnil;
b7826503
PJ
2904 CHECK_STRING (filename);
2905 CHECK_STRING (linkname);
d9bc1c99
RS
2906 /* If the link target has a ~, we must expand it to get
2907 a truly valid file name. Otherwise, do not expand;
2908 we want to permit links to relative file names. */
d5db4077 2909 if (SREF (filename, 0) == '~')
d9bc1c99 2910 filename = Fexpand_file_name (filename, Qnil);
1ffc5c90
RS
2911
2912 if (!NILP (Ffile_directory_p (linkname)))
dac24db4 2913 linkname = Fexpand_file_name (Ffile_name_nondirectory (filename), linkname);
1ffc5c90
RS
2914 else
2915 linkname = Fexpand_file_name (linkname, Qnil);
32f4334d
RS
2916
2917 /* If the file name has special constructs in it,
2918 call the corresponding file handler. */
49307295 2919 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
32f4334d 2920 if (!NILP (handler))
36712b0a
KH
2921 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2922 linkname, ok_if_already_exists));
32f4334d 2923
adc6741c
RS
2924 /* If the new link name has special constructs in it,
2925 call the corresponding file handler. */
2926 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2927 if (!NILP (handler))
2928 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2929 linkname, ok_if_already_exists));
2930
474d35ca 2931#ifdef S_IFLNK
b1d1b865
RS
2932 encoded_filename = ENCODE_FILE (filename);
2933 encoded_linkname = ENCODE_FILE (linkname);
2934
265a9e55 2935 if (NILP (ok_if_already_exists)
93c30b5f 2936 || INTEGERP (ok_if_already_exists))
2f868094 2937 barf_or_query_if_file_exists (linkname, "make it a link",
b8b29dc9 2938 INTEGERP (ok_if_already_exists), 0, 0);
d5db4077
KR
2939 if (0 > symlink (SDATA (encoded_filename),
2940 SDATA (encoded_linkname)))
570d7624
JB
2941 {
2942 /* If we didn't complain already, silently delete existing file. */
2943 if (errno == EEXIST)
2944 {
d5db4077
KR
2945 unlink (SDATA (encoded_linkname));
2946 if (0 <= symlink (SDATA (encoded_filename),
2947 SDATA (encoded_linkname)))
1a04498e
KH
2948 {
2949 UNGCPRO;
2950 return Qnil;
2951 }
570d7624
JB
2952 }
2953
a9f2aeae 2954 report_file_error ("Making symbolic link", list2 (filename, linkname));
570d7624
JB
2955 }
2956 UNGCPRO;
2957 return Qnil;
474d35ca
MA
2958
2959#else
2960 UNGCPRO;
2961 xsignal1 (Qfile_error, build_string ("Symbolic links are not supported"));
2962
570d7624 2963#endif /* S_IFLNK */
474d35ca 2964}
570d7624
JB
2965
2966#ifdef VMS
2967
2968DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2969 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
8c1a1077
PJ
2970 doc: /* Define the job-wide logical name NAME to have the value STRING.
2971If STRING is nil or a null string, the logical name NAME is deleted. */)
2972 (name, string)
3b7f6e60 2973 Lisp_Object name;
570d7624
JB
2974 Lisp_Object string;
2975{
b7826503 2976 CHECK_STRING (name);
265a9e55 2977 if (NILP (string))
d5db4077 2978 delete_logical_name (SDATA (name));
570d7624
JB
2979 else
2980 {
b7826503 2981 CHECK_STRING (string);
570d7624 2982
d5db4077
KR
2983 if (SCHARS (string) == 0)
2984 delete_logical_name (SDATA (name));
570d7624 2985 else
d5db4077 2986 define_logical_name (SDATA (name), SDATA (string));
570d7624
JB
2987 }
2988
2989 return string;
2990}
2991#endif /* VMS */
2992
2993#ifdef HPUX_NET
2994
2995DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
8c1a1077 2996 doc: /* Open a network connection to PATH using LOGIN as the login string. */)
570d7624
JB
2997 (path, login)
2998 Lisp_Object path, login;
2999{
3000 int netresult;
199607e4 3001
b7826503
PJ
3002 CHECK_STRING (path);
3003 CHECK_STRING (login);
199607e4 3004
d5db4077 3005 netresult = netunam (SDATA (path), SDATA (login));
570d7624
JB
3006
3007 if (netresult == -1)
3008 return Qnil;
3009 else
3010 return Qt;
3011}
3012#endif /* HPUX_NET */
3013\f
3014DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
3015 1, 1, 0,
8c1a1077
PJ
3016 doc: /* Return t if file FILENAME specifies an absolute file name.
3017On Unix, this is a name starting with a `/' or a `~'. */)
570d7624
JB
3018 (filename)
3019 Lisp_Object filename;
3020{
b7826503 3021 CHECK_STRING (filename);
c70a4df6 3022 return file_name_absolute_p (SDATA (filename)) ? Qt : Qnil;
570d7624 3023}
3beeedfe
RS
3024\f
3025/* Return nonzero if file FILENAME exists and can be executed. */
3026
3027static int
3028check_executable (filename)
3029 char *filename;
3030{
3be3c08e
RS
3031#ifdef DOS_NT
3032 int len = strlen (filename);
3033 char *suffix;
3034 struct stat st;
3035 if (stat (filename, &st) < 0)
3036 return 0;
34ead71a 3037#if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
199607e4
RS
3038 return ((st.st_mode & S_IEXEC) != 0);
3039#else
3be3c08e
RS
3040 return (S_ISREG (st.st_mode)
3041 && len >= 5
3042 && (stricmp ((suffix = filename + len-4), ".com") == 0
3043 || stricmp (suffix, ".exe") == 0
2dc3be7e
RS
3044 || stricmp (suffix, ".bat") == 0)
3045 || (st.st_mode & S_IFMT) == S_IFDIR);
199607e4 3046#endif /* not WINDOWSNT */
3be3c08e 3047#else /* not DOS_NT */
de0be7dd
RS
3048#ifdef HAVE_EUIDACCESS
3049 return (euidaccess (filename, 1) >= 0);
3beeedfe
RS
3050#else
3051 /* Access isn't quite right because it uses the real uid
3052 and we really want to test with the effective uid.
3053 But Unix doesn't give us a right way to do it. */
3054 return (access (filename, 1) >= 0);
3055#endif
3be3c08e 3056#endif /* not DOS_NT */
3beeedfe
RS
3057}
3058
3059/* Return nonzero if file FILENAME exists and can be written. */
3060
3061static int
3062check_writable (filename)
3063 char *filename;
3064{
3be3c08e
RS
3065#ifdef MSDOS
3066 struct stat st;
3067 if (stat (filename, &st) < 0)
3068 return 0;
3069 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
3070#else /* not MSDOS */
41f3fb38
KH
3071#ifdef HAVE_EUIDACCESS
3072 return (euidaccess (filename, 2) >= 0);
3beeedfe
RS
3073#else
3074 /* Access isn't quite right because it uses the real uid
3075 and we really want to test with the effective uid.
3076 But Unix doesn't give us a right way to do it.
3077 Opening with O_WRONLY could work for an ordinary file,
3078 but would lose for directories. */
3079 return (access (filename, 2) >= 0);
3080#endif
3be3c08e 3081#endif /* not MSDOS */
3beeedfe 3082}
570d7624
JB
3083
3084DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
68780e2a
RS
3085 doc: /* Return t if file FILENAME exists (whether or not you can read it.)
3086See also `file-readable-p' and `file-attributes'.
3087This returns nil for a symlink to a nonexistent file.
3088Use `file-symlink-p' to test for such links. */)
8c1a1077 3089 (filename)
570d7624
JB
3090 Lisp_Object filename;
3091{
199607e4 3092 Lisp_Object absname;
32f4334d 3093 Lisp_Object handler;
4018b5ef 3094 struct stat statbuf;
570d7624 3095
b7826503 3096 CHECK_STRING (filename);
199607e4 3097 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3098
3099 /* If the file name has special constructs in it,
3100 call the corresponding file handler. */
199607e4 3101 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
32f4334d 3102 if (!NILP (handler))
199607e4 3103 return call2 (handler, Qfile_exists_p, absname);
32f4334d 3104
b1d1b865
RS
3105 absname = ENCODE_FILE (absname);
3106
d5db4077 3107 return (stat (SDATA (absname), &statbuf) >= 0) ? Qt : Qnil;
570d7624
JB
3108}
3109
3110DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
8c1a1077
PJ
3111 doc: /* Return t if FILENAME can be executed by you.
3112For a directory, this means you can access files in that directory. */)
3113 (filename)
3114 Lisp_Object filename;
570d7624 3115{
199607e4 3116 Lisp_Object absname;
32f4334d 3117 Lisp_Object handler;
570d7624 3118
b7826503 3119 CHECK_STRING (filename);
199607e4 3120 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3121
3122 /* If the file name has special constructs in it,
3123 call the corresponding file handler. */
199607e4 3124 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
32f4334d 3125 if (!NILP (handler))
199607e4 3126 return call2 (handler, Qfile_executable_p, absname);
32f4334d 3127
b1d1b865
RS
3128 absname = ENCODE_FILE (absname);
3129
d5db4077 3130 return (check_executable (SDATA (absname)) ? Qt : Qnil);
570d7624
JB
3131}
3132
3133DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
8c1a1077
PJ
3134 doc: /* Return t if file FILENAME exists and you can read it.
3135See also `file-exists-p' and `file-attributes'. */)
3136 (filename)
570d7624
JB
3137 Lisp_Object filename;
3138{
199607e4 3139 Lisp_Object absname;
32f4334d 3140 Lisp_Object handler;
4018b5ef 3141 int desc;
bb369dc6
RS
3142 int flags;
3143 struct stat statbuf;
570d7624 3144
b7826503 3145 CHECK_STRING (filename);
199607e4 3146 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3147
3148 /* If the file name has special constructs in it,
3149 call the corresponding file handler. */
199607e4 3150 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
32f4334d 3151 if (!NILP (handler))
199607e4 3152 return call2 (handler, Qfile_readable_p, absname);
32f4334d 3153
b1d1b865
RS
3154 absname = ENCODE_FILE (absname);
3155
fb4c6c96
AC
3156#if defined(DOS_NT) || defined(macintosh)
3157 /* Under MS-DOS, Windows, and Macintosh, open does not work for
3158 directories. */
d5db4077 3159 if (access (SDATA (absname), 0) == 0)
a8a7d065
RS
3160 return Qt;
3161 return Qnil;
fb4c6c96 3162#else /* not DOS_NT and not macintosh */
bb369dc6
RS
3163 flags = O_RDONLY;
3164#if defined (S_ISFIFO) && defined (O_NONBLOCK)
3165 /* Opening a fifo without O_NONBLOCK can wait.
3166 We don't want to wait. But we don't want to mess wth O_NONBLOCK
3167 except in the case of a fifo, on a system which handles it. */
d5db4077 3168 desc = stat (SDATA (absname), &statbuf);
bb369dc6
RS
3169 if (desc < 0)
3170 return Qnil;
3171 if (S_ISFIFO (statbuf.st_mode))
3172 flags |= O_NONBLOCK;
3173#endif
d5db4077 3174 desc = emacs_open (SDATA (absname), flags, 0);
4018b5ef
RS
3175 if (desc < 0)
3176 return Qnil;
68c45bf0 3177 emacs_close (desc);
4018b5ef 3178 return Qt;
fb4c6c96 3179#endif /* not DOS_NT and not macintosh */
570d7624
JB
3180}
3181
f793dc6c
RS
3182/* Having this before file-symlink-p mysteriously caused it to be forgotten
3183 on the RT/PC. */
3184DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
8c1a1077
PJ
3185 doc: /* Return t if file FILENAME can be written or created by you. */)
3186 (filename)
f793dc6c
RS
3187 Lisp_Object filename;
3188{
b1d1b865 3189 Lisp_Object absname, dir, encoded;
f793dc6c
RS
3190 Lisp_Object handler;
3191 struct stat statbuf;
3192
b7826503 3193 CHECK_STRING (filename);
199607e4 3194 absname = Fexpand_file_name (filename, Qnil);
f793dc6c
RS
3195
3196 /* If the file name has special constructs in it,
3197 call the corresponding file handler. */
199607e4 3198 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
f793dc6c 3199 if (!NILP (handler))
199607e4 3200 return call2 (handler, Qfile_writable_p, absname);
f793dc6c 3201
b1d1b865 3202 encoded = ENCODE_FILE (absname);
d5db4077
KR
3203 if (stat (SDATA (encoded), &statbuf) >= 0)
3204 return (check_writable (SDATA (encoded))
f793dc6c 3205 ? Qt : Qnil);
b1d1b865 3206
199607e4 3207 dir = Ffile_name_directory (absname);
f793dc6c
RS
3208#ifdef VMS
3209 if (!NILP (dir))
3210 dir = Fdirectory_file_name (dir);
3211#endif /* VMS */
3212#ifdef MSDOS
3213 if (!NILP (dir))
3214 dir = Fdirectory_file_name (dir);
3215#endif /* MSDOS */
b1d1b865
RS
3216
3217 dir = ENCODE_FILE (dir);
e3e8a75a
GM
3218#ifdef WINDOWSNT
3219 /* The read-only attribute of the parent directory doesn't affect
3220 whether a file or directory can be created within it. Some day we
3221 should check ACLs though, which do affect this. */
d5db4077 3222 if (stat (SDATA (dir), &statbuf) < 0)
e3e8a75a
GM
3223 return Qnil;
3224 return (statbuf.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3225#else
d5db4077 3226 return (check_writable (!NILP (dir) ? (char *) SDATA (dir) : "")
f793dc6c 3227 ? Qt : Qnil);
e3e8a75a 3228#endif
f793dc6c
RS
3229}
3230\f
1f8653eb 3231DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
8c1a1077
PJ
3232 doc: /* Access file FILENAME, and get an error if that does not work.
3233The second argument STRING is used in the error message.
a4e03fe5 3234If there is no error, returns nil. */)
8c1a1077 3235 (filename, string)
1f8653eb
RS
3236 Lisp_Object filename, string;
3237{
49475635 3238 Lisp_Object handler, encoded_filename, absname;
1f8653eb
RS
3239 int fd;
3240
b7826503 3241 CHECK_STRING (filename);
49475635
EZ
3242 absname = Fexpand_file_name (filename, Qnil);
3243
b7826503 3244 CHECK_STRING (string);
1f8653eb
RS
3245
3246 /* If the file name has special constructs in it,
3247 call the corresponding file handler. */
49475635 3248 handler = Ffind_file_name_handler (absname, Qaccess_file);
1f8653eb 3249 if (!NILP (handler))
49475635 3250 return call3 (handler, Qaccess_file, absname, string);
1f8653eb 3251
49475635 3252 encoded_filename = ENCODE_FILE (absname);
b1d1b865 3253
d5db4077 3254 fd = emacs_open (SDATA (encoded_filename), O_RDONLY, 0);
1f8653eb 3255 if (fd < 0)
d5db4077 3256 report_file_error (SDATA (string), Fcons (filename, Qnil));
68c45bf0 3257 emacs_close (fd);
1f8653eb
RS
3258
3259 return Qnil;
3260}
3261\f
570d7624 3262DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
8c1a1077 3263 doc: /* Return non-nil if file FILENAME is the name of a symbolic link.
1c353c74 3264The value is the link target, as a string.
68780e2a
RS
3265Otherwise it returns nil.
3266
3267This function returns t when given the name of a symlink that
3268points to a nonexistent file. */)
8c1a1077 3269 (filename)
570d7624
JB
3270 Lisp_Object filename;
3271{
32f4334d 3272 Lisp_Object handler;
570d7624 3273
b7826503 3274 CHECK_STRING (filename);
570d7624
JB
3275 filename = Fexpand_file_name (filename, Qnil);
3276
32f4334d
RS
3277 /* If the file name has special constructs in it,
3278 call the corresponding file handler. */
49307295 3279 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
32f4334d
RS
3280 if (!NILP (handler))
3281 return call2 (handler, Qfile_symlink_p, filename);
3282
5adcec23
JR
3283#ifdef S_IFLNK
3284 {
3285 char *buf;
3286 int bufsize;
3287 int valsize;
3288 Lisp_Object val;
3289
b1d1b865
RS
3290 filename = ENCODE_FILE (filename);
3291
81c3310d
GM
3292 bufsize = 50;
3293 buf = NULL;
3294 do
570d7624 3295 {
81c3310d
GM
3296 bufsize *= 2;
3297 buf = (char *) xrealloc (buf, bufsize);
570d7624 3298 bzero (buf, bufsize);
efdc16c9 3299
81c3310d 3300 errno = 0;
d5db4077 3301 valsize = readlink (SDATA (filename), buf, bufsize);
bcdd93b3
GM
3302 if (valsize == -1)
3303 {
81c3310d
GM
3304#ifdef ERANGE
3305 /* HP-UX reports ERANGE if buffer is too small. */
bcdd93b3
GM
3306 if (errno == ERANGE)
3307 valsize = bufsize;
3308 else
81c3310d 3309#endif
bcdd93b3
GM
3310 {
3311 xfree (buf);
3312 return Qnil;
3313 }
81c3310d 3314 }
570d7624 3315 }
81c3310d 3316 while (valsize >= bufsize);
efdc16c9 3317
570d7624 3318 val = make_string (buf, valsize);
69ac1891
GM
3319 if (buf[0] == '/' && index (buf, ':'))
3320 val = concat2 (build_string ("/:"), val);
9ac0d9e0 3321 xfree (buf);
cd913586
KH
3322 val = DECODE_FILE (val);
3323 return val;
5adcec23 3324 }
570d7624
JB
3325#else /* not S_IFLNK */
3326 return Qnil;
3327#endif /* not S_IFLNK */
3328}
3329
570d7624 3330DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
8c1a1077
PJ
3331 doc: /* Return t if FILENAME names an existing directory.
3332Symbolic links to directories count as directories.
3333See `file-symlink-p' to distinguish symlinks. */)
3334 (filename)
570d7624
JB
3335 Lisp_Object filename;
3336{
199607e4 3337 register Lisp_Object absname;
570d7624 3338 struct stat st;
32f4334d 3339 Lisp_Object handler;
570d7624 3340
199607e4 3341 absname = expand_and_dir_to_file (filename, current_buffer->directory);
570d7624 3342
32f4334d
RS
3343 /* If the file name has special constructs in it,
3344 call the corresponding file handler. */
199607e4 3345 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
32f4334d 3346 if (!NILP (handler))
199607e4 3347 return call2 (handler, Qfile_directory_p, absname);
32f4334d 3348
b1d1b865
RS
3349 absname = ENCODE_FILE (absname);
3350
d5db4077 3351 if (stat (SDATA (absname), &st) < 0)
570d7624
JB
3352 return Qnil;
3353 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3354}
3355
b72dea2a 3356DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
e385ec41
RS
3357 doc: /* Return t if file FILENAME names a directory you can open.
3358For the value to be t, FILENAME must specify the name of a directory as a file,
3359and the directory must allow you to open files in it. In order to use a
8c1a1077
PJ
3360directory as a buffer's current directory, this predicate must return true.
3361A directory name spec may be given instead; then the value is t
3362if the directory so specified exists and really is a readable and
3363searchable directory. */)
3364 (filename)
b72dea2a
JB
3365 Lisp_Object filename;
3366{
32f4334d 3367 Lisp_Object handler;
1a04498e 3368 int tem;
d26859eb 3369 struct gcpro gcpro1;
32f4334d
RS
3370
3371 /* If the file name has special constructs in it,
3372 call the corresponding file handler. */
49307295 3373 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
32f4334d
RS
3374 if (!NILP (handler))
3375 return call2 (handler, Qfile_accessible_directory_p, filename);
3376
d26859eb 3377 GCPRO1 (filename);
1a04498e
KH
3378 tem = (NILP (Ffile_directory_p (filename))
3379 || NILP (Ffile_executable_p (filename)));
d26859eb 3380 UNGCPRO;
1a04498e 3381 return tem ? Qnil : Qt;
b72dea2a
JB
3382}
3383
f793dc6c 3384DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
19a9c3b7
LH
3385 doc: /* Return t if FILENAME names a regular file.
3386This is the sort of file that holds an ordinary stream of data bytes.
3387Symbolic links to regular files count as regular files.
3388See `file-symlink-p' to distinguish symlinks. */)
8c1a1077 3389 (filename)
f793dc6c
RS
3390 Lisp_Object filename;
3391{
199607e4 3392 register Lisp_Object absname;
f793dc6c
RS
3393 struct stat st;
3394 Lisp_Object handler;
3395
199607e4 3396 absname = expand_and_dir_to_file (filename, current_buffer->directory);
f793dc6c
RS
3397
3398 /* If the file name has special constructs in it,
3399 call the corresponding file handler. */
199607e4 3400 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
f793dc6c 3401 if (!NILP (handler))
199607e4 3402 return call2 (handler, Qfile_regular_p, absname);
f793dc6c 3403
b1d1b865
RS
3404 absname = ENCODE_FILE (absname);
3405
c1c4693e
RS
3406#ifdef WINDOWSNT
3407 {
3408 int result;
3409 Lisp_Object tem = Vw32_get_true_file_attributes;
3410
3411 /* Tell stat to use expensive method to get accurate info. */
3412 Vw32_get_true_file_attributes = Qt;
d5db4077 3413 result = stat (SDATA (absname), &st);
c1c4693e
RS
3414 Vw32_get_true_file_attributes = tem;
3415
3416 if (result < 0)
3417 return Qnil;
3418 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3419 }
3420#else
d5db4077 3421 if (stat (SDATA (absname), &st) < 0)
f793dc6c
RS
3422 return Qnil;
3423 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
c1c4693e 3424#endif
f793dc6c
RS
3425}
3426\f
570d7624 3427DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
d4a42098
KS
3428 doc: /* Return mode bits of file named FILENAME, as an integer.
3429Return nil, if file does not exist or is not accessible. */)
8c1a1077 3430 (filename)
570d7624
JB
3431 Lisp_Object filename;
3432{
199607e4 3433 Lisp_Object absname;
570d7624 3434 struct stat st;
32f4334d 3435 Lisp_Object handler;
570d7624 3436
199607e4 3437 absname = expand_and_dir_to_file (filename, current_buffer->directory);
570d7624 3438
32f4334d
RS
3439 /* If the file name has special constructs in it,
3440 call the corresponding file handler. */
199607e4 3441 handler = Ffind_file_name_handler (absname, Qfile_modes);
32f4334d 3442 if (!NILP (handler))
199607e4 3443 return call2 (handler, Qfile_modes, absname);
32f4334d 3444
b1d1b865
RS
3445 absname = ENCODE_FILE (absname);
3446
d5db4077 3447 if (stat (SDATA (absname), &st) < 0)
570d7624 3448 return Qnil;
34ead71a 3449#if defined (MSDOS) && __DJGPP__ < 2
d5db4077 3450 if (check_executable (SDATA (absname)))
3be3c08e 3451 st.st_mode |= S_IEXEC;
34ead71a 3452#endif /* MSDOS && __DJGPP__ < 2 */
3ace87e3 3453
570d7624
JB
3454 return make_number (st.st_mode & 07777);
3455}
3456
3457DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
8c1a1077
PJ
3458 doc: /* Set mode bits of file named FILENAME to MODE (an integer).
3459Only the 12 low bits of MODE are used. */)
570d7624
JB
3460 (filename, mode)
3461 Lisp_Object filename, mode;
3462{
b1d1b865 3463 Lisp_Object absname, encoded_absname;
32f4334d 3464 Lisp_Object handler;
570d7624 3465
199607e4 3466 absname = Fexpand_file_name (filename, current_buffer->directory);
b7826503 3467 CHECK_NUMBER (mode);
570d7624 3468
32f4334d
RS
3469 /* If the file name has special constructs in it,
3470 call the corresponding file handler. */
199607e4 3471 handler = Ffind_file_name_handler (absname, Qset_file_modes);
32f4334d 3472 if (!NILP (handler))
199607e4 3473 return call3 (handler, Qset_file_modes, absname, mode);
32f4334d 3474
b1d1b865
RS
3475 encoded_absname = ENCODE_FILE (absname);
3476
d5db4077 3477 if (chmod (SDATA (encoded_absname), XINT (mode)) < 0)
199607e4 3478 report_file_error ("Doing chmod", Fcons (absname, Qnil));
570d7624
JB
3479
3480 return Qnil;
3481}
3482
c24e9a53 3483DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
8c1a1077
PJ
3484 doc: /* Set the file permission bits for newly created files.
3485The argument MODE should be an integer; only the low 9 bits are used.
3486This setting is inherited by subprocesses. */)
3487 (mode)
5f85ea58 3488 Lisp_Object mode;
36a8c287 3489{
b7826503 3490 CHECK_NUMBER (mode);
199607e4 3491
5f85ea58 3492 umask ((~ XINT (mode)) & 0777);
36a8c287
JB
3493
3494 return Qnil;
3495}
3496
c24e9a53 3497DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
8c1a1077
PJ
3498 doc: /* Return the default file protection for created files.
3499The value is an integer. */)
3500 ()
36a8c287 3501{
5f85ea58
RS
3502 int realmask;
3503 Lisp_Object value;
36a8c287 3504
5f85ea58
RS
3505 realmask = umask (0);
3506 umask (realmask);
36a8c287 3507
46283abe 3508 XSETINT (value, (~ realmask) & 0777);
5f85ea58 3509 return value;
36a8c287 3510}
819da85b
EZ
3511\f
3512extern int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
3513
3514DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 2, 0,
3515 doc: /* Set times of file FILENAME to TIME.
3516Set both access and modification times.
3517Return t on success, else nil.
3518Use the current time if TIME is nil. TIME is in the format of
3519`current-time'. */)
3520 (filename, time)
3521 Lisp_Object filename, time;
3522{
3523 Lisp_Object absname, encoded_absname;
3524 Lisp_Object handler;
3525 time_t sec;
3526 int usec;
3527
3528 if (! lisp_time_argument (time, &sec, &usec))
3529 error ("Invalid time specification");
3530
3531 absname = Fexpand_file_name (filename, current_buffer->directory);
3532
3533 /* If the file name has special constructs in it,
3534 call the corresponding file handler. */
3535 handler = Ffind_file_name_handler (absname, Qset_file_times);
3536 if (!NILP (handler))
3537 return call3 (handler, Qset_file_times, absname, time);
3538
3539 encoded_absname = ENCODE_FILE (absname);
5df5e07c 3540
819da85b
EZ
3541 {
3542 EMACS_TIME t;
3543
3544 EMACS_SET_SECS (t, sec);
3545 EMACS_SET_USECS (t, usec);
3546
3547 if (set_file_times (SDATA (encoded_absname), t, t))
3548 {
3549#ifdef DOS_NT
3550 struct stat st;
3551
3552 /* Setting times on a directory always fails. */
3553 if (stat (SDATA (encoded_absname), &st) == 0
3554 && (st.st_mode & S_IFMT) == S_IFDIR)
3555 return Qnil;
3556#endif
3557 report_file_error ("Setting file times", Fcons (absname, Qnil));
3558 return Qnil;
3559 }
3560 }
3561
3562 return Qt;
3563}
f793dc6c 3564\f
697c17a2 3565#ifdef HAVE_SYNC
85ffea93 3566DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
8c1a1077
PJ
3567 doc: /* Tell Unix to finish all pending disk updates. */)
3568 ()
85ffea93
RS
3569{
3570 sync ();
3571 return Qnil;
3572}
3573
697c17a2 3574#endif /* HAVE_SYNC */
85ffea93 3575
570d7624 3576DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
8c1a1077
PJ
3577 doc: /* Return t if file FILE1 is newer than file FILE2.
3578If FILE1 does not exist, the answer is nil;
3579otherwise, if FILE2 does not exist, the answer is t. */)
3580 (file1, file2)
570d7624
JB
3581 Lisp_Object file1, file2;
3582{
199607e4 3583 Lisp_Object absname1, absname2;
570d7624
JB
3584 struct stat st;
3585 int mtime1;
32f4334d 3586 Lisp_Object handler;
09121adc 3587 struct gcpro gcpro1, gcpro2;
570d7624 3588
b7826503
PJ
3589 CHECK_STRING (file1);
3590 CHECK_STRING (file2);
570d7624 3591
199607e4
RS
3592 absname1 = Qnil;
3593 GCPRO2 (absname1, file2);
3594 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3595 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
09121adc 3596 UNGCPRO;
570d7624 3597
32f4334d
RS
3598 /* If the file name has special constructs in it,
3599 call the corresponding file handler. */
199607e4 3600 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
51cf6d37 3601 if (NILP (handler))
199607e4 3602 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
32f4334d 3603 if (!NILP (handler))
199607e4 3604 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
32f4334d 3605
b1d1b865
RS
3606 GCPRO2 (absname1, absname2);
3607 absname1 = ENCODE_FILE (absname1);
3608 absname2 = ENCODE_FILE (absname2);
3609 UNGCPRO;
3610
d5db4077 3611 if (stat (SDATA (absname1), &st) < 0)
570d7624
JB
3612 return Qnil;
3613
3614 mtime1 = st.st_mtime;
3615
d5db4077 3616 if (stat (SDATA (absname2), &st) < 0)
570d7624
JB
3617 return Qt;
3618
3619 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3620}
3621\f
5e570b75 3622#ifdef DOS_NT
4c3c22f3 3623Lisp_Object Qfind_buffer_file_type;
5e570b75 3624#endif /* DOS_NT */
4c3c22f3 3625
6fdaa9a0
KH
3626#ifndef READ_BUF_SIZE
3627#define READ_BUF_SIZE (64 << 10)
3628#endif
3629
98a7d268
KH
3630extern void adjust_markers_for_delete P_ ((int, int, int, int));
3631
3632/* This function is called after Lisp functions to decide a coding
3633 system are called, or when they cause an error. Before they are
3634 called, the current buffer is set unibyte and it contains only a
3635 newly inserted text (thus the buffer was empty before the
3636 insertion).
3637
3638 The functions may set markers, overlays, text properties, or even
3639 alter the buffer contents, change the current buffer.
3640
3641 Here, we reset all those changes by:
3642 o set back the current buffer.
3643 o move all markers and overlays to BEG.
3644 o remove all text properties.
3645 o set back the buffer multibyteness. */
f736ffbf
KH
3646
3647static Lisp_Object
98a7d268
KH
3648decide_coding_unwind (unwind_data)
3649 Lisp_Object unwind_data;
f736ffbf 3650{
98a7d268 3651 Lisp_Object multibyte, undo_list, buffer;
f736ffbf 3652
98a7d268
KH
3653 multibyte = XCAR (unwind_data);
3654 unwind_data = XCDR (unwind_data);
3655 undo_list = XCAR (unwind_data);
3656 buffer = XCDR (unwind_data);
3657
3658 if (current_buffer != XBUFFER (buffer))
3659 set_buffer_internal (XBUFFER (buffer));
3660 adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
3661 adjust_overlays_for_delete (BEG, Z - BEG);
3662 BUF_INTERVALS (current_buffer) = 0;
3663 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3664
3665 /* Now we are safe to change the buffer's multibyteness directly. */
3666 current_buffer->enable_multibyte_characters = multibyte;
3667 current_buffer->undo_list = undo_list;
f736ffbf
KH
3668
3669 return Qnil;
3670}
3671
55587f8a 3672
1b978129 3673/* Used to pass values from insert-file-contents to read_non_regular. */
55587f8a 3674
1b978129
GM
3675static int non_regular_fd;
3676static int non_regular_inserted;
3677static int non_regular_nbytes;
55587f8a 3678
55587f8a 3679
1b978129
GM
3680/* Read from a non-regular file.
3681 Read non_regular_trytry bytes max from non_regular_fd.
3682 Non_regular_inserted specifies where to put the read bytes.
3683 Value is the number of bytes read. */
55587f8a
GM
3684
3685static Lisp_Object
1b978129 3686read_non_regular ()
55587f8a 3687{
1b978129 3688 int nbytes;
efdc16c9 3689
1b978129
GM
3690 immediate_quit = 1;
3691 QUIT;
3692 nbytes = emacs_read (non_regular_fd,
28c3eb5a 3693 BEG_ADDR + PT_BYTE - BEG_BYTE + non_regular_inserted,
1b978129 3694 non_regular_nbytes);
1b978129
GM
3695 immediate_quit = 0;
3696 return make_number (nbytes);
3697}
55587f8a 3698
d0e2444e 3699
1b978129
GM
3700/* Condition-case handler used when reading from non-regular files
3701 in insert-file-contents. */
3702
3703static Lisp_Object
3704read_non_regular_quit ()
3705{
55587f8a
GM
3706 return Qnil;
3707}
3708
3709
570d7624 3710DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
8c1a1077
PJ
3711 1, 5, 0,
3712 doc: /* Insert contents of file FILENAME after point.
cf6d2357 3713Returns list of absolute file name and number of characters inserted.
8c1a1077
PJ
3714If second argument VISIT is non-nil, the buffer's visited filename
3715and last save file modtime are set, and it is marked unmodified.
3716If visiting and the file does not exist, visiting is completed
3717before the error is signaled.
3718The optional third and fourth arguments BEG and END
3719specify what portion of the file to insert.
3720These arguments count bytes in the file, not characters in the buffer.
3721If VISIT is non-nil, BEG and END must be nil.
3722
3723If optional fifth argument REPLACE is non-nil,
3724it means replace the current buffer contents (in the accessible portion)
3725with the file contents. This is better than simply deleting and inserting
3726the whole thing because (1) it preserves some marker positions
3727and (2) it puts less data in the undo list.
3728When REPLACE is non-nil, the value is the number of characters actually read,
3729which is often less than the number of characters to be read.
3730
3731This does code conversion according to the value of
3732`coding-system-for-read' or `file-coding-system-alist',
3733and sets the variable `last-coding-system-used' to the coding system
3734actually used. */)
3735 (filename, visit, beg, end, replace)
3d0387c0 3736 Lisp_Object filename, visit, beg, end, replace;
570d7624
JB
3737{
3738 struct stat st;
3739 register int fd;
ec7adf26 3740 int inserted = 0;
570d7624 3741 register int how_much;
6fdaa9a0 3742 register int unprocessed;
331379bf 3743 int count = SPECPDL_INDEX ();
b1d1b865
RS
3744 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3745 Lisp_Object handler, val, insval, orig_filename;
d6a3cc15 3746 Lisp_Object p;
6bbd7a29 3747 int total = 0;
53c34c46 3748 int not_regular = 0;
feb9dc27 3749 unsigned char read_buf[READ_BUF_SIZE];
6fdaa9a0 3750 struct coding_system coding;
3dbcf3f6 3751 unsigned char buffer[1 << 14];
727a0b4a 3752 int replace_handled = 0;
ec7adf26 3753 int set_coding_system = 0;
f736ffbf 3754 int coding_system_decided = 0;
1b978129 3755 int read_quit = 0;
490ee853 3756 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
68780e2a 3757 int we_locked_file = 0;
32f4334d 3758
95385625
RS
3759 if (current_buffer->base_buffer && ! NILP (visit))
3760 error ("Cannot do file visiting in an indirect buffer");
3761
3762 if (!NILP (current_buffer->read_only))
3763 Fbarf_if_buffer_read_only ();
3764
32f4334d 3765 val = Qnil;
d6a3cc15 3766 p = Qnil;
b1d1b865 3767 orig_filename = Qnil;
32f4334d 3768
b1d1b865 3769 GCPRO4 (filename, val, p, orig_filename);
570d7624 3770
b7826503 3771 CHECK_STRING (filename);
570d7624
JB
3772 filename = Fexpand_file_name (filename, Qnil);
3773
32f4334d
RS
3774 /* If the file name has special constructs in it,
3775 call the corresponding file handler. */
49307295 3776 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
32f4334d
RS
3777 if (!NILP (handler))
3778 {
3d0387c0
RS
3779 val = call6 (handler, Qinsert_file_contents, filename,
3780 visit, beg, end, replace);
03699b14
KR
3781 if (CONSP (val) && CONSP (XCDR (val)))
3782 inserted = XINT (XCAR (XCDR (val)));
32f4334d
RS
3783 goto handled;
3784 }
3785
b1d1b865
RS
3786 orig_filename = filename;
3787 filename = ENCODE_FILE (filename);
3788
570d7624
JB
3789 fd = -1;
3790
c1c4693e
RS
3791#ifdef WINDOWSNT
3792 {
3793 Lisp_Object tem = Vw32_get_true_file_attributes;
3794
3795 /* Tell stat to use expensive method to get accurate info. */
3796 Vw32_get_true_file_attributes = Qt;
d5db4077 3797 total = stat (SDATA (filename), &st);
c1c4693e
RS
3798 Vw32_get_true_file_attributes = tem;
3799 }
3800 if (total < 0)
3801#else
570d7624 3802#ifndef APOLLO
d5db4077 3803 if (stat (SDATA (filename), &st) < 0)
570d7624 3804#else
d5db4077 3805 if ((fd = emacs_open (SDATA (filename), O_RDONLY, 0)) < 0
570d7624
JB
3806 || fstat (fd, &st) < 0)
3807#endif /* not APOLLO */
c1c4693e 3808#endif /* WINDOWSNT */
570d7624 3809 {
68c45bf0 3810 if (fd >= 0) emacs_close (fd);
99bc28f4 3811 badopen:
265a9e55 3812 if (NILP (visit))
b1d1b865 3813 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
570d7624
JB
3814 st.st_mtime = -1;
3815 how_much = 0;
0de6b8f4 3816 if (!NILP (Vcoding_system_for_read))
22d92d6b 3817 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
570d7624
JB
3818 goto notfound;
3819 }
3820
99bc28f4 3821#ifdef S_IFREG
be53b411
JB
3822 /* This code will need to be changed in order to work on named
3823 pipes, and it's probably just not worth it. So we should at
3824 least signal an error. */
99bc28f4 3825 if (!S_ISREG (st.st_mode))
330bfe57 3826 {
d4b8687b
RS
3827 not_regular = 1;
3828
3829 if (! NILP (visit))
3830 goto notfound;
3831
3832 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
24b1ddad
KS
3833 xsignal2 (Qfile_error,
3834 build_string ("not a regular file"), orig_filename);
330bfe57 3835 }
be53b411
JB
3836#endif
3837
99bc28f4 3838 if (fd < 0)
d5db4077 3839 if ((fd = emacs_open (SDATA (filename), O_RDONLY, 0)) < 0)
99bc28f4
KH
3840 goto badopen;
3841
3842 /* Replacement should preserve point as it preserves markers. */
3843 if (!NILP (replace))
3844 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3845
3846 record_unwind_protect (close_file_unwind, make_number (fd));
3847
570d7624 3848 /* Supposedly happens on VMS. */
11d300db
JR
3849 /* Can happen on any platform that uses long as type of off_t, but allows
3850 file sizes to exceed 2Gb. VMS is no longer officially supported, so
3851 give a message suitable for the latter case. */
d4b8687b 3852 if (! not_regular && st.st_size < 0)
11d300db 3853 error ("Maximum buffer size exceeded");
be53b411 3854
9c856db9
GM
3855 /* Prevent redisplay optimizations. */
3856 current_buffer->clip_changed = 1;
3857
9f57b6b4
KH
3858 if (!NILP (visit))
3859 {
3860 if (!NILP (beg) || !NILP (end))
3861 error ("Attempt to visit less than an entire file");
3862 if (BEG < Z && NILP (replace))
3863 error ("Cannot do file visiting in a non-empty buffer");
3864 }
7fded690
JB
3865
3866 if (!NILP (beg))
b7826503 3867 CHECK_NUMBER (beg);
7fded690 3868 else
2acfd7ae 3869 XSETFASTINT (beg, 0);
7fded690
JB
3870
3871 if (!NILP (end))
b7826503 3872 CHECK_NUMBER (end);
7fded690
JB
3873 else
3874 {
d4b8687b
RS
3875 if (! not_regular)
3876 {
3877 XSETINT (end, st.st_size);
68c45bf0
PE
3878
3879 /* Arithmetic overflow can occur if an Emacs integer cannot
3880 represent the file size, or if the calculations below
3881 overflow. The calculations below double the file size
3882 twice, so check that it can be multiplied by 4 safely. */
3883 if (XINT (end) != st.st_size
3884 || ((int) st.st_size * 4) / 4 != st.st_size)
d4b8687b 3885 error ("Maximum buffer size exceeded");
d21dd12d
GM
3886
3887 /* The file size returned from stat may be zero, but data
3888 may be readable nonetheless, for example when this is a
3889 file in the /proc filesystem. */
3890 if (st.st_size == 0)
3891 XSETINT (end, READ_BUF_SIZE);
d4b8687b 3892 }
7fded690
JB
3893 }
3894
356a6224
KH
3895 if (EQ (Vcoding_system_for_read, Qauto_save_coding))
3896 {
3897 /* We use emacs-mule for auto saving... */
3898 setup_coding_system (Qemacs_mule, &coding);
3899 /* ... but with the special flag to indicate to read in a
3900 multibyte sequence for eight-bit-control char as is. */
3901 coding.flags = 1;
3902 coding.src_multibyte = 0;
3903 coding.dst_multibyte
3904 = !NILP (current_buffer->enable_multibyte_characters);
3905 coding.eol_type = CODING_EOL_LF;
3906 coding_system_decided = 1;
3907 }
3908 else if (BEG < Z)
f736ffbf
KH
3909 {
3910 /* Decide the coding system to use for reading the file now
3911 because we can't use an optimized method for handling
3912 `coding:' tag if the current buffer is not empty. */
3913 Lisp_Object val;
3914 val = Qnil;
feb9dc27 3915
f736ffbf
KH
3916 if (!NILP (Vcoding_system_for_read))
3917 val = Vcoding_system_for_read;
f736ffbf
KH
3918 else
3919 {
3920 /* Don't try looking inside a file for a coding system
3921 specification if it is not seekable. */
3922 if (! not_regular && ! NILP (Vset_auto_coding_function))
3923 {
3924 /* Find a coding system specified in the heading two
3925 lines or in the tailing several lines of the file.
3926 We assume that the 1K-byte and 3K-byte for heading
003a7eaa 3927 and tailing respectively are sufficient for this
f736ffbf 3928 purpose. */
07590973 3929 int nread;
f736ffbf
KH
3930
3931 if (st.st_size <= (1024 * 4))
68c45bf0 3932 nread = emacs_read (fd, read_buf, 1024 * 4);
f736ffbf
KH
3933 else
3934 {
68c45bf0 3935 nread = emacs_read (fd, read_buf, 1024);
f736ffbf
KH
3936 if (nread >= 0)
3937 {
3938 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3939 report_file_error ("Setting file position",
3940 Fcons (orig_filename, Qnil));
68c45bf0 3941 nread += emacs_read (fd, read_buf + nread, 1024 * 3);
f736ffbf
KH
3942 }
3943 }
feb9dc27 3944
f736ffbf
KH
3945 if (nread < 0)
3946 error ("IO error reading %s: %s",
d5db4077 3947 SDATA (orig_filename), emacs_strerror (errno));
f736ffbf
KH
3948 else if (nread > 0)
3949 {
f736ffbf 3950 struct buffer *prev = current_buffer;
685fc579
RS
3951 Lisp_Object buffer;
3952 struct buffer *buf;
f736ffbf
KH
3953
3954 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1d92afcd 3955
685fc579
RS
3956 buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
3957 buf = XBUFFER (buffer);
3958
29ea8ae9 3959 delete_all_overlays (buf);
685fc579
RS
3960 buf->directory = current_buffer->directory;
3961 buf->read_only = Qnil;
3962 buf->filename = Qnil;
3963 buf->undo_list = Qt;
29ea8ae9
SM
3964 eassert (buf->overlays_before == NULL);
3965 eassert (buf->overlays_after == NULL);
efdc16c9 3966
685fc579
RS
3967 set_buffer_internal (buf);
3968 Ferase_buffer ();
3969 buf->enable_multibyte_characters = Qnil;
3970
f736ffbf
KH
3971 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3972 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
1255deb9
KH
3973 val = call2 (Vset_auto_coding_function,
3974 filename, make_number (nread));
f736ffbf 3975 set_buffer_internal (prev);
efdc16c9 3976
f736ffbf
KH
3977 /* Discard the unwind protect for recovering the
3978 current buffer. */
3979 specpdl_ptr--;
3980
3981 /* Rewind the file for the actual read done later. */
3982 if (lseek (fd, 0, 0) < 0)
3983 report_file_error ("Setting file position",
3984 Fcons (orig_filename, Qnil));
3985 }
3986 }
feb9dc27 3987
f736ffbf
KH
3988 if (NILP (val))
3989 {
3990 /* If we have not yet decided a coding system, check
3991 file-coding-system-alist. */
3992 Lisp_Object args[6], coding_systems;
3993
3994 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3995 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3996 coding_systems = Ffind_operation_coding_system (6, args);
3997 if (CONSP (coding_systems))
03699b14 3998 val = XCAR (coding_systems);
f736ffbf
KH
3999 }
4000 }
c9e82392 4001
f736ffbf 4002 setup_coding_system (Fcheck_coding_system (val), &coding);
f8569325
DL
4003 /* Ensure we set Vlast_coding_system_used. */
4004 set_coding_system = 1;
c8a6d68a 4005
237a6fd2
RS
4006 if (NILP (current_buffer->enable_multibyte_characters)
4007 && ! NILP (val))
4008 /* We must suppress all character code conversion except for
4009 end-of-line conversion. */
57515cfe 4010 setup_raw_text_coding_system (&coding);
54369368 4011
8c3b9441
KH
4012 coding.src_multibyte = 0;
4013 coding.dst_multibyte
4014 = !NILP (current_buffer->enable_multibyte_characters);
f736ffbf
KH
4015 coding_system_decided = 1;
4016 }
6cf71bf1 4017
3d0387c0
RS
4018 /* If requested, replace the accessible part of the buffer
4019 with the file contents. Avoid replacing text at the
4020 beginning or end of the buffer that matches the file contents;
3dbcf3f6
RS
4021 that preserves markers pointing to the unchanged parts.
4022
4023 Here we implement this feature in an optimized way
4024 for the case where code conversion is NOT needed.
4025 The following if-statement handles the case of conversion
727a0b4a
RS
4026 in a less optimal way.
4027
4028 If the code conversion is "automatic" then we try using this
4029 method and hope for the best.
4030 But if we discover the need for conversion, we give up on this method
4031 and let the following if-statement handle the replace job. */
3dbcf3f6 4032 if (!NILP (replace)
f736ffbf 4033 && BEGV < ZV
8c3b9441 4034 && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))
3d0387c0 4035 {
ec7adf26
RS
4036 /* same_at_start and same_at_end count bytes,
4037 because file access counts bytes
4038 and BEG and END count bytes. */
4039 int same_at_start = BEGV_BYTE;
4040 int same_at_end = ZV_BYTE;
9c28748f 4041 int overlap;
6fdaa9a0
KH
4042 /* There is still a possibility we will find the need to do code
4043 conversion. If that happens, we set this variable to 1 to
727a0b4a 4044 give up on handling REPLACE in the optimized way. */
6fdaa9a0 4045 int giveup_match_end = 0;
9c28748f 4046
4d2a0879
RS
4047 if (XINT (beg) != 0)
4048 {
4049 if (lseek (fd, XINT (beg), 0) < 0)
4050 report_file_error ("Setting file position",
b1d1b865 4051 Fcons (orig_filename, Qnil));
4d2a0879
RS
4052 }
4053
3d0387c0
RS
4054 immediate_quit = 1;
4055 QUIT;
4056 /* Count how many chars at the start of the file
4057 match the text at the beginning of the buffer. */
4058 while (1)
4059 {
4060 int nread, bufpos;
4061
68c45bf0 4062 nread = emacs_read (fd, buffer, sizeof buffer);
3d0387c0
RS
4063 if (nread < 0)
4064 error ("IO error reading %s: %s",
d5db4077 4065 SDATA (orig_filename), emacs_strerror (errno));
3d0387c0
RS
4066 else if (nread == 0)
4067 break;
6fdaa9a0 4068
0ef69138 4069 if (coding.type == coding_type_undecided)
727a0b4a 4070 detect_coding (&coding, buffer, nread);
8c3b9441 4071 if (coding.common_flags & CODING_REQUIRE_DECODING_MASK)
727a0b4a
RS
4072 /* We found that the file should be decoded somehow.
4073 Let's give up here. */
4074 {
4075 giveup_match_end = 1;
4076 break;
4077 }
4078
0ef69138 4079 if (coding.eol_type == CODING_EOL_UNDECIDED)
727a0b4a 4080 detect_eol (&coding, buffer, nread);
1b335d29 4081 if (coding.eol_type != CODING_EOL_UNDECIDED
70ec4328 4082 && coding.eol_type != CODING_EOL_LF)
727a0b4a
RS
4083 /* We found that the format of eol should be decoded.
4084 Let's give up here. */
4085 {
4086 giveup_match_end = 1;
4087 break;
4088 }
4089
3d0387c0 4090 bufpos = 0;
ec7adf26 4091 while (bufpos < nread && same_at_start < ZV_BYTE
6fdaa9a0 4092 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3d0387c0
RS
4093 same_at_start++, bufpos++;
4094 /* If we found a discrepancy, stop the scan.
8e6208c5 4095 Otherwise loop around and scan the next bufferful. */
3d0387c0
RS
4096 if (bufpos != nread)
4097 break;
4098 }
4099 immediate_quit = 0;
4100 /* If the file matches the buffer completely,
4101 there's no need to replace anything. */
ec7adf26 4102 if (same_at_start - BEGV_BYTE == XINT (end))
3d0387c0 4103 {
68c45bf0 4104 emacs_close (fd);
a1d2b64a 4105 specpdl_ptr--;
1051b3b3 4106 /* Truncate the buffer to the size of the file. */
7dae4502 4107 del_range_1 (same_at_start, same_at_end, 0, 0);
3d0387c0
RS
4108 goto handled;
4109 }
4110 immediate_quit = 1;
4111 QUIT;
4112 /* Count how many chars at the end of the file
6fdaa9a0
KH
4113 match the text at the end of the buffer. But, if we have
4114 already found that decoding is necessary, don't waste time. */
4115 while (!giveup_match_end)
3d0387c0
RS
4116 {
4117 int total_read, nread, bufpos, curpos, trial;
4118
4119 /* At what file position are we now scanning? */
ec7adf26 4120 curpos = XINT (end) - (ZV_BYTE - same_at_end);
fc81fa9e
KH
4121 /* If the entire file matches the buffer tail, stop the scan. */
4122 if (curpos == 0)
4123 break;
3d0387c0
RS
4124 /* How much can we scan in the next step? */
4125 trial = min (curpos, sizeof buffer);
4126 if (lseek (fd, curpos - trial, 0) < 0)
4127 report_file_error ("Setting file position",
b1d1b865 4128 Fcons (orig_filename, Qnil));
3d0387c0 4129
b02439c8 4130 total_read = nread = 0;
3d0387c0
RS
4131 while (total_read < trial)
4132 {
68c45bf0 4133 nread = emacs_read (fd, buffer + total_read, trial - total_read);
2bd2273e 4134 if (nread < 0)
3d0387c0 4135 error ("IO error reading %s: %s",
d5db4077 4136 SDATA (orig_filename), emacs_strerror (errno));
2bd2273e
GM
4137 else if (nread == 0)
4138 break;
3d0387c0
RS
4139 total_read += nread;
4140 }
efdc16c9 4141
8e6208c5 4142 /* Scan this bufferful from the end, comparing with
3d0387c0
RS
4143 the Emacs buffer. */
4144 bufpos = total_read;
efdc16c9 4145
3d0387c0
RS
4146 /* Compare with same_at_start to avoid counting some buffer text
4147 as matching both at the file's beginning and at the end. */
4148 while (bufpos > 0 && same_at_end > same_at_start
6fdaa9a0 4149 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3d0387c0 4150 same_at_end--, bufpos--;
727a0b4a 4151
3d0387c0 4152 /* If we found a discrepancy, stop the scan.
8e6208c5 4153 Otherwise loop around and scan the preceding bufferful. */
3d0387c0 4154 if (bufpos != 0)
727a0b4a
RS
4155 {
4156 /* If this discrepancy is because of code conversion,
4157 we cannot use this method; giveup and try the other. */
4158 if (same_at_end > same_at_start
4159 && FETCH_BYTE (same_at_end - 1) >= 0200
71312b68 4160 && ! NILP (current_buffer->enable_multibyte_characters)
c8a6d68a 4161 && (CODING_MAY_REQUIRE_DECODING (&coding)))
727a0b4a
RS
4162 giveup_match_end = 1;
4163 break;
4164 }
b02439c8
GM
4165
4166 if (nread == 0)
4167 break;
3d0387c0
RS
4168 }
4169 immediate_quit = 0;
9c28748f 4170
727a0b4a
RS
4171 if (! giveup_match_end)
4172 {
ec7adf26
RS
4173 int temp;
4174
727a0b4a 4175 /* We win! We can handle REPLACE the optimized way. */
9c28748f 4176
20f6783d
RS
4177 /* Extend the start of non-matching text area to multibyte
4178 character boundary. */
4179 if (! NILP (current_buffer->enable_multibyte_characters))
4180 while (same_at_start > BEGV_BYTE
4181 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4182 same_at_start--;
4183
4184 /* Extend the end of non-matching text area to multibyte
71312b68
RS
4185 character boundary. */
4186 if (! NILP (current_buffer->enable_multibyte_characters))
ec7adf26
RS
4187 while (same_at_end < ZV_BYTE
4188 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
71312b68
RS
4189 same_at_end++;
4190
727a0b4a 4191 /* Don't try to reuse the same piece of text twice. */
ec7adf26
RS
4192 overlap = (same_at_start - BEGV_BYTE
4193 - (same_at_end + st.st_size - ZV));
727a0b4a
RS
4194 if (overlap > 0)
4195 same_at_end += overlap;
9c28748f 4196
727a0b4a 4197 /* Arrange to read only the nonmatching middle part of the file. */
ec7adf26
RS
4198 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
4199 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3dbcf3f6 4200
ec7adf26 4201 del_range_byte (same_at_start, same_at_end, 0);
727a0b4a 4202 /* Insert from the file at the proper position. */
ec7adf26
RS
4203 temp = BYTE_TO_CHAR (same_at_start);
4204 SET_PT_BOTH (temp, same_at_start);
727a0b4a
RS
4205
4206 /* If display currently starts at beginning of line,
4207 keep it that way. */
4208 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4209 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4210
4211 replace_handled = 1;
4212 }
3dbcf3f6
RS
4213 }
4214
4215 /* If requested, replace the accessible part of the buffer
4216 with the file contents. Avoid replacing text at the
4217 beginning or end of the buffer that matches the file contents;
4218 that preserves markers pointing to the unchanged parts.
4219
4220 Here we implement this feature for the case where code conversion
4221 is needed, in a simple way that needs a lot of memory.
4222 The preceding if-statement handles the case of no conversion
4223 in a more optimized way. */
f736ffbf 4224 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
3dbcf3f6 4225 {
ec7adf26
RS
4226 int same_at_start = BEGV_BYTE;
4227 int same_at_end = ZV_BYTE;
3dbcf3f6
RS
4228 int overlap;
4229 int bufpos;
4230 /* Make sure that the gap is large enough. */
4231 int bufsize = 2 * st.st_size;
b00ca0d7 4232 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
ec7adf26 4233 int temp;
3dbcf3f6
RS
4234
4235 /* First read the whole file, performing code conversion into
4236 CONVERSION_BUFFER. */
4237
727a0b4a
RS
4238 if (lseek (fd, XINT (beg), 0) < 0)
4239 {
68cfd853 4240 xfree (conversion_buffer);
727a0b4a 4241 report_file_error ("Setting file position",
b1d1b865 4242 Fcons (orig_filename, Qnil));
727a0b4a
RS
4243 }
4244
3dbcf3f6
RS
4245 total = st.st_size; /* Total bytes in the file. */
4246 how_much = 0; /* Bytes read from file so far. */
4247 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4248 unprocessed = 0; /* Bytes not processed in previous loop. */
4249
4250 while (how_much < total)
4251 {
4252 /* try is reserved in some compilers (Microsoft C) */
4253 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
cadf50ff 4254 unsigned char *destination = read_buf + unprocessed;
3dbcf3f6
RS
4255 int this;
4256
4257 /* Allow quitting out of the actual I/O. */
4258 immediate_quit = 1;
4259 QUIT;
68c45bf0 4260 this = emacs_read (fd, destination, trytry);
3dbcf3f6
RS
4261 immediate_quit = 0;
4262
4263 if (this < 0 || this + unprocessed == 0)
4264 {
4265 how_much = this;
4266 break;
4267 }
4268
4269 how_much += this;
4270
c8a6d68a 4271 if (CODING_MAY_REQUIRE_DECODING (&coding))
3dbcf3f6 4272 {
c8a6d68a 4273 int require, result;
3dbcf3f6
RS
4274
4275 this += unprocessed;
4276
4277 /* If we are using more space than estimated,
4278 make CONVERSION_BUFFER bigger. */
4279 require = decoding_buffer_size (&coding, this);
4280 if (inserted + require + 2 * (total - how_much) > bufsize)
4281 {
4282 bufsize = inserted + require + 2 * (total - how_much);
92cf1086 4283 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
3dbcf3f6
RS
4284 }
4285
4286 /* Convert this batch with results in CONVERSION_BUFFER. */
4287 if (how_much >= total) /* This is the last block. */
c8a6d68a 4288 coding.mode |= CODING_MODE_LAST_BLOCK;
1ddb09f5
GM
4289 if (coding.composing != COMPOSITION_DISABLED)
4290 coding_allocate_composition_data (&coding, BEGV);
c8a6d68a
KH
4291 result = decode_coding (&coding, read_buf,
4292 conversion_buffer + inserted,
4293 this, bufsize - inserted);
3dbcf3f6
RS
4294
4295 /* Save for next iteration whatever we didn't convert. */
c8a6d68a
KH
4296 unprocessed = this - coding.consumed;
4297 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
8c3b9441
KH
4298 if (!NILP (current_buffer->enable_multibyte_characters))
4299 this = coding.produced;
4300 else
4301 this = str_as_unibyte (conversion_buffer + inserted,
4302 coding.produced);
3dbcf3f6
RS
4303 }
4304
4305 inserted += this;
4306 }
4307
c8a6d68a 4308 /* At this point, INSERTED is how many characters (i.e. bytes)
3dbcf3f6
RS
4309 are present in CONVERSION_BUFFER.
4310 HOW_MUCH should equal TOTAL,
4311 or should be <= 0 if we couldn't read the file. */
4312
4313 if (how_much < 0)
4314 {
a36837e4 4315 xfree (conversion_buffer);
e254e5e5 4316 coding_free_composition_data (&coding);
17ad716a
KH
4317 error ("IO error reading %s: %s",
4318 SDATA (orig_filename), emacs_strerror (errno));
3dbcf3f6
RS
4319 }
4320
4321 /* Compare the beginning of the converted file
4322 with the buffer text. */
4323
4324 bufpos = 0;
4325 while (bufpos < inserted && same_at_start < same_at_end
4326 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
4327 same_at_start++, bufpos++;
4328
4329 /* If the file matches the buffer completely,
4330 there's no need to replace anything. */
4331
4332 if (bufpos == inserted)
4333 {
a36837e4 4334 xfree (conversion_buffer);
e254e5e5 4335 coding_free_composition_data (&coding);
68c45bf0 4336 emacs_close (fd);
3dbcf3f6
RS
4337 specpdl_ptr--;
4338 /* Truncate the buffer to the size of the file. */
427f5aab
KH
4339 del_range_byte (same_at_start, same_at_end, 0);
4340 inserted = 0;
3dbcf3f6
RS
4341 goto handled;
4342 }
4343
20f6783d
RS
4344 /* Extend the start of non-matching text area to multibyte
4345 character boundary. */
4346 if (! NILP (current_buffer->enable_multibyte_characters))
4347 while (same_at_start > BEGV_BYTE
4348 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4349 same_at_start--;
4350
3dbcf3f6
RS
4351 /* Scan this bufferful from the end, comparing with
4352 the Emacs buffer. */
4353 bufpos = inserted;
4354
4355 /* Compare with same_at_start to avoid counting some buffer text
4356 as matching both at the file's beginning and at the end. */
4357 while (bufpos > 0 && same_at_end > same_at_start
4358 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
4359 same_at_end--, bufpos--;
4360
20f6783d
RS
4361 /* Extend the end of non-matching text area to multibyte
4362 character boundary. */
4363 if (! NILP (current_buffer->enable_multibyte_characters))
4364 while (same_at_end < ZV_BYTE
4365 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
4366 same_at_end++;
4367
3dbcf3f6 4368 /* Don't try to reuse the same piece of text twice. */
ec7adf26 4369 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3dbcf3f6
RS
4370 if (overlap > 0)
4371 same_at_end += overlap;
4372
727a0b4a
RS
4373 /* If display currently starts at beginning of line,
4374 keep it that way. */
4375 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4376 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4377
3dbcf3f6
RS
4378 /* Replace the chars that we need to replace,
4379 and update INSERTED to equal the number of bytes
4380 we are taking from the file. */
4b70e2c9 4381 inserted -= (ZV_BYTE - same_at_end) + (same_at_start - BEGV_BYTE);
427f5aab 4382
643c73b9 4383 if (same_at_end != same_at_start)
427f5aab
KH
4384 {
4385 del_range_byte (same_at_start, same_at_end, 0);
4386 temp = GPT;
4387 same_at_start = GPT_BYTE;
4388 }
643c73b9
RS
4389 else
4390 {
643c73b9 4391 temp = BYTE_TO_CHAR (same_at_start);
643c73b9 4392 }
427f5aab
KH
4393 /* Insert from the file at the proper position. */
4394 SET_PT_BOTH (temp, same_at_start);
4b70e2c9 4395 insert_1 (conversion_buffer + same_at_start - BEGV_BYTE, inserted,
ec7adf26 4396 0, 0, 0);
1ddb09f5
GM
4397 if (coding.cmp_data && coding.cmp_data->used)
4398 coding_restore_composition (&coding, Fcurrent_buffer ());
4399 coding_free_composition_data (&coding);
efdc16c9 4400
427f5aab
KH
4401 /* Set `inserted' to the number of inserted characters. */
4402 inserted = PT - temp;
77343e1d
KH
4403 /* Set point before the inserted characters. */
4404 SET_PT_BOTH (temp, same_at_start);
3dbcf3f6 4405
93184560 4406 xfree (conversion_buffer);
68c45bf0 4407 emacs_close (fd);
3dbcf3f6
RS
4408 specpdl_ptr--;
4409
3dbcf3f6 4410 goto handled;
3d0387c0
RS
4411 }
4412
d4b8687b
RS
4413 if (! not_regular)
4414 {
4415 register Lisp_Object temp;
7fded690 4416
d4b8687b 4417 total = XINT (end) - XINT (beg);
570d7624 4418
d4b8687b
RS
4419 /* Make sure point-max won't overflow after this insertion. */
4420 XSETINT (temp, total);
4421 if (total != XINT (temp))
4422 error ("Maximum buffer size exceeded");
4423 }
4424 else
4425 /* For a special file, all we can do is guess. */
4426 total = READ_BUF_SIZE;
570d7624 4427
68780e2a
RS
4428 if (NILP (visit) && inserted > 0)
4429 {
4430#ifdef CLASH_DETECTION
4431 if (!NILP (current_buffer->file_truename)
4432 /* Make binding buffer-file-name to nil effective. */
4433 && !NILP (current_buffer->filename)
4434 && SAVE_MODIFF >= MODIFF)
4435 we_locked_file = 1;
4436#endif /* CLASH_DETECTION */
4437 prepare_to_modify_buffer (GPT, GPT, NULL);
4438 }
570d7624 4439
7fe52289 4440 move_gap (PT);
7fded690
JB
4441 if (GAP_SIZE < total)
4442 make_gap (total - GAP_SIZE);
4443
a1d2b64a 4444 if (XINT (beg) != 0 || !NILP (replace))
7fded690
JB
4445 {
4446 if (lseek (fd, XINT (beg), 0) < 0)
b1d1b865
RS
4447 report_file_error ("Setting file position",
4448 Fcons (orig_filename, Qnil));
7fded690
JB
4449 }
4450
6fdaa9a0 4451 /* In the following loop, HOW_MUCH contains the total bytes read so
c8a6d68a
KH
4452 far for a regular file, and not changed for a special file. But,
4453 before exiting the loop, it is set to a negative value if I/O
4454 error occurs. */
a1d2b64a 4455 how_much = 0;
efdc16c9 4456
6fdaa9a0
KH
4457 /* Total bytes inserted. */
4458 inserted = 0;
efdc16c9 4459
c8a6d68a
KH
4460 /* Here, we don't do code conversion in the loop. It is done by
4461 code_convert_region after all data are read into the buffer. */
1b978129
GM
4462 {
4463 int gap_size = GAP_SIZE;
efdc16c9 4464
1b978129
GM
4465 while (how_much < total)
4466 {
5e570b75 4467 /* try is reserved in some compilers (Microsoft C) */
1b978129
GM
4468 int trytry = min (total - how_much, READ_BUF_SIZE);
4469 int this;
570d7624 4470
1b978129
GM
4471 if (not_regular)
4472 {
4473 Lisp_Object val;
570d7624 4474
1b978129
GM
4475 /* Maybe make more room. */
4476 if (gap_size < trytry)
4477 {
4478 make_gap (total - gap_size);
4479 gap_size = GAP_SIZE;
4480 }
4481
4482 /* Read from the file, capturing `quit'. When an
4483 error occurs, end the loop, and arrange for a quit
4484 to be signaled after decoding the text we read. */
4485 non_regular_fd = fd;
4486 non_regular_inserted = inserted;
4487 non_regular_nbytes = trytry;
4488 val = internal_condition_case_1 (read_non_regular, Qnil, Qerror,
4489 read_non_regular_quit);
4490 if (NILP (val))
4491 {
4492 read_quit = 1;
4493 break;
4494 }
4495
4496 this = XINT (val);
4497 }
4498 else
4499 {
4500 /* Allow quitting out of the actual I/O. We don't make text
4501 part of the buffer until all the reading is done, so a C-g
4502 here doesn't do any harm. */
4503 immediate_quit = 1;
4504 QUIT;
28c3eb5a 4505 this = emacs_read (fd, BEG_ADDR + PT_BYTE - BEG_BYTE + inserted, trytry);
1b978129
GM
4506 immediate_quit = 0;
4507 }
efdc16c9 4508
1b978129
GM
4509 if (this <= 0)
4510 {
4511 how_much = this;
4512 break;
4513 }
4514
4515 gap_size -= this;
4516
4517 /* For a regular file, where TOTAL is the real size,
4518 count HOW_MUCH to compare with it.
4519 For a special file, where TOTAL is just a buffer size,
4520 so don't bother counting in HOW_MUCH.
4521 (INSERTED is where we count the number of characters inserted.) */
4522 if (! not_regular)
4523 how_much += this;
4524 inserted += this;
4525 }
4526 }
4527
68780e2a
RS
4528 /* Now we have read all the file data into the gap.
4529 If it was empty, undo marking the buffer modified. */
4530
4531 if (inserted == 0)
4532 {
6840d350 4533#ifdef CLASH_DETECTION
68780e2a
RS
4534 if (we_locked_file)
4535 unlock_file (current_buffer->file_truename);
6840d350 4536#endif
68780e2a
RS
4537 Vdeactivate_mark = old_Vdeactivate_mark;
4538 }
83c1cf6d
RS
4539 else
4540 Vdeactivate_mark = Qt;
68780e2a 4541
1b978129
GM
4542 /* Make the text read part of the buffer. */
4543 GAP_SIZE -= inserted;
4544 GPT += inserted;
4545 GPT_BYTE += inserted;
4546 ZV += inserted;
4547 ZV_BYTE += inserted;
4548 Z += inserted;
4549 Z_BYTE += inserted;
6fdaa9a0 4550
c8a6d68a
KH
4551 if (GAP_SIZE > 0)
4552 /* Put an anchor to ensure multi-byte form ends at gap. */
4553 *GPT_ADDR = 0;
d4b8687b 4554
68c45bf0 4555 emacs_close (fd);
6fdaa9a0 4556
c8a6d68a
KH
4557 /* Discard the unwind protect for closing the file. */
4558 specpdl_ptr--;
6fdaa9a0 4559
c8a6d68a
KH
4560 if (how_much < 0)
4561 error ("IO error reading %s: %s",
d5db4077 4562 SDATA (orig_filename), emacs_strerror (errno));
ec7adf26 4563
f8569325
DL
4564 notfound:
4565
2df42e09 4566 if (! coding_system_decided)
c8a6d68a 4567 {
2df42e09 4568 /* The coding system is not yet decided. Decide it by an
dfe35e7b
RS
4569 optimized method for handling `coding:' tag.
4570
4571 Note that we can get here only if the buffer was empty
4572 before the insertion. */
2df42e09
KH
4573 Lisp_Object val;
4574 val = Qnil;
f736ffbf 4575
2df42e09
KH
4576 if (!NILP (Vcoding_system_for_read))
4577 val = Vcoding_system_for_read;
4578 else
4579 {
98a7d268
KH
4580 /* Since we are sure that the current buffer was empty
4581 before the insertion, we can toggle
4582 enable-multibyte-characters directly here without taking
4583 care of marker adjustment and byte combining problem. By
4584 this way, we can run Lisp program safely before decoding
4585 the inserted text. */
4586 Lisp_Object unwind_data;
87e3d54c 4587 int count = SPECPDL_INDEX ();
2df42e09 4588
98a7d268
KH
4589 unwind_data = Fcons (current_buffer->enable_multibyte_characters,
4590 Fcons (current_buffer->undo_list,
4591 Fcurrent_buffer ()));
87e3d54c 4592 current_buffer->enable_multibyte_characters = Qnil;
98a7d268
KH
4593 current_buffer->undo_list = Qt;
4594 record_unwind_protect (decide_coding_unwind, unwind_data);
4595
4596 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4597 {
1255deb9
KH
4598 val = call2 (Vset_auto_coding_function,
4599 filename, make_number (inserted));
2df42e09 4600 }
f736ffbf 4601
2df42e09
KH
4602 if (NILP (val))
4603 {
4604 /* If the coding system is not yet decided, check
4605 file-coding-system-alist. */
4606 Lisp_Object args[6], coding_systems;
f736ffbf 4607
2df42e09
KH
4608 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4609 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4610 coding_systems = Ffind_operation_coding_system (6, args);
4611 if (CONSP (coding_systems))
03699b14 4612 val = XCAR (coding_systems);
f736ffbf 4613 }
98a7d268
KH
4614 unbind_to (count, Qnil);
4615 inserted = Z_BYTE - BEG_BYTE;
2df42e09 4616 }
f736ffbf 4617
2df42e09
KH
4618 /* The following kludgy code is to avoid some compiler bug.
4619 We can't simply do
4620 setup_coding_system (val, &coding);
4621 on some system. */
4622 {
4623 struct coding_system temp_coding;
87e3d54c 4624 setup_coding_system (Fcheck_coding_system (val), &temp_coding);
2df42e09
KH
4625 bcopy (&temp_coding, &coding, sizeof coding);
4626 }
f8569325
DL
4627 /* Ensure we set Vlast_coding_system_used. */
4628 set_coding_system = 1;
f736ffbf 4629
237a6fd2
RS
4630 if (NILP (current_buffer->enable_multibyte_characters)
4631 && ! NILP (val))
4632 /* We must suppress all character code conversion except for
2df42e09
KH
4633 end-of-line conversion. */
4634 setup_raw_text_coding_system (&coding);
6db43875
KH
4635 coding.src_multibyte = 0;
4636 coding.dst_multibyte
4637 = !NILP (current_buffer->enable_multibyte_characters);
2df42e09 4638 }
f736ffbf 4639
8c3b9441 4640 if (!NILP (visit)
24766480
GM
4641 /* Can't do this if part of the buffer might be preserved. */
4642 && NILP (replace)
8c3b9441
KH
4643 && (coding.type == coding_type_no_conversion
4644 || coding.type == coding_type_raw_text))
4645 {
24766480
GM
4646 /* Visiting a file with these coding system makes the buffer
4647 unibyte. */
4648 current_buffer->enable_multibyte_characters = Qnil;
e1249666 4649 coding.dst_multibyte = 0;
8c3b9441
KH
4650 }
4651
c91beee2 4652 if (inserted > 0 || coding.type == coding_type_ccl)
2df42e09 4653 {
c8a6d68a 4654 if (CODING_MAY_REQUIRE_DECODING (&coding))
64e0ae2a 4655 {
fe56282f
KH
4656 if (coding.type == coding_type_ccl)
4657 coding.spec.ccl.decoder.quit_silently = 1;
64e0ae2a
KH
4658 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4659 &coding, 0, 0);
fe56282f
KH
4660 if (coding.type == coding_type_ccl)
4661 coding.spec.ccl.decoder.quit_silently = 0;
4662 if (coding.result == CODING_FINISH_INTERRUPT)
4663 {
4664 /* Fixme: It is better that we report that the decoding
4665 was interruppted by the user, and the current buffer
4666 contents doesn't reflect the file correctly. */
4667 Fsignal (Qquit, Qnil);
4668 }
8c3b9441 4669 inserted = coding.produced_char;
f8198e19 4670 }
e9cea947
AS
4671 else
4672 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
8c3b9441 4673 inserted);
2df42e09 4674 }
570d7624 4675
cf6d2357
RS
4676 /* Now INSERTED is measured in characters. */
4677
04e6f79c 4678#ifdef DOS_NT
2df42e09
KH
4679 /* Use the conversion type to determine buffer-file-type
4680 (find-buffer-file-type is now used to help determine the
4681 conversion). */
efdc16c9 4682 if ((coding.eol_type == CODING_EOL_UNDECIDED
2df42e09
KH
4683 || coding.eol_type == CODING_EOL_LF)
4684 && ! CODING_REQUIRE_DECODING (&coding))
4685 current_buffer->buffer_file_type = Qt;
4686 else
4687 current_buffer->buffer_file_type = Qnil;
04e6f79c 4688#endif
570d7624 4689
32f4334d 4690 handled:
570d7624 4691
265a9e55 4692 if (!NILP (visit))
570d7624 4693 {
cfadd376
RS
4694 if (!EQ (current_buffer->undo_list, Qt))
4695 current_buffer->undo_list = Qnil;
570d7624 4696#ifdef APOLLO
d5db4077 4697 stat (SDATA (filename), &st);
570d7624 4698#endif
62bcf009 4699
a7e82472
RS
4700 if (NILP (handler))
4701 {
4702 current_buffer->modtime = st.st_mtime;
b1d1b865 4703 current_buffer->filename = orig_filename;
a7e82472 4704 }
62bcf009 4705
95385625 4706 SAVE_MODIFF = MODIFF;
570d7624 4707 current_buffer->auto_save_modified = MODIFF;
2acfd7ae 4708 XSETFASTINT (current_buffer->save_length, Z - BEG);
570d7624 4709#ifdef CLASH_DETECTION
32f4334d
RS
4710 if (NILP (handler))
4711 {
f471f4c2
RS
4712 if (!NILP (current_buffer->file_truename))
4713 unlock_file (current_buffer->file_truename);
32f4334d
RS
4714 unlock_file (filename);
4715 }
570d7624 4716#endif /* CLASH_DETECTION */
330bfe57 4717 if (not_regular)
24b1ddad
KS
4718 xsignal2 (Qfile_error,
4719 build_string ("not a regular file"), orig_filename);
570d7624
JB
4720 }
4721
b6426b03
KH
4722 if (set_coding_system)
4723 Vlast_coding_system_used = coding.symbol;
4724
2080470e 4725 if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))
b6426b03 4726 {
37a3c774
KH
4727 insval = call2 (Qafter_insert_file_set_coding, make_number (inserted),
4728 visit);
b6426b03
KH
4729 if (! NILP (insval))
4730 {
4731 CHECK_NUMBER (insval);
4732 inserted = XFASTINT (insval);
4733 }
4734 }
4735
0d420e88 4736 /* Decode file format */
c8a6d68a 4737 if (inserted > 0)
0d420e88 4738 {
ed8e506f 4739 int empty_undo_list_p = 0;
efdc16c9 4740
ed8e506f
GM
4741 /* If we're anyway going to discard undo information, don't
4742 record it in the first place. The buffer's undo list at this
4743 point is either nil or t when visiting a file. */
4744 if (!NILP (visit))
4745 {
4746 empty_undo_list_p = NILP (current_buffer->undo_list);
4747 current_buffer->undo_list = Qt;
4748 }
efdc16c9 4749
199607e4 4750 insval = call3 (Qformat_decode,
c8a6d68a 4751 Qnil, make_number (inserted), visit);
b7826503 4752 CHECK_NUMBER (insval);
c8a6d68a 4753 inserted = XFASTINT (insval);
efdc16c9 4754
ed8e506f
GM
4755 if (!NILP (visit))
4756 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
0d420e88
BG
4757 }
4758
0342d8c5
RS
4759 /* Call after-change hooks for the inserted text, aside from the case
4760 of normal visiting (not with REPLACE), which is done in a new buffer
4761 "before" the buffer is changed. */
c8a6d68a 4762 if (inserted > 0 && total > 0
0342d8c5 4763 && (NILP (visit) || !NILP (replace)))
ce51c54c
KH
4764 {
4765 signal_after_change (PT, 0, inserted);
4766 update_compositions (PT, PT, CHECK_BORDER);
4767 }
b56567b5 4768
f8569325 4769 p = Vafter_insert_file_functions;
28c3eb5a 4770 while (CONSP (p))
d6a3cc15 4771 {
28c3eb5a 4772 insval = call1 (XCAR (p), make_number (inserted));
f8569325 4773 if (!NILP (insval))
d6a3cc15 4774 {
b7826503 4775 CHECK_NUMBER (insval);
f8569325 4776 inserted = XFASTINT (insval);
d6a3cc15 4777 }
f8569325 4778 QUIT;
28c3eb5a 4779 p = XCDR (p);
f8569325
DL
4780 }
4781
4782 if (!NILP (visit)
4783 && current_buffer->modtime == -1)
4784 {
4785 /* If visiting nonexistent file, return nil. */
4786 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
d6a3cc15
RS
4787 }
4788
1b978129
GM
4789 if (read_quit)
4790 Fsignal (Qquit, Qnil);
4791
ec7adf26 4792 /* ??? Retval needs to be dealt with in all cases consistently. */
a1d2b64a 4793 if (NILP (val))
b1d1b865 4794 val = Fcons (orig_filename,
a1d2b64a
RS
4795 Fcons (make_number (inserted),
4796 Qnil));
4797
4798 RETURN_UNGCPRO (unbind_to (count, val));
570d7624 4799}
7fded690 4800\f
236a12f2
SM
4801static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
4802static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
4803 Lisp_Object, Lisp_Object));
d6a3cc15 4804
6fc6f94b 4805/* If build_annotations switched buffers, switch back to BUF.
6fdaa9a0
KH
4806 Kill the temporary buffer that was selected in the meantime.
4807
4808 Since this kill only the last temporary buffer, some buffers remain
4809 not killed if build_annotations switched buffers more than once.
4810 -- K.Handa */
6fc6f94b 4811
199607e4 4812static Lisp_Object
6fc6f94b
RS
4813build_annotations_unwind (buf)
4814 Lisp_Object buf;
4815{
4816 Lisp_Object tembuf;
4817
4818 if (XBUFFER (buf) == current_buffer)
4819 return Qnil;
4820 tembuf = Fcurrent_buffer ();
4821 Fset_buffer (buf);
4822 Fkill_buffer (tembuf);
4823 return Qnil;
4824}
4825
7c82a4a9
SM
4826/* Decide the coding-system to encode the data with. */
4827
4828void
4829choose_write_coding_system (start, end, filename,
4830 append, visit, lockname, coding)
4831 Lisp_Object start, end, filename, append, visit, lockname;
4832 struct coding_system *coding;
4833{
4834 Lisp_Object val;
4835
dc2628c1
RS
4836 if (auto_saving
4837 && NILP (Fstring_equal (current_buffer->filename,
4838 current_buffer->auto_save_file_name)))
356a6224
KH
4839 {
4840 /* We use emacs-mule for auto saving... */
4841 setup_coding_system (Qemacs_mule, coding);
4842 /* ... but with the special flag to indicate not to strip off
4843 leading code of eight-bit-control chars. */
4844 coding->flags = 1;
29cbc482
KH
4845 /* We force LF for end-of-line because that is faster. */
4846 coding->eol_type = CODING_EOL_LF;
356a6224
KH
4847 goto done_setup_coding;
4848 }
7c82a4a9 4849 else if (!NILP (Vcoding_system_for_write))
42b01e1e
KH
4850 {
4851 val = Vcoding_system_for_write;
4852 if (coding_system_require_warning
4853 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4854 /* Confirm that VAL can surely encode the current region. */
4855 val = call5 (Vselect_safe_coding_system_function,
4856 start, end, Fcons (Qt, Fcons (val, Qnil)),
4857 Qnil, filename);
4858 }
7c82a4a9
SM
4859 else
4860 {
4861 /* If the variable `buffer-file-coding-system' is set locally,
4862 it means that the file was read with some kind of code
4863 conversion or the variable is explicitly set by users. We
4864 had better write it out with the same coding system even if
4865 `enable-multibyte-characters' is nil.
4866
4867 If it is not set locally, we anyway have to convert EOL
4868 format if the default value of `buffer-file-coding-system'
4869 tells that it is not Unix-like (LF only) format. */
4870 int using_default_coding = 0;
4871 int force_raw_text = 0;
4872
4873 val = current_buffer->buffer_file_coding_system;
4874 if (NILP (val)
4875 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4876 {
4877 val = Qnil;
4878 if (NILP (current_buffer->enable_multibyte_characters))
4879 force_raw_text = 1;
4880 }
efdc16c9 4881
7c82a4a9
SM
4882 if (NILP (val))
4883 {
4884 /* Check file-coding-system-alist. */
4885 Lisp_Object args[7], coding_systems;
4886
4887 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4888 args[3] = filename; args[4] = append; args[5] = visit;
4889 args[6] = lockname;
4890 coding_systems = Ffind_operation_coding_system (7, args);
4891 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4892 val = XCDR (coding_systems);
4893 }
4894
4895 if (NILP (val)
4896 && !NILP (current_buffer->buffer_file_coding_system))
4897 {
4898 /* If we still have not decided a coding system, use the
4899 default value of buffer-file-coding-system. */
4900 val = current_buffer->buffer_file_coding_system;
4901 using_default_coding = 1;
4902 }
efdc16c9 4903
7c82a4a9
SM
4904 if (!force_raw_text
4905 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4906 /* Confirm that VAL can surely encode the current region. */
905a4276
PJ
4907 val = call5 (Vselect_safe_coding_system_function,
4908 start, end, val, Qnil, filename);
7c82a4a9
SM
4909
4910 setup_coding_system (Fcheck_coding_system (val), coding);
4911 if (coding->eol_type == CODING_EOL_UNDECIDED
4912 && !using_default_coding)
4913 {
4914 if (! EQ (default_buffer_file_coding.symbol,
4915 buffer_defaults.buffer_file_coding_system))
4916 setup_coding_system (buffer_defaults.buffer_file_coding_system,
4917 &default_buffer_file_coding);
4918 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)
4919 {
4920 Lisp_Object subsidiaries;
4921
4922 coding->eol_type = default_buffer_file_coding.eol_type;
4923 subsidiaries = Fget (coding->symbol, Qeol_type);
4924 if (VECTORP (subsidiaries)
4925 && XVECTOR (subsidiaries)->size == 3)
4926 coding->symbol
4927 = XVECTOR (subsidiaries)->contents[coding->eol_type];
4928 }
4929 }
4930
4931 if (force_raw_text)
4932 setup_raw_text_coding_system (coding);
4933 goto done_setup_coding;
4934 }
4935
4936 setup_coding_system (Fcheck_coding_system (val), coding);
4937
4938 done_setup_coding:
452dd0be
KH
4939 if (coding->eol_type == CODING_EOL_UNDECIDED)
4940 coding->eol_type = system_eol_type;
7c82a4a9
SM
4941 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4942 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4943}
4944
de1d0127 4945DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
8c1a1077
PJ
4946 "r\nFWrite region to file: \ni\ni\ni\np",
4947 doc: /* Write current region into specified file.
c2efea25
RS
4948When called from a program, requires three arguments:
4949START, END and FILENAME. START and END are normally buffer positions
4950specifying the part of the buffer to write.
4951If START is nil, that means to use the entire buffer contents.
4952If START is a string, then output that string to the file
4953instead of any buffer contents; END is ignored.
4954
8c1a1077
PJ
4955Optional fourth argument APPEND if non-nil means
4956 append to existing file contents (if any). If it is an integer,
4957 seek to that offset in the file before writing.
36e50520 4958Optional fifth argument VISIT, if t or a string, means
8c1a1077
PJ
4959 set the last-save-file-modtime of buffer to this file's modtime
4960 and mark buffer not modified.
4961If VISIT is a string, it is a second file name;
4962 the output goes to FILENAME, but the buffer is marked as visiting VISIT.
4963 VISIT is also the file name to lock and unlock for clash detection.
4964If VISIT is neither t nor nil nor a string,
5f4e6aa9 4965 that means do not display the \"Wrote file\" message.
8c1a1077
PJ
4966The optional sixth arg LOCKNAME, if non-nil, specifies the name to
4967 use for locking and unlocking, overriding FILENAME and VISIT.
4968The optional seventh arg MUSTBENEW, if non-nil, insists on a check
4969 for an existing file with the same name. If MUSTBENEW is `excl',
4970 that means to get an error if the file already exists; never overwrite.
4971 If MUSTBENEW is neither nil nor `excl', that means ask for
4972 confirmation before overwriting, but do go ahead and overwrite the file
4973 if the user confirms.
8c1a1077
PJ
4974
4975This does code conversion according to the value of
4976`coding-system-for-write', `buffer-file-coding-system', or
4977`file-coding-system-alist', and sets the variable
4978`last-coding-system-used' to the coding system actually used. */)
4979 (start, end, filename, append, visit, lockname, mustbenew)
f7b4065f 4980 Lisp_Object start, end, filename, append, visit, lockname, mustbenew;
570d7624
JB
4981{
4982 register int desc;
4983 int failure;
6bbd7a29 4984 int save_errno = 0;
19290c65 4985 const unsigned char *fn;
570d7624 4986 struct stat st;
c975dd7a 4987 int tem;
aed13378 4988 int count = SPECPDL_INDEX ();
6fc6f94b 4989 int count1;
570d7624 4990#ifdef VMS
5e570b75 4991 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
570d7624 4992#endif /* VMS */
3eac9910 4993 Lisp_Object handler;
4ad827c5 4994 Lisp_Object visit_file;
65b7d3e7 4995 Lisp_Object annotations;
b1d1b865 4996 Lisp_Object encoded_filename;
d3a67486
SM
4997 int visiting = (EQ (visit, Qt) || STRINGP (visit));
4998 int quietly = !NILP (visit);
7204a979 4999 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
6fc6f94b 5000 struct buffer *given_buffer;
5e570b75 5001#ifdef DOS_NT
fa228724 5002 int buffer_file_type = O_BINARY;
5e570b75 5003#endif /* DOS_NT */
6fdaa9a0 5004 struct coding_system coding;
570d7624 5005
d3a67486 5006 if (current_buffer->base_buffer && visiting)
95385625
RS
5007 error ("Cannot do file visiting in an indirect buffer");
5008
561cb8e1 5009 if (!NILP (start) && !STRINGP (start))
570d7624
JB
5010 validate_region (&start, &end);
5011
95c1c901 5012 visit_file = Qnil;
59fac292 5013 GCPRO5 (start, filename, visit, visit_file, lockname);
b56567b5 5014
570d7624 5015 filename = Fexpand_file_name (filename, Qnil);
de1d0127 5016
236a12f2 5017 if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl))
b8b29dc9 5018 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
de1d0127 5019
561cb8e1 5020 if (STRINGP (visit))
e5176bae 5021 visit_file = Fexpand_file_name (visit, Qnil);
4ad827c5
RS
5022 else
5023 visit_file = filename;
5024
7204a979
RS
5025 if (NILP (lockname))
5026 lockname = visit_file;
5027
65b7d3e7
RS
5028 annotations = Qnil;
5029
32f4334d
RS
5030 /* If the file name has special constructs in it,
5031 call the corresponding file handler. */
49307295 5032 handler = Ffind_file_name_handler (filename, Qwrite_region);
b56ad927 5033 /* If FILENAME has no handler, see if VISIT has one. */
93c30b5f 5034 if (NILP (handler) && STRINGP (visit))
199607e4 5035 handler = Ffind_file_name_handler (visit, Qwrite_region);
3eac9910 5036
32f4334d
RS
5037 if (!NILP (handler))
5038 {
32f4334d 5039 Lisp_Object val;
51cf6d37
RS
5040 val = call6 (handler, Qwrite_region, start, end,
5041 filename, append, visit);
32f4334d 5042
d6a3cc15 5043 if (visiting)
32f4334d 5044 {
95385625 5045 SAVE_MODIFF = MODIFF;
2acfd7ae 5046 XSETFASTINT (current_buffer->save_length, Z - BEG);
3b7792ed 5047 current_buffer->filename = visit_file;
32f4334d 5048 }
09121adc 5049 UNGCPRO;
32f4334d
RS
5050 return val;
5051 }
5052
4a38de71
KH
5053 record_unwind_protect (save_restriction_restore, save_restriction_save ());
5054
561cb8e1
RS
5055 /* Special kludge to simplify auto-saving. */
5056 if (NILP (start))
5057 {
2acfd7ae
KH
5058 XSETFASTINT (start, BEG);
5059 XSETFASTINT (end, Z);
4a38de71 5060 Fwiden ();
561cb8e1
RS
5061 }
5062
6fc6f94b 5063 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
aed13378 5064 count1 = SPECPDL_INDEX ();
6fc6f94b
RS
5065
5066 given_buffer = current_buffer;
bf3428a1
RS
5067
5068 if (!STRINGP (start))
236a12f2 5069 {
bf3428a1
RS
5070 annotations = build_annotations (start, end);
5071
5072 if (current_buffer != given_buffer)
5073 {
5074 XSETFASTINT (start, BEGV);
5075 XSETFASTINT (end, ZV);
5076 }
236a12f2
SM
5077 }
5078
5079 UNGCPRO;
5080
5081 GCPRO5 (start, filename, annotations, visit_file, lockname);
5082
59fac292
SM
5083 /* Decide the coding-system to encode the data with.
5084 We used to make this choice before calling build_annotations, but that
5085 leads to problems when a write-annotate-function takes care of
5086 unsavable chars (as was the case with X-Symbol). */
5087 choose_write_coding_system (start, end, filename,
5088 append, visit, lockname, &coding);
5089 Vlast_coding_system_used = coding.symbol;
5090
236a12f2 5091 given_buffer = current_buffer;
bf3428a1 5092 if (! STRINGP (start))
6fc6f94b 5093 {
bf3428a1
RS
5094 annotations = build_annotations_2 (start, end,
5095 coding.pre_write_conversion, annotations);
5096 if (current_buffer != given_buffer)
5097 {
5098 XSETFASTINT (start, BEGV);
5099 XSETFASTINT (end, ZV);
5100 }
6fc6f94b 5101 }
d6a3cc15 5102
570d7624
JB
5103#ifdef CLASH_DETECTION
5104 if (!auto_saving)
84f6296a 5105 {
a9171faa 5106#if 0 /* This causes trouble for GNUS. */
84f6296a
RS
5107 /* If we've locked this file for some other buffer,
5108 query before proceeding. */
5109 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
bffd00b0 5110 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
a9171faa 5111#endif
84f6296a
RS
5112
5113 lock_file (lockname);
5114 }
570d7624
JB
5115#endif /* CLASH_DETECTION */
5116
b1d1b865
RS
5117 encoded_filename = ENCODE_FILE (filename);
5118
d5db4077 5119 fn = SDATA (encoded_filename);
570d7624 5120 desc = -1;
265a9e55 5121 if (!NILP (append))
5e570b75 5122#ifdef DOS_NT
68c45bf0 5123 desc = emacs_open (fn, O_WRONLY | buffer_file_type, 0);
5e570b75 5124#else /* not DOS_NT */
68c45bf0 5125 desc = emacs_open (fn, O_WRONLY, 0);
5e570b75 5126#endif /* not DOS_NT */
570d7624 5127
b1d1b865 5128 if (desc < 0 && (NILP (append) || errno == ENOENT))
570d7624 5129#ifdef VMS
5e570b75 5130 if (auto_saving) /* Overwrite any previous version of autosave file */
570d7624 5131 {
5e570b75 5132 vms_truncate (fn); /* if fn exists, truncate to zero length */
68c45bf0 5133 desc = emacs_open (fn, O_RDWR, 0);
570d7624 5134 if (desc < 0)
561cb8e1 5135 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
d5db4077 5136 ? SDATA (current_buffer->filename) : 0,
b72dea2a 5137 fn);
570d7624 5138 }
5e570b75 5139 else /* Write to temporary name and rename if no errors */
570d7624
JB
5140 {
5141 Lisp_Object temp_name;
5142 temp_name = Ffile_name_directory (filename);
5143
265a9e55 5144 if (!NILP (temp_name))
570d7624
JB
5145 {
5146 temp_name = Fmake_temp_name (concat2 (temp_name,
5147 build_string ("$$SAVE$$")));
d5db4077
KR
5148 fname = SDATA (filename);
5149 fn = SDATA (temp_name);
570d7624
JB
5150 desc = creat_copy_attrs (fname, fn);
5151 if (desc < 0)
5152 {
5153 /* If we can't open the temporary file, try creating a new
5154 version of the original file. VMS "creat" creates a
5155 new version rather than truncating an existing file. */
5156 fn = fname;
5157 fname = 0;
5158 desc = creat (fn, 0666);
5159#if 0 /* This can clobber an existing file and fail to replace it,
5160 if the user runs out of space. */
5161 if (desc < 0)
5162 {
5163 /* We can't make a new version;
5164 try to truncate and rewrite existing version if any. */
5165 vms_truncate (fn);
68c45bf0 5166 desc = emacs_open (fn, O_RDWR, 0);
570d7624
JB
5167 }
5168#endif
5169 }
5170 }
5171 else
5172 desc = creat (fn, 0666);
5173 }
5174#else /* not VMS */
5e570b75 5175#ifdef DOS_NT
68c45bf0 5176 desc = emacs_open (fn,
95522746
GM
5177 O_WRONLY | O_CREAT | buffer_file_type
5178 | (EQ (mustbenew, Qexcl) ? O_EXCL : O_TRUNC),
68c45bf0 5179 S_IREAD | S_IWRITE);
5e570b75 5180#else /* not DOS_NT */
68c45bf0 5181 desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT
7c752c80 5182 | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
68c45bf0 5183 auto_saving ? auto_save_mode_bits : 0666);
5e570b75 5184#endif /* not DOS_NT */
570d7624
JB
5185#endif /* not VMS */
5186
5187 if (desc < 0)
5188 {
5189#ifdef CLASH_DETECTION
5190 save_errno = errno;
7204a979 5191 if (!auto_saving) unlock_file (lockname);
570d7624
JB
5192 errno = save_errno;
5193#endif /* CLASH_DETECTION */
43fb7d9a 5194 UNGCPRO;
570d7624
JB
5195 report_file_error ("Opening output file", Fcons (filename, Qnil));
5196 }
5197
5198 record_unwind_protect (close_file_unwind, make_number (desc));
5199
c1c4693e 5200 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
43fb7d9a
DL
5201 {
5202 long ret;
efdc16c9 5203
43fb7d9a
DL
5204 if (NUMBERP (append))
5205 ret = lseek (desc, XINT (append), 1);
5206 else
5207 ret = lseek (desc, 0, 2);
5208 if (ret < 0)
5209 {
570d7624 5210#ifdef CLASH_DETECTION
43fb7d9a 5211 if (!auto_saving) unlock_file (lockname);
570d7624 5212#endif /* CLASH_DETECTION */
43fb7d9a
DL
5213 UNGCPRO;
5214 report_file_error ("Lseek error", Fcons (filename, Qnil));
5215 }
5216 }
efdc16c9 5217
43fb7d9a 5218 UNGCPRO;
570d7624
JB
5219
5220#ifdef VMS
5221/*
5222 * Kludge Warning: The VMS C RTL likes to insert carriage returns
5223 * if we do writes that don't end with a carriage return. Furthermore
5224 * it cannot handle writes of more then 16K. The modified
5225 * version of "sys_write" in SYSDEP.C (see comment there) copes with
e0f24100 5226 * this EXCEPT for the last record (if it doesn't end with a carriage
570d7624
JB
5227 * return). This implies that if your buffer doesn't end with a carriage
5228 * return, you get one free... tough. However it also means that if
5229 * we make two calls to sys_write (a la the following code) you can
5230 * get one at the gap as well. The easiest way to fix this (honest)
5231 * is to move the gap to the next newline (or the end of the buffer).
5232 * Thus this change.
5233 *
5234 * Yech!
5235 */
5236 if (GPT > BEG && GPT_ADDR[-1] != '\n')
5237 move_gap (find_next_newline (GPT, 1));
cdfb0f1d
KH
5238#else
5239 /* Whether VMS or not, we must move the gap to the next of newline
5240 when we must put designation sequences at beginning of line. */
5241 if (INTEGERP (start)
5242 && coding.type == coding_type_iso2022
5243 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
5244 && GPT > BEG && GPT_ADDR[-1] != '\n')
ec7adf26
RS
5245 {
5246 int opoint = PT, opoint_byte = PT_BYTE;
5247 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
5248 move_gap_both (PT, PT_BYTE);
5249 SET_PT_BOTH (opoint, opoint_byte);
5250 }
570d7624
JB
5251#endif
5252
5253 failure = 0;
5254 immediate_quit = 1;
5255
561cb8e1 5256 if (STRINGP (start))
570d7624 5257 {
d5db4077 5258 failure = 0 > a_write (desc, start, 0, SCHARS (start),
ce51c54c 5259 &annotations, &coding);
570d7624
JB
5260 save_errno = errno;
5261 }
5262 else if (XINT (start) != XINT (end))
5263 {
ec7adf26
RS
5264 tem = CHAR_TO_BYTE (XINT (start));
5265
570d7624
JB
5266 if (XINT (start) < GPT)
5267 {
ce51c54c
KH
5268 failure = 0 > a_write (desc, Qnil, XINT (start),
5269 min (GPT, XINT (end)) - XINT (start),
5270 &annotations, &coding);
570d7624
JB
5271 save_errno = errno;
5272 }
5273
5274 if (XINT (end) > GPT && !failure)
5275 {
ce51c54c
KH
5276 tem = max (XINT (start), GPT);
5277 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
5278 &annotations, &coding);
d6a3cc15
RS
5279 save_errno = errno;
5280 }
69f6e679
RS
5281 }
5282 else
5283 {
5284 /* If file was empty, still need to write the annotations */
c8a6d68a 5285 coding.mode |= CODING_MODE_LAST_BLOCK;
ce51c54c 5286 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
6fdaa9a0
KH
5287 save_errno = errno;
5288 }
5289
c8a6d68a
KH
5290 if (CODING_REQUIRE_FLUSHING (&coding)
5291 && !(coding.mode & CODING_MODE_LAST_BLOCK)
1354debd 5292 && ! failure)
6fdaa9a0
KH
5293 {
5294 /* We have to flush out a data. */
c8a6d68a 5295 coding.mode |= CODING_MODE_LAST_BLOCK;
ce51c54c 5296 failure = 0 > e_write (desc, Qnil, 0, 0, &coding);
69f6e679 5297 save_errno = errno;
570d7624
JB
5298 }
5299
5300 immediate_quit = 0;
5301
6e23c83e 5302#ifdef HAVE_FSYNC
570d7624
JB
5303 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
5304 Disk full in NFS may be reported here. */
1daffa1c
RS
5305 /* mib says that closing the file will try to write as fast as NFS can do
5306 it, and that means the fsync here is not crucial for autosave files. */
ccf61795 5307 if (!auto_saving && !write_region_inhibit_fsync && fsync (desc) < 0)
cb33c142 5308 {
41618deb
AS
5309 /* If fsync fails with EINTR, don't treat that as serious. Also
5310 ignore EINVAL which happens when fsync is not supported on this
5311 file. */
5312 if (errno != EINTR && errno != EINVAL)
cb33c142
KH
5313 failure = 1, save_errno = errno;
5314 }
570d7624
JB
5315#endif
5316
199607e4 5317 /* Spurious "file has changed on disk" warnings have been
570d7624
JB
5318 observed on Suns as well.
5319 It seems that `close' can change the modtime, under nfs.
5320
5321 (This has supposedly been fixed in Sunos 4,
5322 but who knows about all the other machines with NFS?) */
5323#if 0
5324
5325 /* On VMS and APOLLO, must do the stat after the close
5326 since closing changes the modtime. */
5327#ifndef VMS
5328#ifndef APOLLO
5329 /* Recall that #if defined does not work on VMS. */
5330#define FOO
5331 fstat (desc, &st);
5332#endif
5333#endif
5334#endif
5335
5336 /* NFS can report a write failure now. */
68c45bf0 5337 if (emacs_close (desc) < 0)
570d7624
JB
5338 failure = 1, save_errno = errno;
5339
5340#ifdef VMS
5341 /* If we wrote to a temporary name and had no errors, rename to real name. */
5342 if (fname)
5343 {
5344 if (!failure)
5345 failure = (rename (fn, fname) != 0), save_errno = errno;
5346 fn = fname;
5347 }
5348#endif /* VMS */
5349
5350#ifndef FOO
5351 stat (fn, &st);
5352#endif
6fc6f94b
RS
5353 /* Discard the unwind protect for close_file_unwind. */
5354 specpdl_ptr = specpdl + count1;
5355 /* Restore the original current buffer. */
98295b48 5356 visit_file = unbind_to (count, visit_file);
570d7624
JB
5357
5358#ifdef CLASH_DETECTION
5359 if (!auto_saving)
7204a979 5360 unlock_file (lockname);
570d7624
JB
5361#endif /* CLASH_DETECTION */
5362
5363 /* Do this before reporting IO error
5364 to avoid a "file has changed on disk" warning on
5365 next attempt to save. */
d6a3cc15 5366 if (visiting)
570d7624
JB
5367 current_buffer->modtime = st.st_mtime;
5368
5369 if (failure)
d5db4077 5370 error ("IO error writing %s: %s", SDATA (filename),
68c45bf0 5371 emacs_strerror (save_errno));
570d7624 5372
d6a3cc15 5373 if (visiting)
570d7624 5374 {
95385625 5375 SAVE_MODIFF = MODIFF;
2acfd7ae 5376 XSETFASTINT (current_buffer->save_length, Z - BEG);
3b7792ed 5377 current_buffer->filename = visit_file;
f4226e89 5378 update_mode_lines++;
570d7624 5379 }
d6a3cc15 5380 else if (quietly)
dc2628c1
RS
5381 {
5382 if (auto_saving
5383 && ! NILP (Fstring_equal (current_buffer->filename,
5384 current_buffer->auto_save_file_name)))
5385 SAVE_MODIFF = MODIFF;
5386
5387 return Qnil;
5388 }
570d7624
JB
5389
5390 if (!auto_saving)
2a6f12e2 5391 message_with_string ((INTEGERP (append)
0c328a0e
RS
5392 ? "Updated %s"
5393 : ! NILP (append)
5394 ? "Added to %s"
5395 : "Wrote %s"),
5396 visit_file, 1);
570d7624
JB
5397
5398 return Qnil;
5399}
ec7adf26 5400\f
d6a3cc15
RS
5401Lisp_Object merge ();
5402
5403DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
8c1a1077
PJ
5404 doc: /* Return t if (car A) is numerically less than (car B). */)
5405 (a, b)
d6a3cc15
RS
5406 Lisp_Object a, b;
5407{
5408 return Flss (Fcar (a), Fcar (b));
5409}
5410
5411/* Build the complete list of annotations appropriate for writing out
5412 the text between START and END, by calling all the functions in
6fc6f94b
RS
5413 write-region-annotate-functions and merging the lists they return.
5414 If one of these functions switches to a different buffer, we assume
5415 that buffer contains altered text. Therefore, the caller must
5416 make sure to restore the current buffer in all cases,
5417 as save-excursion would do. */
d6a3cc15
RS
5418
5419static Lisp_Object
236a12f2
SM
5420build_annotations (start, end)
5421 Lisp_Object start, end;
d6a3cc15
RS
5422{
5423 Lisp_Object annotations;
5424 Lisp_Object p, res;
5425 struct gcpro gcpro1, gcpro2;
0a20b684 5426 Lisp_Object original_buffer;
bd235610 5427 int i, used_global = 0;
0a20b684
RS
5428
5429 XSETBUFFER (original_buffer, current_buffer);
d6a3cc15
RS
5430
5431 annotations = Qnil;
5432 p = Vwrite_region_annotate_functions;
5433 GCPRO2 (annotations, p);
28c3eb5a 5434 while (CONSP (p))
d6a3cc15 5435 {
6fc6f94b 5436 struct buffer *given_buffer = current_buffer;
bd235610
SM
5437 if (EQ (Qt, XCAR (p)) && !used_global)
5438 { /* Use the global value of the hook. */
5439 Lisp_Object arg[2];
5440 used_global = 1;
5441 arg[0] = Fdefault_value (Qwrite_region_annotate_functions);
5442 arg[1] = XCDR (p);
5443 p = Fappend (2, arg);
5444 continue;
5445 }
6fc6f94b 5446 Vwrite_region_annotations_so_far = annotations;
28c3eb5a 5447 res = call2 (XCAR (p), start, end);
6fc6f94b
RS
5448 /* If the function makes a different buffer current,
5449 assume that means this buffer contains altered text to be output.
5450 Reset START and END from the buffer bounds
5451 and discard all previous annotations because they should have
5452 been dealt with by this function. */
5453 if (current_buffer != given_buffer)
5454 {
3cf29f61
RS
5455 XSETFASTINT (start, BEGV);
5456 XSETFASTINT (end, ZV);
6fc6f94b
RS
5457 annotations = Qnil;
5458 }
d6a3cc15
RS
5459 Flength (res); /* Check basic validity of return value */
5460 annotations = merge (annotations, res, Qcar_less_than_car);
28c3eb5a 5461 p = XCDR (p);
d6a3cc15 5462 }
0d420e88
BG
5463
5464 /* Now do the same for annotation functions implied by the file-format */
f844ba4e
LT
5465 if (auto_saving && (!EQ (current_buffer->auto_save_file_format, Qt)))
5466 p = current_buffer->auto_save_file_format;
0d420e88
BG
5467 else
5468 p = current_buffer->file_format;
28c3eb5a 5469 for (i = 0; CONSP (p); p = XCDR (p), ++i)
0d420e88
BG
5470 {
5471 struct buffer *given_buffer = current_buffer;
efdc16c9 5472
0d420e88 5473 Vwrite_region_annotations_so_far = annotations;
532ed661
GM
5474
5475 /* Value is either a list of annotations or nil if the function
5476 has written annotations to a temporary buffer, which is now
5477 current. */
28c3eb5a 5478 res = call5 (Qformat_annotate_function, XCAR (p), start, end,
532ed661 5479 original_buffer, make_number (i));
0d420e88
BG
5480 if (current_buffer != given_buffer)
5481 {
3cf29f61
RS
5482 XSETFASTINT (start, BEGV);
5483 XSETFASTINT (end, ZV);
0d420e88
BG
5484 annotations = Qnil;
5485 }
efdc16c9 5486
532ed661
GM
5487 if (CONSP (res))
5488 annotations = merge (annotations, res, Qcar_less_than_car);
0d420e88 5489 }
6fdaa9a0 5490
236a12f2
SM
5491 UNGCPRO;
5492 return annotations;
5493}
5494
5495static Lisp_Object
5496build_annotations_2 (start, end, pre_write_conversion, annotations)
5497 Lisp_Object start, end, pre_write_conversion, annotations;
5498{
5499 struct gcpro gcpro1;
5500 Lisp_Object res;
5501
5502 GCPRO1 (annotations);
6fdaa9a0
KH
5503 /* At last, do the same for the function PRE_WRITE_CONVERSION
5504 implied by the current coding-system. */
5505 if (!NILP (pre_write_conversion))
5506 {
5507 struct buffer *given_buffer = current_buffer;
5508 Vwrite_region_annotations_so_far = annotations;
5509 res = call2 (pre_write_conversion, start, end);
6fdaa9a0 5510 Flength (res);
cdfb0f1d
KH
5511 annotations = (current_buffer != given_buffer
5512 ? res
5513 : merge (annotations, res, Qcar_less_than_car));
6fdaa9a0
KH
5514 }
5515
d6a3cc15
RS
5516 UNGCPRO;
5517 return annotations;
5518}
ec7adf26 5519\f
ce51c54c
KH
5520/* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5521 If STRING is nil, POS is the character position in the current buffer.
d6a3cc15 5522 Intersperse with them the annotations from *ANNOT
ce51c54c 5523 which fall within the range of POS to POS + NCHARS,
d6a3cc15
RS
5524 each at its appropriate position.
5525
ec7adf26
RS
5526 We modify *ANNOT by discarding elements as we use them up.
5527
d6a3cc15
RS
5528 The return value is negative in case of system call failure. */
5529
ec7adf26 5530static int
ce51c54c 5531a_write (desc, string, pos, nchars, annot, coding)
d6a3cc15 5532 int desc;
ce51c54c
KH
5533 Lisp_Object string;
5534 register int nchars;
5535 int pos;
d6a3cc15 5536 Lisp_Object *annot;
6fdaa9a0 5537 struct coding_system *coding;
d6a3cc15
RS
5538{
5539 Lisp_Object tem;
5540 int nextpos;
ce51c54c 5541 int lastpos = pos + nchars;
d6a3cc15 5542
eb15aa18 5543 while (NILP (*annot) || CONSP (*annot))
d6a3cc15
RS
5544 {
5545 tem = Fcar_safe (Fcar (*annot));
ce51c54c 5546 nextpos = pos - 1;
ec7adf26 5547 if (INTEGERP (tem))
ce51c54c 5548 nextpos = XFASTINT (tem);
ec7adf26
RS
5549
5550 /* If there are no more annotations in this range,
5551 output the rest of the range all at once. */
ce51c54c
KH
5552 if (! (nextpos >= pos && nextpos <= lastpos))
5553 return e_write (desc, string, pos, lastpos, coding);
ec7adf26
RS
5554
5555 /* Output buffer text up to the next annotation's position. */
ce51c54c 5556 if (nextpos > pos)
d6a3cc15 5557 {
055a28c9 5558 if (0 > e_write (desc, string, pos, nextpos, coding))
d6a3cc15 5559 return -1;
ce51c54c 5560 pos = nextpos;
d6a3cc15 5561 }
ec7adf26 5562 /* Output the annotation. */
d6a3cc15
RS
5563 tem = Fcdr (Fcar (*annot));
5564 if (STRINGP (tem))
5565 {
d5db4077 5566 if (0 > e_write (desc, tem, 0, SCHARS (tem), coding))
d6a3cc15
RS
5567 return -1;
5568 }
5569 *annot = Fcdr (*annot);
5570 }
dfcf069d 5571 return 0;
d6a3cc15
RS
5572}
5573
6fdaa9a0
KH
5574#ifndef WRITE_BUF_SIZE
5575#define WRITE_BUF_SIZE (16 * 1024)
5576#endif
5577
ce51c54c
KH
5578/* Write text in the range START and END into descriptor DESC,
5579 encoding them with coding system CODING. If STRING is nil, START
5580 and END are character positions of the current buffer, else they
5581 are indexes to the string STRING. */
ec7adf26
RS
5582
5583static int
ce51c54c 5584e_write (desc, string, start, end, coding)
570d7624 5585 int desc;
ce51c54c
KH
5586 Lisp_Object string;
5587 int start, end;
6fdaa9a0 5588 struct coding_system *coding;
570d7624 5589{
ce51c54c
KH
5590 register char *addr;
5591 register int nbytes;
6fdaa9a0 5592 char buf[WRITE_BUF_SIZE];
ce51c54c
KH
5593 int return_val = 0;
5594
5595 if (start >= end)
5596 coding->composing = COMPOSITION_DISABLED;
5597 if (coding->composing != COMPOSITION_DISABLED)
5598 coding_save_composition (coding, start, end, string);
5599
5600 if (STRINGP (string))
5601 {
d5db4077
KR
5602 addr = SDATA (string);
5603 nbytes = SBYTES (string);
8c3b9441 5604 coding->src_multibyte = STRING_MULTIBYTE (string);
ce51c54c
KH
5605 }
5606 else if (start < end)
5607 {
5608 /* It is assured that the gap is not in the range START and END-1. */
5609 addr = CHAR_POS_ADDR (start);
5610 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
8c3b9441
KH
5611 coding->src_multibyte
5612 = !NILP (current_buffer->enable_multibyte_characters);
ce51c54c
KH
5613 }
5614 else
5615 {
5616 addr = "";
5617 nbytes = 0;
8c3b9441 5618 coding->src_multibyte = 1;
ce51c54c 5619 }
570d7624 5620
6fdaa9a0
KH
5621 /* We used to have a code for handling selective display here. But,
5622 now it is handled within encode_coding. */
5623 while (1)
570d7624 5624 {
b4132433
KH
5625 int result;
5626
5627 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
c8a6d68a 5628 if (coding->produced > 0)
6fdaa9a0 5629 {
68c45bf0 5630 coding->produced -= emacs_write (desc, buf, coding->produced);
ce51c54c
KH
5631 if (coding->produced)
5632 {
5633 return_val = -1;
5634 break;
5635 }
570d7624 5636 }
ca91fb26
KH
5637 nbytes -= coding->consumed;
5638 addr += coding->consumed;
5639 if (result == CODING_FINISH_INSUFFICIENT_SRC
5640 && nbytes > 0)
b4132433
KH
5641 {
5642 /* The source text ends by an incomplete multibyte form.
5643 There's no way other than write it out as is. */
68c45bf0 5644 nbytes -= emacs_write (desc, addr, nbytes);
ce51c54c
KH
5645 if (nbytes)
5646 {
5647 return_val = -1;
5648 break;
5649 }
b4132433 5650 }
ec7adf26 5651 if (nbytes <= 0)
6fdaa9a0 5652 break;
ce51c54c
KH
5653 start += coding->consumed_char;
5654 if (coding->cmp_data)
5655 coding_adjust_composition_offset (coding, start);
570d7624 5656 }
0c41a39c
KH
5657
5658 if (coding->cmp_data)
5659 coding_free_composition_data (coding);
5660
055a28c9 5661 return return_val;
570d7624 5662}
ec7adf26 5663\f
570d7624 5664DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
8c1a1077
PJ
5665 Sverify_visited_file_modtime, 1, 1, 0,
5666 doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
d01ca4a8
LT
5667This means that the file has not been changed since it was visited or saved.
5668See Info node `(elisp)Modification Time' for more details. */)
8c1a1077 5669 (buf)
570d7624
JB
5670 Lisp_Object buf;
5671{
5672 struct buffer *b;
5673 struct stat st;
32f4334d 5674 Lisp_Object handler;
b1d1b865 5675 Lisp_Object filename;
570d7624 5676
b7826503 5677 CHECK_BUFFER (buf);
570d7624
JB
5678 b = XBUFFER (buf);
5679
93c30b5f 5680 if (!STRINGP (b->filename)) return Qt;
570d7624
JB
5681 if (b->modtime == 0) return Qt;
5682
32f4334d
RS
5683 /* If the file name has special constructs in it,
5684 call the corresponding file handler. */
49307295
KH
5685 handler = Ffind_file_name_handler (b->filename,
5686 Qverify_visited_file_modtime);
32f4334d 5687 if (!NILP (handler))
09121adc 5688 return call2 (handler, Qverify_visited_file_modtime, buf);
32f4334d 5689
b1d1b865
RS
5690 filename = ENCODE_FILE (b->filename);
5691
d5db4077 5692 if (stat (SDATA (filename), &st) < 0)
570d7624
JB
5693 {
5694 /* If the file doesn't exist now and didn't exist before,
5695 we say that it isn't modified, provided the error is a tame one. */
5696 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
5697 st.st_mtime = -1;
5698 else
5699 st.st_mtime = 0;
5700 }
5701 if (st.st_mtime == b->modtime
5702 /* If both are positive, accept them if they are off by one second. */
5703 || (st.st_mtime > 0 && b->modtime > 0
5704 && (st.st_mtime == b->modtime + 1
5705 || st.st_mtime == b->modtime - 1)))
5706 return Qt;
5707 return Qnil;
5708}
5709
5710DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
8c1a1077
PJ
5711 Sclear_visited_file_modtime, 0, 0, 0,
5712 doc: /* Clear out records of last mod time of visited file.
5713Next attempt to save will certainly not complain of a discrepancy. */)
5714 ()
570d7624
JB
5715{
5716 current_buffer->modtime = 0;
5717 return Qnil;
5718}
5719
f5d5eccf 5720DEFUN ("visited-file-modtime", Fvisited_file_modtime,
8c1a1077
PJ
5721 Svisited_file_modtime, 0, 0, 0,
5722 doc: /* Return the current buffer's recorded visited file modification time.
e5fcddc8 5723The value is a list of the form (HIGH LOW), like the time values
d01ca4a8
LT
5724that `file-attributes' returns. If the current buffer has no recorded
5725file modification time, this function returns 0.
5726See Info node `(elisp)Modification Time' for more details. */)
8c1a1077 5727 ()
f5d5eccf 5728{
73ff9d42
RS
5729 if (! current_buffer->modtime)
5730 return make_number (0);
5731 return make_time ((time_t) current_buffer->modtime);
f5d5eccf
RS
5732}
5733
570d7624 5734DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
8c1a1077
PJ
5735 Sset_visited_file_modtime, 0, 1, 0,
5736 doc: /* Update buffer's recorded modification time from the visited file's time.
5737Useful if the buffer was not read from the file normally
5738or if the file itself has been changed for some known benign reason.
5739An argument specifies the modification time value to use
5740\(instead of that of the visited file), in the form of a list
5741\(HIGH . LOW) or (HIGH LOW). */)
5742 (time_list)
f5d5eccf 5743 Lisp_Object time_list;
570d7624 5744{
f5d5eccf
RS
5745 if (!NILP (time_list))
5746 current_buffer->modtime = cons_to_long (time_list);
5747 else
5748 {
5749 register Lisp_Object filename;
5750 struct stat st;
5751 Lisp_Object handler;
570d7624 5752
f5d5eccf 5753 filename = Fexpand_file_name (current_buffer->filename, Qnil);
32f4334d 5754
f5d5eccf
RS
5755 /* If the file name has special constructs in it,
5756 call the corresponding file handler. */
49307295 5757 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
f5d5eccf 5758 if (!NILP (handler))
caf3c431 5759 /* The handler can find the file name the same way we did. */
76c881b0 5760 return call2 (handler, Qset_visited_file_modtime, Qnil);
b1d1b865
RS
5761
5762 filename = ENCODE_FILE (filename);
5763
d5db4077 5764 if (stat (SDATA (filename), &st) >= 0)
f5d5eccf
RS
5765 current_buffer->modtime = st.st_mtime;
5766 }
570d7624
JB
5767
5768 return Qnil;
5769}
5770\f
5771Lisp_Object
d7f31e22
GM
5772auto_save_error (error)
5773 Lisp_Object error;
570d7624 5774{
d7f31e22
GM
5775 Lisp_Object args[3], msg;
5776 int i, nbytes;
5777 struct gcpro gcpro1;
dfc22242
KS
5778 char *msgbuf;
5779 USE_SAFE_ALLOCA;
efdc16c9 5780
31e31a15
CY
5781 auto_save_error_occurred = 1;
5782
570d7624 5783 ring_bell ();
efdc16c9 5784
d7f31e22
GM
5785 args[0] = build_string ("Auto-saving %s: %s");
5786 args[1] = current_buffer->name;
5787 args[2] = Ferror_message_string (error);
5788 msg = Fformat (3, args);
5789 GCPRO1 (msg);
d5db4077 5790 nbytes = SBYTES (msg);
dfc22242
KS
5791 SAFE_ALLOCA (msgbuf, char *, nbytes);
5792 bcopy (SDATA (msg), msgbuf, nbytes);
d7f31e22
GM
5793
5794 for (i = 0; i < 3; ++i)
5795 {
5796 if (i == 0)
dfc22242 5797 message2 (msgbuf, nbytes, STRING_MULTIBYTE (msg));
d7f31e22 5798 else
dfc22242 5799 message2_nolog (msgbuf, nbytes, STRING_MULTIBYTE (msg));
d7f31e22
GM
5800 Fsleep_for (make_number (1), Qnil);
5801 }
5802
e01f7773 5803 SAFE_FREE ();
d7f31e22 5804 UNGCPRO;
570d7624
JB
5805 return Qnil;
5806}
5807
5808Lisp_Object
5809auto_save_1 ()
5810{
570d7624 5811 struct stat st;
d4a42098
KS
5812 Lisp_Object modes;
5813
5814 auto_save_mode_bits = 0666;
570d7624
JB
5815
5816 /* Get visited file's mode to become the auto save file's mode. */
d4a42098
KS
5817 if (! NILP (current_buffer->filename))
5818 {
5819 if (stat (SDATA (current_buffer->filename), &st) >= 0)
5820 /* But make sure we can overwrite it later! */
5821 auto_save_mode_bits = st.st_mode | 0600;
5822 else if ((modes = Ffile_modes (current_buffer->filename),
5823 INTEGERP (modes)))
5824 /* Remote files don't cooperate with stat. */
5825 auto_save_mode_bits = XINT (modes) | 0600;
5826 }
570d7624
JB
5827
5828 return
f8a12fae
CY
5829 Fwrite_region (Qnil, Qnil, current_buffer->auto_save_file_name, Qnil,
5830 NILP (Vauto_save_visited_file_name) ? Qlambda : Qt,
5831 Qnil, Qnil);
570d7624
JB
5832}
5833
e54d3b5d 5834static Lisp_Object
fff7e982
KS
5835do_auto_save_unwind (arg) /* used as unwind-protect function */
5836 Lisp_Object arg;
e54d3b5d 5837{
fff7e982 5838 FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
3be3c08e 5839 auto_saving = 0;
fff7e982 5840 if (stream != NULL)
aab12958
YM
5841 {
5842 BLOCK_INPUT;
5843 fclose (stream);
5844 UNBLOCK_INPUT;
5845 }
e54d3b5d
RS
5846 return Qnil;
5847}
5848
a8c828be
RS
5849static Lisp_Object
5850do_auto_save_unwind_1 (value) /* used as unwind-protect function */
5851 Lisp_Object value;
5852{
5853 minibuffer_auto_raise = XINT (value);
5854 return Qnil;
5855}
5856
5794dd61
RS
5857static Lisp_Object
5858do_auto_save_make_dir (dir)
5859 Lisp_Object dir;
5860{
26816cbf
SG
5861 Lisp_Object mode;
5862
5863 call2 (Qmake_directory, dir, Qt);
5864 XSETFASTINT (mode, 0700);
5865 return Fset_file_modes (dir, mode);
5794dd61
RS
5866}
5867
5868static Lisp_Object
5869do_auto_save_eh (ignore)
5870 Lisp_Object ignore;
5871{
5872 return Qnil;
5873}
5874
570d7624 5875DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
8c1a1077
PJ
5876 doc: /* Auto-save all buffers that need it.
5877This is all buffers that have auto-saving enabled
5878and are changed since last auto-saved.
5879Auto-saving writes the buffer into a file
5880so that your editing is not lost if the system crashes.
5881This file is not the file you visited; that changes only when you save.
5882Normally we run the normal hook `auto-save-hook' before saving.
5883
5884A non-nil NO-MESSAGE argument means do not print any message if successful.
5885A non-nil CURRENT-ONLY argument means save only current buffer. */)
5886 (no_message, current_only)
17857782 5887 Lisp_Object no_message, current_only;
570d7624
JB
5888{
5889 struct buffer *old = current_buffer, *b;
5890 Lisp_Object tail, buf;
5891 int auto_saved = 0;
f14b1c68 5892 int do_handled_files;
ff4c9993 5893 Lisp_Object oquit;
fff7e982 5894 FILE *stream = NULL;
aed13378 5895 int count = SPECPDL_INDEX ();
a8c828be 5896 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
5794dd61 5897 int old_message_p = 0;
d57563b6 5898 struct gcpro gcpro1, gcpro2;
38da540d
RS
5899
5900 if (max_specpdl_size < specpdl_size + 40)
5901 max_specpdl_size = specpdl_size + 40;
5902
5903 if (minibuf_level)
5904 no_message = Qt;
5905
5794dd61
RS
5906 if (NILP (no_message))
5907 {
5908 old_message_p = push_message ();
5909 record_unwind_protect (pop_message_unwind, Qnil);
5910 }
efdc16c9 5911
ff4c9993
RS
5912 /* Ordinarily don't quit within this function,
5913 but don't make it impossible to quit (in case we get hung in I/O). */
5914 oquit = Vquit_flag;
5915 Vquit_flag = Qnil;
570d7624
JB
5916
5917 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
5918 point to non-strings reached from Vbuffer_alist. */
5919
265a9e55 5920 if (!NILP (Vrun_hooks))
570d7624
JB
5921 call1 (Vrun_hooks, intern ("auto-save-hook"));
5922
e54d3b5d
RS
5923 if (STRINGP (Vauto_save_list_file_name))
5924 {
0894672f 5925 Lisp_Object listfile;
efdc16c9 5926
258fd2cb 5927 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
0894672f
GM
5928
5929 /* Don't try to create the directory when shutting down Emacs,
5930 because creating the directory might signal an error, and
5931 that would leave Emacs in a strange state. */
5932 if (!NILP (Vrun_hooks))
5933 {
5934 Lisp_Object dir;
d57563b6
RS
5935 dir = Qnil;
5936 GCPRO2 (dir, listfile);
0894672f
GM
5937 dir = Ffile_name_directory (listfile);
5938 if (NILP (Ffile_directory_p (dir)))
5794dd61
RS
5939 internal_condition_case_1 (do_auto_save_make_dir,
5940 dir, Fcons (Fcons (Qfile_error, Qnil), Qnil),
5941 do_auto_save_eh);
d57563b6 5942 UNGCPRO;
0894672f 5943 }
efdc16c9 5944
d5db4077 5945 stream = fopen (SDATA (listfile), "w");
1b335d29 5946 }
199607e4 5947
fff7e982
KS
5948 record_unwind_protect (do_auto_save_unwind,
5949 make_save_value (stream, 0));
a8c828be
RS
5950 record_unwind_protect (do_auto_save_unwind_1,
5951 make_number (minibuffer_auto_raise));
5952 minibuffer_auto_raise = 0;
3be3c08e 5953 auto_saving = 1;
31e31a15 5954 auto_save_error_occurred = 0;
3be3c08e 5955
dc2628c1
RS
5956 /* On first pass, save all files that don't have handlers.
5957 On second pass, save all files that do have handlers.
5958
5959 If Emacs is crashing, the handlers may tweak what is causing
5960 Emacs to crash in the first place, and it would be a shame if
5961 Emacs failed to autosave perfectly ordinary files because it
5962 couldn't handle some ange-ftp'd file. */
5963
f14b1c68 5964 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
03699b14 5965 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCDR (tail))
f14b1c68 5966 {
03699b14 5967 buf = XCDR (XCAR (tail));
f14b1c68 5968 b = XBUFFER (buf);
199607e4 5969
e54d3b5d 5970 /* Record all the buffers that have auto save mode
258fd2cb
RS
5971 in the special file that lists them. For each of these buffers,
5972 Record visited name (if any) and auto save name. */
93c30b5f 5973 if (STRINGP (b->auto_save_file_name)
1b335d29 5974 && stream != NULL && do_handled_files == 0)
e54d3b5d 5975 {
aab12958 5976 BLOCK_INPUT;
258fd2cb
RS
5977 if (!NILP (b->filename))
5978 {
d5db4077
KR
5979 fwrite (SDATA (b->filename), 1,
5980 SBYTES (b->filename), stream);
258fd2cb 5981 }
1b335d29 5982 putc ('\n', stream);
d5db4077
KR
5983 fwrite (SDATA (b->auto_save_file_name), 1,
5984 SBYTES (b->auto_save_file_name), stream);
1b335d29 5985 putc ('\n', stream);
aab12958 5986 UNBLOCK_INPUT;
e54d3b5d 5987 }
17857782 5988
f14b1c68
JB
5989 if (!NILP (current_only)
5990 && b != current_buffer)
5991 continue;
e54d3b5d 5992
95385625
RS
5993 /* Don't auto-save indirect buffers.
5994 The base buffer takes care of it. */
5995 if (b->base_buffer)
5996 continue;
5997
f14b1c68
JB
5998 /* Check for auto save enabled
5999 and file changed since last auto save
6000 and file changed since last real save. */
93c30b5f 6001 if (STRINGP (b->auto_save_file_name)
95385625 6002 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
f14b1c68 6003 && b->auto_save_modified < BUF_MODIFF (b)
82c2d839
RS
6004 /* -1 means we've turned off autosaving for a while--see below. */
6005 && XINT (b->save_length) >= 0
f14b1c68 6006 && (do_handled_files
49307295
KH
6007 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
6008 Qwrite_region))))
f14b1c68 6009 {
b60247d9
RS
6010 EMACS_TIME before_time, after_time;
6011
6012 EMACS_GET_TIME (before_time);
6013
6014 /* If we had a failure, don't try again for 20 minutes. */
6015 if (b->auto_save_failure_time >= 0
6016 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
6017 continue;
6018
f14b1c68
JB
6019 if ((XFASTINT (b->save_length) * 10
6020 > (BUF_Z (b) - BUF_BEG (b)) * 13)
6021 /* A short file is likely to change a large fraction;
6022 spare the user annoying messages. */
6023 && XFASTINT (b->save_length) > 5000
6024 /* These messages are frequent and annoying for `*mail*'. */
6025 && !EQ (b->filename, Qnil)
6026 && NILP (no_message))
6027 {
6028 /* It has shrunk too much; turn off auto-saving here. */
a8c828be 6029 minibuffer_auto_raise = orig_minibuffer_auto_raise;
fd91d0d4 6030 message_with_string ("Buffer %s has shrunk a lot; auto save disabled in that buffer until next real save",
60d67b83 6031 b->name, 1);
a8c828be 6032 minibuffer_auto_raise = 0;
82c2d839
RS
6033 /* Turn off auto-saving until there's a real save,
6034 and prevent any more warnings. */
46283abe 6035 XSETINT (b->save_length, -1);
f14b1c68
JB
6036 Fsleep_for (make_number (1), Qnil);
6037 continue;
6038 }
6039 set_buffer_internal (b);
6040 if (!auto_saved && NILP (no_message))
6041 message1 ("Auto-saving...");
6042 internal_condition_case (auto_save_1, Qt, auto_save_error);
6043 auto_saved++;
6044 b->auto_save_modified = BUF_MODIFF (b);
2acfd7ae 6045 XSETFASTINT (current_buffer->save_length, Z - BEG);
f14b1c68 6046 set_buffer_internal (old);
b60247d9
RS
6047
6048 EMACS_GET_TIME (after_time);
6049
6050 /* If auto-save took more than 60 seconds,
6051 assume it was an NFS failure that got a timeout. */
6052 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
6053 b->auto_save_failure_time = EMACS_SECS (after_time);
f14b1c68
JB
6054 }
6055 }
570d7624 6056
b67f2ca5
RS
6057 /* Prevent another auto save till enough input events come in. */
6058 record_auto_save ();
570d7624 6059
17857782 6060 if (auto_saved && NILP (no_message))
f05b275b 6061 {
5794dd61 6062 if (old_message_p)
31f3d831 6063 {
5794dd61
RS
6064 /* If we are going to restore an old message,
6065 give time to read ours. */
83f8d903 6066 sit_for (make_number (1), 0, 0);
c71106e5 6067 restore_message ();
31f3d831 6068 }
31e31a15
CY
6069 else if (!auto_save_error_occurred)
6070 /* Don't overwrite the error message if an error occurred.
6071 If we displayed a message and then restored a state
5794dd61 6072 with no message, leave a "done" message on the screen. */
f05b275b
KH
6073 message1 ("Auto-saving...done");
6074 }
570d7624 6075
ff4c9993
RS
6076 Vquit_flag = oquit;
6077
5794dd61 6078 /* This restores the message-stack status. */
e54d3b5d 6079 unbind_to (count, Qnil);
570d7624
JB
6080 return Qnil;
6081}
6082
6083DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
8c1a1077
PJ
6084 Sset_buffer_auto_saved, 0, 0, 0,
6085 doc: /* Mark current buffer as auto-saved with its current text.
6086No auto-save file will be written until the buffer changes again. */)
6087 ()
570d7624
JB
6088{
6089 current_buffer->auto_save_modified = MODIFF;
2acfd7ae 6090 XSETFASTINT (current_buffer->save_length, Z - BEG);
b60247d9
RS
6091 current_buffer->auto_save_failure_time = -1;
6092 return Qnil;
6093}
6094
6095DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
8c1a1077
PJ
6096 Sclear_buffer_auto_save_failure, 0, 0, 0,
6097 doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
6098 ()
b60247d9
RS
6099{
6100 current_buffer->auto_save_failure_time = -1;
570d7624
JB
6101 return Qnil;
6102}
6103
6104DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
8c1a1077 6105 0, 0, 0,
68780e2a
RS
6106 doc: /* Return t if current buffer has been auto-saved recently.
6107More precisely, if it has been auto-saved since last read from or saved
6108in the visited file. If the buffer has no visited file,
6109then any auto-save counts as "recent". */)
8c1a1077 6110 ()
570d7624 6111{
95385625 6112 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
570d7624
JB
6113}
6114\f
6115/* Reading and completing file names */
6116extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
24eb74a3 6117extern Lisp_Object Qcompletion_ignore_case;
570d7624 6118
6e710ae5
RS
6119/* In the string VAL, change each $ to $$ and return the result. */
6120
6121static Lisp_Object
6122double_dollars (val)
6123 Lisp_Object val;
6124{
19290c65
KR
6125 register const unsigned char *old;
6126 register unsigned char *new;
6e710ae5
RS
6127 register int n;
6128 int osize, count;
6129
d5db4077 6130 osize = SBYTES (val);
60d67b83
RS
6131
6132 /* Count the number of $ characters. */
d5db4077 6133 for (n = osize, count = 0, old = SDATA (val); n > 0; n--)
6e710ae5
RS
6134 if (*old++ == '$') count++;
6135 if (count > 0)
6136 {
d5db4077
KR
6137 old = SDATA (val);
6138 val = make_uninit_multibyte_string (SCHARS (val) + count,
60d67b83 6139 osize + count);
d5db4077 6140 new = SDATA (val);
6e710ae5
RS
6141 for (n = osize; n > 0; n--)
6142 if (*old != '$')
6143 *new++ = *old++;
6144 else
6145 {
6146 *new++ = '$';
6147 *new++ = '$';
6148 old++;
6149 }
6150 }
6151 return val;
6152}
6153
59ffe07d
KS
6154static Lisp_Object
6155read_file_name_cleanup (arg)
6156 Lisp_Object arg;
6157{
c4174fbb 6158 return (current_buffer->directory = arg);
59ffe07d
KS
6159}
6160
570d7624 6161DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
8c1a1077
PJ
6162 3, 3, 0,
6163 doc: /* Internal subroutine for read-file-name. Do not call this. */)
6164 (string, dir, action)
570d7624
JB
6165 Lisp_Object string, dir, action;
6166 /* action is nil for complete, t for return list of completions,
6167 lambda for verify final value */
6168{
6169 Lisp_Object name, specdir, realdir, val, orig_string;
09121adc 6170 int changed;
8ce069f5 6171 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
09121adc 6172
b7826503 6173 CHECK_STRING (string);
58cc3710 6174
09121adc
RS
6175 realdir = dir;
6176 name = string;
6177 orig_string = Qnil;
6178 specdir = Qnil;
6179 changed = 0;
6180 /* No need to protect ACTION--we only compare it with t and nil. */
8ce069f5 6181 GCPRO5 (string, realdir, name, specdir, orig_string);
570d7624 6182
d5db4077 6183 if (SCHARS (string) == 0)
570d7624 6184 {
570d7624 6185 if (EQ (action, Qlambda))
09121adc
RS
6186 {
6187 UNGCPRO;
6188 return Qnil;
6189 }
570d7624
JB
6190 }
6191 else
6192 {
6193 orig_string = string;
6194 string = Fsubstitute_in_file_name (string);
09121adc 6195 changed = NILP (Fstring_equal (string, orig_string));
570d7624 6196 name = Ffile_name_nondirectory (string);
09121adc
RS
6197 val = Ffile_name_directory (string);
6198 if (! NILP (val))
6199 realdir = Fexpand_file_name (val, realdir);
570d7624
JB
6200 }
6201
265a9e55 6202 if (NILP (action))
570d7624
JB
6203 {
6204 specdir = Ffile_name_directory (string);
aaf469fc 6205 val = Ffile_name_completion (name, realdir, Vread_file_name_predicate);
09121adc 6206 UNGCPRO;
93c30b5f 6207 if (!STRINGP (val))
570d7624 6208 {
09121adc 6209 if (changed)
dbd04e01 6210 return double_dollars (string);
09121adc 6211 return val;
570d7624
JB
6212 }
6213
265a9e55 6214 if (!NILP (specdir))
570d7624
JB
6215 val = concat2 (specdir, val);
6216#ifndef VMS
6e710ae5
RS
6217 return double_dollars (val);
6218#else /* not VMS */
09121adc 6219 return val;
6e710ae5 6220#endif /* not VMS */
570d7624 6221 }
09121adc 6222 UNGCPRO;
570d7624
JB
6223
6224 if (EQ (action, Qt))
59ffe07d
KS
6225 {
6226 Lisp_Object all = Ffile_name_all_completions (name, realdir);
6227 Lisp_Object comp;
6228 int count;
6229
6230 if (NILP (Vread_file_name_predicate)
6231 || EQ (Vread_file_name_predicate, Qfile_exists_p))
6232 return all;
da46f04f
KS
6233
6234#ifndef VMS
6235 if (EQ (Vread_file_name_predicate, Qfile_directory_p))
6236 {
efdc16c9 6237 /* Brute-force speed up for directory checking:
da46f04f
KS
6238 Discard strings which don't end in a slash. */
6239 for (comp = Qnil; CONSP (all); all = XCDR (all))
6240 {
6241 Lisp_Object tem = XCAR (all);
6242 int len;
994a7262
RS
6243 if (STRINGP (tem)
6244 && (len = SBYTES (tem), len > 0)
6245 && IS_DIRECTORY_SEP (SREF (tem, len-1)))
da46f04f
KS
6246 comp = Fcons (tem, comp);
6247 }
6248 }
6249 else
6250#endif
6251 {
6252 /* Must do it the hard (and slow) way. */
a3911e8c 6253 Lisp_Object tem;
da46f04f 6254 GCPRO3 (all, comp, specdir);
aed13378 6255 count = SPECPDL_INDEX ();
da46f04f
KS
6256 record_unwind_protect (read_file_name_cleanup, current_buffer->directory);
6257 current_buffer->directory = realdir;
6258 for (comp = Qnil; CONSP (all); all = XCDR (all))
a3911e8c
KR
6259 {
6260 tem = call1 (Vread_file_name_predicate, XCAR (all));
6261 if (!NILP (tem))
6262 comp = Fcons (XCAR (all), comp);
6263 }
da46f04f
KS
6264 unbind_to (count, Qnil);
6265 UNGCPRO;
6266 }
59ffe07d
KS
6267 return Fnreverse (comp);
6268 }
6269
570d7624
JB
6270 /* Only other case actually used is ACTION = lambda */
6271#ifdef VMS
6272 /* Supposedly this helps commands such as `cd' that read directory names,
6273 but can someone explain how it helps them? -- RMS */
d5db4077 6274 if (SCHARS (name) == 0)
570d7624
JB
6275 return Qt;
6276#endif /* VMS */
238aedc9 6277 string = Fexpand_file_name (string, dir);
59ffe07d
KS
6278 if (!NILP (Vread_file_name_predicate))
6279 return call1 (Vread_file_name_predicate, string);
570d7624
JB
6280 return Ffile_exists_p (string);
6281}
6282
88208bb8
JD
6283DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p,
6284 Snext_read_file_uses_dialog_p, 0, 0, 0,
6285 doc: /* Return t if a call to `read-file-name' will use a dialog.
6286The return value is only relevant for a call to `read-file-name' that happens
6287before any other event (mouse or keypress) is handeled. */)
6288 ()
6289{
b15325b2 6290#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON)
88208bb8
JD
6291 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
6292 && use_dialog_box
6293 && use_file_dialog
6294 && have_menus_p ())
6295 return Qt;
6296#endif
6297 return Qnil;
6298}
d4a42098 6299
59ffe07d 6300DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
8c1a1077
PJ
6301 doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
6302Value is not expanded---you must call `expand-file-name' yourself.
238aedc9
LT
6303Default name to DEFAULT-FILENAME if user exits the minibuffer with
6304the same non-empty string that was inserted by this function.
8c1a1077
PJ
6305 (If DEFAULT-FILENAME is omitted, the visited file name is used,
6306 except that if INITIAL is specified, that combined with DIR is used.)
238aedc9
LT
6307If the user exits with an empty minibuffer, this function returns
6308an empty string. (This can only happen if the user erased the
6309pre-inserted contents or if `insert-default-directory' is nil.)
8c1a1077
PJ
6310Fourth arg MUSTMATCH non-nil means require existing file's name.
6311 Non-nil and non-t means also require confirmation after completion.
6312Fifth arg INITIAL specifies text to start with.
238aedc9
LT
6313If optional sixth arg PREDICATE is non-nil, possible completions and
6314the resulting file name must satisfy (funcall PREDICATE NAME).
6315DIR should be an absolute directory name. It defaults to the value of
6316`default-directory'.
8c1a1077
PJ
6317
6318If this command was invoked with the mouse, use a file dialog box if
6319`use-dialog-box' is non-nil, and the window system or X toolkit in use
d35c2489
JPW
6320provides a file dialog box.
6321
6322See also `read-file-name-completion-ignore-case'
6323and `read-file-name-function'. */)
59ffe07d
KS
6324 (prompt, dir, default_filename, mustmatch, initial, predicate)
6325 Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate;
570d7624 6326{
8d6d9fef 6327 Lisp_Object val, insdef, tem;
570d7624
JB
6328 struct gcpro gcpro1, gcpro2;
6329 register char *homedir;
d7231f93 6330 Lisp_Object decoded_homedir;
62f555a5
RS
6331 int replace_in_history = 0;
6332 int add_to_history = 0;
570d7624
JB
6333 int count;
6334
265a9e55 6335 if (NILP (dir))
570d7624 6336 dir = current_buffer->directory;
abd5b7f2
RS
6337 if (NILP (Ffile_name_absolute_p (dir)))
6338 dir = Fexpand_file_name (dir, Qnil);
3b7f6e60 6339 if (NILP (default_filename))
abd5b7f2
RS
6340 default_filename
6341 = (!NILP (initial)
6342 ? Fexpand_file_name (initial, dir)
6343 : current_buffer->filename);
570d7624
JB
6344
6345 /* If dir starts with user's homedir, change that to ~. */
6346 homedir = (char *) egetenv ("HOME");
199607e4 6347#ifdef DOS_NT
417c884a
EZ
6348 /* homedir can be NULL in temacs, since Vprocess_environment is not
6349 yet set up. We shouldn't crash in that case. */
6350 if (homedir != 0)
6351 {
6352 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
6353 CORRECT_DIR_SEPS (homedir);
6354 }
199607e4 6355#endif
d7231f93
KH
6356 if (homedir != 0)
6357 decoded_homedir
6358 = DECODE_FILE (make_unibyte_string (homedir, strlen (homedir)));
570d7624 6359 if (homedir != 0
93c30b5f 6360 && STRINGP (dir)
d7231f93
KH
6361 && !strncmp (SDATA (decoded_homedir), SDATA (dir),
6362 SBYTES (decoded_homedir))
6363 && IS_DIRECTORY_SEP (SREF (dir, SBYTES (decoded_homedir))))
570d7624 6364 {
60204046 6365 dir = Fsubstring (dir, make_number (SCHARS (decoded_homedir)), Qnil);
d7231f93 6366 dir = concat2 (build_string ("~"), dir);
570d7624 6367 }
8d6d9fef
AS
6368 /* Likewise for default_filename. */
6369 if (homedir != 0
6370 && STRINGP (default_filename)
d7231f93
KH
6371 && !strncmp (SDATA (decoded_homedir), SDATA (default_filename),
6372 SBYTES (decoded_homedir))
6373 && IS_DIRECTORY_SEP (SREF (default_filename, SBYTES (decoded_homedir))))
8d6d9fef
AS
6374 {
6375 default_filename
d7231f93 6376 = Fsubstring (default_filename,
60204046 6377 make_number (SCHARS (decoded_homedir)), Qnil);
d7231f93 6378 default_filename = concat2 (build_string ("~"), default_filename);
8d6d9fef
AS
6379 }
6380 if (!NILP (default_filename))
b537a6c7 6381 {
b7826503 6382 CHECK_STRING (default_filename);
b537a6c7
RS
6383 default_filename = double_dollars (default_filename);
6384 }
570d7624 6385
58cc3710 6386 if (insert_default_directory && STRINGP (dir))
570d7624
JB
6387 {
6388 insdef = dir;
265a9e55 6389 if (!NILP (initial))
570d7624 6390 {
15c65264 6391 Lisp_Object args[2], pos;
570d7624
JB
6392
6393 args[0] = insdef;
6394 args[1] = initial;
6395 insdef = Fconcat (2, args);
d5db4077 6396 pos = make_number (SCHARS (double_dollars (dir)));
8d6d9fef 6397 insdef = Fcons (double_dollars (insdef), pos);
570d7624 6398 }
6e710ae5 6399 else
8d6d9fef 6400 insdef = double_dollars (insdef);
570d7624 6401 }
58cc3710 6402 else if (STRINGP (initial))
8d6d9fef 6403 insdef = Fcons (double_dollars (initial), make_number (0));
570d7624 6404 else
8d6d9fef 6405 insdef = Qnil;
570d7624 6406
59ffe07d
KS
6407 if (!NILP (Vread_file_name_function))
6408 {
6409 Lisp_Object args[7];
6410
6411 GCPRO2 (insdef, default_filename);
6412 args[0] = Vread_file_name_function;
6413 args[1] = prompt;
6414 args[2] = dir;
6415 args[3] = default_filename;
6416 args[4] = mustmatch;
6417 args[5] = initial;
6418 args[6] = predicate;
6419 RETURN_UNGCPRO (Ffuncall (7, args));
6420 }
6421
aed13378 6422 count = SPECPDL_INDEX ();
24eb74a3 6423 specbind (Qcompletion_ignore_case,
316ef0dc 6424 read_file_name_completion_ignore_case ? Qt : Qnil);
a79485af 6425 specbind (intern ("minibuffer-completing-file-name"), Qt);
efdc16c9 6426 specbind (intern ("read-file-name-predicate"),
59ffe07d 6427 (NILP (predicate) ? Qfile_exists_p : predicate));
a79485af 6428
3b7f6e60 6429 GCPRO2 (insdef, default_filename);
c60ee5e7 6430
b15325b2 6431#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON)
88208bb8 6432 if (! NILP (Fnext_read_file_uses_dialog_p ()))
9c856db9 6433 {
9172b88d
GM
6434 /* If DIR contains a file name, split it. */
6435 Lisp_Object file;
6436 file = Ffile_name_nondirectory (dir);
d5db4077 6437 if (SCHARS (file) && NILP (default_filename))
9172b88d
GM
6438 {
6439 default_filename = file;
6440 dir = Ffile_name_directory (dir);
6441 }
f73f57bd
JR
6442 if (!NILP(default_filename))
6443 default_filename = Fexpand_file_name (default_filename, dir);
f9d64bb3
JD
6444 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch,
6445 EQ (predicate, Qfile_directory_p) ? Qt : Qnil);
9c856db9
GM
6446 add_to_history = 1;
6447 }
6448 else
6449#endif
6450 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
6451 dir, mustmatch, insdef,
6452 Qfile_name_history, default_filename, Qnil);
62f555a5
RS
6453
6454 tem = Fsymbol_value (Qfile_name_history);
03699b14 6455 if (CONSP (tem) && EQ (XCAR (tem), val))
62f555a5
RS
6456 replace_in_history = 1;
6457
6458 /* If Fcompleting_read returned the inserted default string itself
a8c828be
RS
6459 (rather than a new string with the same contents),
6460 it has to mean that the user typed RET with the minibuffer empty.
6461 In that case, we really want to return ""
6462 so that commands such as set-visited-file-name can distinguish. */
6463 if (EQ (val, default_filename))
62f555a5
RS
6464 {
6465 /* In this case, Fcompleting_read has not added an element
6466 to the history. Maybe we should. */
6467 if (! replace_in_history)
6468 add_to_history = 1;
6469
4a9f0fae 6470 val = empty_string;
62f555a5 6471 }
570d7624 6472
570d7624 6473 unbind_to (count, Qnil);
570d7624 6474 UNGCPRO;
265a9e55 6475 if (NILP (val))
570d7624 6476 error ("No file name specified");
62f555a5 6477
8d6d9fef 6478 tem = Fstring_equal (val, CONSP (insdef) ? XCAR (insdef) : insdef);
62f555a5 6479
3b7f6e60 6480 if (!NILP (tem) && !NILP (default_filename))
62f555a5 6481 val = default_filename;
62f555a5 6482 val = Fsubstitute_in_file_name (val);
570d7624 6483
62f555a5
RS
6484 if (replace_in_history)
6485 /* Replace what Fcompleting_read added to the history
6486 with what we will actually return. */
75fa7206
RS
6487 {
6488 Lisp_Object val1 = double_dollars (val);
6489 tem = Fsymbol_value (Qfile_name_history);
c1558952 6490 if (history_delete_duplicates)
75fa7206
RS
6491 XSETCDR (tem, Fdelete (val1, XCDR(tem)));
6492 XSETCAR (tem, val1);
6493 }
62f555a5 6494 else if (add_to_history)
570d7624 6495 {
62f555a5
RS
6496 /* Add the value to the history--but not if it matches
6497 the last value already there. */
8d6d9fef 6498 Lisp_Object val1 = double_dollars (val);
62f555a5 6499 tem = Fsymbol_value (Qfile_name_history);
03699b14 6500 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
75fa7206
RS
6501 {
6502 if (history_delete_duplicates) tem = Fdelete (val1, tem);
6503 Fset (Qfile_name_history, Fcons (val1, tem));
6504 }
570d7624 6505 }
efdc16c9 6506
62f555a5 6507 return val;
570d7624 6508}
9c856db9 6509
570d7624 6510\f
dbda5089
GV
6511void
6512init_fileio_once ()
6513{
6514 /* Must be set before any path manipulation is performed. */
6515 XSETFASTINT (Vdirectory_sep_char, '/');
6516}
6517
9c856db9 6518\f
dfcf069d 6519void
570d7624
JB
6520syms_of_fileio ()
6521{
f6c9b683 6522 Qoperations = intern ("operations");
0bf2eed2 6523 Qexpand_file_name = intern ("expand-file-name");
273e0829 6524 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
0bf2eed2
RS
6525 Qdirectory_file_name = intern ("directory-file-name");
6526 Qfile_name_directory = intern ("file-name-directory");
6527 Qfile_name_nondirectory = intern ("file-name-nondirectory");
642ef245 6528 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
0bf2eed2 6529 Qfile_name_as_directory = intern ("file-name-as-directory");
32f4334d 6530 Qcopy_file = intern ("copy-file");
a6e6e718 6531 Qmake_directory_internal = intern ("make-directory-internal");
b272d624 6532 Qmake_directory = intern ("make-directory");
32f4334d
RS
6533 Qdelete_directory = intern ("delete-directory");
6534 Qdelete_file = intern ("delete-file");
6535 Qrename_file = intern ("rename-file");
6536 Qadd_name_to_file = intern ("add-name-to-file");
6537 Qmake_symbolic_link = intern ("make-symbolic-link");
6538 Qfile_exists_p = intern ("file-exists-p");
6539 Qfile_executable_p = intern ("file-executable-p");
6540 Qfile_readable_p = intern ("file-readable-p");
32f4334d 6541 Qfile_writable_p = intern ("file-writable-p");
1f8653eb
RS
6542 Qfile_symlink_p = intern ("file-symlink-p");
6543 Qaccess_file = intern ("access-file");
32f4334d 6544 Qfile_directory_p = intern ("file-directory-p");
adedc71d 6545 Qfile_regular_p = intern ("file-regular-p");
32f4334d
RS
6546 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
6547 Qfile_modes = intern ("file-modes");
6548 Qset_file_modes = intern ("set-file-modes");
819da85b 6549 Qset_file_times = intern ("set-file-times");
32f4334d
RS
6550 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
6551 Qinsert_file_contents = intern ("insert-file-contents");
6552 Qwrite_region = intern ("write-region");
6553 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
3ec46acd 6554 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
356a6224 6555 Qauto_save_coding = intern ("auto-save-coding");
32f4334d 6556
f6c9b683 6557 staticpro (&Qoperations);
642ef245 6558 staticpro (&Qexpand_file_name);
273e0829 6559 staticpro (&Qsubstitute_in_file_name);
642ef245
JB
6560 staticpro (&Qdirectory_file_name);
6561 staticpro (&Qfile_name_directory);
6562 staticpro (&Qfile_name_nondirectory);
6563 staticpro (&Qunhandled_file_name_directory);
6564 staticpro (&Qfile_name_as_directory);
15c65264 6565 staticpro (&Qcopy_file);
c34b559d 6566 staticpro (&Qmake_directory_internal);
b272d624 6567 staticpro (&Qmake_directory);
15c65264
RS
6568 staticpro (&Qdelete_directory);
6569 staticpro (&Qdelete_file);
6570 staticpro (&Qrename_file);
6571 staticpro (&Qadd_name_to_file);
6572 staticpro (&Qmake_symbolic_link);
6573 staticpro (&Qfile_exists_p);
6574 staticpro (&Qfile_executable_p);
6575 staticpro (&Qfile_readable_p);
15c65264 6576 staticpro (&Qfile_writable_p);
1f8653eb
RS
6577 staticpro (&Qaccess_file);
6578 staticpro (&Qfile_symlink_p);
15c65264 6579 staticpro (&Qfile_directory_p);
adedc71d 6580 staticpro (&Qfile_regular_p);
15c65264
RS
6581 staticpro (&Qfile_accessible_directory_p);
6582 staticpro (&Qfile_modes);
6583 staticpro (&Qset_file_modes);
819da85b 6584 staticpro (&Qset_file_times);
15c65264
RS
6585 staticpro (&Qfile_newer_than_file_p);
6586 staticpro (&Qinsert_file_contents);
6587 staticpro (&Qwrite_region);
6588 staticpro (&Qverify_visited_file_modtime);
0a61794b 6589 staticpro (&Qset_visited_file_modtime);
356a6224 6590 staticpro (&Qauto_save_coding);
642ef245
JB
6591
6592 Qfile_name_history = intern ("file-name-history");
6593 Fset (Qfile_name_history, Qnil);
15c65264
RS
6594 staticpro (&Qfile_name_history);
6595
570d7624
JB
6596 Qfile_error = intern ("file-error");
6597 staticpro (&Qfile_error);
199607e4 6598 Qfile_already_exists = intern ("file-already-exists");
570d7624 6599 staticpro (&Qfile_already_exists);
c0b7b21c
RS
6600 Qfile_date_error = intern ("file-date-error");
6601 staticpro (&Qfile_date_error);
505ab9bc
RS
6602 Qexcl = intern ("excl");
6603 staticpro (&Qexcl);
570d7624 6604
5e570b75 6605#ifdef DOS_NT
4c3c22f3
RS
6606 Qfind_buffer_file_type = intern ("find-buffer-file-type");
6607 staticpro (&Qfind_buffer_file_type);
5e570b75 6608#endif /* DOS_NT */
4c3c22f3 6609
b1d1b865 6610 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
8c1a1077 6611 doc: /* *Coding system for encoding file names.
346ebf53 6612If it is nil, `default-file-name-coding-system' (which see) is used. */);
b1d1b865
RS
6613 Vfile_name_coding_system = Qnil;
6614
cd913586
KH
6615 DEFVAR_LISP ("default-file-name-coding-system",
6616 &Vdefault_file_name_coding_system,
8c1a1077 6617 doc: /* Default coding system for encoding file names.
346ebf53 6618This variable is used only when `file-name-coding-system' is nil.
8c1a1077 6619
346ebf53 6620This variable is set/changed by the command `set-language-environment'.
8c1a1077 6621User should not set this variable manually,
346ebf53 6622instead use `file-name-coding-system' to get a constant encoding
8c1a1077 6623of file names regardless of the current language environment. */);
cd913586
KH
6624 Vdefault_file_name_coding_system = Qnil;
6625
0d420e88
BG
6626 Qformat_decode = intern ("format-decode");
6627 staticpro (&Qformat_decode);
6628 Qformat_annotate_function = intern ("format-annotate-function");
6629 staticpro (&Qformat_annotate_function);
2080470e
KH
6630 Qafter_insert_file_set_coding = intern ("after-insert-file-set-coding");
6631 staticpro (&Qafter_insert_file_set_coding);
efdc16c9 6632
d6a3cc15
RS
6633 Qcar_less_than_car = intern ("car-less-than-car");
6634 staticpro (&Qcar_less_than_car);
6635
570d7624 6636 Fput (Qfile_error, Qerror_conditions,
24b1ddad 6637 list2 (Qfile_error, Qerror));
570d7624
JB
6638 Fput (Qfile_error, Qerror_message,
6639 build_string ("File error"));
6640
6641 Fput (Qfile_already_exists, Qerror_conditions,
24b1ddad 6642 list3 (Qfile_already_exists, Qfile_error, Qerror));
570d7624
JB
6643 Fput (Qfile_already_exists, Qerror_message,
6644 build_string ("File already exists"));
6645
c0b7b21c 6646 Fput (Qfile_date_error, Qerror_conditions,
24b1ddad 6647 list3 (Qfile_date_error, Qfile_error, Qerror));
c0b7b21c
RS
6648 Fput (Qfile_date_error, Qerror_message,
6649 build_string ("Cannot set file date"));
6650
59ffe07d
KS
6651 DEFVAR_LISP ("read-file-name-function", &Vread_file_name_function,
6652 doc: /* If this is non-nil, `read-file-name' does its work by calling this function. */);
6653 Vread_file_name_function = Qnil;
6654
6655 DEFVAR_LISP ("read-file-name-predicate", &Vread_file_name_predicate,
6656 doc: /* Current predicate used by `read-file-name-internal'. */);
6657 Vread_file_name_predicate = Qnil;
6658
316ef0dc
JPW
6659 DEFVAR_BOOL ("read-file-name-completion-ignore-case", &read_file_name_completion_ignore_case,
6660 doc: /* *Non-nil means when reading a file name completion ignores case. */);
6661#if defined VMS || defined DOS_NT || defined MAC_OS
6662 read_file_name_completion_ignore_case = 1;
6663#else
6664 read_file_name_completion_ignore_case = 0;
6665#endif
6666
570d7624 6667 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
238aedc9 6668 doc: /* *Non-nil means when reading a filename start with default dir in minibuffer.
d375705e
EZ
6669
6670When the initial minibuffer contents show a name of a file or a directory,
6671typing RETURN without editing the initial contents is equivalent to typing
6672the default file name.
6673
238aedc9 6674If this variable is non-nil, the minibuffer contents are always
d375705e 6675initially non-empty, and typing RETURN without editing will fetch the
238aedc9 6676default name, if one is provided. Note however that this default name
d375705e
EZ
6677is not necessarily the same as initial contents inserted in the minibuffer,
6678if the initial contents is just the default directory.
6679
238aedc9
LT
6680If this variable is nil, the minibuffer often starts out empty. In
6681that case you may have to explicitly fetch the next history element to
d375705e
EZ
6682request the default name; typing RETURN without editing will leave
6683the minibuffer empty.
6684
6685For some commands, exiting with an empty minibuffer has a special meaning,
6686such as making the current buffer visit no file in the case of
6687`set-visited-file-name'. */);
570d7624
JB
6688 insert_default_directory = 1;
6689
6690 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
8c1a1077
PJ
6691 doc: /* *Non-nil means write new files with record format `stmlf'.
6692nil means use format `var'. This variable is meaningful only on VMS. */);
570d7624
JB
6693 vms_stmlf_recfm = 0;
6694
199607e4 6695 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
8c1a1077 6696 doc: /* Directory separator character for built-in functions that return file names.
d57563b6 6697The value is always ?/. Don't use this variable, just use `/'. */);
199607e4 6698
1d1826db 6699 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
8c1a1077
PJ
6700 doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
6701If a file name matches REGEXP, then all I/O on that file is done by calling
6702HANDLER.
6703
6704The first argument given to HANDLER is the name of the I/O primitive
6705to be handled; the remaining arguments are the arguments that were
6706passed to that primitive. For example, if you do
6707 (file-exists-p FILENAME)
6708and FILENAME is handled by HANDLER, then HANDLER is called like this:
6709 (funcall HANDLER 'file-exists-p FILENAME)
6710The function `find-file-name-handler' checks this list for a handler
6711for its argument. */);
09121adc
RS
6712 Vfile_name_handler_alist = Qnil;
6713
0414b394
KH
6714 DEFVAR_LISP ("set-auto-coding-function",
6715 &Vset_auto_coding_function,
8c1a1077
PJ
6716 doc: /* If non-nil, a function to call to decide a coding system of file.
6717Two arguments are passed to this function: the file name
6718and the length of a file contents following the point.
6719This function should return a coding system to decode the file contents.
6720It should check the file name against `auto-coding-alist'.
6721If no coding system is decided, it should check a coding system
6722specified in the heading lines with the format:
6723 -*- ... coding: CODING-SYSTEM; ... -*-
6724or local variable spec of the tailing lines with `coding:' tag. */);
0414b394 6725 Vset_auto_coding_function = Qnil;
c9e82392 6726
d6a3cc15 6727 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
8c1a1077 6728 doc: /* A list of functions to be called at the end of `insert-file-contents'.
cf6d2357
RS
6729Each is passed one argument, the number of characters inserted.
6730It should return the new character count, and leave point the same.
6731If `insert-file-contents' is intercepted by a handler from
6732`file-name-handler-alist', that handler is responsible for calling the
6733functions in `after-insert-file-functions' if appropriate. */);
d6a3cc15
RS
6734 Vafter_insert_file_functions = Qnil;
6735
6736 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
8c1a1077
PJ
6737 doc: /* A list of functions to be called at the start of `write-region'.
6738Each is passed two arguments, START and END as for `write-region'.
6739These are usually two numbers but not always; see the documentation
6740for `write-region'. The function should return a list of pairs
6741of the form (POSITION . STRING), consisting of strings to be effectively
6742inserted at the specified positions of the file being written (1 means to
6743insert before the first byte written). The POSITIONs must be sorted into
6744increasing order. If there are several functions in the list, the several
28c3eb5a 6745lists are merged destructively. Alternatively, the function can return
bd235610
SM
6746with a different buffer current; in that case it should pay attention
6747to the annotations returned by previous functions and listed in
6748`write-region-annotations-so-far'.*/);
d6a3cc15 6749 Vwrite_region_annotate_functions = Qnil;
bd235610
SM
6750 staticpro (&Qwrite_region_annotate_functions);
6751 Qwrite_region_annotate_functions
6752 = intern ("write-region-annotate-functions");
d6a3cc15 6753
6fc6f94b
RS
6754 DEFVAR_LISP ("write-region-annotations-so-far",
6755 &Vwrite_region_annotations_so_far,
8c1a1077
PJ
6756 doc: /* When an annotation function is called, this holds the previous annotations.
6757These are the annotations made by other annotation functions
6758that were already called. See also `write-region-annotate-functions'. */);
6fc6f94b
RS
6759 Vwrite_region_annotations_so_far = Qnil;
6760
82c2d839 6761 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
8c1a1077
PJ
6762 doc: /* A list of file name handlers that temporarily should not be used.
6763This applies only to the operation `inhibit-file-name-operation'. */);
82c2d839
RS
6764 Vinhibit_file_name_handlers = Qnil;
6765
a65970a0 6766 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
8c1a1077 6767 doc: /* The operation for which `inhibit-file-name-handlers' is applicable. */);
a65970a0
RS
6768 Vinhibit_file_name_operation = Qnil;
6769
e54d3b5d 6770 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
8c1a1077
PJ
6771 doc: /* File name in which we write a list of all auto save file names.
6772This variable is initialized automatically from `auto-save-list-file-prefix'
6773shortly after Emacs reads your `.emacs' file, if you have not yet given it
6774a non-nil value. */);
e54d3b5d
RS
6775 Vauto_save_list_file_name = Qnil;
6776
f8a12fae
CY
6777 DEFVAR_LISP ("auto-save-visited-file-name", &Vauto_save_visited_file_name,
6778 doc: /* Non-nil says auto-save a buffer in the file it is visiting, when practical.
6779Normally auto-save files are written under other names. */);
6780 Vauto_save_visited_file_name = Qnil;
6781
ccf61795
RF
6782#ifdef HAVE_FSYNC
6783 DEFVAR_BOOL ("write-region-inhibit-fsync", &write_region_inhibit_fsync,
e3f509dd
RF
6784 doc: /* *Non-nil means don't call fsync in `write-region'.
6785This variable affects calls to `write-region' as well as save commands.
6786A non-nil value may result in data loss! */);
ccf61795
RF
6787 write_region_inhibit_fsync = 0;
6788#endif
6789
642ef245 6790 defsubr (&Sfind_file_name_handler);
570d7624
JB
6791 defsubr (&Sfile_name_directory);
6792 defsubr (&Sfile_name_nondirectory);
642ef245 6793 defsubr (&Sunhandled_file_name_directory);
570d7624
JB
6794 defsubr (&Sfile_name_as_directory);
6795 defsubr (&Sdirectory_file_name);
6796 defsubr (&Smake_temp_name);
6797 defsubr (&Sexpand_file_name);
6798 defsubr (&Ssubstitute_in_file_name);
6799 defsubr (&Scopy_file);
9bbe01fb 6800 defsubr (&Smake_directory_internal);
aa734e17 6801 defsubr (&Sdelete_directory);
570d7624
JB
6802 defsubr (&Sdelete_file);
6803 defsubr (&Srename_file);
6804 defsubr (&Sadd_name_to_file);
570d7624 6805 defsubr (&Smake_symbolic_link);
570d7624
JB
6806#ifdef VMS
6807 defsubr (&Sdefine_logical_name);
6808#endif /* VMS */
6809#ifdef HPUX_NET
6810 defsubr (&Ssysnetunam);
6811#endif /* HPUX_NET */
6812 defsubr (&Sfile_name_absolute_p);
6813 defsubr (&Sfile_exists_p);
6814 defsubr (&Sfile_executable_p);
6815 defsubr (&Sfile_readable_p);
6816 defsubr (&Sfile_writable_p);
1f8653eb 6817 defsubr (&Saccess_file);
570d7624
JB
6818 defsubr (&Sfile_symlink_p);
6819 defsubr (&Sfile_directory_p);
b72dea2a 6820 defsubr (&Sfile_accessible_directory_p);
f793dc6c 6821 defsubr (&Sfile_regular_p);
570d7624
JB
6822 defsubr (&Sfile_modes);
6823 defsubr (&Sset_file_modes);
819da85b 6824 defsubr (&Sset_file_times);
c24e9a53
RS
6825 defsubr (&Sset_default_file_modes);
6826 defsubr (&Sdefault_file_modes);
570d7624
JB
6827 defsubr (&Sfile_newer_than_file_p);
6828 defsubr (&Sinsert_file_contents);
6829 defsubr (&Swrite_region);
d6a3cc15 6830 defsubr (&Scar_less_than_car);
570d7624
JB
6831 defsubr (&Sverify_visited_file_modtime);
6832 defsubr (&Sclear_visited_file_modtime);
f5d5eccf 6833 defsubr (&Svisited_file_modtime);
570d7624
JB
6834 defsubr (&Sset_visited_file_modtime);
6835 defsubr (&Sdo_auto_save);
6836 defsubr (&Sset_buffer_auto_saved);
b60247d9 6837 defsubr (&Sclear_buffer_auto_save_failure);
570d7624
JB
6838 defsubr (&Srecent_auto_save_p);
6839
6840 defsubr (&Sread_file_name_internal);
6841 defsubr (&Sread_file_name);
88208bb8 6842 defsubr (&Snext_read_file_uses_dialog_p);
85ffea93 6843
697c17a2 6844#ifdef HAVE_SYNC
85ffea93 6845 defsubr (&Sunix_sync);
483a2e10 6846#endif
570d7624 6847}
ab5796a9
MB
6848
6849/* arch-tag: 64ba3fd7-f844-4fb2-ba4b-427eb928786c
6850 (do not change this comment) */