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