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