Check for overflow when converting integer to cons and back.
[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 3247
15cbd324
EZ
3248 /* Check whether the size is too large or negative, which can happen on a
3249 platform that allows file sizes greater than the maximum off_t value. */
2a47c44d 3250 if (! not_regular
d1f3d2af 3251 && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX))
11d300db 3252 error ("Maximum buffer size exceeded");
be53b411 3253
9c856db9
GM
3254 /* Prevent redisplay optimizations. */
3255 current_buffer->clip_changed = 1;
3256
9f57b6b4
KH
3257 if (!NILP (visit))
3258 {
3259 if (!NILP (beg) || !NILP (end))
3260 error ("Attempt to visit less than an entire file");
3261 if (BEG < Z && NILP (replace))
3262 error ("Cannot do file visiting in a non-empty buffer");
3263 }
7fded690
JB
3264
3265 if (!NILP (beg))
b7826503 3266 CHECK_NUMBER (beg);
7fded690 3267 else
2acfd7ae 3268 XSETFASTINT (beg, 0);
7fded690
JB
3269
3270 if (!NILP (end))
b7826503 3271 CHECK_NUMBER (end);
7fded690
JB
3272 else
3273 {
d4b8687b
RS
3274 if (! not_regular)
3275 {
3276 XSETINT (end, st.st_size);
68c45bf0 3277
d21dd12d
GM
3278 /* The file size returned from stat may be zero, but data
3279 may be readable nonetheless, for example when this is a
3280 file in the /proc filesystem. */
3281 if (st.st_size == 0)
3282 XSETINT (end, READ_BUF_SIZE);
d4b8687b 3283 }
7fded690
JB
3284 }
3285
356a6224 3286 if (EQ (Vcoding_system_for_read, Qauto_save_coding))
5560aecd 3287 {
75421805 3288 coding_system = coding_inherit_eol_type (Qutf_8_emacs, Qunix);
5560aecd
KH
3289 setup_coding_system (coding_system, &coding);
3290 /* Ensure we set Vlast_coding_system_used. */
3291 set_coding_system = 1;
3292 }
356a6224 3293 else if (BEG < Z)
f736ffbf
KH
3294 {
3295 /* Decide the coding system to use for reading the file now
3296 because we can't use an optimized method for handling
3297 `coding:' tag if the current buffer is not empty. */
f736ffbf 3298 if (!NILP (Vcoding_system_for_read))
db327c7e 3299 coding_system = Vcoding_system_for_read;
f736ffbf
KH
3300 else
3301 {
3302 /* Don't try looking inside a file for a coding system
3303 specification if it is not seekable. */
3304 if (! not_regular && ! NILP (Vset_auto_coding_function))
3305 {
3306 /* Find a coding system specified in the heading two
3307 lines or in the tailing several lines of the file.
3308 We assume that the 1K-byte and 3K-byte for heading
003a7eaa 3309 and tailing respectively are sufficient for this
f736ffbf 3310 purpose. */
ae19ba7c 3311 EMACS_INT nread;
f736ffbf
KH
3312
3313 if (st.st_size <= (1024 * 4))
68c45bf0 3314 nread = emacs_read (fd, read_buf, 1024 * 4);
f736ffbf
KH
3315 else
3316 {
68c45bf0 3317 nread = emacs_read (fd, read_buf, 1024);
f736ffbf
KH
3318 if (nread >= 0)
3319 {
3320 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3321 report_file_error ("Setting file position",
3322 Fcons (orig_filename, Qnil));
68c45bf0 3323 nread += emacs_read (fd, read_buf + nread, 1024 * 3);
f736ffbf
KH
3324 }
3325 }
feb9dc27 3326
f736ffbf
KH
3327 if (nread < 0)
3328 error ("IO error reading %s: %s",
d5db4077 3329 SDATA (orig_filename), emacs_strerror (errno));
f736ffbf
KH
3330 else if (nread > 0)
3331 {
f736ffbf 3332 struct buffer *prev = current_buffer;
f839df0c 3333 Lisp_Object workbuf;
685fc579 3334 struct buffer *buf;
f736ffbf
KH
3335
3336 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1d92afcd 3337
f839df0c
PE
3338 workbuf = Fget_buffer_create (build_string (" *code-converting-work*"));
3339 buf = XBUFFER (workbuf);
685fc579 3340
29ea8ae9 3341 delete_all_overlays (buf);
4b4deea2
TT
3342 BVAR (buf, directory) = BVAR (current_buffer, directory);
3343 BVAR (buf, read_only) = Qnil;
3344 BVAR (buf, filename) = Qnil;
3345 BVAR (buf, undo_list) = Qt;
29ea8ae9
SM
3346 eassert (buf->overlays_before == NULL);
3347 eassert (buf->overlays_after == NULL);
efdc16c9 3348
685fc579
RS
3349 set_buffer_internal (buf);
3350 Ferase_buffer ();
4b4deea2 3351 BVAR (buf, enable_multibyte_characters) = Qnil;
685fc579 3352
b68864e5 3353 insert_1_both ((char *) read_buf, nread, nread, 0, 0, 0);
f736ffbf 3354 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
db327c7e 3355 coding_system = call2 (Vset_auto_coding_function,
8f924df7 3356 filename, make_number (nread));
f736ffbf 3357 set_buffer_internal (prev);
efdc16c9 3358
f736ffbf
KH
3359 /* Discard the unwind protect for recovering the
3360 current buffer. */
3361 specpdl_ptr--;
3362
3363 /* Rewind the file for the actual read done later. */
3364 if (lseek (fd, 0, 0) < 0)
3365 report_file_error ("Setting file position",
3366 Fcons (orig_filename, Qnil));
3367 }
3368 }
feb9dc27 3369
db327c7e 3370 if (NILP (coding_system))
f736ffbf
KH
3371 {
3372 /* If we have not yet decided a coding system, check
3373 file-coding-system-alist. */
8f924df7 3374 Lisp_Object args[6];
f736ffbf
KH
3375
3376 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3377 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
8f924df7
KH
3378 coding_system = Ffind_operation_coding_system (6, args);
3379 if (CONSP (coding_system))
3380 coding_system = XCAR (coding_system);
f736ffbf
KH
3381 }
3382 }
c9e82392 3383
db327c7e
KH
3384 if (NILP (coding_system))
3385 coding_system = Qundecided;
3386 else
3387 CHECK_CODING_SYSTEM (coding_system);
c8a6d68a 3388
4b4deea2 3389 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
237a6fd2
RS
3390 /* We must suppress all character code conversion except for
3391 end-of-line conversion. */
db327c7e 3392 coding_system = raw_text_coding_system (coding_system);
54369368 3393
db327c7e
KH
3394 setup_coding_system (coding_system, &coding);
3395 /* Ensure we set Vlast_coding_system_used. */
3396 set_coding_system = 1;
f736ffbf 3397 }
6cf71bf1 3398
3d0387c0
RS
3399 /* If requested, replace the accessible part of the buffer
3400 with the file contents. Avoid replacing text at the
3401 beginning or end of the buffer that matches the file contents;
3dbcf3f6
RS
3402 that preserves markers pointing to the unchanged parts.
3403
3404 Here we implement this feature in an optimized way
3405 for the case where code conversion is NOT needed.
3406 The following if-statement handles the case of conversion
727a0b4a
RS
3407 in a less optimal way.
3408
3409 If the code conversion is "automatic" then we try using this
3410 method and hope for the best.
3411 But if we discover the need for conversion, we give up on this method
3412 and let the following if-statement handle the replace job. */
3dbcf3f6 3413 if (!NILP (replace)
f736ffbf 3414 && BEGV < ZV
db327c7e
KH
3415 && (NILP (coding_system)
3416 || ! CODING_REQUIRE_DECODING (&coding)))
3d0387c0 3417 {
ec7adf26
RS
3418 /* same_at_start and same_at_end count bytes,
3419 because file access counts bytes
3420 and BEG and END count bytes. */
ae19ba7c
SM
3421 EMACS_INT same_at_start = BEGV_BYTE;
3422 EMACS_INT same_at_end = ZV_BYTE;
3423 EMACS_INT overlap;
6fdaa9a0
KH
3424 /* There is still a possibility we will find the need to do code
3425 conversion. If that happens, we set this variable to 1 to
727a0b4a 3426 give up on handling REPLACE in the optimized way. */
6fdaa9a0 3427 int giveup_match_end = 0;
9c28748f 3428
4d2a0879
RS
3429 if (XINT (beg) != 0)
3430 {
3431 if (lseek (fd, XINT (beg), 0) < 0)
3432 report_file_error ("Setting file position",
b1d1b865 3433 Fcons (orig_filename, Qnil));
4d2a0879
RS
3434 }
3435
3d0387c0
RS
3436 immediate_quit = 1;
3437 QUIT;
3438 /* Count how many chars at the start of the file
3439 match the text at the beginning of the buffer. */
3440 while (1)
3441 {
ae19ba7c 3442 EMACS_INT nread, bufpos;
3d0387c0 3443
68c45bf0 3444 nread = emacs_read (fd, buffer, sizeof buffer);
3d0387c0
RS
3445 if (nread < 0)
3446 error ("IO error reading %s: %s",
5976c3fe 3447 SSDATA (orig_filename), emacs_strerror (errno));
3d0387c0
RS
3448 else if (nread == 0)
3449 break;
6fdaa9a0 3450
db327c7e 3451 if (CODING_REQUIRE_DETECTION (&coding))
727a0b4a 3452 {
5976c3fe
PE
3453 coding_system = detect_coding_system ((unsigned char *) buffer,
3454 nread, nread, 1, 0,
db327c7e
KH
3455 coding_system);
3456 setup_coding_system (coding_system, &coding);
727a0b4a
RS
3457 }
3458
db327c7e
KH
3459 if (CODING_REQUIRE_DECODING (&coding))
3460 /* We found that the file should be decoded somehow.
727a0b4a
RS
3461 Let's give up here. */
3462 {
3463 giveup_match_end = 1;
3464 break;
3465 }
3466
3d0387c0 3467 bufpos = 0;
ec7adf26 3468 while (bufpos < nread && same_at_start < ZV_BYTE
6fdaa9a0 3469 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3d0387c0
RS
3470 same_at_start++, bufpos++;
3471 /* If we found a discrepancy, stop the scan.
8e6208c5 3472 Otherwise loop around and scan the next bufferful. */
3d0387c0
RS
3473 if (bufpos != nread)
3474 break;
3475 }
3476 immediate_quit = 0;
3477 /* If the file matches the buffer completely,
3478 there's no need to replace anything. */
ec7adf26 3479 if (same_at_start - BEGV_BYTE == XINT (end))
3d0387c0 3480 {
68c45bf0 3481 emacs_close (fd);
a1d2b64a 3482 specpdl_ptr--;
1051b3b3 3483 /* Truncate the buffer to the size of the file. */
7dae4502 3484 del_range_1 (same_at_start, same_at_end, 0, 0);
3d0387c0
RS
3485 goto handled;
3486 }
3487 immediate_quit = 1;
3488 QUIT;
3489 /* Count how many chars at the end of the file
6fdaa9a0
KH
3490 match the text at the end of the buffer. But, if we have
3491 already found that decoding is necessary, don't waste time. */
3492 while (!giveup_match_end)
3d0387c0 3493 {
ae19ba7c 3494 EMACS_INT total_read, nread, bufpos, curpos, trial;
3d0387c0
RS
3495
3496 /* At what file position are we now scanning? */
ec7adf26 3497 curpos = XINT (end) - (ZV_BYTE - same_at_end);
fc81fa9e
KH
3498 /* If the entire file matches the buffer tail, stop the scan. */
3499 if (curpos == 0)
3500 break;
3d0387c0
RS
3501 /* How much can we scan in the next step? */
3502 trial = min (curpos, sizeof buffer);
3503 if (lseek (fd, curpos - trial, 0) < 0)
3504 report_file_error ("Setting file position",
b1d1b865 3505 Fcons (orig_filename, Qnil));
3d0387c0 3506
b02439c8 3507 total_read = nread = 0;
3d0387c0
RS
3508 while (total_read < trial)
3509 {
68c45bf0 3510 nread = emacs_read (fd, buffer + total_read, trial - total_read);
2bd2273e 3511 if (nread < 0)
3d0387c0 3512 error ("IO error reading %s: %s",
d5db4077 3513 SDATA (orig_filename), emacs_strerror (errno));
2bd2273e
GM
3514 else if (nread == 0)
3515 break;
3d0387c0
RS
3516 total_read += nread;
3517 }
efdc16c9 3518
8e6208c5 3519 /* Scan this bufferful from the end, comparing with
3d0387c0
RS
3520 the Emacs buffer. */
3521 bufpos = total_read;
efdc16c9 3522
3d0387c0
RS
3523 /* Compare with same_at_start to avoid counting some buffer text
3524 as matching both at the file's beginning and at the end. */
3525 while (bufpos > 0 && same_at_end > same_at_start
6fdaa9a0 3526 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3d0387c0 3527 same_at_end--, bufpos--;
727a0b4a 3528
3d0387c0 3529 /* If we found a discrepancy, stop the scan.
8e6208c5 3530 Otherwise loop around and scan the preceding bufferful. */
3d0387c0 3531 if (bufpos != 0)
727a0b4a
RS
3532 {
3533 /* If this discrepancy is because of code conversion,
3534 we cannot use this method; giveup and try the other. */
3535 if (same_at_end > same_at_start
3536 && FETCH_BYTE (same_at_end - 1) >= 0200
4b4deea2 3537 && ! NILP (BVAR (current_buffer, enable_multibyte_characters))
c8a6d68a 3538 && (CODING_MAY_REQUIRE_DECODING (&coding)))
727a0b4a
RS
3539 giveup_match_end = 1;
3540 break;
3541 }
b02439c8
GM
3542
3543 if (nread == 0)
3544 break;
3d0387c0
RS
3545 }
3546 immediate_quit = 0;
9c28748f 3547
727a0b4a
RS
3548 if (! giveup_match_end)
3549 {
ae19ba7c 3550 EMACS_INT temp;
ec7adf26 3551
727a0b4a 3552 /* We win! We can handle REPLACE the optimized way. */
9c28748f 3553
20f6783d
RS
3554 /* Extend the start of non-matching text area to multibyte
3555 character boundary. */
4b4deea2 3556 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
20f6783d
RS
3557 while (same_at_start > BEGV_BYTE
3558 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
3559 same_at_start--;
3560
3561 /* Extend the end of non-matching text area to multibyte
71312b68 3562 character boundary. */
4b4deea2 3563 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
ec7adf26
RS
3564 while (same_at_end < ZV_BYTE
3565 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
71312b68
RS
3566 same_at_end++;
3567
727a0b4a 3568 /* Don't try to reuse the same piece of text twice. */
ec7adf26
RS
3569 overlap = (same_at_start - BEGV_BYTE
3570 - (same_at_end + st.st_size - ZV));
727a0b4a
RS
3571 if (overlap > 0)
3572 same_at_end += overlap;
9c28748f 3573
727a0b4a 3574 /* Arrange to read only the nonmatching middle part of the file. */
ec7adf26
RS
3575 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
3576 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3dbcf3f6 3577
ec7adf26 3578 del_range_byte (same_at_start, same_at_end, 0);
727a0b4a 3579 /* Insert from the file at the proper position. */
ec7adf26
RS
3580 temp = BYTE_TO_CHAR (same_at_start);
3581 SET_PT_BOTH (temp, same_at_start);
727a0b4a
RS
3582
3583 /* If display currently starts at beginning of line,
3584 keep it that way. */
3585 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3586 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3587
3588 replace_handled = 1;
3589 }
3dbcf3f6
RS
3590 }
3591
3592 /* If requested, replace the accessible part of the buffer
3593 with the file contents. Avoid replacing text at the
3594 beginning or end of the buffer that matches the file contents;
3595 that preserves markers pointing to the unchanged parts.
3596
3597 Here we implement this feature for the case where code conversion
3598 is needed, in a simple way that needs a lot of memory.
3599 The preceding if-statement handles the case of no conversion
3600 in a more optimized way. */
f736ffbf 3601 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
3dbcf3f6 3602 {
13818c30
SM
3603 EMACS_INT same_at_start = BEGV_BYTE;
3604 EMACS_INT same_at_end = ZV_BYTE;
3605 EMACS_INT same_at_start_charpos;
3606 EMACS_INT inserted_chars;
3607 EMACS_INT overlap;
3608 EMACS_INT bufpos;
db327c7e 3609 unsigned char *decoded;
ae19ba7c 3610 EMACS_INT temp;
43aae36e 3611 EMACS_INT this = 0;
8f924df7 3612 int this_count = SPECPDL_INDEX ();
4b4deea2 3613 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
5b359650 3614 Lisp_Object conversion_buffer;
db327c7e 3615
5b359650 3616 conversion_buffer = code_conversion_save (1, multibyte);
3dbcf3f6
RS
3617
3618 /* First read the whole file, performing code conversion into
3619 CONVERSION_BUFFER. */
3620
727a0b4a 3621 if (lseek (fd, XINT (beg), 0) < 0)
8f924df7
KH
3622 report_file_error ("Setting file position",
3623 Fcons (orig_filename, Qnil));
727a0b4a 3624
3dbcf3f6
RS
3625 total = st.st_size; /* Total bytes in the file. */
3626 how_much = 0; /* Bytes read from file so far. */
3627 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3628 unprocessed = 0; /* Bytes not processed in previous loop. */
3629
2ba48777 3630 GCPRO1 (conversion_buffer);
3dbcf3f6
RS
3631 while (how_much < total)
3632 {
db327c7e
KH
3633 /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
3634 quitting while reading a huge while. */
3dbcf3f6 3635 /* try is reserved in some compilers (Microsoft C) */
ae19ba7c
SM
3636 EMACS_INT trytry = min (total - how_much,
3637 READ_BUF_SIZE - unprocessed);
3dbcf3f6
RS
3638
3639 /* Allow quitting out of the actual I/O. */
3640 immediate_quit = 1;
3641 QUIT;
db327c7e 3642 this = emacs_read (fd, read_buf + unprocessed, trytry);
3dbcf3f6
RS
3643 immediate_quit = 0;
3644
db327c7e 3645 if (this <= 0)
43aae36e 3646 break;
3dbcf3f6
RS
3647
3648 how_much += this;
3649
bf1c0f27
SM
3650 BUF_TEMP_SET_PT (XBUFFER (conversion_buffer),
3651 BUF_Z (XBUFFER (conversion_buffer)));
5976c3fe
PE
3652 decode_coding_c_string (&coding, (unsigned char *) read_buf,
3653 unprocessed + this, conversion_buffer);
db327c7e
KH
3654 unprocessed = coding.carryover_bytes;
3655 if (coding.carryover_bytes > 0)
72af86bd 3656 memcpy (read_buf, coding.carryover, unprocessed);
3dbcf3f6 3657 }
2ba48777 3658 UNGCPRO;
db327c7e 3659 emacs_close (fd);
3dbcf3f6 3660
db65a627
CY
3661 /* We should remove the unwind_protect calling
3662 close_file_unwind, but other stuff has been added the stack,
3663 so defer the removal till we reach the `handled' label. */
3664 deferred_remove_unwind_protect = 1;
3665
db327c7e
KH
3666 /* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
3667 if we couldn't read the file. */
3dbcf3f6 3668
43aae36e 3669 if (this < 0)
4ed925c6
MB
3670 error ("IO error reading %s: %s",
3671 SDATA (orig_filename), emacs_strerror (errno));
3dbcf3f6 3672
db327c7e
KH
3673 if (unprocessed > 0)
3674 {
3675 coding.mode |= CODING_MODE_LAST_BLOCK;
5976c3fe
PE
3676 decode_coding_c_string (&coding, (unsigned char *) read_buf,
3677 unprocessed, conversion_buffer);
db327c7e
KH
3678 coding.mode &= ~CODING_MODE_LAST_BLOCK;
3679 }
3680
50b06221 3681 coding_system = CODING_ID_NAME (coding.id);
f6a07420 3682 set_coding_system = 1;
db327c7e 3683 decoded = BUF_BEG_ADDR (XBUFFER (conversion_buffer));
50342b35
KH
3684 inserted = (BUF_Z_BYTE (XBUFFER (conversion_buffer))
3685 - BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
db327c7e
KH
3686
3687 /* Compare the beginning of the converted string with the buffer
3688 text. */
3dbcf3f6
RS
3689
3690 bufpos = 0;
3691 while (bufpos < inserted && same_at_start < same_at_end
db327c7e 3692 && FETCH_BYTE (same_at_start) == decoded[bufpos])
3dbcf3f6
RS
3693 same_at_start++, bufpos++;
3694
db327c7e 3695 /* If the file matches the head of buffer completely,
3dbcf3f6
RS
3696 there's no need to replace anything. */
3697
3698 if (bufpos == inserted)
3699 {
3dbcf3f6 3700 /* Truncate the buffer to the size of the file. */
18a9f8d9
SM
3701 if (same_at_start == same_at_end)
3702 nochange = 1;
3703 else
3704 del_range_byte (same_at_start, same_at_end, 0);
427f5aab 3705 inserted = 0;
e8553dd1
KH
3706
3707 unbind_to (this_count, Qnil);
3dbcf3f6
RS
3708 goto handled;
3709 }
3710
db327c7e
KH
3711 /* Extend the start of non-matching text area to the previous
3712 multibyte character boundary. */
4b4deea2 3713 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
20f6783d
RS
3714 while (same_at_start > BEGV_BYTE
3715 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
3716 same_at_start--;
3717
3dbcf3f6
RS
3718 /* Scan this bufferful from the end, comparing with
3719 the Emacs buffer. */
3720 bufpos = inserted;
3721
3722 /* Compare with same_at_start to avoid counting some buffer text
3723 as matching both at the file's beginning and at the end. */
3724 while (bufpos > 0 && same_at_end > same_at_start
db327c7e 3725 && FETCH_BYTE (same_at_end - 1) == decoded[bufpos - 1])
3dbcf3f6
RS
3726 same_at_end--, bufpos--;
3727
db327c7e
KH
3728 /* Extend the end of non-matching text area to the next
3729 multibyte character boundary. */
4b4deea2 3730 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
20f6783d
RS
3731 while (same_at_end < ZV_BYTE
3732 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3733 same_at_end++;
3734
3dbcf3f6 3735 /* Don't try to reuse the same piece of text twice. */
ec7adf26 3736 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3dbcf3f6
RS
3737 if (overlap > 0)
3738 same_at_end += overlap;
3739
727a0b4a
RS
3740 /* If display currently starts at beginning of line,
3741 keep it that way. */
3742 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3743 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3744
3dbcf3f6
RS
3745 /* Replace the chars that we need to replace,
3746 and update INSERTED to equal the number of bytes
db327c7e 3747 we are taking from the decoded string. */
4b70e2c9 3748 inserted -= (ZV_BYTE - same_at_end) + (same_at_start - BEGV_BYTE);
427f5aab 3749
643c73b9 3750 if (same_at_end != same_at_start)
427f5aab
KH
3751 {
3752 del_range_byte (same_at_start, same_at_end, 0);
3753 temp = GPT;
3754 same_at_start = GPT_BYTE;
3755 }
643c73b9
RS
3756 else
3757 {
643c73b9 3758 temp = BYTE_TO_CHAR (same_at_start);
643c73b9 3759 }
427f5aab
KH
3760 /* Insert from the file at the proper position. */
3761 SET_PT_BOTH (temp, same_at_start);
50342b35
KH
3762 same_at_start_charpos
3763 = buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
7f5d2c72
SM
3764 same_at_start - BEGV_BYTE
3765 + BUF_BEG_BYTE (XBUFFER (conversion_buffer)));
50342b35
KH
3766 inserted_chars
3767 = (buf_bytepos_to_charpos (XBUFFER (conversion_buffer),
7f5d2c72
SM
3768 same_at_start + inserted - BEGV_BYTE
3769 + BUF_BEG_BYTE (XBUFFER (conversion_buffer)))
50342b35 3770 - same_at_start_charpos);
d07af40d
KH
3771 /* This binding is to avoid ask-user-about-supersession-threat
3772 being called in insert_from_buffer (via in
3773 prepare_to_modify_buffer). */
3774 specbind (intern ("buffer-file-name"), Qnil);
db327c7e 3775 insert_from_buffer (XBUFFER (conversion_buffer),
50342b35 3776 same_at_start_charpos, inserted_chars, 0);
427f5aab
KH
3777 /* Set `inserted' to the number of inserted characters. */
3778 inserted = PT - temp;
77343e1d
KH
3779 /* Set point before the inserted characters. */
3780 SET_PT_BOTH (temp, same_at_start);
3dbcf3f6 3781
db327c7e 3782 unbind_to (this_count, Qnil);
3dbcf3f6 3783
3dbcf3f6 3784 goto handled;
3d0387c0
RS
3785 }
3786
d4b8687b
RS
3787 if (! not_regular)
3788 {
3789 register Lisp_Object temp;
7fded690 3790
d4b8687b 3791 total = XINT (end) - XINT (beg);
570d7624 3792
d4b8687b
RS
3793 /* Make sure point-max won't overflow after this insertion. */
3794 XSETINT (temp, total);
3795 if (total != XINT (temp))
3796 error ("Maximum buffer size exceeded");
3797 }
3798 else
3799 /* For a special file, all we can do is guess. */
3800 total = READ_BUF_SIZE;
570d7624 3801
8b913b57 3802 if (NILP (visit) && total > 0)
68780e2a
RS
3803 {
3804#ifdef CLASH_DETECTION
4b4deea2 3805 if (!NILP (BVAR (current_buffer, file_truename))
68780e2a 3806 /* Make binding buffer-file-name to nil effective. */
4b4deea2 3807 && !NILP (BVAR (current_buffer, filename))
68780e2a
RS
3808 && SAVE_MODIFF >= MODIFF)
3809 we_locked_file = 1;
3810#endif /* CLASH_DETECTION */
3811 prepare_to_modify_buffer (GPT, GPT, NULL);
3812 }
570d7624 3813
7fe52289 3814 move_gap (PT);
7fded690
JB
3815 if (GAP_SIZE < total)
3816 make_gap (total - GAP_SIZE);
3817
a1d2b64a 3818 if (XINT (beg) != 0 || !NILP (replace))
7fded690
JB
3819 {
3820 if (lseek (fd, XINT (beg), 0) < 0)
b1d1b865
RS
3821 report_file_error ("Setting file position",
3822 Fcons (orig_filename, Qnil));
7fded690
JB
3823 }
3824
6fdaa9a0 3825 /* In the following loop, HOW_MUCH contains the total bytes read so
c8a6d68a
KH
3826 far for a regular file, and not changed for a special file. But,
3827 before exiting the loop, it is set to a negative value if I/O
3828 error occurs. */
a1d2b64a 3829 how_much = 0;
efdc16c9 3830
6fdaa9a0
KH
3831 /* Total bytes inserted. */
3832 inserted = 0;
efdc16c9 3833
c8a6d68a 3834 /* Here, we don't do code conversion in the loop. It is done by
db327c7e 3835 decode_coding_gap after all data are read into the buffer. */
1b978129 3836 {
ae19ba7c 3837 EMACS_INT gap_size = GAP_SIZE;
efdc16c9 3838
1b978129
GM
3839 while (how_much < total)
3840 {
5e570b75 3841 /* try is reserved in some compilers (Microsoft C) */
ae19ba7c
SM
3842 EMACS_INT trytry = min (total - how_much, READ_BUF_SIZE);
3843 EMACS_INT this;
570d7624 3844
1b978129
GM
3845 if (not_regular)
3846 {
f839df0c 3847 Lisp_Object nbytes;
570d7624 3848
1b978129
GM
3849 /* Maybe make more room. */
3850 if (gap_size < trytry)
3851 {
3852 make_gap (total - gap_size);
3853 gap_size = GAP_SIZE;
3854 }
3855
3856 /* Read from the file, capturing `quit'. When an
3857 error occurs, end the loop, and arrange for a quit
3858 to be signaled after decoding the text we read. */
3859 non_regular_fd = fd;
3860 non_regular_inserted = inserted;
3861 non_regular_nbytes = trytry;
f839df0c
PE
3862 nbytes = internal_condition_case_1 (read_non_regular,
3863 Qnil, Qerror,
3864 read_non_regular_quit);
3865 if (NILP (nbytes))
1b978129
GM
3866 {
3867 read_quit = 1;
3868 break;
3869 }
3870
f839df0c 3871 this = XINT (nbytes);
1b978129
GM
3872 }
3873 else
3874 {
3875 /* Allow quitting out of the actual I/O. We don't make text
3876 part of the buffer until all the reading is done, so a C-g
3877 here doesn't do any harm. */
3878 immediate_quit = 1;
3879 QUIT;
5976c3fe
PE
3880 this = emacs_read (fd,
3881 ((char *) BEG_ADDR + PT_BYTE - BEG_BYTE
3882 + inserted),
3883 trytry);
1b978129
GM
3884 immediate_quit = 0;
3885 }
efdc16c9 3886
1b978129
GM
3887 if (this <= 0)
3888 {
3889 how_much = this;
3890 break;
3891 }
3892
3893 gap_size -= this;
3894
3895 /* For a regular file, where TOTAL is the real size,
3896 count HOW_MUCH to compare with it.
3897 For a special file, where TOTAL is just a buffer size,
3898 so don't bother counting in HOW_MUCH.
3899 (INSERTED is where we count the number of characters inserted.) */
3900 if (! not_regular)
3901 how_much += this;
3902 inserted += this;
3903 }
3904 }
3905
68780e2a
RS
3906 /* Now we have read all the file data into the gap.
3907 If it was empty, undo marking the buffer modified. */
3908
3909 if (inserted == 0)
3910 {
6840d350 3911#ifdef CLASH_DETECTION
68780e2a 3912 if (we_locked_file)
4b4deea2 3913 unlock_file (BVAR (current_buffer, file_truename));
6840d350 3914#endif
68780e2a
RS
3915 Vdeactivate_mark = old_Vdeactivate_mark;
3916 }
83c1cf6d
RS
3917 else
3918 Vdeactivate_mark = Qt;
68780e2a 3919
1b978129
GM
3920 /* Make the text read part of the buffer. */
3921 GAP_SIZE -= inserted;
3922 GPT += inserted;
3923 GPT_BYTE += inserted;
3924 ZV += inserted;
3925 ZV_BYTE += inserted;
3926 Z += inserted;
3927 Z_BYTE += inserted;
6fdaa9a0 3928
c8a6d68a
KH
3929 if (GAP_SIZE > 0)
3930 /* Put an anchor to ensure multi-byte form ends at gap. */
3931 *GPT_ADDR = 0;
d4b8687b 3932
68c45bf0 3933 emacs_close (fd);
6fdaa9a0 3934
c8a6d68a
KH
3935 /* Discard the unwind protect for closing the file. */
3936 specpdl_ptr--;
6fdaa9a0 3937
c8a6d68a
KH
3938 if (how_much < 0)
3939 error ("IO error reading %s: %s",
d5db4077 3940 SDATA (orig_filename), emacs_strerror (errno));
ec7adf26 3941
f8569325
DL
3942 notfound:
3943
db327c7e 3944 if (NILP (coding_system))
c8a6d68a 3945 {
2df42e09 3946 /* The coding system is not yet decided. Decide it by an
dfe35e7b
RS
3947 optimized method for handling `coding:' tag.
3948
3949 Note that we can get here only if the buffer was empty
3950 before the insertion. */
f736ffbf 3951
2df42e09 3952 if (!NILP (Vcoding_system_for_read))
db327c7e 3953 coding_system = Vcoding_system_for_read;
2df42e09
KH
3954 else
3955 {
98a7d268
KH
3956 /* Since we are sure that the current buffer was empty
3957 before the insertion, we can toggle
3958 enable-multibyte-characters directly here without taking
9a7f80aa
KH
3959 care of marker adjustment. By this way, we can run Lisp
3960 program safely before decoding the inserted text. */
98a7d268 3961 Lisp_Object unwind_data;
f839df0c 3962 int count1 = SPECPDL_INDEX ();
2df42e09 3963
4b4deea2
TT
3964 unwind_data = Fcons (BVAR (current_buffer, enable_multibyte_characters),
3965 Fcons (BVAR (current_buffer, undo_list),
98a7d268 3966 Fcurrent_buffer ()));
4b4deea2
TT
3967 BVAR (current_buffer, enable_multibyte_characters) = Qnil;
3968 BVAR (current_buffer, undo_list) = Qt;
98a7d268
KH
3969 record_unwind_protect (decide_coding_unwind, unwind_data);
3970
3971 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
3972 {
db327c7e 3973 coding_system = call2 (Vset_auto_coding_function,
8f924df7 3974 filename, make_number (inserted));
2df42e09 3975 }
f736ffbf 3976
db327c7e 3977 if (NILP (coding_system))
2df42e09
KH
3978 {
3979 /* If the coding system is not yet decided, check
3980 file-coding-system-alist. */
8f924df7 3981 Lisp_Object args[6];
f736ffbf 3982
2df42e09
KH
3983 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3984 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
8f924df7
KH
3985 coding_system = Ffind_operation_coding_system (6, args);
3986 if (CONSP (coding_system))
3987 coding_system = XCAR (coding_system);
f736ffbf 3988 }
f839df0c 3989 unbind_to (count1, Qnil);
98a7d268 3990 inserted = Z_BYTE - BEG_BYTE;
2df42e09 3991 }
f736ffbf 3992
db327c7e
KH
3993 if (NILP (coding_system))
3994 coding_system = Qundecided;
3995 else
3996 CHECK_CODING_SYSTEM (coding_system);
f736ffbf 3997
4b4deea2 3998 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
237a6fd2 3999 /* We must suppress all character code conversion except for
2df42e09 4000 end-of-line conversion. */
db327c7e 4001 coding_system = raw_text_coding_system (coding_system);
db327c7e
KH
4002 setup_coding_system (coding_system, &coding);
4003 /* Ensure we set Vlast_coding_system_used. */
4004 set_coding_system = 1;
2df42e09 4005 }
f736ffbf 4006
db327c7e 4007 if (!NILP (visit))
8c3b9441 4008 {
db327c7e 4009 /* When we visit a file by raw-text, we change the buffer to
9a7f80aa 4010 unibyte. */
db327c7e
KH
4011 if (CODING_FOR_UNIBYTE (&coding)
4012 /* Can't do this if part of the buffer might be preserved. */
4013 && NILP (replace))
4014 /* Visiting a file with these coding system makes the buffer
4015 unibyte. */
4b4deea2 4016 BVAR (current_buffer, enable_multibyte_characters) = Qnil;
8c3b9441
KH
4017 }
4018
4b4deea2 4019 coding.dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
5b359650 4020 if (CODING_MAY_REQUIRE_DECODING (&coding)
1c157f8d 4021 && (inserted > 0 || CODING_REQUIRE_FLUSHING (&coding)))
2df42e09 4022 {
db327c7e
KH
4023 move_gap_both (PT, PT_BYTE);
4024 GAP_SIZE += inserted;
4025 ZV_BYTE -= inserted;
4026 Z_BYTE -= inserted;
4027 ZV -= inserted;
4028 Z -= inserted;
4029 decode_coding_gap (&coding, inserted, inserted);
4030 inserted = coding.produced_char;
5b359650 4031 coding_system = CODING_ID_NAME (coding.id);
2df42e09 4032 }
db327c7e
KH
4033 else if (inserted > 0)
4034 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4035 inserted);
570d7624 4036
cf6d2357
RS
4037 /* Now INSERTED is measured in characters. */
4038
32f4334d 4039 handled:
570d7624 4040
db65a627
CY
4041 if (deferred_remove_unwind_protect)
4042 /* If requested above, discard the unwind protect for closing the
4043 file. */
4044 specpdl_ptr--;
4045
265a9e55 4046 if (!NILP (visit))
570d7624 4047 {
4b4deea2
TT
4048 if (!EQ (BVAR (current_buffer, undo_list), Qt) && !nochange)
4049 BVAR (current_buffer, undo_list) = Qnil;
62bcf009 4050
a7e82472
RS
4051 if (NILP (handler))
4052 {
4053 current_buffer->modtime = st.st_mtime;
58b963f7 4054 current_buffer->modtime_size = st.st_size;
4b4deea2 4055 BVAR (current_buffer, filename) = orig_filename;
a7e82472 4056 }
62bcf009 4057
95385625 4058 SAVE_MODIFF = MODIFF;
0b5397c2 4059 BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
4b4deea2 4060 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
570d7624 4061#ifdef CLASH_DETECTION
32f4334d
RS
4062 if (NILP (handler))
4063 {
4b4deea2
TT
4064 if (!NILP (BVAR (current_buffer, file_truename)))
4065 unlock_file (BVAR (current_buffer, file_truename));
32f4334d
RS
4066 unlock_file (filename);
4067 }
570d7624 4068#endif /* CLASH_DETECTION */
330bfe57 4069 if (not_regular)
24b1ddad
KS
4070 xsignal2 (Qfile_error,
4071 build_string ("not a regular file"), orig_filename);
570d7624
JB
4072 }
4073
b6426b03 4074 if (set_coding_system)
8f924df7 4075 Vlast_coding_system_used = coding_system;
b6426b03 4076
2080470e 4077 if (! NILP (Ffboundp (Qafter_insert_file_set_coding)))
b6426b03 4078 {
37a3c774
KH
4079 insval = call2 (Qafter_insert_file_set_coding, make_number (inserted),
4080 visit);
b6426b03
KH
4081 if (! NILP (insval))
4082 {
4083 CHECK_NUMBER (insval);
4084 inserted = XFASTINT (insval);
4085 }
4086 }
4087
6420e80c 4088 /* Decode file format. */
c8a6d68a 4089 if (inserted > 0)
0d420e88 4090 {
6420e80c 4091 /* Don't run point motion or modification hooks when decoding. */
f839df0c 4092 int count1 = SPECPDL_INDEX ();
ae19ba7c 4093 EMACS_INT old_inserted = inserted;
6f2528d8
MR
4094 specbind (Qinhibit_point_motion_hooks, Qt);
4095 specbind (Qinhibit_modification_hooks, Qt);
4096
6420e80c 4097 /* Save old undo list and don't record undo for decoding. */
4b4deea2
TT
4098 old_undo = BVAR (current_buffer, undo_list);
4099 BVAR (current_buffer, undo_list) = Qt;
efdc16c9 4100
6f2528d8 4101 if (NILP (replace))
ed8e506f 4102 {
6f2528d8
MR
4103 insval = call3 (Qformat_decode,
4104 Qnil, make_number (inserted), visit);
4105 CHECK_NUMBER (insval);
4106 inserted = XFASTINT (insval);
4107 }
4108 else
4109 {
4110 /* If REPLACE is non-nil and we succeeded in not replacing the
6420e80c
AS
4111 beginning or end of the buffer text with the file's contents,
4112 call format-decode with `point' positioned at the beginning
4113 of the buffer and `inserted' equalling the number of
4114 characters in the buffer. Otherwise, format-decode might
4115 fail to correctly analyze the beginning or end of the buffer.
4116 Hence we temporarily save `point' and `inserted' here and
4117 restore `point' iff format-decode did not insert or delete
4118 any text. Otherwise we leave `point' at point-min. */
ae19ba7c
SM
4119 EMACS_INT opoint = PT;
4120 EMACS_INT opoint_byte = PT_BYTE;
4121 EMACS_INT oinserted = ZV - BEGV;
cac4219c 4122 int ochars_modiff = CHARS_MODIFF;
1f163f28
MA
4123
4124 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
6f2528d8
MR
4125 insval = call3 (Qformat_decode,
4126 Qnil, make_number (oinserted), visit);
4127 CHECK_NUMBER (insval);
cac4219c
MR
4128 if (ochars_modiff == CHARS_MODIFF)
4129 /* format_decode didn't modify buffer's characters => move
4130 point back to position before inserted text and leave
6420e80c 4131 value of inserted alone. */
6f2528d8 4132 SET_PT_BOTH (opoint, opoint_byte);
cac4219c
MR
4133 else
4134 /* format_decode modified buffer's characters => consider
6420e80c 4135 entire buffer changed and leave point at point-min. */
cac4219c 4136 inserted = XFASTINT (insval);
ed8e506f 4137 }
efdc16c9 4138
6f2528d8 4139 /* For consistency with format-decode call these now iff inserted > 0
6420e80c 4140 (martin 2007-06-28). */
6f2528d8
MR
4141 p = Vafter_insert_file_functions;
4142 while (CONSP (p))
4143 {
4144 if (NILP (replace))
4145 {
4146 insval = call1 (XCAR (p), make_number (inserted));
4147 if (!NILP (insval))
4148 {
4149 CHECK_NUMBER (insval);
4150 inserted = XFASTINT (insval);
4151 }
4152 }
4153 else
4154 {
6420e80c
AS
4155 /* For the rationale of this see the comment on
4156 format-decode above. */
ae19ba7c
SM
4157 EMACS_INT opoint = PT;
4158 EMACS_INT opoint_byte = PT_BYTE;
4159 EMACS_INT oinserted = ZV - BEGV;
cac4219c 4160 int ochars_modiff = CHARS_MODIFF;
1f163f28 4161
6f2528d8
MR
4162 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
4163 insval = call1 (XCAR (p), make_number (oinserted));
4164 if (!NILP (insval))
4165 {
4166 CHECK_NUMBER (insval);
cac4219c
MR
4167 if (ochars_modiff == CHARS_MODIFF)
4168 /* after_insert_file_functions didn't modify
4169 buffer's characters => move point back to
4170 position before inserted text and leave value of
6420e80c 4171 inserted alone. */
6f2528d8 4172 SET_PT_BOTH (opoint, opoint_byte);
cac4219c
MR
4173 else
4174 /* after_insert_file_functions did modify buffer's
4175 characters => consider entire buffer changed and
6420e80c 4176 leave point at point-min. */
cac4219c 4177 inserted = XFASTINT (insval);
6f2528d8
MR
4178 }
4179 }
4180
4181 QUIT;
4182 p = XCDR (p);
ed8e506f 4183 }
efdc16c9 4184
6f2528d8
MR
4185 if (NILP (visit))
4186 {
4b4deea2 4187 BVAR (current_buffer, undo_list) = old_undo;
6420e80c 4188 if (CONSP (old_undo) && inserted != old_inserted)
6f2528d8 4189 {
6420e80c
AS
4190 /* Adjust the last undo record for the size change during
4191 the format conversion. */
6f2528d8 4192 Lisp_Object tem = XCAR (old_undo);
6420e80c
AS
4193 if (CONSP (tem) && INTEGERP (XCAR (tem))
4194 && INTEGERP (XCDR (tem))
4195 && XFASTINT (XCDR (tem)) == PT + old_inserted)
4196 XSETCDR (tem, make_number (PT + inserted));
6f2528d8
MR
4197 }
4198 }
6f2528d8 4199 else
1bc99c9c 4200 /* If undo_list was Qt before, keep it that way.
6420e80c 4201 Otherwise start with an empty undo_list. */
4b4deea2 4202 BVAR (current_buffer, undo_list) = EQ (old_undo, Qt) ? Qt : Qnil;
efdc16c9 4203
f839df0c 4204 unbind_to (count1, Qnil);
0d420e88
BG
4205 }
4206
0342d8c5
RS
4207 /* Call after-change hooks for the inserted text, aside from the case
4208 of normal visiting (not with REPLACE), which is done in a new buffer
4209 "before" the buffer is changed. */
c8a6d68a 4210 if (inserted > 0 && total > 0
0342d8c5 4211 && (NILP (visit) || !NILP (replace)))
ce51c54c
KH
4212 {
4213 signal_after_change (PT, 0, inserted);
4214 update_compositions (PT, PT, CHECK_BORDER);
4215 }
b56567b5 4216
f8569325
DL
4217 if (!NILP (visit)
4218 && current_buffer->modtime == -1)
4219 {
4220 /* If visiting nonexistent file, return nil. */
4221 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
d6a3cc15
RS
4222 }
4223
1b978129
GM
4224 if (read_quit)
4225 Fsignal (Qquit, Qnil);
4226
ec7adf26 4227 /* ??? Retval needs to be dealt with in all cases consistently. */
a1d2b64a 4228 if (NILP (val))
b1d1b865 4229 val = Fcons (orig_filename,
a1d2b64a
RS
4230 Fcons (make_number (inserted),
4231 Qnil));
4232
4233 RETURN_UNGCPRO (unbind_to (count, val));
570d7624 4234}
7fded690 4235\f
f57e2426 4236static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
d6a3cc15 4237
199607e4 4238static Lisp_Object
971de7fb 4239build_annotations_unwind (Lisp_Object arg)
6fc6f94b 4240{
67fbc0cb 4241 Vwrite_region_annotation_buffers = arg;
6fc6f94b
RS
4242 return Qnil;
4243}
4244
7c82a4a9
SM
4245/* Decide the coding-system to encode the data with. */
4246
c934586d 4247static Lisp_Object
dd4c5104
DN
4248choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
4249 Lisp_Object append, Lisp_Object visit, Lisp_Object lockname,
4250 struct coding_system *coding)
7c82a4a9
SM
4251{
4252 Lisp_Object val;
75421805 4253 Lisp_Object eol_parent = Qnil;
7c82a4a9 4254
6b61353c 4255 if (auto_saving
4b4deea2
TT
4256 && NILP (Fstring_equal (BVAR (current_buffer, filename),
4257 BVAR (current_buffer, auto_save_file_name))))
75421805
KH
4258 {
4259 val = Qutf_8_emacs;
4260 eol_parent = Qunix;
4261 }
7c82a4a9 4262 else if (!NILP (Vcoding_system_for_write))
42b01e1e
KH
4263 {
4264 val = Vcoding_system_for_write;
4265 if (coding_system_require_warning
4266 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4267 /* Confirm that VAL can surely encode the current region. */
4268 val = call5 (Vselect_safe_coding_system_function,
4269 start, end, Fcons (Qt, Fcons (val, Qnil)),
4270 Qnil, filename);
4271 }
7c82a4a9
SM
4272 else
4273 {
4274 /* If the variable `buffer-file-coding-system' is set locally,
4275 it means that the file was read with some kind of code
4276 conversion or the variable is explicitly set by users. We
4277 had better write it out with the same coding system even if
4278 `enable-multibyte-characters' is nil.
4279
4280 If it is not set locally, we anyway have to convert EOL
4281 format if the default value of `buffer-file-coding-system'
4282 tells that it is not Unix-like (LF only) format. */
4283 int using_default_coding = 0;
4284 int force_raw_text = 0;
4285
4b4deea2 4286 val = BVAR (current_buffer, buffer_file_coding_system);
7c82a4a9
SM
4287 if (NILP (val)
4288 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4289 {
4290 val = Qnil;
4b4deea2 4291 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
7c82a4a9
SM
4292 force_raw_text = 1;
4293 }
efdc16c9 4294
7c82a4a9
SM
4295 if (NILP (val))
4296 {
4297 /* Check file-coding-system-alist. */
4298 Lisp_Object args[7], coding_systems;
4299
4300 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4301 args[3] = filename; args[4] = append; args[5] = visit;
4302 args[6] = lockname;
4303 coding_systems = Ffind_operation_coding_system (7, args);
4304 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4305 val = XCDR (coding_systems);
4306 }
4307
c934586d 4308 if (NILP (val))
7c82a4a9
SM
4309 {
4310 /* If we still have not decided a coding system, use the
4311 default value of buffer-file-coding-system. */
4b4deea2 4312 val = BVAR (current_buffer, buffer_file_coding_system);
7c82a4a9
SM
4313 using_default_coding = 1;
4314 }
efdc16c9 4315
db327c7e
KH
4316 if (! NILP (val) && ! force_raw_text)
4317 {
4318 Lisp_Object spec, attrs;
4319
4320 CHECK_CODING_SYSTEM_GET_SPEC (val, spec);
4321 attrs = AREF (spec, 0);
4322 if (EQ (CODING_ATTR_TYPE (attrs), Qraw_text))
4323 force_raw_text = 1;
4324 }
4325
7c82a4a9
SM
4326 if (!force_raw_text
4327 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4328 /* Confirm that VAL can surely encode the current region. */
905a4276
PJ
4329 val = call5 (Vselect_safe_coding_system_function,
4330 start, end, val, Qnil, filename);
7c82a4a9 4331
db327c7e
KH
4332 /* If the decided coding-system doesn't specify end-of-line
4333 format, we use that of
4334 `default-buffer-file-coding-system'. */
c934586d 4335 if (! using_default_coding
4b4deea2 4336 && ! NILP (BVAR (&buffer_defaults, buffer_file_coding_system)))
db327c7e 4337 val = (coding_inherit_eol_type
4b4deea2 4338 (val, BVAR (&buffer_defaults, buffer_file_coding_system)));
7c82a4a9 4339
db327c7e
KH
4340 /* If we decide not to encode text, use `raw-text' or one of its
4341 subsidiaries. */
7c82a4a9 4342 if (force_raw_text)
db327c7e 4343 val = raw_text_coding_system (val);
7c82a4a9
SM
4344 }
4345
75421805 4346 val = coding_inherit_eol_type (val, eol_parent);
c934586d 4347 setup_coding_system (val, coding);
7c82a4a9 4348
4b4deea2 4349 if (!STRINGP (start) && !NILP (BVAR (current_buffer, selective_display)))
7c82a4a9 4350 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
c934586d 4351 return val;
7c82a4a9
SM
4352}
4353
a7ca3326 4354DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
8c1a1077
PJ
4355 "r\nFWrite region to file: \ni\ni\ni\np",
4356 doc: /* Write current region into specified file.
c2efea25
RS
4357When called from a program, requires three arguments:
4358START, END and FILENAME. START and END are normally buffer positions
4359specifying the part of the buffer to write.
4360If START is nil, that means to use the entire buffer contents.
4361If START is a string, then output that string to the file
4362instead of any buffer contents; END is ignored.
4363
8c1a1077
PJ
4364Optional fourth argument APPEND if non-nil means
4365 append to existing file contents (if any). If it is an integer,
4366 seek to that offset in the file before writing.
36e50520 4367Optional fifth argument VISIT, if t or a string, means
8c1a1077
PJ
4368 set the last-save-file-modtime of buffer to this file's modtime
4369 and mark buffer not modified.
4370If VISIT is a string, it is a second file name;
4371 the output goes to FILENAME, but the buffer is marked as visiting VISIT.
4372 VISIT is also the file name to lock and unlock for clash detection.
4373If VISIT is neither t nor nil nor a string,
5f4e6aa9 4374 that means do not display the \"Wrote file\" message.
8c1a1077
PJ
4375The optional sixth arg LOCKNAME, if non-nil, specifies the name to
4376 use for locking and unlocking, overriding FILENAME and VISIT.
4377The optional seventh arg MUSTBENEW, if non-nil, insists on a check
4378 for an existing file with the same name. If MUSTBENEW is `excl',
4379 that means to get an error if the file already exists; never overwrite.
4380 If MUSTBENEW is neither nil nor `excl', that means ask for
4381 confirmation before overwriting, but do go ahead and overwrite the file
4382 if the user confirms.
8c1a1077
PJ
4383
4384This does code conversion according to the value of
4385`coding-system-for-write', `buffer-file-coding-system', or
4386`file-coding-system-alist', and sets the variable
aacd8ba1
GM
4387`last-coding-system-used' to the coding system actually used.
4388
4389This calls `write-region-annotate-functions' at the start, and
4390`write-region-post-annotation-function' at the end. */)
5842a27b 4391 (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
570d7624
JB
4392{
4393 register int desc;
4394 int failure;
6bbd7a29 4395 int save_errno = 0;
5976c3fe 4396 const char *fn;
570d7624 4397 struct stat st;
aed13378 4398 int count = SPECPDL_INDEX ();
6fc6f94b 4399 int count1;
3eac9910 4400 Lisp_Object handler;
4ad827c5 4401 Lisp_Object visit_file;
65b7d3e7 4402 Lisp_Object annotations;
b1d1b865 4403 Lisp_Object encoded_filename;
d3a67486
SM
4404 int visiting = (EQ (visit, Qt) || STRINGP (visit));
4405 int quietly = !NILP (visit);
7204a979 4406 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
6fc6f94b 4407 struct buffer *given_buffer;
6fdaa9a0 4408 struct coding_system coding;
570d7624 4409
d3a67486 4410 if (current_buffer->base_buffer && visiting)
95385625
RS
4411 error ("Cannot do file visiting in an indirect buffer");
4412
561cb8e1 4413 if (!NILP (start) && !STRINGP (start))
570d7624
JB
4414 validate_region (&start, &end);
4415
95c1c901 4416 visit_file = Qnil;
59fac292 4417 GCPRO5 (start, filename, visit, visit_file, lockname);
b56567b5 4418
570d7624 4419 filename = Fexpand_file_name (filename, Qnil);
de1d0127 4420
236a12f2 4421 if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl))
b8b29dc9 4422 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
de1d0127 4423
561cb8e1 4424 if (STRINGP (visit))
e5176bae 4425 visit_file = Fexpand_file_name (visit, Qnil);
4ad827c5
RS
4426 else
4427 visit_file = filename;
4428
7204a979
RS
4429 if (NILP (lockname))
4430 lockname = visit_file;
4431
65b7d3e7
RS
4432 annotations = Qnil;
4433
32f4334d
RS
4434 /* If the file name has special constructs in it,
4435 call the corresponding file handler. */
49307295 4436 handler = Ffind_file_name_handler (filename, Qwrite_region);
b56ad927 4437 /* If FILENAME has no handler, see if VISIT has one. */
93c30b5f 4438 if (NILP (handler) && STRINGP (visit))
199607e4 4439 handler = Ffind_file_name_handler (visit, Qwrite_region);
3eac9910 4440
32f4334d
RS
4441 if (!NILP (handler))
4442 {
32f4334d 4443 Lisp_Object val;
51cf6d37
RS
4444 val = call6 (handler, Qwrite_region, start, end,
4445 filename, append, visit);
32f4334d 4446
d6a3cc15 4447 if (visiting)
32f4334d 4448 {
95385625 4449 SAVE_MODIFF = MODIFF;
4b4deea2
TT
4450 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
4451 BVAR (current_buffer, filename) = visit_file;
32f4334d 4452 }
09121adc 4453 UNGCPRO;
32f4334d
RS
4454 return val;
4455 }
4456
4a38de71
KH
4457 record_unwind_protect (save_restriction_restore, save_restriction_save ());
4458
561cb8e1
RS
4459 /* Special kludge to simplify auto-saving. */
4460 if (NILP (start))
4461 {
6b3d752c
SM
4462 /* Do it later, so write-region-annotate-function can work differently
4463 if we save "the buffer" vs "a region".
4464 This is useful in tar-mode. --Stef
2acfd7ae 4465 XSETFASTINT (start, BEG);
6b3d752c 4466 XSETFASTINT (end, Z); */
4a38de71 4467 Fwiden ();
561cb8e1
RS
4468 }
4469
67fbc0cb
CY
4470 record_unwind_protect (build_annotations_unwind,
4471 Vwrite_region_annotation_buffers);
4472 Vwrite_region_annotation_buffers = Fcons (Fcurrent_buffer (), Qnil);
aed13378 4473 count1 = SPECPDL_INDEX ();
6fc6f94b
RS
4474
4475 given_buffer = current_buffer;
bf3428a1
RS
4476
4477 if (!STRINGP (start))
236a12f2 4478 {
bf3428a1
RS
4479 annotations = build_annotations (start, end);
4480
4481 if (current_buffer != given_buffer)
4482 {
4483 XSETFASTINT (start, BEGV);
4484 XSETFASTINT (end, ZV);
4485 }
236a12f2
SM
4486 }
4487
6b3d752c
SM
4488 if (NILP (start))
4489 {
4490 XSETFASTINT (start, BEGV);
4491 XSETFASTINT (end, ZV);
4492 }
4493
236a12f2
SM
4494 UNGCPRO;
4495
4496 GCPRO5 (start, filename, annotations, visit_file, lockname);
4497
59fac292
SM
4498 /* Decide the coding-system to encode the data with.
4499 We used to make this choice before calling build_annotations, but that
4500 leads to problems when a write-annotate-function takes care of
4501 unsavable chars (as was the case with X-Symbol). */
c934586d
KH
4502 Vlast_coding_system_used
4503 = choose_write_coding_system (start, end, filename,
4504 append, visit, lockname, &coding);
d6a3cc15 4505
570d7624
JB
4506#ifdef CLASH_DETECTION
4507 if (!auto_saving)
67fbc0cb 4508 lock_file (lockname);
570d7624
JB
4509#endif /* CLASH_DETECTION */
4510
b1d1b865
RS
4511 encoded_filename = ENCODE_FILE (filename);
4512
5976c3fe 4513 fn = SSDATA (encoded_filename);
570d7624 4514 desc = -1;
265a9e55 4515 if (!NILP (append))
5e570b75 4516#ifdef DOS_NT
05c65251 4517 desc = emacs_open (fn, O_WRONLY | O_BINARY, 0);
5e570b75 4518#else /* not DOS_NT */
68c45bf0 4519 desc = emacs_open (fn, O_WRONLY, 0);
5e570b75 4520#endif /* not DOS_NT */
570d7624 4521
b1d1b865 4522 if (desc < 0 && (NILP (append) || errno == ENOENT))
5e570b75 4523#ifdef DOS_NT
68c45bf0 4524 desc = emacs_open (fn,
05c65251 4525 O_WRONLY | O_CREAT | O_BINARY
95522746 4526 | (EQ (mustbenew, Qexcl) ? O_EXCL : O_TRUNC),
68c45bf0 4527 S_IREAD | S_IWRITE);
5e570b75 4528#else /* not DOS_NT */
68c45bf0 4529 desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT
7c752c80 4530 | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
68c45bf0 4531 auto_saving ? auto_save_mode_bits : 0666);
5e570b75 4532#endif /* not DOS_NT */
570d7624
JB
4533
4534 if (desc < 0)
4535 {
4536#ifdef CLASH_DETECTION
4537 save_errno = errno;
7204a979 4538 if (!auto_saving) unlock_file (lockname);
570d7624
JB
4539 errno = save_errno;
4540#endif /* CLASH_DETECTION */
43fb7d9a 4541 UNGCPRO;
570d7624
JB
4542 report_file_error ("Opening output file", Fcons (filename, Qnil));
4543 }
4544
4545 record_unwind_protect (close_file_unwind, make_number (desc));
4546
c1c4693e 4547 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
43fb7d9a
DL
4548 {
4549 long ret;
efdc16c9 4550
43fb7d9a
DL
4551 if (NUMBERP (append))
4552 ret = lseek (desc, XINT (append), 1);
4553 else
4554 ret = lseek (desc, 0, 2);
4555 if (ret < 0)
4556 {
570d7624 4557#ifdef CLASH_DETECTION
43fb7d9a 4558 if (!auto_saving) unlock_file (lockname);
570d7624 4559#endif /* CLASH_DETECTION */
43fb7d9a
DL
4560 UNGCPRO;
4561 report_file_error ("Lseek error", Fcons (filename, Qnil));
4562 }
4563 }
efdc16c9 4564
43fb7d9a 4565 UNGCPRO;
570d7624 4566
570d7624
JB
4567 failure = 0;
4568 immediate_quit = 1;
4569
561cb8e1 4570 if (STRINGP (start))
570d7624 4571 {
d5db4077 4572 failure = 0 > a_write (desc, start, 0, SCHARS (start),
ce51c54c 4573 &annotations, &coding);
570d7624
JB
4574 save_errno = errno;
4575 }
4576 else if (XINT (start) != XINT (end))
4577 {
db327c7e
KH
4578 failure = 0 > a_write (desc, Qnil,
4579 XINT (start), XINT (end) - XINT (start),
4580 &annotations, &coding);
4581 save_errno = errno;
69f6e679
RS
4582 }
4583 else
4584 {
4585 /* If file was empty, still need to write the annotations */
c8a6d68a 4586 coding.mode |= CODING_MODE_LAST_BLOCK;
ce51c54c 4587 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
6fdaa9a0
KH
4588 save_errno = errno;
4589 }
4590
c8a6d68a
KH
4591 if (CODING_REQUIRE_FLUSHING (&coding)
4592 && !(coding.mode & CODING_MODE_LAST_BLOCK)
1354debd 4593 && ! failure)
6fdaa9a0
KH
4594 {
4595 /* We have to flush out a data. */
c8a6d68a 4596 coding.mode |= CODING_MODE_LAST_BLOCK;
db327c7e 4597 failure = 0 > e_write (desc, Qnil, 1, 1, &coding);
69f6e679 4598 save_errno = errno;
570d7624
JB
4599 }
4600
4601 immediate_quit = 0;
4602
6e23c83e 4603#ifdef HAVE_FSYNC
570d7624
JB
4604 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4605 Disk full in NFS may be reported here. */
1daffa1c
RS
4606 /* mib says that closing the file will try to write as fast as NFS can do
4607 it, and that means the fsync here is not crucial for autosave files. */
ccf61795 4608 if (!auto_saving && !write_region_inhibit_fsync && fsync (desc) < 0)
cb33c142 4609 {
6cff77fd
AS
4610 /* If fsync fails with EINTR, don't treat that as serious. Also
4611 ignore EINVAL which happens when fsync is not supported on this
4612 file. */
4613 if (errno != EINTR && errno != EINVAL)
cb33c142
KH
4614 failure = 1, save_errno = errno;
4615 }
570d7624
JB
4616#endif
4617
570d7624 4618 /* NFS can report a write failure now. */
68c45bf0 4619 if (emacs_close (desc) < 0)
570d7624
JB
4620 failure = 1, save_errno = errno;
4621
570d7624 4622 stat (fn, &st);
67fbc0cb 4623
6fc6f94b
RS
4624 /* Discard the unwind protect for close_file_unwind. */
4625 specpdl_ptr = specpdl + count1;
67fbc0cb
CY
4626
4627 /* Call write-region-post-annotation-function. */
294fa707 4628 while (CONSP (Vwrite_region_annotation_buffers))
67fbc0cb
CY
4629 {
4630 Lisp_Object buf = XCAR (Vwrite_region_annotation_buffers);
4631 if (!NILP (Fbuffer_live_p (buf)))
4632 {
4633 Fset_buffer (buf);
4634 if (FUNCTIONP (Vwrite_region_post_annotation_function))
4635 call0 (Vwrite_region_post_annotation_function);
4636 }
4637 Vwrite_region_annotation_buffers
4638 = XCDR (Vwrite_region_annotation_buffers);
4639 }
4640
4641 unbind_to (count, Qnil);
570d7624
JB
4642
4643#ifdef CLASH_DETECTION
4644 if (!auto_saving)
7204a979 4645 unlock_file (lockname);
570d7624
JB
4646#endif /* CLASH_DETECTION */
4647
4648 /* Do this before reporting IO error
4649 to avoid a "file has changed on disk" warning on
4650 next attempt to save. */
d6a3cc15 4651 if (visiting)
58b963f7
SM
4652 {
4653 current_buffer->modtime = st.st_mtime;
4654 current_buffer->modtime_size = st.st_size;
4655 }
570d7624
JB
4656
4657 if (failure)
d5db4077 4658 error ("IO error writing %s: %s", SDATA (filename),
68c45bf0 4659 emacs_strerror (save_errno));
570d7624 4660
d6a3cc15 4661 if (visiting)
570d7624 4662 {
95385625 4663 SAVE_MODIFF = MODIFF;
4b4deea2
TT
4664 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
4665 BVAR (current_buffer, filename) = visit_file;
f4226e89 4666 update_mode_lines++;
570d7624 4667 }
d6a3cc15 4668 else if (quietly)
6b61353c
KH
4669 {
4670 if (auto_saving
4b4deea2
TT
4671 && ! NILP (Fstring_equal (BVAR (current_buffer, filename),
4672 BVAR (current_buffer, auto_save_file_name))))
6b61353c
KH
4673 SAVE_MODIFF = MODIFF;
4674
4675 return Qnil;
4676 }
570d7624
JB
4677
4678 if (!auto_saving)
6b61353c 4679 message_with_string ((INTEGERP (append)
0c328a0e
RS
4680 ? "Updated %s"
4681 : ! NILP (append)
4682 ? "Added to %s"
4683 : "Wrote %s"),
4684 visit_file, 1);
570d7624
JB
4685
4686 return Qnil;
4687}
ec7adf26 4688\f
dd4c5104 4689Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object);
d6a3cc15
RS
4690
4691DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
8c1a1077 4692 doc: /* Return t if (car A) is numerically less than (car B). */)
5842a27b 4693 (Lisp_Object a, Lisp_Object b)
d6a3cc15
RS
4694{
4695 return Flss (Fcar (a), Fcar (b));
4696}
4697
4698/* Build the complete list of annotations appropriate for writing out
4699 the text between START and END, by calling all the functions in
6fc6f94b
RS
4700 write-region-annotate-functions and merging the lists they return.
4701 If one of these functions switches to a different buffer, we assume
4702 that buffer contains altered text. Therefore, the caller must
4703 make sure to restore the current buffer in all cases,
4704 as save-excursion would do. */
d6a3cc15
RS
4705
4706static Lisp_Object
971de7fb 4707build_annotations (Lisp_Object start, Lisp_Object end)
d6a3cc15
RS
4708{
4709 Lisp_Object annotations;
4710 Lisp_Object p, res;
4711 struct gcpro gcpro1, gcpro2;
0a20b684 4712 Lisp_Object original_buffer;
bd235610 4713 int i, used_global = 0;
0a20b684
RS
4714
4715 XSETBUFFER (original_buffer, current_buffer);
d6a3cc15
RS
4716
4717 annotations = Qnil;
4718 p = Vwrite_region_annotate_functions;
4719 GCPRO2 (annotations, p);
28c3eb5a 4720 while (CONSP (p))
d6a3cc15 4721 {
6fc6f94b 4722 struct buffer *given_buffer = current_buffer;
bd235610
SM
4723 if (EQ (Qt, XCAR (p)) && !used_global)
4724 { /* Use the global value of the hook. */
4725 Lisp_Object arg[2];
4726 used_global = 1;
4727 arg[0] = Fdefault_value (Qwrite_region_annotate_functions);
4728 arg[1] = XCDR (p);
4729 p = Fappend (2, arg);
4730 continue;
4731 }
6fc6f94b 4732 Vwrite_region_annotations_so_far = annotations;
28c3eb5a 4733 res = call2 (XCAR (p), start, end);
6fc6f94b
RS
4734 /* If the function makes a different buffer current,
4735 assume that means this buffer contains altered text to be output.
4736 Reset START and END from the buffer bounds
4737 and discard all previous annotations because they should have
4738 been dealt with by this function. */
4739 if (current_buffer != given_buffer)
4740 {
67fbc0cb
CY
4741 Vwrite_region_annotation_buffers
4742 = Fcons (Fcurrent_buffer (),
4743 Vwrite_region_annotation_buffers);
3cf29f61
RS
4744 XSETFASTINT (start, BEGV);
4745 XSETFASTINT (end, ZV);
6fc6f94b
RS
4746 annotations = Qnil;
4747 }
d6a3cc15
RS
4748 Flength (res); /* Check basic validity of return value */
4749 annotations = merge (annotations, res, Qcar_less_than_car);
28c3eb5a 4750 p = XCDR (p);
d6a3cc15 4751 }
0d420e88
BG
4752
4753 /* Now do the same for annotation functions implied by the file-format */
4b4deea2
TT
4754 if (auto_saving && (!EQ (BVAR (current_buffer, auto_save_file_format), Qt)))
4755 p = BVAR (current_buffer, auto_save_file_format);
0d420e88 4756 else
4b4deea2 4757 p = BVAR (current_buffer, file_format);
28c3eb5a 4758 for (i = 0; CONSP (p); p = XCDR (p), ++i)
0d420e88
BG
4759 {
4760 struct buffer *given_buffer = current_buffer;
efdc16c9 4761
0d420e88 4762 Vwrite_region_annotations_so_far = annotations;
532ed661
GM
4763
4764 /* Value is either a list of annotations or nil if the function
4765 has written annotations to a temporary buffer, which is now
4766 current. */
28c3eb5a 4767 res = call5 (Qformat_annotate_function, XCAR (p), start, end,
532ed661 4768 original_buffer, make_number (i));
0d420e88
BG
4769 if (current_buffer != given_buffer)
4770 {
3cf29f61
RS
4771 XSETFASTINT (start, BEGV);
4772 XSETFASTINT (end, ZV);
0d420e88
BG
4773 annotations = Qnil;
4774 }
efdc16c9 4775
532ed661
GM
4776 if (CONSP (res))
4777 annotations = merge (annotations, res, Qcar_less_than_car);
0d420e88 4778 }
6fdaa9a0 4779
236a12f2
SM
4780 UNGCPRO;
4781 return annotations;
4782}
4783
ec7adf26 4784\f
ce51c54c
KH
4785/* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
4786 If STRING is nil, POS is the character position in the current buffer.
d6a3cc15 4787 Intersperse with them the annotations from *ANNOT
ce51c54c 4788 which fall within the range of POS to POS + NCHARS,
d6a3cc15
RS
4789 each at its appropriate position.
4790
ec7adf26
RS
4791 We modify *ANNOT by discarding elements as we use them up.
4792
d6a3cc15
RS
4793 The return value is negative in case of system call failure. */
4794
ec7adf26 4795static int
8a2cbd72
EZ
4796a_write (int desc, Lisp_Object string, EMACS_INT pos,
4797 register EMACS_INT nchars, Lisp_Object *annot,
4798 struct coding_system *coding)
d6a3cc15
RS
4799{
4800 Lisp_Object tem;
8a2cbd72
EZ
4801 EMACS_INT nextpos;
4802 EMACS_INT lastpos = pos + nchars;
d6a3cc15 4803
eb15aa18 4804 while (NILP (*annot) || CONSP (*annot))
d6a3cc15
RS
4805 {
4806 tem = Fcar_safe (Fcar (*annot));
ce51c54c 4807 nextpos = pos - 1;
ec7adf26 4808 if (INTEGERP (tem))
ce51c54c 4809 nextpos = XFASTINT (tem);
ec7adf26
RS
4810
4811 /* If there are no more annotations in this range,
4812 output the rest of the range all at once. */
ce51c54c
KH
4813 if (! (nextpos >= pos && nextpos <= lastpos))
4814 return e_write (desc, string, pos, lastpos, coding);
ec7adf26
RS
4815
4816 /* Output buffer text up to the next annotation's position. */
ce51c54c 4817 if (nextpos > pos)
d6a3cc15 4818 {
055a28c9 4819 if (0 > e_write (desc, string, pos, nextpos, coding))
d6a3cc15 4820 return -1;
ce51c54c 4821 pos = nextpos;
d6a3cc15 4822 }
ec7adf26 4823 /* Output the annotation. */
d6a3cc15
RS
4824 tem = Fcdr (Fcar (*annot));
4825 if (STRINGP (tem))
4826 {
d5db4077 4827 if (0 > e_write (desc, tem, 0, SCHARS (tem), coding))
d6a3cc15
RS
4828 return -1;
4829 }
4830 *annot = Fcdr (*annot);
4831 }
dfcf069d 4832 return 0;
d6a3cc15
RS
4833}
4834
6fdaa9a0 4835
ce51c54c
KH
4836/* Write text in the range START and END into descriptor DESC,
4837 encoding them with coding system CODING. If STRING is nil, START
4838 and END are character positions of the current buffer, else they
4839 are indexes to the string STRING. */
ec7adf26
RS
4840
4841static int
8a2cbd72
EZ
4842e_write (int desc, Lisp_Object string, EMACS_INT start, EMACS_INT end,
4843 struct coding_system *coding)
570d7624 4844{
ce51c54c
KH
4845 if (STRINGP (string))
4846 {
db327c7e 4847 start = 0;
8f924df7 4848 end = SCHARS (string);
ce51c54c 4849 }
570d7624 4850
6fdaa9a0
KH
4851 /* We used to have a code for handling selective display here. But,
4852 now it is handled within encode_coding. */
01ca97a2
KH
4853
4854 while (start < end)
570d7624 4855 {
01ca97a2 4856 if (STRINGP (string))
6ad568dd 4857 {
01ca97a2
KH
4858 coding->src_multibyte = SCHARS (string) < SBYTES (string);
4859 if (CODING_REQUIRE_ENCODING (coding))
4860 {
4861 encode_coding_object (coding, string,
4862 start, string_char_to_byte (string, start),
4863 end, string_char_to_byte (string, end), Qt);
4864 }
4865 else
4866 {
4867 coding->dst_object = string;
4868 coding->consumed_char = SCHARS (string);
4869 coding->produced = SBYTES (string);
4870 }
6ad568dd 4871 }
db327c7e 4872 else
6ad568dd 4873 {
8a2cbd72
EZ
4874 EMACS_INT start_byte = CHAR_TO_BYTE (start);
4875 EMACS_INT end_byte = CHAR_TO_BYTE (end);
b4132433 4876
01ca97a2
KH
4877 coding->src_multibyte = (end - start) < (end_byte - start_byte);
4878 if (CODING_REQUIRE_ENCODING (coding))
4879 {
4880 encode_coding_object (coding, Fcurrent_buffer (),
4881 start, start_byte, end, end_byte, Qt);
4882 }
4883 else
4884 {
4885 coding->dst_object = Qnil;
4886 coding->dst_pos_byte = start_byte;
4887 if (start >= GPT || end <= GPT)
4888 {
4889 coding->consumed_char = end - start;
4890 coding->produced = end_byte - start_byte;
4891 }
4892 else
4893 {
4894 coding->consumed_char = GPT - start;
4895 coding->produced = GPT_BYTE - start_byte;
4896 }
4897 }
c185d744 4898 }
01ca97a2
KH
4899
4900 if (coding->produced > 0)
c185d744 4901 {
01ca97a2
KH
4902 coding->produced -=
4903 emacs_write (desc,
4904 STRINGP (coding->dst_object)
42a5b22f
PE
4905 ? SSDATA (coding->dst_object)
4906 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte),
01ca97a2
KH
4907 coding->produced);
4908
4909 if (coding->produced)
4910 return -1;
570d7624 4911 }
01ca97a2 4912 start += coding->consumed_char;
c185d744
KH
4913 }
4914
4915 return 0;
570d7624 4916}
ec7adf26 4917\f
a7ca3326 4918DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
ec1b9b17 4919 Sverify_visited_file_modtime, 0, 1, 0,
8c1a1077 4920 doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
6b61353c 4921This means that the file has not been changed since it was visited or saved.
ec1b9b17 4922If BUF is omitted or nil, it defaults to the current buffer.
6b61353c 4923See Info node `(elisp)Modification Time' for more details. */)
5842a27b 4924 (Lisp_Object buf)
570d7624
JB
4925{
4926 struct buffer *b;
4927 struct stat st;
32f4334d 4928 Lisp_Object handler;
b1d1b865 4929 Lisp_Object filename;
570d7624 4930
ec1b9b17
GM
4931 if (NILP (buf))
4932 b = current_buffer;
4933 else
4934 {
4935 CHECK_BUFFER (buf);
4936 b = XBUFFER (buf);
4937 }
570d7624 4938
4b4deea2 4939 if (!STRINGP (BVAR (b, filename))) return Qt;
570d7624
JB
4940 if (b->modtime == 0) return Qt;
4941
32f4334d
RS
4942 /* If the file name has special constructs in it,
4943 call the corresponding file handler. */
4b4deea2 4944 handler = Ffind_file_name_handler (BVAR (b, filename),
49307295 4945 Qverify_visited_file_modtime);
32f4334d 4946 if (!NILP (handler))
09121adc 4947 return call2 (handler, Qverify_visited_file_modtime, buf);
32f4334d 4948
4b4deea2 4949 filename = ENCODE_FILE (BVAR (b, filename));
b1d1b865 4950
42a5b22f 4951 if (stat (SSDATA (filename), &st) < 0)
570d7624
JB
4952 {
4953 /* If the file doesn't exist now and didn't exist before,
4954 we say that it isn't modified, provided the error is a tame one. */
4955 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
4956 st.st_mtime = -1;
4957 else
4958 st.st_mtime = 0;
4959 }
58b963f7
SM
4960 if ((st.st_mtime == b->modtime
4961 /* If both are positive, accept them if they are off by one second. */
4962 || (st.st_mtime > 0 && b->modtime > 0
7f9bbdbb 4963 && (st.st_mtime - 1 == b->modtime
58b963f7
SM
4964 || st.st_mtime == b->modtime - 1)))
4965 && (st.st_size == b->modtime_size
4966 || b->modtime_size < 0))
570d7624
JB
4967 return Qt;
4968 return Qnil;
4969}
4970
4971DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
8c1a1077
PJ
4972 Sclear_visited_file_modtime, 0, 0, 0,
4973 doc: /* Clear out records of last mod time of visited file.
4974Next attempt to save will certainly not complain of a discrepancy. */)
5842a27b 4975 (void)
570d7624
JB
4976{
4977 current_buffer->modtime = 0;
58b963f7 4978 current_buffer->modtime_size = -1;
570d7624
JB
4979 return Qnil;
4980}
4981
f5d5eccf 4982DEFUN ("visited-file-modtime", Fvisited_file_modtime,
8c1a1077
PJ
4983 Svisited_file_modtime, 0, 0, 0,
4984 doc: /* Return the current buffer's recorded visited file modification time.
e5fcddc8 4985The value is a list of the form (HIGH LOW), like the time values
6b61353c
KH
4986that `file-attributes' returns. If the current buffer has no recorded
4987file modification time, this function returns 0.
4988See Info node `(elisp)Modification Time' for more details. */)
5842a27b 4989 (void)
f5d5eccf 4990{
73ff9d42
RS
4991 if (! current_buffer->modtime)
4992 return make_number (0);
84acfcf0 4993 return make_time (current_buffer->modtime);
f5d5eccf
RS
4994}
4995
570d7624 4996DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
8c1a1077
PJ
4997 Sset_visited_file_modtime, 0, 1, 0,
4998 doc: /* Update buffer's recorded modification time from the visited file's time.
4999Useful if the buffer was not read from the file normally
5000or if the file itself has been changed for some known benign reason.
5001An argument specifies the modification time value to use
5002\(instead of that of the visited file), in the form of a list
5003\(HIGH . LOW) or (HIGH LOW). */)
5842a27b 5004 (Lisp_Object time_list)
570d7624 5005{
f5d5eccf 5006 if (!NILP (time_list))
58b963f7 5007 {
be44ca6c 5008 CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime);
58b963f7
SM
5009 current_buffer->modtime_size = -1;
5010 }
f5d5eccf
RS
5011 else
5012 {
5013 register Lisp_Object filename;
5014 struct stat st;
5015 Lisp_Object handler;
570d7624 5016
4b4deea2 5017 filename = Fexpand_file_name (BVAR (current_buffer, filename), Qnil);
32f4334d 5018
f5d5eccf
RS
5019 /* If the file name has special constructs in it,
5020 call the corresponding file handler. */
49307295 5021 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
f5d5eccf 5022 if (!NILP (handler))
caf3c431 5023 /* The handler can find the file name the same way we did. */
76c881b0 5024 return call2 (handler, Qset_visited_file_modtime, Qnil);
b1d1b865
RS
5025
5026 filename = ENCODE_FILE (filename);
5027
42a5b22f 5028 if (stat (SSDATA (filename), &st) >= 0)
58b963f7
SM
5029 {
5030 current_buffer->modtime = st.st_mtime;
5031 current_buffer->modtime_size = st.st_size;
5032 }
f5d5eccf 5033 }
570d7624
JB
5034
5035 return Qnil;
5036}
5037\f
f14b7e14 5038static Lisp_Object
f839df0c 5039auto_save_error (Lisp_Object error_val)
570d7624 5040{
d7f31e22
GM
5041 Lisp_Object args[3], msg;
5042 int i, nbytes;
5043 struct gcpro gcpro1;
dfc22242
KS
5044 char *msgbuf;
5045 USE_SAFE_ALLOCA;
efdc16c9 5046
ca730bf0
CY
5047 auto_save_error_occurred = 1;
5048
385ed61f 5049 ring_bell (XFRAME (selected_frame));
efdc16c9 5050
d7f31e22 5051 args[0] = build_string ("Auto-saving %s: %s");
4b4deea2 5052 args[1] = BVAR (current_buffer, name);
f839df0c 5053 args[2] = Ferror_message_string (error_val);
d7f31e22
GM
5054 msg = Fformat (3, args);
5055 GCPRO1 (msg);
d5db4077 5056 nbytes = SBYTES (msg);
dfc22242 5057 SAFE_ALLOCA (msgbuf, char *, nbytes);
72af86bd 5058 memcpy (msgbuf, SDATA (msg), nbytes);
d7f31e22
GM
5059
5060 for (i = 0; i < 3; ++i)
5061 {
5062 if (i == 0)
dfc22242 5063 message2 (msgbuf, nbytes, STRING_MULTIBYTE (msg));
d7f31e22 5064 else
dfc22242 5065 message2_nolog (msgbuf, nbytes, STRING_MULTIBYTE (msg));
d7f31e22
GM
5066 Fsleep_for (make_number (1), Qnil);
5067 }
5068
e01f7773 5069 SAFE_FREE ();
d7f31e22 5070 UNGCPRO;
570d7624
JB
5071 return Qnil;
5072}
5073
f14b7e14 5074static Lisp_Object
971de7fb 5075auto_save_1 (void)
570d7624 5076{
570d7624 5077 struct stat st;
d4a42098
KS
5078 Lisp_Object modes;
5079
5080 auto_save_mode_bits = 0666;
570d7624
JB
5081
5082 /* Get visited file's mode to become the auto save file's mode. */
4b4deea2 5083 if (! NILP (BVAR (current_buffer, filename)))
d4a42098 5084 {
4b4deea2 5085 if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0)
d4a42098
KS
5086 /* But make sure we can overwrite it later! */
5087 auto_save_mode_bits = st.st_mode | 0600;
4b4deea2 5088 else if ((modes = Ffile_modes (BVAR (current_buffer, filename)),
d4a42098
KS
5089 INTEGERP (modes)))
5090 /* Remote files don't cooperate with stat. */
5091 auto_save_mode_bits = XINT (modes) | 0600;
5092 }
570d7624
JB
5093
5094 return
4b4deea2 5095 Fwrite_region (Qnil, Qnil, BVAR (current_buffer, auto_save_file_name), Qnil,
699b53bc
CY
5096 NILP (Vauto_save_visited_file_name) ? Qlambda : Qt,
5097 Qnil, Qnil);
570d7624
JB
5098}
5099
e54d3b5d 5100static Lisp_Object
971de7fb 5101do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
410ed5c3 5102
e54d3b5d 5103{
fff7e982 5104 FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
3be3c08e 5105 auto_saving = 0;
fff7e982 5106 if (stream != NULL)
aab12958
YM
5107 {
5108 BLOCK_INPUT;
5109 fclose (stream);
5110 UNBLOCK_INPUT;
5111 }
e54d3b5d
RS
5112 return Qnil;
5113}
5114
a8c828be 5115static Lisp_Object
971de7fb 5116do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */
410ed5c3 5117
a8c828be
RS
5118{
5119 minibuffer_auto_raise = XINT (value);
5120 return Qnil;
5121}
5122
5794dd61 5123static Lisp_Object
971de7fb 5124do_auto_save_make_dir (Lisp_Object dir)
5794dd61 5125{
26816cbf
SG
5126 Lisp_Object mode;
5127
5128 call2 (Qmake_directory, dir, Qt);
5129 XSETFASTINT (mode, 0700);
5130 return Fset_file_modes (dir, mode);
5794dd61
RS
5131}
5132
5133static Lisp_Object
971de7fb 5134do_auto_save_eh (Lisp_Object ignore)
5794dd61
RS
5135{
5136 return Qnil;
5137}
5138
a7ca3326 5139DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
8c1a1077
PJ
5140 doc: /* Auto-save all buffers that need it.
5141This is all buffers that have auto-saving enabled
5142and are changed since last auto-saved.
5143Auto-saving writes the buffer into a file
5144so that your editing is not lost if the system crashes.
5145This file is not the file you visited; that changes only when you save.
5146Normally we run the normal hook `auto-save-hook' before saving.
5147
5148A non-nil NO-MESSAGE argument means do not print any message if successful.
5149A non-nil CURRENT-ONLY argument means save only current buffer. */)
5842a27b 5150 (Lisp_Object no_message, Lisp_Object current_only)
570d7624
JB
5151{
5152 struct buffer *old = current_buffer, *b;
dee091a3 5153 Lisp_Object tail, buf, hook;
570d7624 5154 int auto_saved = 0;
f14b1c68 5155 int do_handled_files;
ff4c9993 5156 Lisp_Object oquit;
fff7e982 5157 FILE *stream = NULL;
aed13378 5158 int count = SPECPDL_INDEX ();
a8c828be 5159 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
5794dd61 5160 int old_message_p = 0;
d57563b6 5161 struct gcpro gcpro1, gcpro2;
38da540d
RS
5162
5163 if (max_specpdl_size < specpdl_size + 40)
5164 max_specpdl_size = specpdl_size + 40;
5165
5166 if (minibuf_level)
5167 no_message = Qt;
5168
5794dd61
RS
5169 if (NILP (no_message))
5170 {
5171 old_message_p = push_message ();
5172 record_unwind_protect (pop_message_unwind, Qnil);
5173 }
efdc16c9 5174
ff4c9993
RS
5175 /* Ordinarily don't quit within this function,
5176 but don't make it impossible to quit (in case we get hung in I/O). */
5177 oquit = Vquit_flag;
5178 Vquit_flag = Qnil;
570d7624
JB
5179
5180 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
5181 point to non-strings reached from Vbuffer_alist. */
5182
dee091a3
JD
5183 hook = intern ("auto-save-hook");
5184 Frun_hooks (1, &hook);
570d7624 5185
e54d3b5d
RS
5186 if (STRINGP (Vauto_save_list_file_name))
5187 {
0894672f 5188 Lisp_Object listfile;
efdc16c9 5189
258fd2cb 5190 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
0894672f
GM
5191
5192 /* Don't try to create the directory when shutting down Emacs,
5193 because creating the directory might signal an error, and
5194 that would leave Emacs in a strange state. */
5195 if (!NILP (Vrun_hooks))
5196 {
5197 Lisp_Object dir;
d57563b6
RS
5198 dir = Qnil;
5199 GCPRO2 (dir, listfile);
0894672f
GM
5200 dir = Ffile_name_directory (listfile);
5201 if (NILP (Ffile_directory_p (dir)))
5794dd61
RS
5202 internal_condition_case_1 (do_auto_save_make_dir,
5203 dir, Fcons (Fcons (Qfile_error, Qnil), Qnil),
5204 do_auto_save_eh);
d57563b6 5205 UNGCPRO;
0894672f 5206 }
efdc16c9 5207
42a5b22f 5208 stream = fopen (SSDATA (listfile), "w");
1b335d29 5209 }
199607e4 5210
fff7e982
KS
5211 record_unwind_protect (do_auto_save_unwind,
5212 make_save_value (stream, 0));
a8c828be
RS
5213 record_unwind_protect (do_auto_save_unwind_1,
5214 make_number (minibuffer_auto_raise));
5215 minibuffer_auto_raise = 0;
3be3c08e 5216 auto_saving = 1;
ca730bf0 5217 auto_save_error_occurred = 0;
3be3c08e 5218
6b61353c
KH
5219 /* On first pass, save all files that don't have handlers.
5220 On second pass, save all files that do have handlers.
5221
5222 If Emacs is crashing, the handlers may tweak what is causing
5223 Emacs to crash in the first place, and it would be a shame if
5224 Emacs failed to autosave perfectly ordinary files because it
5225 couldn't handle some ange-ftp'd file. */
5226
f14b1c68 5227 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
8e50cc2d 5228 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
f14b1c68 5229 {
03699b14 5230 buf = XCDR (XCAR (tail));
f14b1c68 5231 b = XBUFFER (buf);
199607e4 5232
e54d3b5d 5233 /* Record all the buffers that have auto save mode
258fd2cb
RS
5234 in the special file that lists them. For each of these buffers,
5235 Record visited name (if any) and auto save name. */
4b4deea2 5236 if (STRINGP (BVAR (b, auto_save_file_name))
1b335d29 5237 && stream != NULL && do_handled_files == 0)
e54d3b5d 5238 {
aab12958 5239 BLOCK_INPUT;
4b4deea2 5240 if (!NILP (BVAR (b, filename)))
258fd2cb 5241 {
4b4deea2
TT
5242 fwrite (SDATA (BVAR (b, filename)), 1,
5243 SBYTES (BVAR (b, filename)), stream);
258fd2cb 5244 }
1b335d29 5245 putc ('\n', stream);
4b4deea2
TT
5246 fwrite (SDATA (BVAR (b, auto_save_file_name)), 1,
5247 SBYTES (BVAR (b, auto_save_file_name)), stream);
1b335d29 5248 putc ('\n', stream);
aab12958 5249 UNBLOCK_INPUT;
e54d3b5d 5250 }
17857782 5251
f14b1c68
JB
5252 if (!NILP (current_only)
5253 && b != current_buffer)
5254 continue;
e54d3b5d 5255
95385625
RS
5256 /* Don't auto-save indirect buffers.
5257 The base buffer takes care of it. */
5258 if (b->base_buffer)
5259 continue;
5260
f14b1c68
JB
5261 /* Check for auto save enabled
5262 and file changed since last auto save
5263 and file changed since last real save. */
4b4deea2 5264 if (STRINGP (BVAR (b, auto_save_file_name))
95385625 5265 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
0b5397c2 5266 && BUF_AUTOSAVE_MODIFF (b) < BUF_MODIFF (b)
82c2d839 5267 /* -1 means we've turned off autosaving for a while--see below. */
4b4deea2 5268 && XINT (BVAR (b, save_length)) >= 0
f14b1c68 5269 && (do_handled_files
4b4deea2 5270 || NILP (Ffind_file_name_handler (BVAR (b, auto_save_file_name),
49307295 5271 Qwrite_region))))
f14b1c68 5272 {
b60247d9
RS
5273 EMACS_TIME before_time, after_time;
5274
5275 EMACS_GET_TIME (before_time);
5276
5277 /* If we had a failure, don't try again for 20 minutes. */
5278 if (b->auto_save_failure_time >= 0
5279 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
5280 continue;
5281
090101cf
CY
5282 set_buffer_internal (b);
5283 if (NILP (Vauto_save_include_big_deletions)
4b4deea2 5284 && (XFASTINT (BVAR (b, save_length)) * 10
4be941e3 5285 > (BUF_Z (b) - BUF_BEG (b)) * 13)
f14b1c68
JB
5286 /* A short file is likely to change a large fraction;
5287 spare the user annoying messages. */
4b4deea2 5288 && XFASTINT (BVAR (b, save_length)) > 5000
f14b1c68 5289 /* These messages are frequent and annoying for `*mail*'. */
4b4deea2 5290 && !EQ (BVAR (b, filename), Qnil)
f14b1c68
JB
5291 && NILP (no_message))
5292 {
5293 /* It has shrunk too much; turn off auto-saving here. */
a8c828be 5294 minibuffer_auto_raise = orig_minibuffer_auto_raise;
fd91d0d4 5295 message_with_string ("Buffer %s has shrunk a lot; auto save disabled in that buffer until next real save",
4b4deea2 5296 BVAR (b, name), 1);
a8c828be 5297 minibuffer_auto_raise = 0;
82c2d839
RS
5298 /* Turn off auto-saving until there's a real save,
5299 and prevent any more warnings. */
4b4deea2 5300 XSETINT (BVAR (b, save_length), -1);
f14b1c68
JB
5301 Fsleep_for (make_number (1), Qnil);
5302 continue;
5303 }
f14b1c68
JB
5304 if (!auto_saved && NILP (no_message))
5305 message1 ("Auto-saving...");
5306 internal_condition_case (auto_save_1, Qt, auto_save_error);
5307 auto_saved++;
0b5397c2 5308 BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b);
4b4deea2 5309 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
f14b1c68 5310 set_buffer_internal (old);
b60247d9
RS
5311
5312 EMACS_GET_TIME (after_time);
5313
5314 /* If auto-save took more than 60 seconds,
5315 assume it was an NFS failure that got a timeout. */
5316 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
5317 b->auto_save_failure_time = EMACS_SECS (after_time);
f14b1c68
JB
5318 }
5319 }
570d7624 5320
b67f2ca5
RS
5321 /* Prevent another auto save till enough input events come in. */
5322 record_auto_save ();
570d7624 5323
17857782 5324 if (auto_saved && NILP (no_message))
f05b275b 5325 {
5794dd61 5326 if (old_message_p)
31f3d831 5327 {
5794dd61
RS
5328 /* If we are going to restore an old message,
5329 give time to read ours. */
83f8d903 5330 sit_for (make_number (1), 0, 0);
c71106e5 5331 restore_message ();
31f3d831 5332 }
ca730bf0 5333 else if (!auto_save_error_occurred)
31e31a15
CY
5334 /* Don't overwrite the error message if an error occurred.
5335 If we displayed a message and then restored a state
5794dd61 5336 with no message, leave a "done" message on the screen. */
f05b275b
KH
5337 message1 ("Auto-saving...done");
5338 }
570d7624 5339
ff4c9993
RS
5340 Vquit_flag = oquit;
5341
5794dd61 5342 /* This restores the message-stack status. */
e54d3b5d 5343 unbind_to (count, Qnil);
570d7624
JB
5344 return Qnil;
5345}
5346
5347DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
8c1a1077
PJ
5348 Sset_buffer_auto_saved, 0, 0, 0,
5349 doc: /* Mark current buffer as auto-saved with its current text.
5350No auto-save file will be written until the buffer changes again. */)
5842a27b 5351 (void)
570d7624 5352{
0b5397c2
SM
5353 /* FIXME: This should not be called in indirect buffers, since
5354 they're not autosaved. */
5355 BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
4b4deea2 5356 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
b60247d9
RS
5357 current_buffer->auto_save_failure_time = -1;
5358 return Qnil;
5359}
5360
5361DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
8c1a1077
PJ
5362 Sclear_buffer_auto_save_failure, 0, 0, 0,
5363 doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
5842a27b 5364 (void)
b60247d9
RS
5365{
5366 current_buffer->auto_save_failure_time = -1;
570d7624
JB
5367 return Qnil;
5368}
5369
5370DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
8c1a1077 5371 0, 0, 0,
68780e2a
RS
5372 doc: /* Return t if current buffer has been auto-saved recently.
5373More precisely, if it has been auto-saved since last read from or saved
5374in the visited file. If the buffer has no visited file,
5375then any auto-save counts as "recent". */)
5842a27b 5376 (void)
570d7624 5377{
0b5397c2
SM
5378 /* FIXME: maybe we should return nil for indirect buffers since
5379 they're never autosaved. */
5380 return (SAVE_MODIFF < BUF_AUTOSAVE_MODIFF (current_buffer) ? Qt : Qnil);
570d7624
JB
5381}
5382\f
5383/* Reading and completing file names */
6e710ae5 5384
88208bb8
JD
5385DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p,
5386 Snext_read_file_uses_dialog_p, 0, 0, 0,
5387 doc: /* Return t if a call to `read-file-name' will use a dialog.
5388The return value is only relevant for a call to `read-file-name' that happens
1a0de25c 5389before any other event (mouse or keypress) is handled. */)
5842a27b 5390 (void)
88208bb8 5391{
9e2a2647 5392#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
88208bb8
JD
5393 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
5394 && use_dialog_box
5395 && use_file_dialog
5396 && have_menus_p ())
5397 return Qt;
5398#endif
5399 return Qnil;
5400}
d4a42098 5401
dbd50d4b 5402Lisp_Object
971de7fb 5403Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object initial, Lisp_Object predicate)
570d7624 5404{
fd4ead52 5405 struct gcpro gcpro1;
dbd50d4b 5406 Lisp_Object args[7];
a79485af 5407
71e1f69d 5408 GCPRO1 (default_filename);
dbd50d4b
SM
5409 args[0] = intern ("read-file-name");
5410 args[1] = prompt;
5411 args[2] = dir;
5412 args[3] = default_filename;
5413 args[4] = mustmatch;
5414 args[5] = initial;
5415 args[6] = predicate;
5416 RETURN_UNGCPRO (Ffuncall (7, args));
570d7624 5417}
9c856db9 5418
570d7624 5419\f
dfcf069d 5420void
971de7fb 5421syms_of_fileio (void)
570d7624 5422{
d67b4f80
DN
5423 Qoperations = intern_c_string ("operations");
5424 Qexpand_file_name = intern_c_string ("expand-file-name");
5425 Qsubstitute_in_file_name = intern_c_string ("substitute-in-file-name");
5426 Qdirectory_file_name = intern_c_string ("directory-file-name");
5427 Qfile_name_directory = intern_c_string ("file-name-directory");
5428 Qfile_name_nondirectory = intern_c_string ("file-name-nondirectory");
5429 Qunhandled_file_name_directory = intern_c_string ("unhandled-file-name-directory");
5430 Qfile_name_as_directory = intern_c_string ("file-name-as-directory");
5431 Qcopy_file = intern_c_string ("copy-file");
5432 Qmake_directory_internal = intern_c_string ("make-directory-internal");
5433 Qmake_directory = intern_c_string ("make-directory");
5434 Qdelete_directory_internal = intern_c_string ("delete-directory-internal");
5435 Qdelete_file = intern_c_string ("delete-file");
5436 Qrename_file = intern_c_string ("rename-file");
5437 Qadd_name_to_file = intern_c_string ("add-name-to-file");
5438 Qmake_symbolic_link = intern_c_string ("make-symbolic-link");
5439 Qfile_exists_p = intern_c_string ("file-exists-p");
5440 Qfile_executable_p = intern_c_string ("file-executable-p");
5441 Qfile_readable_p = intern_c_string ("file-readable-p");
5442 Qfile_writable_p = intern_c_string ("file-writable-p");
5443 Qfile_symlink_p = intern_c_string ("file-symlink-p");
5444 Qaccess_file = intern_c_string ("access-file");
5445 Qfile_directory_p = intern_c_string ("file-directory-p");
5446 Qfile_regular_p = intern_c_string ("file-regular-p");
5447 Qfile_accessible_directory_p = intern_c_string ("file-accessible-directory-p");
5448 Qfile_modes = intern_c_string ("file-modes");
5449 Qset_file_modes = intern_c_string ("set-file-modes");
5450 Qset_file_times = intern_c_string ("set-file-times");
574c05e2
KK
5451 Qfile_selinux_context = intern_c_string("file-selinux-context");
5452 Qset_file_selinux_context = intern_c_string("set-file-selinux-context");
d67b4f80
DN
5453 Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p");
5454 Qinsert_file_contents = intern_c_string ("insert-file-contents");
5455 Qwrite_region = intern_c_string ("write-region");
5456 Qverify_visited_file_modtime = intern_c_string ("verify-visited-file-modtime");
5457 Qset_visited_file_modtime = intern_c_string ("set-visited-file-modtime");
5458 Qauto_save_coding = intern_c_string ("auto-save-coding");
32f4334d 5459
f6c9b683 5460 staticpro (&Qoperations);
642ef245 5461 staticpro (&Qexpand_file_name);
273e0829 5462 staticpro (&Qsubstitute_in_file_name);
642ef245
JB
5463 staticpro (&Qdirectory_file_name);
5464 staticpro (&Qfile_name_directory);
5465 staticpro (&Qfile_name_nondirectory);
5466 staticpro (&Qunhandled_file_name_directory);
5467 staticpro (&Qfile_name_as_directory);
15c65264 5468 staticpro (&Qcopy_file);
c34b559d 5469 staticpro (&Qmake_directory_internal);
b272d624 5470 staticpro (&Qmake_directory);
9d8f3bd9 5471 staticpro (&Qdelete_directory_internal);
15c65264
RS
5472 staticpro (&Qdelete_file);
5473 staticpro (&Qrename_file);
5474 staticpro (&Qadd_name_to_file);
5475 staticpro (&Qmake_symbolic_link);
5476 staticpro (&Qfile_exists_p);
5477 staticpro (&Qfile_executable_p);
5478 staticpro (&Qfile_readable_p);
15c65264 5479 staticpro (&Qfile_writable_p);
1f8653eb
RS
5480 staticpro (&Qaccess_file);
5481 staticpro (&Qfile_symlink_p);
15c65264 5482 staticpro (&Qfile_directory_p);
adedc71d 5483 staticpro (&Qfile_regular_p);
15c65264
RS
5484 staticpro (&Qfile_accessible_directory_p);
5485 staticpro (&Qfile_modes);
5486 staticpro (&Qset_file_modes);
819da85b 5487 staticpro (&Qset_file_times);
574c05e2
KK
5488 staticpro (&Qfile_selinux_context);
5489 staticpro (&Qset_file_selinux_context);
15c65264
RS
5490 staticpro (&Qfile_newer_than_file_p);
5491 staticpro (&Qinsert_file_contents);
5492 staticpro (&Qwrite_region);
5493 staticpro (&Qverify_visited_file_modtime);
0a61794b 5494 staticpro (&Qset_visited_file_modtime);
356a6224 5495 staticpro (&Qauto_save_coding);
642ef245 5496
d67b4f80 5497 Qfile_name_history = intern_c_string ("file-name-history");
642ef245 5498 Fset (Qfile_name_history, Qnil);
15c65264
RS
5499 staticpro (&Qfile_name_history);
5500
d67b4f80 5501 Qfile_error = intern_c_string ("file-error");
570d7624 5502 staticpro (&Qfile_error);
d67b4f80 5503 Qfile_already_exists = intern_c_string ("file-already-exists");
570d7624 5504 staticpro (&Qfile_already_exists);
d67b4f80 5505 Qfile_date_error = intern_c_string ("file-date-error");
c0b7b21c 5506 staticpro (&Qfile_date_error);
d67b4f80 5507 Qexcl = intern_c_string ("excl");
505ab9bc 5508 staticpro (&Qexcl);
570d7624 5509
29208e82 5510 DEFVAR_LISP ("file-name-coding-system", Vfile_name_coding_system,
8c1a1077 5511 doc: /* *Coding system for encoding file names.
346ebf53 5512If it is nil, `default-file-name-coding-system' (which see) is used. */);
b1d1b865
RS
5513 Vfile_name_coding_system = Qnil;
5514
cd913586 5515 DEFVAR_LISP ("default-file-name-coding-system",
29208e82 5516 Vdefault_file_name_coding_system,
8c1a1077 5517 doc: /* Default coding system for encoding file names.
346ebf53 5518This variable is used only when `file-name-coding-system' is nil.
8c1a1077 5519
346ebf53 5520This variable is set/changed by the command `set-language-environment'.
8c1a1077 5521User should not set this variable manually,
346ebf53 5522instead use `file-name-coding-system' to get a constant encoding
8c1a1077 5523of file names regardless of the current language environment. */);
cd913586
KH
5524 Vdefault_file_name_coding_system = Qnil;
5525
d67b4f80 5526 Qformat_decode = intern_c_string ("format-decode");
0d420e88 5527 staticpro (&Qformat_decode);
d67b4f80 5528 Qformat_annotate_function = intern_c_string ("format-annotate-function");
0d420e88 5529 staticpro (&Qformat_annotate_function);
d67b4f80 5530 Qafter_insert_file_set_coding = intern_c_string ("after-insert-file-set-coding");
2080470e 5531 staticpro (&Qafter_insert_file_set_coding);
efdc16c9 5532
d67b4f80 5533 Qcar_less_than_car = intern_c_string ("car-less-than-car");
d6a3cc15
RS
5534 staticpro (&Qcar_less_than_car);
5535
570d7624 5536 Fput (Qfile_error, Qerror_conditions,
d67b4f80 5537 Fpurecopy (list2 (Qfile_error, Qerror)));
570d7624 5538 Fput (Qfile_error, Qerror_message,
d67b4f80 5539 make_pure_c_string ("File error"));
570d7624
JB
5540
5541 Fput (Qfile_already_exists, Qerror_conditions,
d67b4f80 5542 Fpurecopy (list3 (Qfile_already_exists, Qfile_error, Qerror)));
570d7624 5543 Fput (Qfile_already_exists, Qerror_message,
d67b4f80 5544 make_pure_c_string ("File already exists"));
570d7624 5545
c0b7b21c 5546 Fput (Qfile_date_error, Qerror_conditions,
d67b4f80 5547 Fpurecopy (list3 (Qfile_date_error, Qfile_error, Qerror)));
c0b7b21c 5548 Fput (Qfile_date_error, Qerror_message,
d67b4f80 5549 make_pure_c_string ("Cannot set file date"));
c0b7b21c 5550
29208e82 5551 DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist,
8c1a1077
PJ
5552 doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
5553If a file name matches REGEXP, then all I/O on that file is done by calling
5554HANDLER.
5555
5556The first argument given to HANDLER is the name of the I/O primitive
5557to be handled; the remaining arguments are the arguments that were
5558passed to that primitive. For example, if you do
5559 (file-exists-p FILENAME)
5560and FILENAME is handled by HANDLER, then HANDLER is called like this:
5561 (funcall HANDLER 'file-exists-p FILENAME)
5562The function `find-file-name-handler' checks this list for a handler
5563for its argument. */);
09121adc
RS
5564 Vfile_name_handler_alist = Qnil;
5565
0414b394 5566 DEFVAR_LISP ("set-auto-coding-function",
29208e82 5567 Vset_auto_coding_function,
8c1a1077
PJ
5568 doc: /* If non-nil, a function to call to decide a coding system of file.
5569Two arguments are passed to this function: the file name
5570and the length of a file contents following the point.
5571This function should return a coding system to decode the file contents.
5572It should check the file name against `auto-coding-alist'.
5573If no coding system is decided, it should check a coding system
5574specified in the heading lines with the format:
5575 -*- ... coding: CODING-SYSTEM; ... -*-
5576or local variable spec of the tailing lines with `coding:' tag. */);
0414b394 5577 Vset_auto_coding_function = Qnil;
c9e82392 5578
29208e82 5579 DEFVAR_LISP ("after-insert-file-functions", Vafter_insert_file_functions,
8c1a1077 5580 doc: /* A list of functions to be called at the end of `insert-file-contents'.
0cf9f5b5
RS
5581Each is passed one argument, the number of characters inserted,
5582with point at the start of the inserted text. Each function
5583should leave point the same, and return the new character count.
cf6d2357
RS
5584If `insert-file-contents' is intercepted by a handler from
5585`file-name-handler-alist', that handler is responsible for calling the
5586functions in `after-insert-file-functions' if appropriate. */);
d6a3cc15
RS
5587 Vafter_insert_file_functions = Qnil;
5588
29208e82 5589 DEFVAR_LISP ("write-region-annotate-functions", Vwrite_region_annotate_functions,
8c1a1077
PJ
5590 doc: /* A list of functions to be called at the start of `write-region'.
5591Each is passed two arguments, START and END as for `write-region'.
5592These are usually two numbers but not always; see the documentation
5593for `write-region'. The function should return a list of pairs
5594of the form (POSITION . STRING), consisting of strings to be effectively
5595inserted at the specified positions of the file being written (1 means to
5596insert before the first byte written). The POSITIONs must be sorted into
67fbc0cb
CY
5597increasing order.
5598
5599If there are several annotation functions, the lists returned by these
5600functions are merged destructively. As each annotation function runs,
5601the variable `write-region-annotations-so-far' contains a list of all
5602annotations returned by previous annotation functions.
5603
5604An annotation function can return with a different buffer current.
5605Doing so removes the annotations returned by previous functions, and
5606resets START and END to `point-min' and `point-max' of the new buffer.
5607
5608After `write-region' completes, Emacs calls the function stored in
5609`write-region-post-annotation-function', once for each buffer that was
5610current when building the annotations (i.e., at least once), with that
5611buffer current. */);
d6a3cc15 5612 Vwrite_region_annotate_functions = Qnil;
bd235610
SM
5613 staticpro (&Qwrite_region_annotate_functions);
5614 Qwrite_region_annotate_functions
d67b4f80 5615 = intern_c_string ("write-region-annotate-functions");
d6a3cc15 5616
67fbc0cb 5617 DEFVAR_LISP ("write-region-post-annotation-function",
29208e82 5618 Vwrite_region_post_annotation_function,
67fbc0cb
CY
5619 doc: /* Function to call after `write-region' completes.
5620The function is called with no arguments. If one or more of the
5621annotation functions in `write-region-annotate-functions' changed the
5622current buffer, the function stored in this variable is called for
5623each of those additional buffers as well, in addition to the original
5624buffer. The relevant buffer is current during each function call. */);
5625 Vwrite_region_post_annotation_function = Qnil;
5626 staticpro (&Vwrite_region_annotation_buffers);
5627
6fc6f94b 5628 DEFVAR_LISP ("write-region-annotations-so-far",
29208e82 5629 Vwrite_region_annotations_so_far,
8c1a1077
PJ
5630 doc: /* When an annotation function is called, this holds the previous annotations.
5631These are the annotations made by other annotation functions
5632that were already called. See also `write-region-annotate-functions'. */);
6fc6f94b
RS
5633 Vwrite_region_annotations_so_far = Qnil;
5634
29208e82 5635 DEFVAR_LISP ("inhibit-file-name-handlers", Vinhibit_file_name_handlers,
8c1a1077
PJ
5636 doc: /* A list of file name handlers that temporarily should not be used.
5637This applies only to the operation `inhibit-file-name-operation'. */);
82c2d839
RS
5638 Vinhibit_file_name_handlers = Qnil;
5639
29208e82 5640 DEFVAR_LISP ("inhibit-file-name-operation", Vinhibit_file_name_operation,
8c1a1077 5641 doc: /* The operation for which `inhibit-file-name-handlers' is applicable. */);
a65970a0
RS
5642 Vinhibit_file_name_operation = Qnil;
5643
29208e82 5644 DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name,
8c1a1077
PJ
5645 doc: /* File name in which we write a list of all auto save file names.
5646This variable is initialized automatically from `auto-save-list-file-prefix'
5647shortly after Emacs reads your `.emacs' file, if you have not yet given it
5648a non-nil value. */);
e54d3b5d
RS
5649 Vauto_save_list_file_name = Qnil;
5650
29208e82 5651 DEFVAR_LISP ("auto-save-visited-file-name", Vauto_save_visited_file_name,
699b53bc
CY
5652 doc: /* Non-nil says auto-save a buffer in the file it is visiting, when practical.
5653Normally auto-save files are written under other names. */);
5654 Vauto_save_visited_file_name = Qnil;
5655
29208e82 5656 DEFVAR_LISP ("auto-save-include-big-deletions", Vauto_save_include_big_deletions,
090101cf
CY
5657 doc: /* If non-nil, auto-save even if a large part of the text is deleted.
5658If nil, deleting a substantial portion of the text disables auto-save
5659in the buffer; this is the default behavior, because the auto-save
5660file is usually more useful if it contains the deleted text. */);
5661 Vauto_save_include_big_deletions = Qnil;
5662
ccf61795 5663#ifdef HAVE_FSYNC
29208e82 5664 DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
e3f509dd
RF
5665 doc: /* *Non-nil means don't call fsync in `write-region'.
5666This variable affects calls to `write-region' as well as save commands.
5667A non-nil value may result in data loss! */);
ccf61795
RF
5668 write_region_inhibit_fsync = 0;
5669#endif
5670
29208e82 5671 DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
6cf29fe8 5672 doc: /* Specifies whether to use the system's trash can.
f1a5d776
CY
5673When non-nil, certain file deletion commands use the function
5674`move-file-to-trash' instead of deleting files outright.
5675This includes interactive calls to `delete-file' and
5676`delete-directory' and the Dired deletion commands. */);
6cf29fe8 5677 delete_by_moving_to_trash = 0;
d67b4f80
DN
5678 Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
5679 Qmove_file_to_trash = intern_c_string ("move-file-to-trash");
6cf29fe8 5680 staticpro (&Qmove_file_to_trash);
8719abec
CY
5681 Qcopy_directory = intern_c_string ("copy-directory");
5682 staticpro (&Qcopy_directory);
5683 Qdelete_directory = intern_c_string ("delete-directory");
5684 staticpro (&Qdelete_directory);
6cf29fe8 5685
642ef245 5686 defsubr (&Sfind_file_name_handler);
570d7624
JB
5687 defsubr (&Sfile_name_directory);
5688 defsubr (&Sfile_name_nondirectory);
642ef245 5689 defsubr (&Sunhandled_file_name_directory);
570d7624
JB
5690 defsubr (&Sfile_name_as_directory);
5691 defsubr (&Sdirectory_file_name);
5692 defsubr (&Smake_temp_name);
5693 defsubr (&Sexpand_file_name);
5694 defsubr (&Ssubstitute_in_file_name);
5695 defsubr (&Scopy_file);
9bbe01fb 5696 defsubr (&Smake_directory_internal);
9d8f3bd9 5697 defsubr (&Sdelete_directory_internal);
570d7624
JB
5698 defsubr (&Sdelete_file);
5699 defsubr (&Srename_file);
5700 defsubr (&Sadd_name_to_file);
570d7624 5701 defsubr (&Smake_symbolic_link);
570d7624
JB
5702 defsubr (&Sfile_name_absolute_p);
5703 defsubr (&Sfile_exists_p);
5704 defsubr (&Sfile_executable_p);
5705 defsubr (&Sfile_readable_p);
5706 defsubr (&Sfile_writable_p);
1f8653eb 5707 defsubr (&Saccess_file);
570d7624
JB
5708 defsubr (&Sfile_symlink_p);
5709 defsubr (&Sfile_directory_p);
b72dea2a 5710 defsubr (&Sfile_accessible_directory_p);
f793dc6c 5711 defsubr (&Sfile_regular_p);
570d7624
JB
5712 defsubr (&Sfile_modes);
5713 defsubr (&Sset_file_modes);
819da85b 5714 defsubr (&Sset_file_times);
574c05e2
KK
5715 defsubr (&Sfile_selinux_context);
5716 defsubr (&Sset_file_selinux_context);
c24e9a53
RS
5717 defsubr (&Sset_default_file_modes);
5718 defsubr (&Sdefault_file_modes);
570d7624
JB
5719 defsubr (&Sfile_newer_than_file_p);
5720 defsubr (&Sinsert_file_contents);
5721 defsubr (&Swrite_region);
d6a3cc15 5722 defsubr (&Scar_less_than_car);
570d7624
JB
5723 defsubr (&Sverify_visited_file_modtime);
5724 defsubr (&Sclear_visited_file_modtime);
f5d5eccf 5725 defsubr (&Svisited_file_modtime);
570d7624
JB
5726 defsubr (&Sset_visited_file_modtime);
5727 defsubr (&Sdo_auto_save);
5728 defsubr (&Sset_buffer_auto_saved);
b60247d9 5729 defsubr (&Sclear_buffer_auto_save_failure);
570d7624
JB
5730 defsubr (&Srecent_auto_save_p);
5731
88208bb8 5732 defsubr (&Snext_read_file_uses_dialog_p);
85ffea93 5733
697c17a2 5734#ifdef HAVE_SYNC
85ffea93 5735 defsubr (&Sunix_sync);
483a2e10 5736#endif
570d7624 5737}