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