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