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