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