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