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