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