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