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