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