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