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