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