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