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