*** empty log message ***
[bpt/emacs.git] / src / fileio.c
CommitLineData
570d7624 1/* File IO for GNU Emacs.
38119822 2 Copyright (C) 1985,86,87,88,93,94,95,96,97,98,99,2000, 2001
43fb7d9a 3 Free Software Foundation, Inc.
570d7624
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4746118a 9the Free Software Foundation; either version 2, or (at your option)
570d7624
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
570d7624 21
18160b98 22#include <config.h>
570d7624 23
612221ab 24#ifdef HAVE_FCNTL_H
bb369dc6
RS
25#include <fcntl.h>
26#endif
27
1b335d29 28#include <stdio.h>
570d7624
JB
29#include <sys/types.h>
30#include <sys/stat.h>
bfb61299 31
29beb080
RS
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif
35
f73b0ada
BF
36#if !defined (S_ISLNK) && defined (S_IFLNK)
37# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
38#endif
39
bb369dc6
RS
40#if !defined (S_ISFIFO) && defined (S_IFIFO)
41# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
42#endif
43
f73b0ada
BF
44#if !defined (S_ISREG) && defined (S_IFREG)
45# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
46#endif
47
bfb61299 48#ifdef VMS
de5bf5d3 49#include "vms-pwd.h"
bfb61299 50#else
570d7624 51#include <pwd.h>
bfb61299
JB
52#endif
53
570d7624 54#include <ctype.h>
bfb61299
JB
55
56#ifdef VMS
3d9f5ce2 57#include "vmsdir.h"
bfb61299
JB
58#include <perror.h>
59#include <stddef.h>
60#include <string.h>
bfb61299
JB
61#endif
62
570d7624
JB
63#include <errno.h>
64
bfb61299 65#ifndef vax11c
f12ef5eb 66#ifndef USE_CRT_DLL
570d7624 67extern int errno;
570d7624 68#endif
f12ef5eb 69#endif
570d7624 70
570d7624
JB
71#ifdef APOLLO
72#include <sys/time.h>
73#endif
74
570d7624 75#include "lisp.h"
8d4e077b 76#include "intervals.h"
570d7624 77#include "buffer.h"
6fdaa9a0
KH
78#include "charset.h"
79#include "coding.h"
570d7624
JB
80#include "window.h"
81
5e570b75
RS
82#ifdef WINDOWSNT
83#define NOMINMAX 1
84#include <windows.h>
85#include <stdlib.h>
86#include <fcntl.h>
87#endif /* not WINDOWSNT */
88
7990d02a
EZ
89#ifdef MSDOS
90#include "msdos.h"
91#include <sys/param.h>
92#if __DJGPP__ >= 2
93#include <fcntl.h>
94#include <string.h>
95#endif
96#endif
97
199607e4
RS
98#ifdef DOS_NT
99#define CORRECT_DIR_SEPS(s) \
100 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
101 else unixtodos_filename (s); \
102 } while (0)
103/* On Windows, drive letters must be alphabetic - on DOS, the Netware
104 redirector allows the six letters between 'Z' and 'a' as well. */
105#ifdef MSDOS
106#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
107#endif
108#ifdef WINDOWSNT
109#define IS_DRIVE(x) isalpha (x)
110#endif
f54b565c
MB
111/* Need to lower-case the drive letter, or else expanded
112 filenames will sometimes compare inequal, because
113 `expand-file-name' doesn't always down-case the drive letter. */
114#define DRIVE_LETTER(x) (tolower (x))
199607e4
RS
115#endif
116
570d7624 117#ifdef VMS
570d7624
JB
118#include <file.h>
119#include <rmsdef.h>
120#include <fab.h>
121#include <nam.h>
122#endif
123
de5bf5d3 124#include "systime.h"
570d7624
JB
125
126#ifdef HPUX
127#include <netio.h>
9b7828a5 128#ifndef HPUX8
47e7b9e5 129#ifndef HPUX9
570d7624
JB
130#include <errnet.h>
131#endif
9b7828a5 132#endif
47e7b9e5 133#endif
570d7624 134
9c856db9
GM
135#include "commands.h"
136extern int use_dialog_box;
137
570d7624
JB
138#ifndef O_WRONLY
139#define O_WRONLY 1
140#endif
141
4018b5ef
RS
142#ifndef O_RDONLY
143#define O_RDONLY 0
144#endif
145
8f6df9b5
EZ
146#ifndef S_ISLNK
147# define lstat stat
148#endif
149
570d7624
JB
150/* Nonzero during writing of auto-save files */
151int auto_saving;
152
153/* Set by auto_save_1 to mode of original file so Fwrite_region will create
154 a new file with the same mode as the original */
155int auto_save_mode_bits;
156
b1d1b865
RS
157/* Coding system for file names, or nil if none. */
158Lisp_Object Vfile_name_coding_system;
159
cd913586
KH
160/* Coding system for file names used only when
161 Vfile_name_coding_system is nil. */
162Lisp_Object Vdefault_file_name_coding_system;
163
199607e4 164/* Alist of elements (REGEXP . HANDLER) for file names
32f4334d
RS
165 whose I/O is done with a special handler. */
166Lisp_Object Vfile_name_handler_alist;
167
0d420e88
BG
168/* Format for auto-save files */
169Lisp_Object Vauto_save_file_format;
170
171/* Lisp functions for translating file formats */
172Lisp_Object Qformat_decode, Qformat_annotate_function;
173
c9e82392 174/* Function to be called to decide a coding system of a reading file. */
0414b394 175Lisp_Object Vset_auto_coding_function;
c9e82392 176
d6a3cc15
RS
177/* Functions to be called to process text properties in inserted file. */
178Lisp_Object Vafter_insert_file_functions;
179
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;
0bf2eed2 1029 Lisp_Object handler;
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)
d7231f93
KH
1292 name
1293 = make_specified_string (nm, -1, strlen (nm),
1294 STRING_MULTIBYTE (name));
199607e4
RS
1295 }
1296 else
1297#endif
1298 /* drive must be set, so this is okay */
d5db4077 1299 if (strcmp (nm - 2, SDATA (name)) != 0)
199607e4 1300 {
d7231f93
KH
1301 name
1302 = make_specified_string (nm, -1, strlen (nm),
1303 STRING_MULTIBYTE (name));
942dc838
KR
1304 SSET (name, 0, DRIVE_LETTER (drive));
1305 SSET (name, 1, ':');
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
d7231f93
KH
1681 return make_specified_string (target, -1, o - target,
1682 STRING_MULTIBYTE (name));
570d7624 1683}
5e570b75 1684
4887597a
EZ
1685#if 0
1686/* PLEASE DO NOT DELETE THIS COMMENTED-OUT VERSION!
1687 This is the old version of expand-file-name, before it was thoroughly
1688 rewritten for Emacs 10.31. We leave this version here commented-out,
1689 because the code is very complex and likely to have subtle bugs. If
1690 bugs _are_ found, it might be of interest to look at the old code and
1691 see what did it do in the relevant situation.
1692
1693 Don't remove this code: it's true that it will be accessible via CVS,
1694 but a few years from deletion, people will forget it is there. */
1695
1696/* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1697DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1698 "Convert FILENAME to absolute, and canonicalize it.\n\
1699Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1700 (does not start with slash); if DEFAULT is nil or missing,\n\
1701the current buffer's value of default-directory is used.\n\
1702Filenames containing `.' or `..' as components are simplified;\n\
1703initial `~/' expands to your home directory.\n\
1704See also the function `substitute-in-file-name'.")
1705 (name, defalt)
1706 Lisp_Object name, defalt;
1707{
1708 unsigned char *nm;
1709
1710 register unsigned char *newdir, *p, *o;
1711 int tlen;
1712 unsigned char *target;
1713 struct passwd *pw;
1714 int lose;
1715#ifdef VMS
1716 unsigned char * colon = 0;
1717 unsigned char * close = 0;
1718 unsigned char * slash = 0;
1719 unsigned char * brack = 0;
1720 int lbrack = 0, rbrack = 0;
1721 int dots = 0;
1722#endif /* VMS */
1723
b7826503 1724 CHECK_STRING (name);
4887597a
EZ
1725
1726#ifdef VMS
1727 /* Filenames on VMS are always upper case. */
1728 name = Fupcase (name);
1729#endif
1730
d5db4077 1731 nm = SDATA (name);
4887597a
EZ
1732
1733 /* If nm is absolute, flush ...// and detect /./ and /../.
1734 If no /./ or /../ we can return right away. */
1735 if (
1736 nm[0] == '/'
1737#ifdef VMS
1738 || index (nm, ':')
1739#endif /* VMS */
1740 )
1741 {
1742 p = nm;
1743 lose = 0;
1744 while (*p)
1745 {
1746 if (p[0] == '/' && p[1] == '/'
1747#ifdef APOLLO
1748 /* // at start of filename is meaningful on Apollo system. */
1749 && nm != p
1750#endif /* APOLLO */
1751 )
1752 nm = p + 1;
1753 if (p[0] == '/' && p[1] == '~')
1754 nm = p + 1, lose = 1;
1755 if (p[0] == '/' && p[1] == '.'
1756 && (p[2] == '/' || p[2] == 0
1757 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1758 lose = 1;
1759#ifdef VMS
1760 if (p[0] == '\\')
1761 lose = 1;
1762 if (p[0] == '/') {
1763 /* if dev:[dir]/, move nm to / */
1764 if (!slash && p > nm && (brack || colon)) {
1765 nm = (brack ? brack + 1 : colon + 1);
1766 lbrack = rbrack = 0;
1767 brack = 0;
1768 colon = 0;
1769 }
1770 slash = p;
1771 }
1772 if (p[0] == '-')
1773#ifndef VMS4_4
1774 /* VMS pre V4.4,convert '-'s in filenames. */
1775 if (lbrack == rbrack)
1776 {
1777 if (dots < 2) /* this is to allow negative version numbers */
1778 p[0] = '_';
1779 }
1780 else
1781#endif /* VMS4_4 */
1782 if (lbrack > rbrack &&
1783 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1784 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1785 lose = 1;
1786#ifndef VMS4_4
1787 else
1788 p[0] = '_';
1789#endif /* VMS4_4 */
1790 /* count open brackets, reset close bracket pointer */
1791 if (p[0] == '[' || p[0] == '<')
1792 lbrack++, brack = 0;
1793 /* count close brackets, set close bracket pointer */
1794 if (p[0] == ']' || p[0] == '>')
1795 rbrack++, brack = p;
1796 /* detect ][ or >< */
1797 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1798 lose = 1;
1799 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1800 nm = p + 1, lose = 1;
1801 if (p[0] == ':' && (colon || slash))
1802 /* if dev1:[dir]dev2:, move nm to dev2: */
1803 if (brack)
1804 {
1805 nm = brack + 1;
1806 brack = 0;
1807 }
1808 /* If /name/dev:, move nm to dev: */
1809 else if (slash)
1810 nm = slash + 1;
1811 /* If node::dev:, move colon following dev */
1812 else if (colon && colon[-1] == ':')
1813 colon = p;
1814 /* If dev1:dev2:, move nm to dev2: */
1815 else if (colon && colon[-1] != ':')
1816 {
1817 nm = colon + 1;
1818 colon = 0;
1819 }
1820 if (p[0] == ':' && !colon)
1821 {
1822 if (p[1] == ':')
1823 p++;
1824 colon = p;
1825 }
1826 if (lbrack == rbrack)
1827 if (p[0] == ';')
1828 dots = 2;
1829 else if (p[0] == '.')
1830 dots++;
1831#endif /* VMS */
1832 p++;
1833 }
1834 if (!lose)
1835 {
1836#ifdef VMS
1837 if (index (nm, '/'))
1838 return build_string (sys_translate_unix (nm));
1839#endif /* VMS */
d5db4077 1840 if (nm == SDATA (name))
4887597a
EZ
1841 return name;
1842 return build_string (nm);
1843 }
1844 }
1845
1846 /* Now determine directory to start with and put it in NEWDIR */
1847
1848 newdir = 0;
1849
1850 if (nm[0] == '~') /* prefix ~ */
1851 if (nm[1] == '/'
1852#ifdef VMS
1853 || nm[1] == ':'
1854#endif /* VMS */
1855 || nm[1] == 0)/* ~/filename */
1856 {
1857 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1858 newdir = (unsigned char *) "";
1859 nm++;
1860#ifdef VMS
1861 nm++; /* Don't leave the slash in nm. */
1862#endif /* VMS */
1863 }
1864 else /* ~user/filename */
1865 {
1866 /* Get past ~ to user */
1867 unsigned char *user = nm + 1;
1868 /* Find end of name. */
1869 unsigned char *ptr = (unsigned char *) index (user, '/');
1870 int len = ptr ? ptr - user : strlen (user);
1871#ifdef VMS
1872 unsigned char *ptr1 = index (user, ':');
1873 if (ptr1 != 0 && ptr1 - user < len)
1874 len = ptr1 - user;
1875#endif /* VMS */
1876 /* Copy the user name into temp storage. */
1877 o = (unsigned char *) alloca (len + 1);
1878 bcopy ((char *) user, o, len);
1879 o[len] = 0;
1880
1881 /* Look up the user name. */
1882 pw = (struct passwd *) getpwnam (o + 1);
1883 if (!pw)
1884 error ("\"%s\" isn't a registered user", o + 1);
1885
1886 newdir = (unsigned char *) pw->pw_dir;
1887
1888 /* Discard the user name from NM. */
1889 nm += len;
1890 }
1891
1892 if (nm[0] != '/'
1893#ifdef VMS
1894 && !index (nm, ':')
1895#endif /* not VMS */
1896 && !newdir)
1897 {
1898 if (NILP (defalt))
1899 defalt = current_buffer->directory;
b7826503 1900 CHECK_STRING (defalt);
d5db4077 1901 newdir = SDATA (defalt);
4887597a
EZ
1902 }
1903
1904 /* Now concatenate the directory and name to new space in the stack frame */
1905
1906 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1907 target = (unsigned char *) alloca (tlen);
1908 *target = 0;
1909
1910 if (newdir)
1911 {
1912#ifndef VMS
1913 if (nm[0] == 0 || nm[0] == '/')
1914 strcpy (target, newdir);
1915 else
1916#endif
1917 file_name_as_directory (target, newdir);
1918 }
1919
1920 strcat (target, nm);
1921#ifdef VMS
1922 if (index (target, '/'))
1923 strcpy (target, sys_translate_unix (target));
1924#endif /* VMS */
1925
1926 /* Now canonicalize by removing /. and /foo/.. if they appear */
1927
1928 p = target;
1929 o = target;
1930
1931 while (*p)
1932 {
1933#ifdef VMS
1934 if (*p != ']' && *p != '>' && *p != '-')
1935 {
1936 if (*p == '\\')
1937 p++;
1938 *o++ = *p++;
1939 }
1940 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1941 /* brackets are offset from each other by 2 */
1942 {
1943 p += 2;
1944 if (*p != '.' && *p != '-' && o[-1] != '.')
1945 /* convert [foo][bar] to [bar] */
1946 while (o[-1] != '[' && o[-1] != '<')
1947 o--;
1948 else if (*p == '-' && *o != '.')
1949 *--p = '.';
1950 }
1951 else if (p[0] == '-' && o[-1] == '.' &&
1952 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1953 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1954 {
1955 do
1956 o--;
1957 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1958 if (p[1] == '.') /* foo.-.bar ==> bar. */
1959 p += 2;
1960 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1961 p++, o--;
1962 /* else [foo.-] ==> [-] */
1963 }
1964 else
1965 {
1966#ifndef VMS4_4
1967 if (*p == '-' &&
1968 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1969 p[1] != ']' && p[1] != '>' && p[1] != '.')
1970 *p = '_';
1971#endif /* VMS4_4 */
1972 *o++ = *p++;
1973 }
1974#else /* not VMS */
1975 if (*p != '/')
1976 {
1977 *o++ = *p++;
1978 }
1979 else if (!strncmp (p, "//", 2)
1980#ifdef APOLLO
1981 /* // at start of filename is meaningful in Apollo system. */
1982 && o != target
1983#endif /* APOLLO */
1984 )
1985 {
1986 o = target;
1987 p++;
1988 }
1989 else if (p[0] == '/' && p[1] == '.' &&
1990 (p[2] == '/' || p[2] == 0))
1991 p += 2;
1992 else if (!strncmp (p, "/..", 3)
1993 /* `/../' is the "superroot" on certain file systems. */
1994 && o != target
1995 && (p[3] == '/' || p[3] == 0))
1996 {
1997 while (o != target && *--o != '/')
1998 ;
1999#ifdef APOLLO
2000 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
2001 ++o;
2002 else
2003#endif /* APOLLO */
2004 if (o == target && *o == '/')
2005 ++o;
2006 p += 3;
2007 }
2008 else
2009 {
2010 *o++ = *p++;
2011 }
2012#endif /* not VMS */
2013 }
2014
2015 return make_string (target, o - target);
2016}
2017#endif
570d7624
JB
2018\f
2019DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
8c1a1077
PJ
2020 Ssubstitute_in_file_name, 1, 1, 0,
2021 doc: /* Substitute environment variables referred to in FILENAME.
2022`$FOO' where FOO is an environment variable name means to substitute
2023the value of that variable. The variable name should be terminated
2024with a character not a letter, digit or underscore; otherwise, enclose
2025the entire variable name in braces.
2026If `/~' appears, all of FILENAME through that `/' is discarded.
2027
2028On VMS, `$' substitution is not done; this function does little and only
2029duplicates what `expand-file-name' does. */)
2030 (filename)
3b7f6e60 2031 Lisp_Object filename;
570d7624
JB
2032{
2033 unsigned char *nm;
2034
2035 register unsigned char *s, *p, *o, *x, *endp;
6bbd7a29 2036 unsigned char *target = NULL;
570d7624
JB
2037 int total = 0;
2038 int substituted = 0;
2039 unsigned char *xnm;
dba493fe 2040 struct passwd *pw;
8ce069f5 2041 Lisp_Object handler;
570d7624 2042
b7826503 2043 CHECK_STRING (filename);
570d7624 2044
8ce069f5
RS
2045 /* If the file name has special constructs in it,
2046 call the corresponding file handler. */
3b7f6e60 2047 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
8ce069f5 2048 if (!NILP (handler))
3b7f6e60 2049 return call2 (handler, Qsubstitute_in_file_name, filename);
8ce069f5 2050
d5db4077 2051 nm = SDATA (filename);
199607e4
RS
2052#ifdef DOS_NT
2053 nm = strcpy (alloca (strlen (nm) + 1), nm);
2054 CORRECT_DIR_SEPS (nm);
d5db4077 2055 substituted = (strcmp (nm, SDATA (filename)) != 0);
a5a1cc06 2056#endif
d5db4077 2057 endp = nm + SBYTES (filename);
570d7624 2058
82330e7f 2059 /* If /~ or // appears, discard everything through first slash. */
570d7624
JB
2060
2061 for (p = nm; p != endp; p++)
2062 {
199607e4 2063 if ((p[0] == '~'
c60ee5e7
JB
2064#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
2065 /* // at start of file name is meaningful in Apollo,
2066 WindowsNT and Cygwin systems. */
199607e4 2067 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
c60ee5e7 2068#else /* not (APOLLO || WINDOWSNT || CYGWIN) */
199607e4 2069 || IS_DIRECTORY_SEP (p[0])
c60ee5e7 2070#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
570d7624 2071 )
5e570b75
RS
2072 && p != nm
2073 && (0
570d7624 2074#ifdef VMS
5e570b75 2075 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
570d7624 2076#endif /* VMS */
5e570b75 2077 || IS_DIRECTORY_SEP (p[-1])))
570d7624 2078 {
dba493fe
EZ
2079 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
2080#ifdef VMS
2081 && *s != ':'
2082#endif /* VMS */
2083 ); s++);
b135bd4c 2084 if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
dba493fe
EZ
2085 {
2086 o = (unsigned char *) alloca (s - p + 1);
2087 bcopy ((char *) p, o, s - p);
2088 o [s - p] = 0;
2089
2090 pw = (struct passwd *) getpwnam (o + 1);
2091 }
2092 /* If we have ~/ or ~user and `user' exists, discard
2093 everything up to ~. But if `user' does not exist, leave
2094 ~user alone, it might be a literal file name. */
b135bd4c 2095 if (IS_DIRECTORY_SEP (p[0]) || s == p + 1 || pw)
dba493fe
EZ
2096 {
2097 nm = p;
2098 substituted = 1;
2099 }
570d7624 2100 }
5e570b75 2101#ifdef DOS_NT
199607e4
RS
2102 /* see comment in expand-file-name about drive specifiers */
2103 else if (IS_DRIVE (p[0]) && p[1] == ':'
2104 && p > nm && IS_DIRECTORY_SEP (p[-1]))
4c3c22f3
RS
2105 {
2106 nm = p;
2107 substituted = 1;
2108 }
5e570b75 2109#endif /* DOS_NT */
570d7624
JB
2110 }
2111
2112#ifdef VMS
d7231f93
KH
2113 return make_specified_string (nm, -1, strlen (nm),
2114 STRING_MULTIBYTE (filename));
570d7624
JB
2115#else
2116
2117 /* See if any variables are substituted into the string
2118 and find the total length of their values in `total' */
2119
2120 for (p = nm; p != endp;)
2121 if (*p != '$')
2122 p++;
2123 else
2124 {
2125 p++;
2126 if (p == endp)
2127 goto badsubst;
2128 else if (*p == '$')
2129 {
2130 /* "$$" means a single "$" */
2131 p++;
2132 total -= 1;
2133 substituted = 1;
2134 continue;
2135 }
2136 else if (*p == '{')
2137 {
2138 o = ++p;
2139 while (p != endp && *p != '}') p++;
2140 if (*p != '}') goto missingclose;
2141 s = p;
2142 }
2143 else
2144 {
2145 o = p;
2146 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2147 s = p;
2148 }
2149
2150 /* Copy out the variable name */
2151 target = (unsigned char *) alloca (s - o + 1);
2152 strncpy (target, o, s - o);
2153 target[s - o] = 0;
5e570b75 2154#ifdef DOS_NT
4c3c22f3 2155 strupr (target); /* $home == $HOME etc. */
5e570b75 2156#endif /* DOS_NT */
570d7624
JB
2157
2158 /* Get variable value */
2159 o = (unsigned char *) egetenv (target);
8d2ced53
SM
2160 if (o)
2161 {
2162 total += strlen (o);
2163 substituted = 1;
2164 }
2165 else if (*p == '}')
2166 goto badvar;
570d7624
JB
2167 }
2168
2169 if (!substituted)
3b7f6e60 2170 return filename;
570d7624
JB
2171
2172 /* If substitution required, recopy the string and do it */
2173 /* Make space in stack frame for the new copy */
d5db4077 2174 xnm = (unsigned char *) alloca (SBYTES (filename) + total + 1);
570d7624
JB
2175 x = xnm;
2176
2177 /* Copy the rest of the name through, replacing $ constructs with values */
2178 for (p = nm; *p;)
2179 if (*p != '$')
2180 *x++ = *p++;
2181 else
2182 {
2183 p++;
2184 if (p == endp)
2185 goto badsubst;
2186 else if (*p == '$')
2187 {
2188 *x++ = *p++;
2189 continue;
2190 }
2191 else if (*p == '{')
2192 {
2193 o = ++p;
2194 while (p != endp && *p != '}') p++;
2195 if (*p != '}') goto missingclose;
2196 s = p++;
2197 }
2198 else
2199 {
2200 o = p;
2201 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2202 s = p;
2203 }
2204
2205 /* Copy out the variable name */
2206 target = (unsigned char *) alloca (s - o + 1);
2207 strncpy (target, o, s - o);
2208 target[s - o] = 0;
5e570b75 2209#ifdef DOS_NT
4c3c22f3 2210 strupr (target); /* $home == $HOME etc. */
5e570b75 2211#endif /* DOS_NT */
570d7624
JB
2212
2213 /* Get variable value */
2214 o = (unsigned char *) egetenv (target);
570d7624 2215 if (!o)
8d2ced53
SM
2216 {
2217 *x++ = '$';
2218 strcpy (x, target); x+= strlen (target);
2219 }
2220 else if (STRING_MULTIBYTE (filename))
60d67b83
RS
2221 {
2222 /* If the original string is multibyte,
2223 convert what we substitute into multibyte. */
60d67b83
RS
2224 while (*o)
2225 {
ce51c54c
KH
2226 int c = unibyte_char_to_multibyte (*o++);
2227 x += CHAR_STRING (c, x);
60d67b83
RS
2228 }
2229 }
2230 else
2231 {
2232 strcpy (x, o);
2233 x += strlen (o);
2234 }
570d7624
JB
2235 }
2236
2237 *x = 0;
2238
82330e7f 2239 /* If /~ or // appears, discard everything through first slash. */
570d7624
JB
2240
2241 for (p = xnm; p != x; p++)
5e570b75 2242 if ((p[0] == '~'
c60ee5e7 2243#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
5e570b75 2244 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
c60ee5e7 2245#else /* not (APOLLO || WINDOWSNT || CYGWIN) */
199607e4 2246 || IS_DIRECTORY_SEP (p[0])
c60ee5e7 2247#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
570d7624 2248 )
ac5b7072 2249 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
570d7624 2250 xnm = p;
5e570b75 2251#ifdef DOS_NT
199607e4 2252 else if (IS_DRIVE (p[0]) && p[1] == ':'
4488d7e1 2253 && p > xnm && IS_DIRECTORY_SEP (p[-1]))
199607e4 2254 xnm = p;
4c3c22f3 2255#endif
570d7624 2256
d7231f93 2257 return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename));
570d7624
JB
2258
2259 badsubst:
2260 error ("Bad format environment-variable substitution");
2261 missingclose:
2262 error ("Missing \"}\" in environment-variable substitution");
2263 badvar:
2264 error ("Substituting nonexistent environment variable \"%s\"", target);
2265
2266 /* NOTREACHED */
2267#endif /* not VMS */
6bbd7a29 2268 return Qnil;
570d7624
JB
2269}
2270\f
067ffa38 2271/* A slightly faster and more convenient way to get
298b760e 2272 (directory-file-name (expand-file-name FOO)). */
067ffa38 2273
570d7624
JB
2274Lisp_Object
2275expand_and_dir_to_file (filename, defdir)
2276 Lisp_Object filename, defdir;
2277{
199607e4 2278 register Lisp_Object absname;
570d7624 2279
199607e4 2280 absname = Fexpand_file_name (filename, defdir);
570d7624
JB
2281#ifdef VMS
2282 {
d5db4077 2283 register int c = SREF (absname, SBYTES (absname) - 1);
570d7624 2284 if (c == ':' || c == ']' || c == '>')
199607e4 2285 absname = Fdirectory_file_name (absname);
570d7624
JB
2286 }
2287#else
199607e4 2288 /* Remove final slash, if any (unless this is the root dir).
570d7624 2289 stat behaves differently depending! */
d5db4077
KR
2290 if (SCHARS (absname) > 1
2291 && IS_DIRECTORY_SEP (SREF (absname, SBYTES (absname) - 1))
2292 && !IS_DEVICE_SEP (SREF (absname, SBYTES (absname)-2)))
ddc61f46 2293 /* We cannot take shortcuts; they might be wrong for magic file names. */
199607e4 2294 absname = Fdirectory_file_name (absname);
570d7624 2295#endif
199607e4 2296 return absname;
570d7624
JB
2297}
2298\f
3ed15d97
RS
2299/* Signal an error if the file ABSNAME already exists.
2300 If INTERACTIVE is nonzero, ask the user whether to proceed,
2301 and bypass the error if the user says to go ahead.
2302 QUERYSTRING is a name for the action that is being considered
2303 to alter the file.
de1d0127 2304
3ed15d97 2305 *STATPTR is used to store the stat information if the file exists.
de1d0127 2306 If the file does not exist, STATPTR->st_mode is set to 0.
b8b29dc9
RS
2307 If STATPTR is null, we don't store into it.
2308
2309 If QUICK is nonzero, we ask for y or n, not yes or no. */
3ed15d97 2310
c4df73f9 2311void
b8b29dc9 2312barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
570d7624
JB
2313 Lisp_Object absname;
2314 unsigned char *querystring;
2315 int interactive;
3ed15d97 2316 struct stat *statptr;
b8b29dc9 2317 int quick;
570d7624 2318{
643c73b9 2319 register Lisp_Object tem, encoded_filename;
4018b5ef 2320 struct stat statbuf;
570d7624
JB
2321 struct gcpro gcpro1;
2322
643c73b9
RS
2323 encoded_filename = ENCODE_FILE (absname);
2324
4018b5ef
RS
2325 /* stat is a good way to tell whether the file exists,
2326 regardless of what access permissions it has. */
d5db4077 2327 if (stat (SDATA (encoded_filename), &statbuf) >= 0)
570d7624
JB
2328 {
2329 if (! interactive)
2330 Fsignal (Qfile_already_exists,
2331 Fcons (build_string ("File already exists"),
2332 Fcons (absname, Qnil)));
2333 GCPRO1 (absname);
67e8e2b8
RS
2334 tem = format2 ("File %s already exists; %s anyway? ",
2335 absname, build_string (querystring));
b8b29dc9
RS
2336 if (quick)
2337 tem = Fy_or_n_p (tem);
2338 else
2339 tem = do_yes_or_no_p (tem);
570d7624 2340 UNGCPRO;
265a9e55 2341 if (NILP (tem))
570d7624
JB
2342 Fsignal (Qfile_already_exists,
2343 Fcons (build_string ("File already exists"),
2344 Fcons (absname, Qnil)));
3ed15d97
RS
2345 if (statptr)
2346 *statptr = statbuf;
2347 }
2348 else
2349 {
2350 if (statptr)
2351 statptr->st_mode = 0;
570d7624
JB
2352 }
2353 return;
2354}
2355
2356DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
8c1a1077
PJ
2357 "fCopy file: \nFCopy %s to file: \np\nP",
2358 doc: /* Copy FILE to NEWNAME. Both args must be strings.
2359If NEWNAME names a directory, copy FILE there.
2360Signals a `file-already-exists' error if file NEWNAME already exists,
2361unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
2362A number as third arg means request confirmation if NEWNAME already exists.
2363This is what happens in interactive use with M-x.
2364Fourth arg KEEP-TIME non-nil means give the new file the same
2365last-modified time as the old one. (This works on only some systems.)
2366A prefix arg makes KEEP-TIME non-nil. */)
2367 (file, newname, ok_if_already_exists, keep_time)
8ca6602c 2368 Lisp_Object file, newname, ok_if_already_exists, keep_time;
570d7624
JB
2369{
2370 int ifd, ofd, n;
2371 char buf[16 * 1024];
3ed15d97 2372 struct stat st, out_st;
32f4334d 2373 Lisp_Object handler;
b1d1b865 2374 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
aed13378 2375 int count = SPECPDL_INDEX ();
f73b0ada 2376 int input_file_statable_p;
b1d1b865 2377 Lisp_Object encoded_file, encoded_newname;
570d7624 2378
b1d1b865
RS
2379 encoded_file = encoded_newname = Qnil;
2380 GCPRO4 (file, newname, encoded_file, encoded_newname);
b7826503
PJ
2381 CHECK_STRING (file);
2382 CHECK_STRING (newname);
b1d1b865 2383
a9d14e54
GM
2384 if (!NILP (Ffile_directory_p (newname)))
2385 newname = Fexpand_file_name (file, newname);
2386 else
2387 newname = Fexpand_file_name (newname, Qnil);
2388
3b7f6e60 2389 file = Fexpand_file_name (file, Qnil);
32f4334d 2390
0bf2eed2 2391 /* If the input file name has special constructs in it,
32f4334d 2392 call the corresponding file handler. */
3b7f6e60 2393 handler = Ffind_file_name_handler (file, Qcopy_file);
0bf2eed2 2394 /* Likewise for output file name. */
51cf6d37 2395 if (NILP (handler))
49307295 2396 handler = Ffind_file_name_handler (newname, Qcopy_file);
32f4334d 2397 if (!NILP (handler))
3b7f6e60 2398 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
8ca6602c 2399 ok_if_already_exists, keep_time));
32f4334d 2400
b1d1b865
RS
2401 encoded_file = ENCODE_FILE (file);
2402 encoded_newname = ENCODE_FILE (newname);
2403
265a9e55 2404 if (NILP (ok_if_already_exists)
93c30b5f 2405 || INTEGERP (ok_if_already_exists))
b1d1b865 2406 barf_or_query_if_file_exists (encoded_newname, "copy to it",
b8b29dc9 2407 INTEGERP (ok_if_already_exists), &out_st, 0);
d5db4077 2408 else if (stat (SDATA (encoded_newname), &out_st) < 0)
3ed15d97 2409 out_st.st_mode = 0;
570d7624 2410
e8691c59 2411#ifdef WINDOWSNT
d5db4077 2412 if (!CopyFile (SDATA (encoded_file),
efdc16c9 2413 SDATA (encoded_newname),
e8691c59
GM
2414 FALSE))
2415 report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
8b53dc06
JR
2416 /* CopyFile retains the timestamp by default. */
2417 else if (NILP (keep_time))
e8691c59
GM
2418 {
2419 EMACS_TIME now;
ad497129
JR
2420 DWORD attributes;
2421 char * filename;
2422
e8691c59 2423 EMACS_GET_TIME (now);
d5db4077 2424 filename = SDATA (encoded_newname);
ad497129
JR
2425
2426 /* Ensure file is writable while its modified time is set. */
2427 attributes = GetFileAttributes (filename);
02cca86b 2428 SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
ad497129
JR
2429 if (set_file_times (filename, now, now))
2430 {
2431 /* Restore original attributes. */
2432 SetFileAttributes (filename, attributes);
2433 Fsignal (Qfile_date_error,
2434 Fcons (build_string ("Cannot set file date"),
2435 Fcons (newname, Qnil)));
2436 }
2437 /* Restore original attributes. */
2438 SetFileAttributes (filename, attributes);
e8691c59
GM
2439 }
2440#else /* not WINDOWSNT */
13336908 2441 immediate_quit = 1;
d5db4077 2442 ifd = emacs_open (SDATA (encoded_file), O_RDONLY, 0);
13336908
RS
2443 immediate_quit = 0;
2444
570d7624 2445 if (ifd < 0)
3b7f6e60 2446 report_file_error ("Opening input file", Fcons (file, Qnil));
570d7624 2447
b5148e85
RS
2448 record_unwind_protect (close_file_unwind, make_number (ifd));
2449
f73b0ada
BF
2450 /* We can only copy regular files and symbolic links. Other files are not
2451 copyable by us. */
2452 input_file_statable_p = (fstat (ifd, &st) >= 0);
2453
f9ba66ce 2454#if !defined (DOS_NT) || __DJGPP__ > 1
3ed15d97
RS
2455 if (out_st.st_mode != 0
2456 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2457 {
2458 errno = 0;
2459 report_file_error ("Input and output files are the same",
3b7f6e60 2460 Fcons (file, Fcons (newname, Qnil)));
3ed15d97
RS
2461 }
2462#endif
2463
f73b0ada
BF
2464#if defined (S_ISREG) && defined (S_ISLNK)
2465 if (input_file_statable_p)
2466 {
2467 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2468 {
2469#if defined (EISDIR)
2470 /* Get a better looking error message. */
2471 errno = EISDIR;
2472#endif /* EISDIR */
3b7f6e60 2473 report_file_error ("Non-regular file", Fcons (file, Qnil));
f73b0ada
BF
2474 }
2475 }
2476#endif /* S_ISREG && S_ISLNK */
2477
570d7624
JB
2478#ifdef VMS
2479 /* Create the copy file with the same record format as the input file */
d5db4077 2480 ofd = sys_creat (SDATA (encoded_newname), 0666, ifd);
570d7624 2481#else
4c3c22f3
RS
2482#ifdef MSDOS
2483 /* System's default file type was set to binary by _fmode in emacs.c. */
d5db4077 2484 ofd = creat (SDATA (encoded_newname), S_IREAD | S_IWRITE);
4c3c22f3 2485#else /* not MSDOS */
d5db4077 2486 ofd = creat (SDATA (encoded_newname), 0666);
4c3c22f3 2487#endif /* not MSDOS */
570d7624
JB
2488#endif /* VMS */
2489 if (ofd < 0)
3ed15d97 2490 report_file_error ("Opening output file", Fcons (newname, Qnil));
b5148e85
RS
2491
2492 record_unwind_protect (close_file_unwind, make_number (ofd));
570d7624 2493
b5148e85
RS
2494 immediate_quit = 1;
2495 QUIT;
68c45bf0
PE
2496 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2497 if (emacs_write (ofd, buf, n) != n)
3ed15d97 2498 report_file_error ("I/O error", Fcons (newname, Qnil));
b5148e85 2499 immediate_quit = 0;
570d7624 2500
5acac34e 2501 /* Closing the output clobbers the file times on some systems. */
68c45bf0 2502 if (emacs_close (ofd) < 0)
5acac34e
RS
2503 report_file_error ("I/O error", Fcons (newname, Qnil));
2504
f73b0ada 2505 if (input_file_statable_p)
570d7624 2506 {
8ca6602c 2507 if (!NILP (keep_time))
570d7624 2508 {
de5bf5d3
JB
2509 EMACS_TIME atime, mtime;
2510 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2511 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
d5db4077 2512 if (set_file_times (SDATA (encoded_newname),
b1d1b865 2513 atime, mtime))
c0b7b21c 2514 Fsignal (Qfile_date_error,
d1b9ed63 2515 Fcons (build_string ("Cannot set file date"),
3dbcf3f6 2516 Fcons (newname, Qnil)));
570d7624 2517 }
2dc3be7e 2518#ifndef MSDOS
d5db4077 2519 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2dc3be7e
RS
2520#else /* MSDOS */
2521#if defined (__DJGPP__) && __DJGPP__ > 1
2522 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2523 and if it can't, it tells so. Otherwise, under MSDOS we usually
2524 get only the READ bit, which will make the copied file read-only,
2525 so it's better not to chmod at all. */
2526 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
d5db4077 2527 chmod (SDATA (encoded_newname), st.st_mode & 07777);
2dc3be7e
RS
2528#endif /* DJGPP version 2 or newer */
2529#endif /* MSDOS */
570d7624
JB
2530 }
2531
68c45bf0 2532 emacs_close (ifd);
e8691c59 2533#endif /* WINDOWSNT */
5acac34e 2534
b5148e85
RS
2535 /* Discard the unwind protects. */
2536 specpdl_ptr = specpdl + count;
2537
570d7624
JB
2538 UNGCPRO;
2539 return Qnil;
2540}
385b6cc7 2541\f
9bbe01fb 2542DEFUN ("make-directory-internal", Fmake_directory_internal,
353cfc19 2543 Smake_directory_internal, 1, 1, 0,
8c1a1077
PJ
2544 doc: /* Create a new directory named DIRECTORY. */)
2545 (directory)
3b7f6e60 2546 Lisp_Object directory;
570d7624 2547{
19290c65 2548 const unsigned char *dir;
32f4334d 2549 Lisp_Object handler;
b1d1b865 2550 Lisp_Object encoded_dir;
570d7624 2551
b7826503 2552 CHECK_STRING (directory);
3b7f6e60 2553 directory = Fexpand_file_name (directory, Qnil);
32f4334d 2554
3b7f6e60 2555 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
32f4334d 2556 if (!NILP (handler))
3b7f6e60 2557 return call2 (handler, Qmake_directory_internal, directory);
9bbe01fb 2558
b1d1b865
RS
2559 encoded_dir = ENCODE_FILE (directory);
2560
d5db4077 2561 dir = SDATA (encoded_dir);
570d7624 2562
5e570b75
RS
2563#ifdef WINDOWSNT
2564 if (mkdir (dir) != 0)
2565#else
570d7624 2566 if (mkdir (dir, 0777) != 0)
5e570b75 2567#endif
3b7f6e60 2568 report_file_error ("Creating directory", Flist (1, &directory));
570d7624 2569
32f4334d 2570 return Qnil;
570d7624
JB
2571}
2572
aa734e17 2573DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
efdc16c9 2574 doc: /* Delete the directory named DIRECTORY. Does not follow symlinks. */)
8c1a1077 2575 (directory)
3b7f6e60 2576 Lisp_Object directory;
570d7624 2577{
19290c65 2578 const unsigned char *dir;
32f4334d 2579 Lisp_Object handler;
b1d1b865 2580 Lisp_Object encoded_dir;
570d7624 2581
b7826503 2582 CHECK_STRING (directory);
3b7f6e60 2583 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
570d7624 2584
3b7f6e60 2585 handler = Ffind_file_name_handler (directory, Qdelete_directory);
32f4334d 2586 if (!NILP (handler))
3b7f6e60 2587 return call2 (handler, Qdelete_directory, directory);
32f4334d 2588
b1d1b865
RS
2589 encoded_dir = ENCODE_FILE (directory);
2590
d5db4077 2591 dir = SDATA (encoded_dir);
b1d1b865 2592
570d7624 2593 if (rmdir (dir) != 0)
3b7f6e60 2594 report_file_error ("Removing directory", Flist (1, &directory));
570d7624
JB
2595
2596 return Qnil;
2597}
2598
2599DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
efdc16c9 2600 doc: /* Delete file named FILENAME. If it is a symlink, remove the symlink.
8c1a1077
PJ
2601If file has multiple names, it continues to exist with the other names. */)
2602 (filename)
570d7624
JB
2603 Lisp_Object filename;
2604{
32f4334d 2605 Lisp_Object handler;
b1d1b865 2606 Lisp_Object encoded_file;
efdc16c9 2607 struct gcpro gcpro1;
b1d1b865 2608
efdc16c9
FP
2609 GCPRO1 (filename);
2610 if (!NILP (Ffile_directory_p (filename)))
2611 Fsignal (Qfile_error,
2612 Fcons (build_string ("Removing old name: is a directory"),
2613 Fcons (filename, Qnil)));
2614 UNGCPRO;
570d7624 2615 filename = Fexpand_file_name (filename, Qnil);
32f4334d 2616
49307295 2617 handler = Ffind_file_name_handler (filename, Qdelete_file);
32f4334d 2618 if (!NILP (handler))
8a9b0da9 2619 return call2 (handler, Qdelete_file, filename);
32f4334d 2620
b1d1b865
RS
2621 encoded_file = ENCODE_FILE (filename);
2622
d5db4077 2623 if (0 > unlink (SDATA (encoded_file)))
570d7624 2624 report_file_error ("Removing old name", Flist (1, &filename));
8a9b0da9 2625 return Qnil;
570d7624
JB
2626}
2627
385b6cc7
RS
2628static Lisp_Object
2629internal_delete_file_1 (ignore)
2630 Lisp_Object ignore;
2631{
2632 return Qt;
2633}
2634
2635/* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2636
2637int
2638internal_delete_file (filename)
2639 Lisp_Object filename;
2640{
2641 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2642 Qt, internal_delete_file_1));
2643}
2644\f
570d7624 2645DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
8c1a1077
PJ
2646 "fRename file: \nFRename %s to file: \np",
2647 doc: /* Rename FILE as NEWNAME. Both args strings.
2648If file has names other than FILE, it continues to have those names.
2649Signals a `file-already-exists' error if a file NEWNAME already exists
2650unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2651A number as third arg means request confirmation if NEWNAME already exists.
2652This is what happens in interactive use with M-x. */)
2653 (file, newname, ok_if_already_exists)
3b7f6e60 2654 Lisp_Object file, newname, ok_if_already_exists;
570d7624
JB
2655{
2656#ifdef NO_ARG_ARRAY
2657 Lisp_Object args[2];
2658#endif
32f4334d 2659 Lisp_Object handler;
b1d1b865
RS
2660 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2661 Lisp_Object encoded_file, encoded_newname;
570d7624 2662
b1d1b865
RS
2663 encoded_file = encoded_newname = Qnil;
2664 GCPRO4 (file, newname, encoded_file, encoded_newname);
b7826503
PJ
2665 CHECK_STRING (file);
2666 CHECK_STRING (newname);
3b7f6e60 2667 file = Fexpand_file_name (file, Qnil);
570d7624 2668 newname = Fexpand_file_name (newname, Qnil);
32f4334d
RS
2669
2670 /* If the file name has special constructs in it,
2671 call the corresponding file handler. */
3b7f6e60 2672 handler = Ffind_file_name_handler (file, Qrename_file);
51cf6d37 2673 if (NILP (handler))
49307295 2674 handler = Ffind_file_name_handler (newname, Qrename_file);
32f4334d 2675 if (!NILP (handler))
36712b0a 2676 RETURN_UNGCPRO (call4 (handler, Qrename_file,
3b7f6e60 2677 file, newname, ok_if_already_exists));
32f4334d 2678
b1d1b865
RS
2679 encoded_file = ENCODE_FILE (file);
2680 encoded_newname = ENCODE_FILE (newname);
2681
bc77278f
EZ
2682#ifdef DOS_NT
2683 /* If the file names are identical but for the case, don't ask for
2684 confirmation: they simply want to change the letter-case of the
2685 file name. */
2686 if (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))
2687#endif
265a9e55 2688 if (NILP (ok_if_already_exists)
93c30b5f 2689 || INTEGERP (ok_if_already_exists))
b1d1b865 2690 barf_or_query_if_file_exists (encoded_newname, "rename to it",
b8b29dc9 2691 INTEGERP (ok_if_already_exists), 0, 0);
570d7624 2692#ifndef BSD4_1
d5db4077 2693 if (0 > rename (SDATA (encoded_file), SDATA (encoded_newname)))
570d7624 2694#else
d5db4077
KR
2695 if (0 > link (SDATA (encoded_file), SDATA (encoded_newname))
2696 || 0 > unlink (SDATA (encoded_file)))
570d7624
JB
2697#endif
2698 {
2699 if (errno == EXDEV)
2700 {
3b7f6e60 2701 Fcopy_file (file, newname,
d093c3ac
RM
2702 /* We have already prompted if it was an integer,
2703 so don't have copy-file prompt again. */
2704 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
3b7f6e60 2705 Fdelete_file (file);
570d7624
JB
2706 }
2707 else
2708#ifdef NO_ARG_ARRAY
2709 {
3b7f6e60 2710 args[0] = file;
570d7624
JB
2711 args[1] = newname;
2712 report_file_error ("Renaming", Flist (2, args));
2713 }
2714#else
3b7f6e60 2715 report_file_error ("Renaming", Flist (2, &file));
570d7624
JB
2716#endif
2717 }
2718 UNGCPRO;
2719 return Qnil;
2720}
2721
2722DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
8c1a1077
PJ
2723 "fAdd name to file: \nFName to add to %s: \np",
2724 doc: /* Give FILE additional name NEWNAME. Both args strings.
2725Signals a `file-already-exists' error if a file NEWNAME already exists
2726unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2727A number as third arg means request confirmation if NEWNAME already exists.
2728This is what happens in interactive use with M-x. */)
2729 (file, newname, ok_if_already_exists)
3b7f6e60 2730 Lisp_Object file, newname, ok_if_already_exists;
570d7624
JB
2731{
2732#ifdef NO_ARG_ARRAY
2733 Lisp_Object args[2];
2734#endif
32f4334d 2735 Lisp_Object handler;
b1d1b865
RS
2736 Lisp_Object encoded_file, encoded_newname;
2737 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
570d7624 2738
b1d1b865
RS
2739 GCPRO4 (file, newname, encoded_file, encoded_newname);
2740 encoded_file = encoded_newname = Qnil;
b7826503
PJ
2741 CHECK_STRING (file);
2742 CHECK_STRING (newname);
3b7f6e60 2743 file = Fexpand_file_name (file, Qnil);
570d7624 2744 newname = Fexpand_file_name (newname, Qnil);
32f4334d
RS
2745
2746 /* If the file name has special constructs in it,
2747 call the corresponding file handler. */
3b7f6e60 2748 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
32f4334d 2749 if (!NILP (handler))
3b7f6e60 2750 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
36712b0a 2751 newname, ok_if_already_exists));
32f4334d 2752
adc6741c
RS
2753 /* If the new name has special constructs in it,
2754 call the corresponding file handler. */
2755 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2756 if (!NILP (handler))
3b7f6e60 2757 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
adc6741c
RS
2758 newname, ok_if_already_exists));
2759
b1d1b865
RS
2760 encoded_file = ENCODE_FILE (file);
2761 encoded_newname = ENCODE_FILE (newname);
2762
265a9e55 2763 if (NILP (ok_if_already_exists)
93c30b5f 2764 || INTEGERP (ok_if_already_exists))
b1d1b865 2765 barf_or_query_if_file_exists (encoded_newname, "make it a new name",
b8b29dc9 2766 INTEGERP (ok_if_already_exists), 0, 0);
5e570b75 2767
d5db4077
KR
2768 unlink (SDATA (newname));
2769 if (0 > link (SDATA (encoded_file), SDATA (encoded_newname)))
570d7624
JB
2770 {
2771#ifdef NO_ARG_ARRAY
3b7f6e60 2772 args[0] = file;
570d7624
JB
2773 args[1] = newname;
2774 report_file_error ("Adding new name", Flist (2, args));
2775#else
3b7f6e60 2776 report_file_error ("Adding new name", Flist (2, &file));
570d7624
JB
2777#endif
2778 }
2779
2780 UNGCPRO;
2781 return Qnil;
2782}
2783
2784#ifdef S_IFLNK
2785DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
8c1a1077
PJ
2786 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2787 doc: /* Make a symbolic link to FILENAME, named LINKNAME. Both args strings.
2788Signals a `file-already-exists' error if a file LINKNAME already exists
2789unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2790A number as third arg means request confirmation if LINKNAME already exists.
2791This happens for interactive use with M-x. */)
2792 (filename, linkname, ok_if_already_exists)
e5d77022 2793 Lisp_Object filename, linkname, ok_if_already_exists;
570d7624
JB
2794{
2795#ifdef NO_ARG_ARRAY
2796 Lisp_Object args[2];
2797#endif
32f4334d 2798 Lisp_Object handler;
b1d1b865
RS
2799 Lisp_Object encoded_filename, encoded_linkname;
2800 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
570d7624 2801
b1d1b865
RS
2802 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2803 encoded_filename = encoded_linkname = Qnil;
b7826503
PJ
2804 CHECK_STRING (filename);
2805 CHECK_STRING (linkname);
d9bc1c99
RS
2806 /* If the link target has a ~, we must expand it to get
2807 a truly valid file name. Otherwise, do not expand;
2808 we want to permit links to relative file names. */
d5db4077 2809 if (SREF (filename, 0) == '~')
d9bc1c99 2810 filename = Fexpand_file_name (filename, Qnil);
e5d77022 2811 linkname = Fexpand_file_name (linkname, Qnil);
32f4334d
RS
2812
2813 /* If the file name has special constructs in it,
2814 call the corresponding file handler. */
49307295 2815 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
32f4334d 2816 if (!NILP (handler))
36712b0a
KH
2817 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2818 linkname, ok_if_already_exists));
32f4334d 2819
adc6741c
RS
2820 /* If the new link name has special constructs in it,
2821 call the corresponding file handler. */
2822 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2823 if (!NILP (handler))
2824 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2825 linkname, ok_if_already_exists));
2826
b1d1b865
RS
2827 encoded_filename = ENCODE_FILE (filename);
2828 encoded_linkname = ENCODE_FILE (linkname);
2829
265a9e55 2830 if (NILP (ok_if_already_exists)
93c30b5f 2831 || INTEGERP (ok_if_already_exists))
b1d1b865 2832 barf_or_query_if_file_exists (encoded_linkname, "make it a link",
b8b29dc9 2833 INTEGERP (ok_if_already_exists), 0, 0);
d5db4077
KR
2834 if (0 > symlink (SDATA (encoded_filename),
2835 SDATA (encoded_linkname)))
570d7624
JB
2836 {
2837 /* If we didn't complain already, silently delete existing file. */
2838 if (errno == EEXIST)
2839 {
d5db4077
KR
2840 unlink (SDATA (encoded_linkname));
2841 if (0 <= symlink (SDATA (encoded_filename),
2842 SDATA (encoded_linkname)))
1a04498e
KH
2843 {
2844 UNGCPRO;
2845 return Qnil;
2846 }
570d7624
JB
2847 }
2848
2849#ifdef NO_ARG_ARRAY
2850 args[0] = filename;
e5d77022 2851 args[1] = linkname;
570d7624
JB
2852 report_file_error ("Making symbolic link", Flist (2, args));
2853#else
2854 report_file_error ("Making symbolic link", Flist (2, &filename));
2855#endif
2856 }
2857 UNGCPRO;
2858 return Qnil;
2859}
2860#endif /* S_IFLNK */
2861
2862#ifdef VMS
2863
2864DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2865 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
8c1a1077
PJ
2866 doc: /* Define the job-wide logical name NAME to have the value STRING.
2867If STRING is nil or a null string, the logical name NAME is deleted. */)
2868 (name, string)
3b7f6e60 2869 Lisp_Object name;
570d7624
JB
2870 Lisp_Object string;
2871{
b7826503 2872 CHECK_STRING (name);
265a9e55 2873 if (NILP (string))
d5db4077 2874 delete_logical_name (SDATA (name));
570d7624
JB
2875 else
2876 {
b7826503 2877 CHECK_STRING (string);
570d7624 2878
d5db4077
KR
2879 if (SCHARS (string) == 0)
2880 delete_logical_name (SDATA (name));
570d7624 2881 else
d5db4077 2882 define_logical_name (SDATA (name), SDATA (string));
570d7624
JB
2883 }
2884
2885 return string;
2886}
2887#endif /* VMS */
2888
2889#ifdef HPUX_NET
2890
2891DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
8c1a1077 2892 doc: /* Open a network connection to PATH using LOGIN as the login string. */)
570d7624
JB
2893 (path, login)
2894 Lisp_Object path, login;
2895{
2896 int netresult;
199607e4 2897
b7826503
PJ
2898 CHECK_STRING (path);
2899 CHECK_STRING (login);
199607e4 2900
d5db4077 2901 netresult = netunam (SDATA (path), SDATA (login));
570d7624
JB
2902
2903 if (netresult == -1)
2904 return Qnil;
2905 else
2906 return Qt;
2907}
2908#endif /* HPUX_NET */
2909\f
2910DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2911 1, 1, 0,
8c1a1077
PJ
2912 doc: /* Return t if file FILENAME specifies an absolute file name.
2913On Unix, this is a name starting with a `/' or a `~'. */)
570d7624
JB
2914 (filename)
2915 Lisp_Object filename;
2916{
19290c65 2917 const unsigned char *ptr;
570d7624 2918
b7826503 2919 CHECK_STRING (filename);
d5db4077 2920 ptr = SDATA (filename);
5e570b75 2921 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
570d7624
JB
2922#ifdef VMS
2923/* ??? This criterion is probably wrong for '<'. */
2924 || index (ptr, ':') || index (ptr, '<')
2925 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2926 && ptr[1] != '.')
2927#endif /* VMS */
5e570b75 2928#ifdef DOS_NT
199607e4 2929 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
4c3c22f3 2930#endif
570d7624
JB
2931 )
2932 return Qt;
2933 else
2934 return Qnil;
2935}
3beeedfe
RS
2936\f
2937/* Return nonzero if file FILENAME exists and can be executed. */
2938
2939static int
2940check_executable (filename)
2941 char *filename;
2942{
3be3c08e
RS
2943#ifdef DOS_NT
2944 int len = strlen (filename);
2945 char *suffix;
2946 struct stat st;
2947 if (stat (filename, &st) < 0)
2948 return 0;
34ead71a 2949#if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
199607e4
RS
2950 return ((st.st_mode & S_IEXEC) != 0);
2951#else
3be3c08e
RS
2952 return (S_ISREG (st.st_mode)
2953 && len >= 5
2954 && (stricmp ((suffix = filename + len-4), ".com") == 0
2955 || stricmp (suffix, ".exe") == 0
2dc3be7e
RS
2956 || stricmp (suffix, ".bat") == 0)
2957 || (st.st_mode & S_IFMT) == S_IFDIR);
199607e4 2958#endif /* not WINDOWSNT */
3be3c08e 2959#else /* not DOS_NT */
de0be7dd
RS
2960#ifdef HAVE_EUIDACCESS
2961 return (euidaccess (filename, 1) >= 0);
3beeedfe
RS
2962#else
2963 /* Access isn't quite right because it uses the real uid
2964 and we really want to test with the effective uid.
2965 But Unix doesn't give us a right way to do it. */
2966 return (access (filename, 1) >= 0);
2967#endif
3be3c08e 2968#endif /* not DOS_NT */
3beeedfe
RS
2969}
2970
2971/* Return nonzero if file FILENAME exists and can be written. */
2972
2973static int
2974check_writable (filename)
2975 char *filename;
2976{
3be3c08e
RS
2977#ifdef MSDOS
2978 struct stat st;
2979 if (stat (filename, &st) < 0)
2980 return 0;
2981 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2982#else /* not MSDOS */
41f3fb38
KH
2983#ifdef HAVE_EUIDACCESS
2984 return (euidaccess (filename, 2) >= 0);
3beeedfe
RS
2985#else
2986 /* Access isn't quite right because it uses the real uid
2987 and we really want to test with the effective uid.
2988 But Unix doesn't give us a right way to do it.
2989 Opening with O_WRONLY could work for an ordinary file,
2990 but would lose for directories. */
2991 return (access (filename, 2) >= 0);
2992#endif
3be3c08e 2993#endif /* not MSDOS */
3beeedfe 2994}
570d7624
JB
2995
2996DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
8c1a1077
PJ
2997 doc: /* Return t if file FILENAME exists. (This does not mean you can read it.)
2998See also `file-readable-p' and `file-attributes'. */)
2999 (filename)
570d7624
JB
3000 Lisp_Object filename;
3001{
199607e4 3002 Lisp_Object absname;
32f4334d 3003 Lisp_Object handler;
4018b5ef 3004 struct stat statbuf;
570d7624 3005
b7826503 3006 CHECK_STRING (filename);
199607e4 3007 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3008
3009 /* If the file name has special constructs in it,
3010 call the corresponding file handler. */
199607e4 3011 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
32f4334d 3012 if (!NILP (handler))
199607e4 3013 return call2 (handler, Qfile_exists_p, absname);
32f4334d 3014
b1d1b865
RS
3015 absname = ENCODE_FILE (absname);
3016
d5db4077 3017 return (stat (SDATA (absname), &statbuf) >= 0) ? Qt : Qnil;
570d7624
JB
3018}
3019
3020DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
8c1a1077
PJ
3021 doc: /* Return t if FILENAME can be executed by you.
3022For a directory, this means you can access files in that directory. */)
3023 (filename)
3024 Lisp_Object filename;
570d7624 3025{
199607e4 3026 Lisp_Object absname;
32f4334d 3027 Lisp_Object handler;
570d7624 3028
b7826503 3029 CHECK_STRING (filename);
199607e4 3030 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3031
3032 /* If the file name has special constructs in it,
3033 call the corresponding file handler. */
199607e4 3034 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
32f4334d 3035 if (!NILP (handler))
199607e4 3036 return call2 (handler, Qfile_executable_p, absname);
32f4334d 3037
b1d1b865
RS
3038 absname = ENCODE_FILE (absname);
3039
d5db4077 3040 return (check_executable (SDATA (absname)) ? Qt : Qnil);
570d7624
JB
3041}
3042
3043DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
8c1a1077
PJ
3044 doc: /* Return t if file FILENAME exists and you can read it.
3045See also `file-exists-p' and `file-attributes'. */)
3046 (filename)
570d7624
JB
3047 Lisp_Object filename;
3048{
199607e4 3049 Lisp_Object absname;
32f4334d 3050 Lisp_Object handler;
4018b5ef 3051 int desc;
bb369dc6
RS
3052 int flags;
3053 struct stat statbuf;
570d7624 3054
b7826503 3055 CHECK_STRING (filename);
199607e4 3056 absname = Fexpand_file_name (filename, Qnil);
32f4334d
RS
3057
3058 /* If the file name has special constructs in it,
3059 call the corresponding file handler. */
199607e4 3060 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
32f4334d 3061 if (!NILP (handler))
199607e4 3062 return call2 (handler, Qfile_readable_p, absname);
32f4334d 3063
b1d1b865
RS
3064 absname = ENCODE_FILE (absname);
3065
fb4c6c96
AC
3066#if defined(DOS_NT) || defined(macintosh)
3067 /* Under MS-DOS, Windows, and Macintosh, open does not work for
3068 directories. */
d5db4077 3069 if (access (SDATA (absname), 0) == 0)
a8a7d065
RS
3070 return Qt;
3071 return Qnil;
fb4c6c96 3072#else /* not DOS_NT and not macintosh */
bb369dc6
RS
3073 flags = O_RDONLY;
3074#if defined (S_ISFIFO) && defined (O_NONBLOCK)
3075 /* Opening a fifo without O_NONBLOCK can wait.
3076 We don't want to wait. But we don't want to mess wth O_NONBLOCK
3077 except in the case of a fifo, on a system which handles it. */
d5db4077 3078 desc = stat (SDATA (absname), &statbuf);
bb369dc6
RS
3079 if (desc < 0)
3080 return Qnil;
3081 if (S_ISFIFO (statbuf.st_mode))
3082 flags |= O_NONBLOCK;
3083#endif
d5db4077 3084 desc = emacs_open (SDATA (absname), flags, 0);
4018b5ef
RS
3085 if (desc < 0)
3086 return Qnil;
68c45bf0 3087 emacs_close (desc);
4018b5ef 3088 return Qt;
fb4c6c96 3089#endif /* not DOS_NT and not macintosh */
570d7624
JB
3090}
3091
f793dc6c
RS
3092/* Having this before file-symlink-p mysteriously caused it to be forgotten
3093 on the RT/PC. */
3094DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
8c1a1077
PJ
3095 doc: /* Return t if file FILENAME can be written or created by you. */)
3096 (filename)
f793dc6c
RS
3097 Lisp_Object filename;
3098{
b1d1b865 3099 Lisp_Object absname, dir, encoded;
f793dc6c
RS
3100 Lisp_Object handler;
3101 struct stat statbuf;
3102
b7826503 3103 CHECK_STRING (filename);
199607e4 3104 absname = Fexpand_file_name (filename, Qnil);
f793dc6c
RS
3105
3106 /* If the file name has special constructs in it,
3107 call the corresponding file handler. */
199607e4 3108 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
f793dc6c 3109 if (!NILP (handler))
199607e4 3110 return call2 (handler, Qfile_writable_p, absname);
f793dc6c 3111
b1d1b865 3112 encoded = ENCODE_FILE (absname);
d5db4077
KR
3113 if (stat (SDATA (encoded), &statbuf) >= 0)
3114 return (check_writable (SDATA (encoded))
f793dc6c 3115 ? Qt : Qnil);
b1d1b865 3116
199607e4 3117 dir = Ffile_name_directory (absname);
f793dc6c
RS
3118#ifdef VMS
3119 if (!NILP (dir))
3120 dir = Fdirectory_file_name (dir);
3121#endif /* VMS */
3122#ifdef MSDOS
3123 if (!NILP (dir))
3124 dir = Fdirectory_file_name (dir);
3125#endif /* MSDOS */
b1d1b865
RS
3126
3127 dir = ENCODE_FILE (dir);
e3e8a75a
GM
3128#ifdef WINDOWSNT
3129 /* The read-only attribute of the parent directory doesn't affect
3130 whether a file or directory can be created within it. Some day we
3131 should check ACLs though, which do affect this. */
d5db4077 3132 if (stat (SDATA (dir), &statbuf) < 0)
e3e8a75a
GM
3133 return Qnil;
3134 return (statbuf.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3135#else
d5db4077 3136 return (check_writable (!NILP (dir) ? (char *) SDATA (dir) : "")
f793dc6c 3137 ? Qt : Qnil);
e3e8a75a 3138#endif
f793dc6c
RS
3139}
3140\f
1f8653eb 3141DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
8c1a1077
PJ
3142 doc: /* Access file FILENAME, and get an error if that does not work.
3143The second argument STRING is used in the error message.
3144If there is no error, we return nil. */)
3145 (filename, string)
1f8653eb
RS
3146 Lisp_Object filename, string;
3147{
49475635 3148 Lisp_Object handler, encoded_filename, absname;
1f8653eb
RS
3149 int fd;
3150
b7826503 3151 CHECK_STRING (filename);
49475635
EZ
3152 absname = Fexpand_file_name (filename, Qnil);
3153
b7826503 3154 CHECK_STRING (string);
1f8653eb
RS
3155
3156 /* If the file name has special constructs in it,
3157 call the corresponding file handler. */
49475635 3158 handler = Ffind_file_name_handler (absname, Qaccess_file);
1f8653eb 3159 if (!NILP (handler))
49475635 3160 return call3 (handler, Qaccess_file, absname, string);
1f8653eb 3161
49475635 3162 encoded_filename = ENCODE_FILE (absname);
b1d1b865 3163
d5db4077 3164 fd = emacs_open (SDATA (encoded_filename), O_RDONLY, 0);
1f8653eb 3165 if (fd < 0)
d5db4077 3166 report_file_error (SDATA (string), Fcons (filename, Qnil));
68c45bf0 3167 emacs_close (fd);
1f8653eb
RS
3168
3169 return Qnil;
3170}
3171\f
570d7624 3172DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
8c1a1077
PJ
3173 doc: /* Return non-nil if file FILENAME is the name of a symbolic link.
3174The value is the name of the file to which it is linked.
3175Otherwise returns nil. */)
3176 (filename)
570d7624
JB
3177 Lisp_Object filename;
3178{
3179#ifdef S_IFLNK
3180 char *buf;
3181 int bufsize;
3182 int valsize;
3183 Lisp_Object val;
32f4334d 3184 Lisp_Object handler;
570d7624 3185
b7826503 3186 CHECK_STRING (filename);
570d7624
JB
3187 filename = Fexpand_file_name (filename, Qnil);
3188
32f4334d
RS
3189 /* If the file name has special constructs in it,
3190 call the corresponding file handler. */
49307295 3191 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
32f4334d
RS
3192 if (!NILP (handler))
3193 return call2 (handler, Qfile_symlink_p, filename);
3194
b1d1b865
RS
3195 filename = ENCODE_FILE (filename);
3196
81c3310d
GM
3197 bufsize = 50;
3198 buf = NULL;
3199 do
570d7624 3200 {
81c3310d
GM
3201 bufsize *= 2;
3202 buf = (char *) xrealloc (buf, bufsize);
570d7624 3203 bzero (buf, bufsize);
efdc16c9 3204
81c3310d 3205 errno = 0;
d5db4077 3206 valsize = readlink (SDATA (filename), buf, bufsize);
bcdd93b3
GM
3207 if (valsize == -1)
3208 {
81c3310d
GM
3209#ifdef ERANGE
3210 /* HP-UX reports ERANGE if buffer is too small. */
bcdd93b3
GM
3211 if (errno == ERANGE)
3212 valsize = bufsize;
3213 else
81c3310d 3214#endif
bcdd93b3
GM
3215 {
3216 xfree (buf);
3217 return Qnil;
3218 }
81c3310d 3219 }
570d7624 3220 }
81c3310d 3221 while (valsize >= bufsize);
efdc16c9 3222
570d7624 3223 val = make_string (buf, valsize);
69ac1891
GM
3224 if (buf[0] == '/' && index (buf, ':'))
3225 val = concat2 (build_string ("/:"), val);
9ac0d9e0 3226 xfree (buf);
cd913586
KH
3227 val = DECODE_FILE (val);
3228 return val;
570d7624
JB
3229#else /* not S_IFLNK */
3230 return Qnil;
3231#endif /* not S_IFLNK */
3232}
3233
570d7624 3234DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
8c1a1077
PJ
3235 doc: /* Return t if FILENAME names an existing directory.
3236Symbolic links to directories count as directories.
3237See `file-symlink-p' to distinguish symlinks. */)
3238 (filename)
570d7624
JB
3239 Lisp_Object filename;
3240{
199607e4 3241 register Lisp_Object absname;
570d7624 3242 struct stat st;
32f4334d 3243 Lisp_Object handler;
570d7624 3244
199607e4 3245 absname = expand_and_dir_to_file (filename, current_buffer->directory);
570d7624 3246
32f4334d
RS
3247 /* If the file name has special constructs in it,
3248 call the corresponding file handler. */
199607e4 3249 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
32f4334d 3250 if (!NILP (handler))
199607e4 3251 return call2 (handler, Qfile_directory_p, absname);
32f4334d 3252
b1d1b865
RS
3253 absname = ENCODE_FILE (absname);
3254
d5db4077 3255 if (stat (SDATA (absname), &st) < 0)
570d7624
JB
3256 return Qnil;
3257 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3258}
3259
b72dea2a 3260DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
e385ec41
RS
3261 doc: /* Return t if file FILENAME names a directory you can open.
3262For the value to be t, FILENAME must specify the name of a directory as a file,
3263and the directory must allow you to open files in it. In order to use a
8c1a1077
PJ
3264directory as a buffer's current directory, this predicate must return true.
3265A directory name spec may be given instead; then the value is t
3266if the directory so specified exists and really is a readable and
3267searchable directory. */)
3268 (filename)
b72dea2a
JB
3269 Lisp_Object filename;
3270{
32f4334d 3271 Lisp_Object handler;
1a04498e 3272 int tem;
d26859eb 3273 struct gcpro gcpro1;
32f4334d
RS
3274
3275 /* If the file name has special constructs in it,
3276 call the corresponding file handler. */
49307295 3277 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
32f4334d
RS
3278 if (!NILP (handler))
3279 return call2 (handler, Qfile_accessible_directory_p, filename);
3280
d26859eb 3281 GCPRO1 (filename);
1a04498e
KH
3282 tem = (NILP (Ffile_directory_p (filename))
3283 || NILP (Ffile_executable_p (filename)));
d26859eb 3284 UNGCPRO;
1a04498e 3285 return tem ? Qnil : Qt;
b72dea2a
JB
3286}
3287
f793dc6c 3288DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
8c1a1077
PJ
3289 doc: /* Return t if file FILENAME is the name of a regular file.
3290This is the sort of file that holds an ordinary stream of data bytes. */)
3291 (filename)
f793dc6c
RS
3292 Lisp_Object filename;
3293{
199607e4 3294 register Lisp_Object absname;
f793dc6c
RS
3295 struct stat st;
3296 Lisp_Object handler;
3297
199607e4 3298 absname = expand_and_dir_to_file (filename, current_buffer->directory);
f793dc6c
RS
3299
3300 /* If the file name has special constructs in it,
3301 call the corresponding file handler. */
199607e4 3302 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
f793dc6c 3303 if (!NILP (handler))
199607e4 3304 return call2 (handler, Qfile_regular_p, absname);
f793dc6c 3305
b1d1b865
RS
3306 absname = ENCODE_FILE (absname);
3307
c1c4693e
RS
3308#ifdef WINDOWSNT
3309 {
3310 int result;
3311 Lisp_Object tem = Vw32_get_true_file_attributes;
3312
3313 /* Tell stat to use expensive method to get accurate info. */
3314 Vw32_get_true_file_attributes = Qt;
d5db4077 3315 result = stat (SDATA (absname), &st);
c1c4693e
RS
3316 Vw32_get_true_file_attributes = tem;
3317
3318 if (result < 0)
3319 return Qnil;
3320 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3321 }
3322#else
d5db4077 3323 if (stat (SDATA (absname), &st) < 0)
f793dc6c
RS
3324 return Qnil;
3325 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
c1c4693e 3326#endif
f793dc6c
RS
3327}
3328\f
570d7624 3329DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
8c1a1077
PJ
3330 doc: /* Return mode bits of file named FILENAME, as an integer. */)
3331 (filename)
570d7624
JB
3332 Lisp_Object filename;
3333{
199607e4 3334 Lisp_Object absname;
570d7624 3335 struct stat st;
32f4334d 3336 Lisp_Object handler;
570d7624 3337
199607e4 3338 absname = expand_and_dir_to_file (filename, current_buffer->directory);
570d7624 3339
32f4334d
RS
3340 /* If the file name has special constructs in it,
3341 call the corresponding file handler. */
199607e4 3342 handler = Ffind_file_name_handler (absname, Qfile_modes);
32f4334d 3343 if (!NILP (handler))
199607e4 3344 return call2 (handler, Qfile_modes, absname);
32f4334d 3345
b1d1b865
RS
3346 absname = ENCODE_FILE (absname);
3347
d5db4077 3348 if (stat (SDATA (absname), &st) < 0)
570d7624 3349 return Qnil;
34ead71a 3350#if defined (MSDOS) && __DJGPP__ < 2
d5db4077 3351 if (check_executable (SDATA (absname)))
3be3c08e 3352 st.st_mode |= S_IEXEC;
34ead71a 3353#endif /* MSDOS && __DJGPP__ < 2 */
3ace87e3 3354
570d7624
JB
3355 return make_number (st.st_mode & 07777);
3356}
3357
3358DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
8c1a1077
PJ
3359 doc: /* Set mode bits of file named FILENAME to MODE (an integer).
3360Only the 12 low bits of MODE are used. */)
570d7624
JB
3361 (filename, mode)
3362 Lisp_Object filename, mode;
3363{
b1d1b865 3364 Lisp_Object absname, encoded_absname;
32f4334d 3365 Lisp_Object handler;
570d7624 3366
199607e4 3367 absname = Fexpand_file_name (filename, current_buffer->directory);
b7826503 3368 CHECK_NUMBER (mode);
570d7624 3369
32f4334d
RS
3370 /* If the file name has special constructs in it,
3371 call the corresponding file handler. */
199607e4 3372 handler = Ffind_file_name_handler (absname, Qset_file_modes);
32f4334d 3373 if (!NILP (handler))
199607e4 3374 return call3 (handler, Qset_file_modes, absname, mode);
32f4334d 3375
b1d1b865
RS
3376 encoded_absname = ENCODE_FILE (absname);
3377
d5db4077 3378 if (chmod (SDATA (encoded_absname), XINT (mode)) < 0)
199607e4 3379 report_file_error ("Doing chmod", Fcons (absname, Qnil));
570d7624
JB
3380
3381 return Qnil;
3382}
3383
c24e9a53 3384DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
8c1a1077
PJ
3385 doc: /* Set the file permission bits for newly created files.
3386The argument MODE should be an integer; only the low 9 bits are used.
3387This setting is inherited by subprocesses. */)
3388 (mode)
5f85ea58 3389 Lisp_Object mode;
36a8c287 3390{
b7826503 3391 CHECK_NUMBER (mode);
199607e4 3392
5f85ea58 3393 umask ((~ XINT (mode)) & 0777);
36a8c287
JB
3394
3395 return Qnil;
3396}
3397
c24e9a53 3398DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
8c1a1077
PJ
3399 doc: /* Return the default file protection for created files.
3400The value is an integer. */)
3401 ()
36a8c287 3402{
5f85ea58
RS
3403 int realmask;
3404 Lisp_Object value;
36a8c287 3405
5f85ea58
RS
3406 realmask = umask (0);
3407 umask (realmask);
36a8c287 3408
46283abe 3409 XSETINT (value, (~ realmask) & 0777);
5f85ea58 3410 return value;
36a8c287 3411}
5df5e07c 3412
f793dc6c 3413\f
5df5e07c
GM
3414#ifdef __NetBSD__
3415#define unix 42
3416#endif
85ffea93 3417
5df5e07c 3418#ifdef unix
85ffea93 3419DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
8c1a1077
PJ
3420 doc: /* Tell Unix to finish all pending disk updates. */)
3421 ()
85ffea93
RS
3422{
3423 sync ();
3424 return Qnil;
3425}
3426
3427#endif /* unix */
3428
570d7624 3429DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
8c1a1077
PJ
3430 doc: /* Return t if file FILE1 is newer than file FILE2.
3431If FILE1 does not exist, the answer is nil;
3432otherwise, if FILE2 does not exist, the answer is t. */)
3433 (file1, file2)
570d7624
JB
3434 Lisp_Object file1, file2;
3435{
199607e4 3436 Lisp_Object absname1, absname2;
570d7624
JB
3437 struct stat st;
3438 int mtime1;
32f4334d 3439 Lisp_Object handler;
09121adc 3440 struct gcpro gcpro1, gcpro2;
570d7624 3441
b7826503
PJ
3442 CHECK_STRING (file1);
3443 CHECK_STRING (file2);
570d7624 3444
199607e4
RS
3445 absname1 = Qnil;
3446 GCPRO2 (absname1, file2);
3447 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3448 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
09121adc 3449 UNGCPRO;
570d7624 3450
32f4334d
RS
3451 /* If the file name has special constructs in it,
3452 call the corresponding file handler. */
199607e4 3453 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
51cf6d37 3454 if (NILP (handler))
199607e4 3455 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
32f4334d 3456 if (!NILP (handler))
199607e4 3457 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
32f4334d 3458
b1d1b865
RS
3459 GCPRO2 (absname1, absname2);
3460 absname1 = ENCODE_FILE (absname1);
3461 absname2 = ENCODE_FILE (absname2);
3462 UNGCPRO;
3463
d5db4077 3464 if (stat (SDATA (absname1), &st) < 0)
570d7624
JB
3465 return Qnil;
3466
3467 mtime1 = st.st_mtime;
3468
d5db4077 3469 if (stat (SDATA (absname2), &st) < 0)
570d7624
JB
3470 return Qt;
3471
3472 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3473}
3474\f
5e570b75 3475#ifdef DOS_NT
4c3c22f3 3476Lisp_Object Qfind_buffer_file_type;
5e570b75 3477#endif /* DOS_NT */
4c3c22f3 3478
6fdaa9a0
KH
3479#ifndef READ_BUF_SIZE
3480#define READ_BUF_SIZE (64 << 10)
3481#endif
3482
98a7d268
KH
3483extern void adjust_markers_for_delete P_ ((int, int, int, int));
3484
3485/* This function is called after Lisp functions to decide a coding
3486 system are called, or when they cause an error. Before they are
3487 called, the current buffer is set unibyte and it contains only a
3488 newly inserted text (thus the buffer was empty before the
3489 insertion).
3490
3491 The functions may set markers, overlays, text properties, or even
3492 alter the buffer contents, change the current buffer.
3493
3494 Here, we reset all those changes by:
3495 o set back the current buffer.
3496 o move all markers and overlays to BEG.
3497 o remove all text properties.
3498 o set back the buffer multibyteness. */
f736ffbf
KH
3499
3500static Lisp_Object
98a7d268
KH
3501decide_coding_unwind (unwind_data)
3502 Lisp_Object unwind_data;
f736ffbf 3503{
98a7d268 3504 Lisp_Object multibyte, undo_list, buffer;
f736ffbf 3505
98a7d268
KH
3506 multibyte = XCAR (unwind_data);
3507 unwind_data = XCDR (unwind_data);
3508 undo_list = XCAR (unwind_data);
3509 buffer = XCDR (unwind_data);
3510
3511 if (current_buffer != XBUFFER (buffer))
3512 set_buffer_internal (XBUFFER (buffer));
3513 adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
3514 adjust_overlays_for_delete (BEG, Z - BEG);
3515 BUF_INTERVALS (current_buffer) = 0;
3516 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3517
3518 /* Now we are safe to change the buffer's multibyteness directly. */
3519 current_buffer->enable_multibyte_characters = multibyte;
3520 current_buffer->undo_list = undo_list;
f736ffbf
KH
3521
3522 return Qnil;
3523}
3524
55587f8a 3525
1b978129 3526/* Used to pass values from insert-file-contents to read_non_regular. */
55587f8a 3527
1b978129
GM
3528static int non_regular_fd;
3529static int non_regular_inserted;
3530static int non_regular_nbytes;
55587f8a 3531
55587f8a 3532
1b978129
GM
3533/* Read from a non-regular file.
3534 Read non_regular_trytry bytes max from non_regular_fd.
3535 Non_regular_inserted specifies where to put the read bytes.
3536 Value is the number of bytes read. */
55587f8a
GM
3537
3538static Lisp_Object
1b978129 3539read_non_regular ()
55587f8a 3540{
1b978129 3541 int nbytes;
efdc16c9 3542
1b978129
GM
3543 immediate_quit = 1;
3544 QUIT;
3545 nbytes = emacs_read (non_regular_fd,
28c3eb5a 3546 BEG_ADDR + PT_BYTE - BEG_BYTE + non_regular_inserted,
1b978129 3547 non_regular_nbytes);
1b978129
GM
3548 immediate_quit = 0;
3549 return make_number (nbytes);
3550}
55587f8a 3551
d0e2444e 3552
1b978129
GM
3553/* Condition-case handler used when reading from non-regular files
3554 in insert-file-contents. */
3555
3556static Lisp_Object
3557read_non_regular_quit ()
3558{
55587f8a
GM
3559 return Qnil;
3560}
3561
3562
570d7624 3563DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
8c1a1077
PJ
3564 1, 5, 0,
3565 doc: /* Insert contents of file FILENAME after point.
3566Returns list of absolute file name and number of bytes inserted.
3567If second argument VISIT is non-nil, the buffer's visited filename
3568and last save file modtime are set, and it is marked unmodified.
3569If visiting and the file does not exist, visiting is completed
3570before the error is signaled.
3571The optional third and fourth arguments BEG and END
3572specify what portion of the file to insert.
3573These arguments count bytes in the file, not characters in the buffer.
3574If VISIT is non-nil, BEG and END must be nil.
3575
3576If optional fifth argument REPLACE is non-nil,
3577it means replace the current buffer contents (in the accessible portion)
3578with the file contents. This is better than simply deleting and inserting
3579the whole thing because (1) it preserves some marker positions
3580and (2) it puts less data in the undo list.
3581When REPLACE is non-nil, the value is the number of characters actually read,
3582which is often less than the number of characters to be read.
3583
3584This does code conversion according to the value of
3585`coding-system-for-read' or `file-coding-system-alist',
3586and sets the variable `last-coding-system-used' to the coding system
3587actually used. */)
3588 (filename, visit, beg, end, replace)
3d0387c0 3589 Lisp_Object filename, visit, beg, end, replace;
570d7624
JB
3590{
3591 struct stat st;
3592 register int fd;
ec7adf26 3593 int inserted = 0;
570d7624 3594 register int how_much;
6fdaa9a0 3595 register int unprocessed;
331379bf 3596 int count = SPECPDL_INDEX ();
b1d1b865
RS
3597 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3598 Lisp_Object handler, val, insval, orig_filename;
d6a3cc15 3599 Lisp_Object p;
6bbd7a29 3600 int total = 0;
53c34c46 3601 int not_regular = 0;
feb9dc27 3602 unsigned char read_buf[READ_BUF_SIZE];
6fdaa9a0 3603 struct coding_system coding;
3dbcf3f6 3604 unsigned char buffer[1 << 14];
727a0b4a 3605 int replace_handled = 0;
ec7adf26 3606 int set_coding_system = 0;
f736ffbf 3607 int coding_system_decided = 0;
1b978129 3608 int read_quit = 0;
32f4334d 3609
95385625
RS
3610 if (current_buffer->base_buffer && ! NILP (visit))
3611 error ("Cannot do file visiting in an indirect buffer");
3612
3613 if (!NILP (current_buffer->read_only))
3614 Fbarf_if_buffer_read_only ();
3615
32f4334d 3616 val = Qnil;
d6a3cc15 3617 p = Qnil;
b1d1b865 3618 orig_filename = Qnil;
32f4334d 3619
b1d1b865 3620 GCPRO4 (filename, val, p, orig_filename);
570d7624 3621
b7826503 3622 CHECK_STRING (filename);
570d7624
JB
3623 filename = Fexpand_file_name (filename, Qnil);
3624
32f4334d
RS
3625 /* If the file name has special constructs in it,
3626 call the corresponding file handler. */
49307295 3627 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
32f4334d
RS
3628 if (!NILP (handler))
3629 {
3d0387c0
RS
3630 val = call6 (handler, Qinsert_file_contents, filename,
3631 visit, beg, end, replace);
03699b14
KR
3632 if (CONSP (val) && CONSP (XCDR (val)))
3633 inserted = XINT (XCAR (XCDR (val)));
32f4334d
RS
3634 goto handled;
3635 }
3636
b1d1b865
RS
3637 orig_filename = filename;
3638 filename = ENCODE_FILE (filename);
3639
570d7624
JB
3640 fd = -1;
3641
c1c4693e
RS
3642#ifdef WINDOWSNT
3643 {
3644 Lisp_Object tem = Vw32_get_true_file_attributes;
3645
3646 /* Tell stat to use expensive method to get accurate info. */
3647 Vw32_get_true_file_attributes = Qt;
d5db4077 3648 total = stat (SDATA (filename), &st);
c1c4693e
RS
3649 Vw32_get_true_file_attributes = tem;
3650 }
3651 if (total < 0)
3652#else
570d7624 3653#ifndef APOLLO
d5db4077 3654 if (stat (SDATA (filename), &st) < 0)
570d7624 3655#else
d5db4077 3656 if ((fd = emacs_open (SDATA (filename), O_RDONLY, 0)) < 0
570d7624
JB
3657 || fstat (fd, &st) < 0)
3658#endif /* not APOLLO */
c1c4693e 3659#endif /* WINDOWSNT */
570d7624 3660 {
68c45bf0 3661 if (fd >= 0) emacs_close (fd);
99bc28f4 3662 badopen:
265a9e55 3663 if (NILP (visit))
b1d1b865 3664 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
570d7624
JB
3665 st.st_mtime = -1;
3666 how_much = 0;
0de6b8f4 3667 if (!NILP (Vcoding_system_for_read))
22d92d6b 3668 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
570d7624
JB
3669 goto notfound;
3670 }
3671
99bc28f4 3672#ifdef S_IFREG
be53b411
JB
3673 /* This code will need to be changed in order to work on named
3674 pipes, and it's probably just not worth it. So we should at
3675 least signal an error. */
99bc28f4 3676 if (!S_ISREG (st.st_mode))
330bfe57 3677 {
d4b8687b
RS
3678 not_regular = 1;
3679
3680 if (! NILP (visit))
3681 goto notfound;
3682
3683 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
330bfe57
RS
3684 Fsignal (Qfile_error,
3685 Fcons (build_string ("not a regular file"),
b1d1b865 3686 Fcons (orig_filename, Qnil)));
330bfe57 3687 }
be53b411
JB
3688#endif
3689
99bc28f4 3690 if (fd < 0)
d5db4077 3691 if ((fd = emacs_open (SDATA (filename), O_RDONLY, 0)) < 0)
99bc28f4
KH
3692 goto badopen;
3693
3694 /* Replacement should preserve point as it preserves markers. */
3695 if (!NILP (replace))
3696 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3697
3698 record_unwind_protect (close_file_unwind, make_number (fd));
3699
570d7624 3700 /* Supposedly happens on VMS. */
11d300db
JR
3701 /* Can happen on any platform that uses long as type of off_t, but allows
3702 file sizes to exceed 2Gb. VMS is no longer officially supported, so
3703 give a message suitable for the latter case. */
d4b8687b 3704 if (! not_regular && st.st_size < 0)
11d300db 3705 error ("Maximum buffer size exceeded");
be53b411 3706
9c856db9
GM
3707 /* Prevent redisplay optimizations. */
3708 current_buffer->clip_changed = 1;
3709
9f57b6b4
KH
3710 if (!NILP (visit))
3711 {
3712 if (!NILP (beg) || !NILP (end))
3713 error ("Attempt to visit less than an entire file");
3714 if (BEG < Z && NILP (replace))
3715 error ("Cannot do file visiting in a non-empty buffer");
3716 }
7fded690
JB
3717
3718 if (!NILP (beg))
b7826503 3719 CHECK_NUMBER (beg);
7fded690 3720 else
2acfd7ae 3721 XSETFASTINT (beg, 0);
7fded690
JB
3722
3723 if (!NILP (end))
b7826503 3724 CHECK_NUMBER (end);
7fded690
JB
3725 else
3726 {
d4b8687b
RS
3727 if (! not_regular)
3728 {
3729 XSETINT (end, st.st_size);
68c45bf0
PE
3730
3731 /* Arithmetic overflow can occur if an Emacs integer cannot
3732 represent the file size, or if the calculations below
3733 overflow. The calculations below double the file size
3734 twice, so check that it can be multiplied by 4 safely. */
3735 if (XINT (end) != st.st_size
3736 || ((int) st.st_size * 4) / 4 != st.st_size)
d4b8687b 3737 error ("Maximum buffer size exceeded");
d21dd12d
GM
3738
3739 /* The file size returned from stat may be zero, but data
3740 may be readable nonetheless, for example when this is a
3741 file in the /proc filesystem. */
3742 if (st.st_size == 0)
3743 XSETINT (end, READ_BUF_SIZE);
d4b8687b 3744 }
7fded690
JB
3745 }
3746
f736ffbf
KH
3747 if (BEG < Z)
3748 {
3749 /* Decide the coding system to use for reading the file now
3750 because we can't use an optimized method for handling
3751 `coding:' tag if the current buffer is not empty. */
3752 Lisp_Object val;
3753 val = Qnil;
feb9dc27 3754
f736ffbf
KH
3755 if (!NILP (Vcoding_system_for_read))
3756 val = Vcoding_system_for_read;
3757 else if (! NILP (replace))
3758 /* In REPLACE mode, we can use the same coding system
3759 that was used to visit the file. */
3760 val = current_buffer->buffer_file_coding_system;
3761 else
3762 {
3763 /* Don't try looking inside a file for a coding system
3764 specification if it is not seekable. */
3765 if (! not_regular && ! NILP (Vset_auto_coding_function))
3766 {
3767 /* Find a coding system specified in the heading two
3768 lines or in the tailing several lines of the file.
3769 We assume that the 1K-byte and 3K-byte for heading
003a7eaa 3770 and tailing respectively are sufficient for this
f736ffbf 3771 purpose. */
07590973 3772 int nread;
f736ffbf
KH
3773
3774 if (st.st_size <= (1024 * 4))
68c45bf0 3775 nread = emacs_read (fd, read_buf, 1024 * 4);
f736ffbf
KH
3776 else
3777 {
68c45bf0 3778 nread = emacs_read (fd, read_buf, 1024);
f736ffbf
KH
3779 if (nread >= 0)
3780 {
3781 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3782 report_file_error ("Setting file position",
3783 Fcons (orig_filename, Qnil));
68c45bf0 3784 nread += emacs_read (fd, read_buf + nread, 1024 * 3);
f736ffbf
KH
3785 }
3786 }
feb9dc27 3787
f736ffbf
KH
3788 if (nread < 0)
3789 error ("IO error reading %s: %s",
d5db4077 3790 SDATA (orig_filename), emacs_strerror (errno));
f736ffbf
KH
3791 else if (nread > 0)
3792 {
f736ffbf 3793 struct buffer *prev = current_buffer;
685fc579
RS
3794 Lisp_Object buffer;
3795 struct buffer *buf;
f736ffbf
KH
3796
3797 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1d92afcd 3798
685fc579
RS
3799 buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
3800 buf = XBUFFER (buffer);
3801
3802 buf->directory = current_buffer->directory;
3803 buf->read_only = Qnil;
3804 buf->filename = Qnil;
3805 buf->undo_list = Qt;
3806 buf->overlays_before = Qnil;
3807 buf->overlays_after = Qnil;
efdc16c9 3808
685fc579
RS
3809 set_buffer_internal (buf);
3810 Ferase_buffer ();
3811 buf->enable_multibyte_characters = Qnil;
3812
f736ffbf
KH
3813 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3814 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
1255deb9
KH
3815 val = call2 (Vset_auto_coding_function,
3816 filename, make_number (nread));
f736ffbf 3817 set_buffer_internal (prev);
efdc16c9 3818
f736ffbf
KH
3819 /* Discard the unwind protect for recovering the
3820 current buffer. */
3821 specpdl_ptr--;
3822
3823 /* Rewind the file for the actual read done later. */
3824 if (lseek (fd, 0, 0) < 0)
3825 report_file_error ("Setting file position",
3826 Fcons (orig_filename, Qnil));
3827 }
3828 }
feb9dc27 3829
f736ffbf
KH
3830 if (NILP (val))
3831 {
3832 /* If we have not yet decided a coding system, check
3833 file-coding-system-alist. */
3834 Lisp_Object args[6], coding_systems;
3835
3836 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3837 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3838 coding_systems = Ffind_operation_coding_system (6, args);
3839 if (CONSP (coding_systems))
03699b14 3840 val = XCAR (coding_systems);
f736ffbf
KH
3841 }
3842 }
c9e82392 3843
f736ffbf 3844 setup_coding_system (Fcheck_coding_system (val), &coding);
f8569325
DL
3845 /* Ensure we set Vlast_coding_system_used. */
3846 set_coding_system = 1;
c8a6d68a 3847
237a6fd2
RS
3848 if (NILP (current_buffer->enable_multibyte_characters)
3849 && ! NILP (val))
3850 /* We must suppress all character code conversion except for
3851 end-of-line conversion. */
57515cfe 3852 setup_raw_text_coding_system (&coding);
54369368 3853
8c3b9441
KH
3854 coding.src_multibyte = 0;
3855 coding.dst_multibyte
3856 = !NILP (current_buffer->enable_multibyte_characters);
f736ffbf
KH
3857 coding_system_decided = 1;
3858 }
6cf71bf1 3859
3d0387c0
RS
3860 /* If requested, replace the accessible part of the buffer
3861 with the file contents. Avoid replacing text at the
3862 beginning or end of the buffer that matches the file contents;
3dbcf3f6
RS
3863 that preserves markers pointing to the unchanged parts.
3864
3865 Here we implement this feature in an optimized way
3866 for the case where code conversion is NOT needed.
3867 The following if-statement handles the case of conversion
727a0b4a
RS
3868 in a less optimal way.
3869
3870 If the code conversion is "automatic" then we try using this
3871 method and hope for the best.
3872 But if we discover the need for conversion, we give up on this method
3873 and let the following if-statement handle the replace job. */
3dbcf3f6 3874 if (!NILP (replace)
f736ffbf 3875 && BEGV < ZV
8c3b9441 3876 && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))
3d0387c0 3877 {
ec7adf26
RS
3878 /* same_at_start and same_at_end count bytes,
3879 because file access counts bytes
3880 and BEG and END count bytes. */
3881 int same_at_start = BEGV_BYTE;
3882 int same_at_end = ZV_BYTE;
9c28748f 3883 int overlap;
6fdaa9a0
KH
3884 /* There is still a possibility we will find the need to do code
3885 conversion. If that happens, we set this variable to 1 to
727a0b4a 3886 give up on handling REPLACE in the optimized way. */
6fdaa9a0 3887 int giveup_match_end = 0;
9c28748f 3888
4d2a0879
RS
3889 if (XINT (beg) != 0)
3890 {
3891 if (lseek (fd, XINT (beg), 0) < 0)
3892 report_file_error ("Setting file position",
b1d1b865 3893 Fcons (orig_filename, Qnil));
4d2a0879
RS
3894 }
3895
3d0387c0
RS
3896 immediate_quit = 1;
3897 QUIT;
3898 /* Count how many chars at the start of the file
3899 match the text at the beginning of the buffer. */
3900 while (1)
3901 {
3902 int nread, bufpos;
3903
68c45bf0 3904 nread = emacs_read (fd, buffer, sizeof buffer);
3d0387c0
RS
3905 if (nread < 0)
3906 error ("IO error reading %s: %s",
d5db4077 3907 SDATA (orig_filename), emacs_strerror (errno));
3d0387c0
RS
3908 else if (nread == 0)
3909 break;
6fdaa9a0 3910
0ef69138 3911 if (coding.type == coding_type_undecided)
727a0b4a 3912 detect_coding (&coding, buffer, nread);
8c3b9441 3913 if (coding.common_flags & CODING_REQUIRE_DECODING_MASK)
727a0b4a
RS
3914 /* We found that the file should be decoded somehow.
3915 Let's give up here. */
3916 {
3917 giveup_match_end = 1;
3918 break;
3919 }
3920
0ef69138 3921 if (coding.eol_type == CODING_EOL_UNDECIDED)
727a0b4a 3922 detect_eol (&coding, buffer, nread);
1b335d29 3923 if (coding.eol_type != CODING_EOL_UNDECIDED
70ec4328 3924 && coding.eol_type != CODING_EOL_LF)
727a0b4a
RS
3925 /* We found that the format of eol should be decoded.
3926 Let's give up here. */
3927 {
3928 giveup_match_end = 1;
3929 break;
3930 }
3931
3d0387c0 3932 bufpos = 0;
ec7adf26 3933 while (bufpos < nread && same_at_start < ZV_BYTE
6fdaa9a0 3934 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3d0387c0
RS
3935 same_at_start++, bufpos++;
3936 /* If we found a discrepancy, stop the scan.
8e6208c5 3937 Otherwise loop around and scan the next bufferful. */
3d0387c0
RS
3938 if (bufpos != nread)
3939 break;
3940 }
3941 immediate_quit = 0;
3942 /* If the file matches the buffer completely,
3943 there's no need to replace anything. */
ec7adf26 3944 if (same_at_start - BEGV_BYTE == XINT (end))
3d0387c0 3945 {
68c45bf0 3946 emacs_close (fd);
a1d2b64a 3947 specpdl_ptr--;
1051b3b3 3948 /* Truncate the buffer to the size of the file. */
7dae4502 3949 del_range_1 (same_at_start, same_at_end, 0, 0);
3d0387c0
RS
3950 goto handled;
3951 }
3952 immediate_quit = 1;
3953 QUIT;
3954 /* Count how many chars at the end of the file
6fdaa9a0
KH
3955 match the text at the end of the buffer. But, if we have
3956 already found that decoding is necessary, don't waste time. */
3957 while (!giveup_match_end)
3d0387c0
RS
3958 {
3959 int total_read, nread, bufpos, curpos, trial;
3960
3961 /* At what file position are we now scanning? */
ec7adf26 3962 curpos = XINT (end) - (ZV_BYTE - same_at_end);
fc81fa9e
KH
3963 /* If the entire file matches the buffer tail, stop the scan. */
3964 if (curpos == 0)
3965 break;
3d0387c0
RS
3966 /* How much can we scan in the next step? */
3967 trial = min (curpos, sizeof buffer);
3968 if (lseek (fd, curpos - trial, 0) < 0)
3969 report_file_error ("Setting file position",
b1d1b865 3970 Fcons (orig_filename, Qnil));
3d0387c0 3971
b02439c8 3972 total_read = nread = 0;
3d0387c0
RS
3973 while (total_read < trial)
3974 {
68c45bf0 3975 nread = emacs_read (fd, buffer + total_read, trial - total_read);
2bd2273e 3976 if (nread < 0)
3d0387c0 3977 error ("IO error reading %s: %s",
d5db4077 3978 SDATA (orig_filename), emacs_strerror (errno));
2bd2273e
GM
3979 else if (nread == 0)
3980 break;
3d0387c0
RS
3981 total_read += nread;
3982 }
efdc16c9 3983
8e6208c5 3984 /* Scan this bufferful from the end, comparing with
3d0387c0
RS
3985 the Emacs buffer. */
3986 bufpos = total_read;
efdc16c9 3987
3d0387c0
RS
3988 /* Compare with same_at_start to avoid counting some buffer text
3989 as matching both at the file's beginning and at the end. */
3990 while (bufpos > 0 && same_at_end > same_at_start
6fdaa9a0 3991 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3d0387c0 3992 same_at_end--, bufpos--;
727a0b4a 3993
3d0387c0 3994 /* If we found a discrepancy, stop the scan.
8e6208c5 3995 Otherwise loop around and scan the preceding bufferful. */
3d0387c0 3996 if (bufpos != 0)
727a0b4a
RS
3997 {
3998 /* If this discrepancy is because of code conversion,
3999 we cannot use this method; giveup and try the other. */
4000 if (same_at_end > same_at_start
4001 && FETCH_BYTE (same_at_end - 1) >= 0200
71312b68 4002 && ! NILP (current_buffer->enable_multibyte_characters)
c8a6d68a 4003 && (CODING_MAY_REQUIRE_DECODING (&coding)))
727a0b4a
RS
4004 giveup_match_end = 1;
4005 break;
4006 }
b02439c8
GM
4007
4008 if (nread == 0)
4009 break;
3d0387c0
RS
4010 }
4011 immediate_quit = 0;
9c28748f 4012
727a0b4a
RS
4013 if (! giveup_match_end)
4014 {
ec7adf26
RS
4015 int temp;
4016
727a0b4a 4017 /* We win! We can handle REPLACE the optimized way. */
9c28748f 4018
20f6783d
RS
4019 /* Extend the start of non-matching text area to multibyte
4020 character boundary. */
4021 if (! NILP (current_buffer->enable_multibyte_characters))
4022 while (same_at_start > BEGV_BYTE
4023 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4024 same_at_start--;
4025
4026 /* Extend the end of non-matching text area to multibyte
71312b68
RS
4027 character boundary. */
4028 if (! NILP (current_buffer->enable_multibyte_characters))
ec7adf26
RS
4029 while (same_at_end < ZV_BYTE
4030 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
71312b68
RS
4031 same_at_end++;
4032
727a0b4a 4033 /* Don't try to reuse the same piece of text twice. */
ec7adf26
RS
4034 overlap = (same_at_start - BEGV_BYTE
4035 - (same_at_end + st.st_size - ZV));
727a0b4a
RS
4036 if (overlap > 0)
4037 same_at_end += overlap;
9c28748f 4038
727a0b4a 4039 /* Arrange to read only the nonmatching middle part of the file. */
ec7adf26
RS
4040 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
4041 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3dbcf3f6 4042
ec7adf26 4043 del_range_byte (same_at_start, same_at_end, 0);
727a0b4a 4044 /* Insert from the file at the proper position. */
ec7adf26
RS
4045 temp = BYTE_TO_CHAR (same_at_start);
4046 SET_PT_BOTH (temp, same_at_start);
727a0b4a
RS
4047
4048 /* If display currently starts at beginning of line,
4049 keep it that way. */
4050 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4051 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4052
4053 replace_handled = 1;
4054 }
3dbcf3f6
RS
4055 }
4056
4057 /* If requested, replace the accessible part of the buffer
4058 with the file contents. Avoid replacing text at the
4059 beginning or end of the buffer that matches the file contents;
4060 that preserves markers pointing to the unchanged parts.
4061
4062 Here we implement this feature for the case where code conversion
4063 is needed, in a simple way that needs a lot of memory.
4064 The preceding if-statement handles the case of no conversion
4065 in a more optimized way. */
f736ffbf 4066 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
3dbcf3f6 4067 {
ec7adf26
RS
4068 int same_at_start = BEGV_BYTE;
4069 int same_at_end = ZV_BYTE;
3dbcf3f6
RS
4070 int overlap;
4071 int bufpos;
4072 /* Make sure that the gap is large enough. */
4073 int bufsize = 2 * st.st_size;
b00ca0d7 4074 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
ec7adf26 4075 int temp;
3dbcf3f6
RS
4076
4077 /* First read the whole file, performing code conversion into
4078 CONVERSION_BUFFER. */
4079
727a0b4a
RS
4080 if (lseek (fd, XINT (beg), 0) < 0)
4081 {
68cfd853 4082 xfree (conversion_buffer);
727a0b4a 4083 report_file_error ("Setting file position",
b1d1b865 4084 Fcons (orig_filename, Qnil));
727a0b4a
RS
4085 }
4086
3dbcf3f6
RS
4087 total = st.st_size; /* Total bytes in the file. */
4088 how_much = 0; /* Bytes read from file so far. */
4089 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4090 unprocessed = 0; /* Bytes not processed in previous loop. */
4091
4092 while (how_much < total)
4093 {
4094 /* try is reserved in some compilers (Microsoft C) */
4095 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
cadf50ff 4096 unsigned char *destination = read_buf + unprocessed;
3dbcf3f6
RS
4097 int this;
4098
4099 /* Allow quitting out of the actual I/O. */
4100 immediate_quit = 1;
4101 QUIT;
68c45bf0 4102 this = emacs_read (fd, destination, trytry);
3dbcf3f6
RS
4103 immediate_quit = 0;
4104
4105 if (this < 0 || this + unprocessed == 0)
4106 {
4107 how_much = this;
4108 break;
4109 }
4110
4111 how_much += this;
4112
c8a6d68a 4113 if (CODING_MAY_REQUIRE_DECODING (&coding))
3dbcf3f6 4114 {
c8a6d68a 4115 int require, result;
3dbcf3f6
RS
4116
4117 this += unprocessed;
4118
4119 /* If we are using more space than estimated,
4120 make CONVERSION_BUFFER bigger. */
4121 require = decoding_buffer_size (&coding, this);
4122 if (inserted + require + 2 * (total - how_much) > bufsize)
4123 {
4124 bufsize = inserted + require + 2 * (total - how_much);
92cf1086 4125 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
3dbcf3f6
RS
4126 }
4127
4128 /* Convert this batch with results in CONVERSION_BUFFER. */
4129 if (how_much >= total) /* This is the last block. */
c8a6d68a 4130 coding.mode |= CODING_MODE_LAST_BLOCK;
1ddb09f5
GM
4131 if (coding.composing != COMPOSITION_DISABLED)
4132 coding_allocate_composition_data (&coding, BEGV);
c8a6d68a
KH
4133 result = decode_coding (&coding, read_buf,
4134 conversion_buffer + inserted,
4135 this, bufsize - inserted);
3dbcf3f6
RS
4136
4137 /* Save for next iteration whatever we didn't convert. */
c8a6d68a
KH
4138 unprocessed = this - coding.consumed;
4139 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
8c3b9441
KH
4140 if (!NILP (current_buffer->enable_multibyte_characters))
4141 this = coding.produced;
4142 else
4143 this = str_as_unibyte (conversion_buffer + inserted,
4144 coding.produced);
3dbcf3f6
RS
4145 }
4146
4147 inserted += this;
4148 }
4149
c8a6d68a 4150 /* At this point, INSERTED is how many characters (i.e. bytes)
3dbcf3f6
RS
4151 are present in CONVERSION_BUFFER.
4152 HOW_MUCH should equal TOTAL,
4153 or should be <= 0 if we couldn't read the file. */
4154
4155 if (how_much < 0)
4156 {
a36837e4 4157 xfree (conversion_buffer);
3dbcf3f6
RS
4158
4159 if (how_much == -1)
4160 error ("IO error reading %s: %s",
d5db4077 4161 SDATA (orig_filename), emacs_strerror (errno));
3dbcf3f6
RS
4162 else if (how_much == -2)
4163 error ("maximum buffer size exceeded");
4164 }
4165
4166 /* Compare the beginning of the converted file
4167 with the buffer text. */
4168
4169 bufpos = 0;
4170 while (bufpos < inserted && same_at_start < same_at_end
4171 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
4172 same_at_start++, bufpos++;
4173
4174 /* If the file matches the buffer completely,
4175 there's no need to replace anything. */
4176
4177 if (bufpos == inserted)
4178 {
a36837e4 4179 xfree (conversion_buffer);
68c45bf0 4180 emacs_close (fd);
3dbcf3f6
RS
4181 specpdl_ptr--;
4182 /* Truncate the buffer to the size of the file. */
427f5aab
KH
4183 del_range_byte (same_at_start, same_at_end, 0);
4184 inserted = 0;
3dbcf3f6
RS
4185 goto handled;
4186 }
4187
20f6783d
RS
4188 /* Extend the start of non-matching text area to multibyte
4189 character boundary. */
4190 if (! NILP (current_buffer->enable_multibyte_characters))
4191 while (same_at_start > BEGV_BYTE
4192 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4193 same_at_start--;
4194
3dbcf3f6
RS
4195 /* Scan this bufferful from the end, comparing with
4196 the Emacs buffer. */
4197 bufpos = inserted;
4198
4199 /* Compare with same_at_start to avoid counting some buffer text
4200 as matching both at the file's beginning and at the end. */
4201 while (bufpos > 0 && same_at_end > same_at_start
4202 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
4203 same_at_end--, bufpos--;
4204
20f6783d
RS
4205 /* Extend the end of non-matching text area to multibyte
4206 character boundary. */
4207 if (! NILP (current_buffer->enable_multibyte_characters))
4208 while (same_at_end < ZV_BYTE
4209 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
4210 same_at_end++;
4211
3dbcf3f6 4212 /* Don't try to reuse the same piece of text twice. */
ec7adf26 4213 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3dbcf3f6
RS
4214 if (overlap > 0)
4215 same_at_end += overlap;
4216
727a0b4a
RS
4217 /* If display currently starts at beginning of line,
4218 keep it that way. */
4219 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4220 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4221
3dbcf3f6
RS
4222 /* Replace the chars that we need to replace,
4223 and update INSERTED to equal the number of bytes
4224 we are taking from the file. */
ec7adf26 4225 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
427f5aab 4226
643c73b9 4227 if (same_at_end != same_at_start)
427f5aab
KH
4228 {
4229 del_range_byte (same_at_start, same_at_end, 0);
4230 temp = GPT;
4231 same_at_start = GPT_BYTE;
4232 }
643c73b9
RS
4233 else
4234 {
643c73b9 4235 temp = BYTE_TO_CHAR (same_at_start);
643c73b9 4236 }
427f5aab
KH
4237 /* Insert from the file at the proper position. */
4238 SET_PT_BOTH (temp, same_at_start);
ec7adf26
RS
4239 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,
4240 0, 0, 0);
1ddb09f5
GM
4241 if (coding.cmp_data && coding.cmp_data->used)
4242 coding_restore_composition (&coding, Fcurrent_buffer ());
4243 coding_free_composition_data (&coding);
efdc16c9 4244
427f5aab
KH
4245 /* Set `inserted' to the number of inserted characters. */
4246 inserted = PT - temp;
3dbcf3f6 4247
93184560 4248 xfree (conversion_buffer);
68c45bf0 4249 emacs_close (fd);
3dbcf3f6
RS
4250 specpdl_ptr--;
4251
3dbcf3f6 4252 goto handled;
3d0387c0
RS
4253 }
4254
d4b8687b
RS
4255 if (! not_regular)
4256 {
4257 register Lisp_Object temp;
7fded690 4258
d4b8687b 4259 total = XINT (end) - XINT (beg);
570d7624 4260
d4b8687b
RS
4261 /* Make sure point-max won't overflow after this insertion. */
4262 XSETINT (temp, total);
4263 if (total != XINT (temp))
4264 error ("Maximum buffer size exceeded");
4265 }
4266 else
4267 /* For a special file, all we can do is guess. */
4268 total = READ_BUF_SIZE;
570d7624 4269
57d8d468 4270 if (NILP (visit) && total > 0)
6c478ee2 4271 prepare_to_modify_buffer (PT, PT, NULL);
570d7624 4272
7fe52289 4273 move_gap (PT);
7fded690
JB
4274 if (GAP_SIZE < total)
4275 make_gap (total - GAP_SIZE);
4276
a1d2b64a 4277 if (XINT (beg) != 0 || !NILP (replace))
7fded690
JB
4278 {
4279 if (lseek (fd, XINT (beg), 0) < 0)
b1d1b865
RS
4280 report_file_error ("Setting file position",
4281 Fcons (orig_filename, Qnil));
7fded690
JB
4282 }
4283
6fdaa9a0 4284 /* In the following loop, HOW_MUCH contains the total bytes read so
c8a6d68a
KH
4285 far for a regular file, and not changed for a special file. But,
4286 before exiting the loop, it is set to a negative value if I/O
4287 error occurs. */
a1d2b64a 4288 how_much = 0;
efdc16c9 4289
6fdaa9a0
KH
4290 /* Total bytes inserted. */
4291 inserted = 0;
efdc16c9 4292
c8a6d68a
KH
4293 /* Here, we don't do code conversion in the loop. It is done by
4294 code_convert_region after all data are read into the buffer. */
1b978129
GM
4295 {
4296 int gap_size = GAP_SIZE;
efdc16c9 4297
1b978129
GM
4298 while (how_much < total)
4299 {
5e570b75 4300 /* try is reserved in some compilers (Microsoft C) */
1b978129
GM
4301 int trytry = min (total - how_much, READ_BUF_SIZE);
4302 int this;
570d7624 4303
1b978129
GM
4304 if (not_regular)
4305 {
4306 Lisp_Object val;
570d7624 4307
1b978129
GM
4308 /* Maybe make more room. */
4309 if (gap_size < trytry)
4310 {
4311 make_gap (total - gap_size);
4312 gap_size = GAP_SIZE;
4313 }
4314
4315 /* Read from the file, capturing `quit'. When an
4316 error occurs, end the loop, and arrange for a quit
4317 to be signaled after decoding the text we read. */
4318 non_regular_fd = fd;
4319 non_regular_inserted = inserted;
4320 non_regular_nbytes = trytry;
4321 val = internal_condition_case_1 (read_non_regular, Qnil, Qerror,
4322 read_non_regular_quit);
4323 if (NILP (val))
4324 {
4325 read_quit = 1;
4326 break;
4327 }
4328
4329 this = XINT (val);
4330 }
4331 else
4332 {
4333 /* Allow quitting out of the actual I/O. We don't make text
4334 part of the buffer until all the reading is done, so a C-g
4335 here doesn't do any harm. */
4336 immediate_quit = 1;
4337 QUIT;
28c3eb5a 4338 this = emacs_read (fd, BEG_ADDR + PT_BYTE - BEG_BYTE + inserted, trytry);
1b978129
GM
4339 immediate_quit = 0;
4340 }
efdc16c9 4341
1b978129
GM
4342 if (this <= 0)
4343 {
4344 how_much = this;
4345 break;
4346 }
4347
4348 gap_size -= this;
4349
4350 /* For a regular file, where TOTAL is the real size,
4351 count HOW_MUCH to compare with it.
4352 For a special file, where TOTAL is just a buffer size,
4353 so don't bother counting in HOW_MUCH.
4354 (INSERTED is where we count the number of characters inserted.) */
4355 if (! not_regular)
4356 how_much += this;
4357 inserted += this;
4358 }
4359 }
4360
4361 /* Make the text read part of the buffer. */
4362 GAP_SIZE -= inserted;
4363 GPT += inserted;
4364 GPT_BYTE += inserted;
4365 ZV += inserted;
4366 ZV_BYTE += inserted;
4367 Z += inserted;
4368 Z_BYTE += inserted;
6fdaa9a0 4369
c8a6d68a
KH
4370 if (GAP_SIZE > 0)
4371 /* Put an anchor to ensure multi-byte form ends at gap. */
4372 *GPT_ADDR = 0;
d4b8687b 4373
68c45bf0 4374 emacs_close (fd);
6fdaa9a0 4375
c8a6d68a
KH
4376 /* Discard the unwind protect for closing the file. */
4377 specpdl_ptr--;
6fdaa9a0 4378
c8a6d68a
KH
4379 if (how_much < 0)
4380 error ("IO error reading %s: %s",
d5db4077 4381 SDATA (orig_filename), emacs_strerror (errno));
ec7adf26 4382
f8569325
DL
4383 notfound:
4384
2df42e09 4385 if (! coding_system_decided)
c8a6d68a 4386 {
2df42e09 4387 /* The coding system is not yet decided. Decide it by an
dfe35e7b
RS
4388 optimized method for handling `coding:' tag.
4389
4390 Note that we can get here only if the buffer was empty
4391 before the insertion. */
2df42e09
KH
4392 Lisp_Object val;
4393 val = Qnil;
f736ffbf 4394
2df42e09
KH
4395 if (!NILP (Vcoding_system_for_read))
4396 val = Vcoding_system_for_read;
4397 else
4398 {
98a7d268
KH
4399 /* Since we are sure that the current buffer was empty
4400 before the insertion, we can toggle
4401 enable-multibyte-characters directly here without taking
4402 care of marker adjustment and byte combining problem. By
4403 this way, we can run Lisp program safely before decoding
4404 the inserted text. */
4405 Lisp_Object unwind_data;
aed13378 4406 int count = SPECPDL_INDEX ();
2df42e09 4407
98a7d268
KH
4408 unwind_data = Fcons (current_buffer->enable_multibyte_characters,
4409 Fcons (current_buffer->undo_list,
4410 Fcurrent_buffer ()));
2df42e09 4411 current_buffer->enable_multibyte_characters = Qnil;
98a7d268
KH
4412 current_buffer->undo_list = Qt;
4413 record_unwind_protect (decide_coding_unwind, unwind_data);
4414
4415 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4416 {
1255deb9
KH
4417 val = call2 (Vset_auto_coding_function,
4418 filename, make_number (inserted));
2df42e09 4419 }
f736ffbf 4420
2df42e09
KH
4421 if (NILP (val))
4422 {
4423 /* If the coding system is not yet decided, check
4424 file-coding-system-alist. */
4425 Lisp_Object args[6], coding_systems;
f736ffbf 4426
2df42e09
KH
4427 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4428 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4429 coding_systems = Ffind_operation_coding_system (6, args);
4430 if (CONSP (coding_systems))
03699b14 4431 val = XCAR (coding_systems);
f736ffbf 4432 }
98a7d268
KH
4433
4434 unbind_to (count, Qnil);
4435 inserted = Z_BYTE - BEG_BYTE;
2df42e09 4436 }
f736ffbf 4437
2df42e09
KH
4438 /* The following kludgy code is to avoid some compiler bug.
4439 We can't simply do
4440 setup_coding_system (val, &coding);
4441 on some system. */
4442 {
4443 struct coding_system temp_coding;
4444 setup_coding_system (val, &temp_coding);
4445 bcopy (&temp_coding, &coding, sizeof coding);
4446 }
f8569325
DL
4447 /* Ensure we set Vlast_coding_system_used. */
4448 set_coding_system = 1;
f736ffbf 4449
237a6fd2
RS
4450 if (NILP (current_buffer->enable_multibyte_characters)
4451 && ! NILP (val))
4452 /* We must suppress all character code conversion except for
2df42e09
KH
4453 end-of-line conversion. */
4454 setup_raw_text_coding_system (&coding);
6db43875
KH
4455 coding.src_multibyte = 0;
4456 coding.dst_multibyte
4457 = !NILP (current_buffer->enable_multibyte_characters);
2df42e09 4458 }
f736ffbf 4459
8c3b9441 4460 if (!NILP (visit)
24766480
GM
4461 /* Can't do this if part of the buffer might be preserved. */
4462 && NILP (replace)
8c3b9441
KH
4463 && (coding.type == coding_type_no_conversion
4464 || coding.type == coding_type_raw_text))
4465 {
24766480
GM
4466 /* Visiting a file with these coding system makes the buffer
4467 unibyte. */
4468 current_buffer->enable_multibyte_characters = Qnil;
e1249666 4469 coding.dst_multibyte = 0;
8c3b9441
KH
4470 }
4471
c91beee2 4472 if (inserted > 0 || coding.type == coding_type_ccl)
2df42e09 4473 {
c8a6d68a 4474 if (CODING_MAY_REQUIRE_DECODING (&coding))
64e0ae2a
KH
4475 {
4476 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4477 &coding, 0, 0);
8c3b9441 4478 inserted = coding.produced_char;
f8198e19 4479 }
e9cea947
AS
4480 else
4481 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
8c3b9441 4482 inserted);
2df42e09 4483 }
570d7624 4484
04e6f79c 4485#ifdef DOS_NT
2df42e09
KH
4486 /* Use the conversion type to determine buffer-file-type
4487 (find-buffer-file-type is now used to help determine the
4488 conversion). */
efdc16c9 4489 if ((coding.eol_type == CODING_EOL_UNDECIDED
2df42e09
KH
4490 || coding.eol_type == CODING_EOL_LF)
4491 && ! CODING_REQUIRE_DECODING (&coding))
4492 current_buffer->buffer_file_type = Qt;
4493 else
4494 current_buffer->buffer_file_type = Qnil;
04e6f79c 4495#endif
570d7624 4496
32f4334d 4497 handled:
570d7624 4498
265a9e55 4499 if (!NILP (visit))
570d7624 4500 {
cfadd376
RS
4501 if (!EQ (current_buffer->undo_list, Qt))
4502 current_buffer->undo_list = Qnil;
570d7624 4503#ifdef APOLLO
d5db4077 4504 stat (SDATA (filename), &st);
570d7624 4505#endif
62bcf009 4506
a7e82472
RS
4507 if (NILP (handler))
4508 {
4509 current_buffer->modtime = st.st_mtime;
b1d1b865 4510 current_buffer->filename = orig_filename;
a7e82472 4511 }
62bcf009 4512
95385625 4513 SAVE_MODIFF = MODIFF;
570d7624 4514 current_buffer->auto_save_modified = MODIFF;
2acfd7ae 4515 XSETFASTINT (current_buffer->save_length, Z - BEG);
570d7624 4516#ifdef CLASH_DETECTION
32f4334d
RS
4517 if (NILP (handler))
4518 {
f471f4c2
RS
4519 if (!NILP (current_buffer->file_truename))
4520 unlock_file (current_buffer->file_truename);
32f4334d
RS
4521 unlock_file (filename);
4522 }
570d7624 4523#endif /* CLASH_DETECTION */
330bfe57
RS
4524 if (not_regular)
4525 Fsignal (Qfile_error,
4526 Fcons (build_string ("not a regular file"),
b1d1b865 4527 Fcons (orig_filename, Qnil)));
570d7624
JB
4528 }
4529
0d420e88 4530 /* Decode file format */
c8a6d68a 4531 if (inserted > 0)
0d420e88 4532 {
ed8e506f 4533 int empty_undo_list_p = 0;
efdc16c9 4534
ed8e506f
GM
4535 /* If we're anyway going to discard undo information, don't
4536 record it in the first place. The buffer's undo list at this
4537 point is either nil or t when visiting a file. */
4538 if (!NILP (visit))
4539 {
4540 empty_undo_list_p = NILP (current_buffer->undo_list);
4541 current_buffer->undo_list = Qt;
4542 }
efdc16c9 4543
199607e4 4544 insval = call3 (Qformat_decode,
c8a6d68a 4545 Qnil, make_number (inserted), visit);
b7826503 4546 CHECK_NUMBER (insval);
c8a6d68a 4547 inserted = XFASTINT (insval);
efdc16c9 4548
ed8e506f
GM
4549 if (!NILP (visit))
4550 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
0d420e88
BG
4551 }
4552
ce51c54c
KH
4553 if (set_coding_system)
4554 Vlast_coding_system_used = coding.symbol;
4555
0342d8c5
RS
4556 /* Call after-change hooks for the inserted text, aside from the case
4557 of normal visiting (not with REPLACE), which is done in a new buffer
4558 "before" the buffer is changed. */
c8a6d68a 4559 if (inserted > 0 && total > 0
0342d8c5 4560 && (NILP (visit) || !NILP (replace)))
ce51c54c
KH
4561 {
4562 signal_after_change (PT, 0, inserted);
4563 update_compositions (PT, PT, CHECK_BORDER);
4564 }
b56567b5 4565
f8569325 4566 p = Vafter_insert_file_functions;
28c3eb5a 4567 while (CONSP (p))
d6a3cc15 4568 {
28c3eb5a 4569 insval = call1 (XCAR (p), make_number (inserted));
f8569325 4570 if (!NILP (insval))
d6a3cc15 4571 {
b7826503 4572 CHECK_NUMBER (insval);
f8569325 4573 inserted = XFASTINT (insval);
d6a3cc15 4574 }
f8569325 4575 QUIT;
28c3eb5a 4576 p = XCDR (p);
f8569325
DL
4577 }
4578
4579 if (!NILP (visit)
4580 && current_buffer->modtime == -1)
4581 {
4582 /* If visiting nonexistent file, return nil. */
4583 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
d6a3cc15
RS
4584 }
4585
1b978129
GM
4586 if (read_quit)
4587 Fsignal (Qquit, Qnil);
4588
ec7adf26 4589 /* ??? Retval needs to be dealt with in all cases consistently. */
a1d2b64a 4590 if (NILP (val))
b1d1b865 4591 val = Fcons (orig_filename,
a1d2b64a
RS
4592 Fcons (make_number (inserted),
4593 Qnil));
4594
4595 RETURN_UNGCPRO (unbind_to (count, val));
570d7624 4596}
7fded690 4597\f
236a12f2
SM
4598static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
4599static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
4600 Lisp_Object, Lisp_Object));
d6a3cc15 4601
6fc6f94b 4602/* If build_annotations switched buffers, switch back to BUF.
6fdaa9a0
KH
4603 Kill the temporary buffer that was selected in the meantime.
4604
4605 Since this kill only the last temporary buffer, some buffers remain
4606 not killed if build_annotations switched buffers more than once.
4607 -- K.Handa */
6fc6f94b 4608
199607e4 4609static Lisp_Object
6fc6f94b
RS
4610build_annotations_unwind (buf)
4611 Lisp_Object buf;
4612{
4613 Lisp_Object tembuf;
4614
4615 if (XBUFFER (buf) == current_buffer)
4616 return Qnil;
4617 tembuf = Fcurrent_buffer ();
4618 Fset_buffer (buf);
4619 Fkill_buffer (tembuf);
4620 return Qnil;
4621}
4622
7c82a4a9
SM
4623/* Decide the coding-system to encode the data with. */
4624
4625void
4626choose_write_coding_system (start, end, filename,
4627 append, visit, lockname, coding)
4628 Lisp_Object start, end, filename, append, visit, lockname;
4629 struct coding_system *coding;
4630{
4631 Lisp_Object val;
4632
4633 if (auto_saving)
4634 val = Qnil;
4635 else if (!NILP (Vcoding_system_for_write))
42b01e1e
KH
4636 {
4637 val = Vcoding_system_for_write;
4638 if (coding_system_require_warning
4639 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4640 /* Confirm that VAL can surely encode the current region. */
4641 val = call5 (Vselect_safe_coding_system_function,
4642 start, end, Fcons (Qt, Fcons (val, Qnil)),
4643 Qnil, filename);
4644 }
7c82a4a9
SM
4645 else
4646 {
4647 /* If the variable `buffer-file-coding-system' is set locally,
4648 it means that the file was read with some kind of code
4649 conversion or the variable is explicitly set by users. We
4650 had better write it out with the same coding system even if
4651 `enable-multibyte-characters' is nil.
4652
4653 If it is not set locally, we anyway have to convert EOL
4654 format if the default value of `buffer-file-coding-system'
4655 tells that it is not Unix-like (LF only) format. */
4656 int using_default_coding = 0;
4657 int force_raw_text = 0;
4658
4659 val = current_buffer->buffer_file_coding_system;
4660 if (NILP (val)
4661 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4662 {
4663 val = Qnil;
4664 if (NILP (current_buffer->enable_multibyte_characters))
4665 force_raw_text = 1;
4666 }
efdc16c9 4667
7c82a4a9
SM
4668 if (NILP (val))
4669 {
4670 /* Check file-coding-system-alist. */
4671 Lisp_Object args[7], coding_systems;
4672
4673 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4674 args[3] = filename; args[4] = append; args[5] = visit;
4675 args[6] = lockname;
4676 coding_systems = Ffind_operation_coding_system (7, args);
4677 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4678 val = XCDR (coding_systems);
4679 }
4680
4681 if (NILP (val)
4682 && !NILP (current_buffer->buffer_file_coding_system))
4683 {
4684 /* If we still have not decided a coding system, use the
4685 default value of buffer-file-coding-system. */
4686 val = current_buffer->buffer_file_coding_system;
4687 using_default_coding = 1;
4688 }
efdc16c9 4689
7c82a4a9
SM
4690 if (!force_raw_text
4691 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4692 /* Confirm that VAL can surely encode the current region. */
905a4276
PJ
4693 val = call5 (Vselect_safe_coding_system_function,
4694 start, end, val, Qnil, filename);
7c82a4a9
SM
4695
4696 setup_coding_system (Fcheck_coding_system (val), coding);
4697 if (coding->eol_type == CODING_EOL_UNDECIDED
4698 && !using_default_coding)
4699 {
4700 if (! EQ (default_buffer_file_coding.symbol,
4701 buffer_defaults.buffer_file_coding_system))
4702 setup_coding_system (buffer_defaults.buffer_file_coding_system,
4703 &default_buffer_file_coding);
4704 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)
4705 {
4706 Lisp_Object subsidiaries;
4707
4708 coding->eol_type = default_buffer_file_coding.eol_type;
4709 subsidiaries = Fget (coding->symbol, Qeol_type);
4710 if (VECTORP (subsidiaries)
4711 && XVECTOR (subsidiaries)->size == 3)
4712 coding->symbol
4713 = XVECTOR (subsidiaries)->contents[coding->eol_type];
4714 }
4715 }
4716
4717 if (force_raw_text)
4718 setup_raw_text_coding_system (coding);
4719 goto done_setup_coding;
4720 }
4721
4722 setup_coding_system (Fcheck_coding_system (val), coding);
4723
4724 done_setup_coding:
4725 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4726 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4727}
4728
de1d0127 4729DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
8c1a1077
PJ
4730 "r\nFWrite region to file: \ni\ni\ni\np",
4731 doc: /* Write current region into specified file.
c2efea25
RS
4732When called from a program, requires three arguments:
4733START, END and FILENAME. START and END are normally buffer positions
4734specifying the part of the buffer to write.
4735If START is nil, that means to use the entire buffer contents.
4736If START is a string, then output that string to the file
4737instead of any buffer contents; END is ignored.
4738
8c1a1077
PJ
4739Optional fourth argument APPEND if non-nil means
4740 append to existing file contents (if any). If it is an integer,
4741 seek to that offset in the file before writing.
4742Optional fifth argument VISIT if t means
4743 set the last-save-file-modtime of buffer to this file's modtime
4744 and mark buffer not modified.
4745If VISIT is a string, it is a second file name;
4746 the output goes to FILENAME, but the buffer is marked as visiting VISIT.
4747 VISIT is also the file name to lock and unlock for clash detection.
4748If VISIT is neither t nor nil nor a string,
5f4e6aa9 4749 that means do not display the \"Wrote file\" message.
8c1a1077
PJ
4750The optional sixth arg LOCKNAME, if non-nil, specifies the name to
4751 use for locking and unlocking, overriding FILENAME and VISIT.
4752The optional seventh arg MUSTBENEW, if non-nil, insists on a check
4753 for an existing file with the same name. If MUSTBENEW is `excl',
4754 that means to get an error if the file already exists; never overwrite.
4755 If MUSTBENEW is neither nil nor `excl', that means ask for
4756 confirmation before overwriting, but do go ahead and overwrite the file
4757 if the user confirms.
8c1a1077
PJ
4758
4759This does code conversion according to the value of
4760`coding-system-for-write', `buffer-file-coding-system', or
4761`file-coding-system-alist', and sets the variable
4762`last-coding-system-used' to the coding system actually used. */)
4763 (start, end, filename, append, visit, lockname, mustbenew)
f7b4065f 4764 Lisp_Object start, end, filename, append, visit, lockname, mustbenew;
570d7624
JB
4765{
4766 register int desc;
4767 int failure;
6bbd7a29 4768 int save_errno = 0;
19290c65 4769 const unsigned char *fn;
570d7624 4770 struct stat st;
c975dd7a 4771 int tem;
aed13378 4772 int count = SPECPDL_INDEX ();
6fc6f94b 4773 int count1;
570d7624 4774#ifdef VMS
5e570b75 4775 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
570d7624 4776#endif /* VMS */
3eac9910 4777 Lisp_Object handler;
4ad827c5 4778 Lisp_Object visit_file;
65b7d3e7 4779 Lisp_Object annotations;
b1d1b865 4780 Lisp_Object encoded_filename;
d3a67486
SM
4781 int visiting = (EQ (visit, Qt) || STRINGP (visit));
4782 int quietly = !NILP (visit);
7204a979 4783 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
6fc6f94b 4784 struct buffer *given_buffer;
5e570b75 4785#ifdef DOS_NT
fa228724 4786 int buffer_file_type = O_BINARY;
5e570b75 4787#endif /* DOS_NT */
6fdaa9a0 4788 struct coding_system coding;
570d7624 4789
d3a67486 4790 if (current_buffer->base_buffer && visiting)
95385625
RS
4791 error ("Cannot do file visiting in an indirect buffer");
4792
561cb8e1 4793 if (!NILP (start) && !STRINGP (start))
570d7624
JB
4794 validate_region (&start, &end);
4795
59fac292 4796 GCPRO5 (start, filename, visit, visit_file, lockname);
b56567b5 4797
570d7624 4798 filename = Fexpand_file_name (filename, Qnil);
de1d0127 4799
236a12f2 4800 if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl))
b8b29dc9 4801 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
de1d0127 4802
561cb8e1 4803 if (STRINGP (visit))
e5176bae 4804 visit_file = Fexpand_file_name (visit, Qnil);
4ad827c5
RS
4805 else
4806 visit_file = filename;
4807
7204a979
RS
4808 if (NILP (lockname))
4809 lockname = visit_file;
4810
65b7d3e7
RS
4811 annotations = Qnil;
4812
32f4334d
RS
4813 /* If the file name has special constructs in it,
4814 call the corresponding file handler. */
49307295 4815 handler = Ffind_file_name_handler (filename, Qwrite_region);
b56ad927 4816 /* If FILENAME has no handler, see if VISIT has one. */
93c30b5f 4817 if (NILP (handler) && STRINGP (visit))
199607e4 4818 handler = Ffind_file_name_handler (visit, Qwrite_region);
3eac9910 4819
32f4334d
RS
4820 if (!NILP (handler))
4821 {
32f4334d 4822 Lisp_Object val;
51cf6d37
RS
4823 val = call6 (handler, Qwrite_region, start, end,
4824 filename, append, visit);
32f4334d 4825
d6a3cc15 4826 if (visiting)
32f4334d 4827 {
95385625 4828 SAVE_MODIFF = MODIFF;
2acfd7ae 4829 XSETFASTINT (current_buffer->save_length, Z - BEG);
3b7792ed 4830 current_buffer->filename = visit_file;
32f4334d 4831 }
09121adc 4832 UNGCPRO;
32f4334d
RS
4833 return val;
4834 }
4835
561cb8e1
RS
4836 /* Special kludge to simplify auto-saving. */
4837 if (NILP (start))
4838 {
2acfd7ae
KH
4839 XSETFASTINT (start, BEG);
4840 XSETFASTINT (end, Z);
561cb8e1
RS
4841 }
4842
6fc6f94b 4843 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
aed13378 4844 count1 = SPECPDL_INDEX ();
6fc6f94b
RS
4845
4846 given_buffer = current_buffer;
bf3428a1
RS
4847
4848 if (!STRINGP (start))
236a12f2 4849 {
bf3428a1
RS
4850 annotations = build_annotations (start, end);
4851
4852 if (current_buffer != given_buffer)
4853 {
4854 XSETFASTINT (start, BEGV);
4855 XSETFASTINT (end, ZV);
4856 }
236a12f2
SM
4857 }
4858
4859 UNGCPRO;
4860
4861 GCPRO5 (start, filename, annotations, visit_file, lockname);
4862
59fac292
SM
4863 /* Decide the coding-system to encode the data with.
4864 We used to make this choice before calling build_annotations, but that
4865 leads to problems when a write-annotate-function takes care of
4866 unsavable chars (as was the case with X-Symbol). */
4867 choose_write_coding_system (start, end, filename,
4868 append, visit, lockname, &coding);
4869 Vlast_coding_system_used = coding.symbol;
4870
236a12f2 4871 given_buffer = current_buffer;
bf3428a1 4872 if (! STRINGP (start))
6fc6f94b 4873 {
bf3428a1
RS
4874 annotations = build_annotations_2 (start, end,
4875 coding.pre_write_conversion, annotations);
4876 if (current_buffer != given_buffer)
4877 {
4878 XSETFASTINT (start, BEGV);
4879 XSETFASTINT (end, ZV);
4880 }
6fc6f94b 4881 }
d6a3cc15 4882
570d7624
JB
4883#ifdef CLASH_DETECTION
4884 if (!auto_saving)
84f6296a 4885 {
a9171faa 4886#if 0 /* This causes trouble for GNUS. */
84f6296a
RS
4887 /* If we've locked this file for some other buffer,
4888 query before proceeding. */
4889 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
bffd00b0 4890 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
a9171faa 4891#endif
84f6296a
RS
4892
4893 lock_file (lockname);
4894 }
570d7624
JB
4895#endif /* CLASH_DETECTION */
4896
b1d1b865
RS
4897 encoded_filename = ENCODE_FILE (filename);
4898
d5db4077 4899 fn = SDATA (encoded_filename);
570d7624 4900 desc = -1;
265a9e55 4901 if (!NILP (append))
5e570b75 4902#ifdef DOS_NT
68c45bf0 4903 desc = emacs_open (fn, O_WRONLY | buffer_file_type, 0);
5e570b75 4904#else /* not DOS_NT */
68c45bf0 4905 desc = emacs_open (fn, O_WRONLY, 0);
5e570b75 4906#endif /* not DOS_NT */
570d7624 4907
b1d1b865 4908 if (desc < 0 && (NILP (append) || errno == ENOENT))
570d7624 4909#ifdef VMS
5e570b75 4910 if (auto_saving) /* Overwrite any previous version of autosave file */
570d7624 4911 {
5e570b75 4912 vms_truncate (fn); /* if fn exists, truncate to zero length */
68c45bf0 4913 desc = emacs_open (fn, O_RDWR, 0);
570d7624 4914 if (desc < 0)
561cb8e1 4915 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
d5db4077 4916 ? SDATA (current_buffer->filename) : 0,
b72dea2a 4917 fn);
570d7624 4918 }
5e570b75 4919 else /* Write to temporary name and rename if no errors */
570d7624
JB
4920 {
4921 Lisp_Object temp_name;
4922 temp_name = Ffile_name_directory (filename);
4923
265a9e55 4924 if (!NILP (temp_name))
570d7624
JB
4925 {
4926 temp_name = Fmake_temp_name (concat2 (temp_name,
4927 build_string ("$$SAVE$$")));
d5db4077
KR
4928 fname = SDATA (filename);
4929 fn = SDATA (temp_name);
570d7624
JB
4930 desc = creat_copy_attrs (fname, fn);
4931 if (desc < 0)
4932 {
4933 /* If we can't open the temporary file, try creating a new
4934 version of the original file. VMS "creat" creates a
4935 new version rather than truncating an existing file. */
4936 fn = fname;
4937 fname = 0;
4938 desc = creat (fn, 0666);
4939#if 0 /* This can clobber an existing file and fail to replace it,
4940 if the user runs out of space. */
4941 if (desc < 0)
4942 {
4943 /* We can't make a new version;
4944 try to truncate and rewrite existing version if any. */
4945 vms_truncate (fn);
68c45bf0 4946 desc = emacs_open (fn, O_RDWR, 0);
570d7624
JB
4947 }
4948#endif
4949 }
4950 }
4951 else
4952 desc = creat (fn, 0666);
4953 }
4954#else /* not VMS */
5e570b75 4955#ifdef DOS_NT
68c45bf0 4956 desc = emacs_open (fn,
95522746
GM
4957 O_WRONLY | O_CREAT | buffer_file_type
4958 | (EQ (mustbenew, Qexcl) ? O_EXCL : O_TRUNC),
68c45bf0 4959 S_IREAD | S_IWRITE);
5e570b75 4960#else /* not DOS_NT */
68c45bf0 4961 desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT
7c752c80 4962 | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
68c45bf0 4963 auto_saving ? auto_save_mode_bits : 0666);
5e570b75 4964#endif /* not DOS_NT */
570d7624
JB
4965#endif /* not VMS */
4966
4967 if (desc < 0)
4968 {
4969#ifdef CLASH_DETECTION
4970 save_errno = errno;
7204a979 4971 if (!auto_saving) unlock_file (lockname);
570d7624
JB
4972 errno = save_errno;
4973#endif /* CLASH_DETECTION */
43fb7d9a 4974 UNGCPRO;
570d7624
JB
4975 report_file_error ("Opening output file", Fcons (filename, Qnil));
4976 }
4977
4978 record_unwind_protect (close_file_unwind, make_number (desc));
4979
c1c4693e 4980 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
43fb7d9a
DL
4981 {
4982 long ret;
efdc16c9 4983
43fb7d9a
DL
4984 if (NUMBERP (append))
4985 ret = lseek (desc, XINT (append), 1);
4986 else
4987 ret = lseek (desc, 0, 2);
4988 if (ret < 0)
4989 {
570d7624 4990#ifdef CLASH_DETECTION
43fb7d9a 4991 if (!auto_saving) unlock_file (lockname);
570d7624 4992#endif /* CLASH_DETECTION */
43fb7d9a
DL
4993 UNGCPRO;
4994 report_file_error ("Lseek error", Fcons (filename, Qnil));
4995 }
4996 }
efdc16c9 4997
43fb7d9a 4998 UNGCPRO;
570d7624
JB
4999
5000#ifdef VMS
5001/*
5002 * Kludge Warning: The VMS C RTL likes to insert carriage returns
5003 * if we do writes that don't end with a carriage return. Furthermore
5004 * it cannot handle writes of more then 16K. The modified
5005 * version of "sys_write" in SYSDEP.C (see comment there) copes with
5006 * this EXCEPT for the last record (iff it doesn't end with a carriage
5007 * return). This implies that if your buffer doesn't end with a carriage
5008 * return, you get one free... tough. However it also means that if
5009 * we make two calls to sys_write (a la the following code) you can
5010 * get one at the gap as well. The easiest way to fix this (honest)
5011 * is to move the gap to the next newline (or the end of the buffer).
5012 * Thus this change.
5013 *
5014 * Yech!
5015 */
5016 if (GPT > BEG && GPT_ADDR[-1] != '\n')
5017 move_gap (find_next_newline (GPT, 1));
cdfb0f1d
KH
5018#else
5019 /* Whether VMS or not, we must move the gap to the next of newline
5020 when we must put designation sequences at beginning of line. */
5021 if (INTEGERP (start)
5022 && coding.type == coding_type_iso2022
5023 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
5024 && GPT > BEG && GPT_ADDR[-1] != '\n')
ec7adf26
RS
5025 {
5026 int opoint = PT, opoint_byte = PT_BYTE;
5027 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
5028 move_gap_both (PT, PT_BYTE);
5029 SET_PT_BOTH (opoint, opoint_byte);
5030 }
570d7624
JB
5031#endif
5032
5033 failure = 0;
5034 immediate_quit = 1;
5035
561cb8e1 5036 if (STRINGP (start))
570d7624 5037 {
d5db4077 5038 failure = 0 > a_write (desc, start, 0, SCHARS (start),
ce51c54c 5039 &annotations, &coding);
570d7624
JB
5040 save_errno = errno;
5041 }
5042 else if (XINT (start) != XINT (end))
5043 {
ec7adf26
RS
5044 tem = CHAR_TO_BYTE (XINT (start));
5045
570d7624
JB
5046 if (XINT (start) < GPT)
5047 {
ce51c54c
KH
5048 failure = 0 > a_write (desc, Qnil, XINT (start),
5049 min (GPT, XINT (end)) - XINT (start),
5050 &annotations, &coding);
570d7624
JB
5051 save_errno = errno;
5052 }
5053
5054 if (XINT (end) > GPT && !failure)
5055 {
ce51c54c
KH
5056 tem = max (XINT (start), GPT);
5057 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
5058 &annotations, &coding);
d6a3cc15
RS
5059 save_errno = errno;
5060 }
69f6e679
RS
5061 }
5062 else
5063 {
5064 /* If file was empty, still need to write the annotations */
c8a6d68a 5065 coding.mode |= CODING_MODE_LAST_BLOCK;
ce51c54c 5066 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
6fdaa9a0
KH
5067 save_errno = errno;
5068 }
5069
c8a6d68a
KH
5070 if (CODING_REQUIRE_FLUSHING (&coding)
5071 && !(coding.mode & CODING_MODE_LAST_BLOCK)
1354debd 5072 && ! failure)
6fdaa9a0
KH
5073 {
5074 /* We have to flush out a data. */
c8a6d68a 5075 coding.mode |= CODING_MODE_LAST_BLOCK;
ce51c54c 5076 failure = 0 > e_write (desc, Qnil, 0, 0, &coding);
69f6e679 5077 save_errno = errno;
570d7624
JB
5078 }
5079
5080 immediate_quit = 0;
5081
6e23c83e 5082#ifdef HAVE_FSYNC
570d7624
JB
5083 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
5084 Disk full in NFS may be reported here. */
1daffa1c
RS
5085 /* mib says that closing the file will try to write as fast as NFS can do
5086 it, and that means the fsync here is not crucial for autosave files. */
5087 if (!auto_saving && fsync (desc) < 0)
cb33c142
KH
5088 {
5089 /* If fsync fails with EINTR, don't treat that as serious. */
5090 if (errno != EINTR)
5091 failure = 1, save_errno = errno;
5092 }
570d7624
JB
5093#endif
5094
199607e4 5095 /* Spurious "file has changed on disk" warnings have been
570d7624
JB
5096 observed on Suns as well.
5097 It seems that `close' can change the modtime, under nfs.
5098
5099 (This has supposedly been fixed in Sunos 4,
5100 but who knows about all the other machines with NFS?) */
5101#if 0
5102
5103 /* On VMS and APOLLO, must do the stat after the close
5104 since closing changes the modtime. */
5105#ifndef VMS
5106#ifndef APOLLO
5107 /* Recall that #if defined does not work on VMS. */
5108#define FOO
5109 fstat (desc, &st);
5110#endif
5111#endif
5112#endif
5113
5114 /* NFS can report a write failure now. */
68c45bf0 5115 if (emacs_close (desc) < 0)
570d7624
JB
5116 failure = 1, save_errno = errno;
5117
5118#ifdef VMS
5119 /* If we wrote to a temporary name and had no errors, rename to real name. */
5120 if (fname)
5121 {
5122 if (!failure)
5123 failure = (rename (fn, fname) != 0), save_errno = errno;
5124 fn = fname;
5125 }
5126#endif /* VMS */
5127
5128#ifndef FOO
5129 stat (fn, &st);
5130#endif
6fc6f94b
RS
5131 /* Discard the unwind protect for close_file_unwind. */
5132 specpdl_ptr = specpdl + count1;
5133 /* Restore the original current buffer. */
98295b48 5134 visit_file = unbind_to (count, visit_file);
570d7624
JB
5135
5136#ifdef CLASH_DETECTION
5137 if (!auto_saving)
7204a979 5138 unlock_file (lockname);
570d7624
JB
5139#endif /* CLASH_DETECTION */
5140
5141 /* Do this before reporting IO error
5142 to avoid a "file has changed on disk" warning on
5143 next attempt to save. */
d6a3cc15 5144 if (visiting)
570d7624
JB
5145 current_buffer->modtime = st.st_mtime;
5146
5147 if (failure)
d5db4077 5148 error ("IO error writing %s: %s", SDATA (filename),
68c45bf0 5149 emacs_strerror (save_errno));
570d7624 5150
d6a3cc15 5151 if (visiting)
570d7624 5152 {
95385625 5153 SAVE_MODIFF = MODIFF;
2acfd7ae 5154 XSETFASTINT (current_buffer->save_length, Z - BEG);
3b7792ed 5155 current_buffer->filename = visit_file;
f4226e89 5156 update_mode_lines++;
570d7624 5157 }
d6a3cc15 5158 else if (quietly)
570d7624
JB
5159 return Qnil;
5160
5161 if (!auto_saving)
60d67b83 5162 message_with_string ("Wrote %s", visit_file, 1);
570d7624
JB
5163
5164 return Qnil;
5165}
ec7adf26 5166\f
d6a3cc15
RS
5167Lisp_Object merge ();
5168
5169DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
8c1a1077
PJ
5170 doc: /* Return t if (car A) is numerically less than (car B). */)
5171 (a, b)
d6a3cc15
RS
5172 Lisp_Object a, b;
5173{
5174 return Flss (Fcar (a), Fcar (b));
5175}
5176
5177/* Build the complete list of annotations appropriate for writing out
5178 the text between START and END, by calling all the functions in
6fc6f94b
RS
5179 write-region-annotate-functions and merging the lists they return.
5180 If one of these functions switches to a different buffer, we assume
5181 that buffer contains altered text. Therefore, the caller must
5182 make sure to restore the current buffer in all cases,
5183 as save-excursion would do. */
d6a3cc15
RS
5184
5185static Lisp_Object
236a12f2
SM
5186build_annotations (start, end)
5187 Lisp_Object start, end;
d6a3cc15
RS
5188{
5189 Lisp_Object annotations;
5190 Lisp_Object p, res;
5191 struct gcpro gcpro1, gcpro2;
0a20b684 5192 Lisp_Object original_buffer;
532ed661 5193 int i;
0a20b684
RS
5194
5195 XSETBUFFER (original_buffer, current_buffer);
d6a3cc15
RS
5196
5197 annotations = Qnil;
5198 p = Vwrite_region_annotate_functions;
5199 GCPRO2 (annotations, p);
28c3eb5a 5200 while (CONSP (p))
d6a3cc15 5201 {
6fc6f94b
RS
5202 struct buffer *given_buffer = current_buffer;
5203 Vwrite_region_annotations_so_far = annotations;
28c3eb5a 5204 res = call2 (XCAR (p), start, end);
6fc6f94b
RS
5205 /* If the function makes a different buffer current,
5206 assume that means this buffer contains altered text to be output.
5207 Reset START and END from the buffer bounds
5208 and discard all previous annotations because they should have
5209 been dealt with by this function. */
5210 if (current_buffer != given_buffer)
5211 {
3cf29f61
RS
5212 XSETFASTINT (start, BEGV);
5213 XSETFASTINT (end, ZV);
6fc6f94b
RS
5214 annotations = Qnil;
5215 }
d6a3cc15
RS
5216 Flength (res); /* Check basic validity of return value */
5217 annotations = merge (annotations, res, Qcar_less_than_car);
28c3eb5a 5218 p = XCDR (p);
d6a3cc15 5219 }
0d420e88
BG
5220
5221 /* Now do the same for annotation functions implied by the file-format */
5222 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
5223 p = Vauto_save_file_format;
5224 else
5225 p = current_buffer->file_format;
28c3eb5a 5226 for (i = 0; CONSP (p); p = XCDR (p), ++i)
0d420e88
BG
5227 {
5228 struct buffer *given_buffer = current_buffer;
efdc16c9 5229
0d420e88 5230 Vwrite_region_annotations_so_far = annotations;
532ed661
GM
5231
5232 /* Value is either a list of annotations or nil if the function
5233 has written annotations to a temporary buffer, which is now
5234 current. */
28c3eb5a 5235 res = call5 (Qformat_annotate_function, XCAR (p), start, end,
532ed661 5236 original_buffer, make_number (i));
0d420e88
BG
5237 if (current_buffer != given_buffer)
5238 {
3cf29f61
RS
5239 XSETFASTINT (start, BEGV);
5240 XSETFASTINT (end, ZV);
0d420e88
BG
5241 annotations = Qnil;
5242 }
efdc16c9 5243
532ed661
GM
5244 if (CONSP (res))
5245 annotations = merge (annotations, res, Qcar_less_than_car);
0d420e88 5246 }
6fdaa9a0 5247
236a12f2
SM
5248 UNGCPRO;
5249 return annotations;
5250}
5251
5252static Lisp_Object
5253build_annotations_2 (start, end, pre_write_conversion, annotations)
5254 Lisp_Object start, end, pre_write_conversion, annotations;
5255{
5256 struct gcpro gcpro1;
5257 Lisp_Object res;
5258
5259 GCPRO1 (annotations);
6fdaa9a0
KH
5260 /* At last, do the same for the function PRE_WRITE_CONVERSION
5261 implied by the current coding-system. */
5262 if (!NILP (pre_write_conversion))
5263 {
5264 struct buffer *given_buffer = current_buffer;
5265 Vwrite_region_annotations_so_far = annotations;
5266 res = call2 (pre_write_conversion, start, end);
6fdaa9a0 5267 Flength (res);
cdfb0f1d
KH
5268 annotations = (current_buffer != given_buffer
5269 ? res
5270 : merge (annotations, res, Qcar_less_than_car));
6fdaa9a0
KH
5271 }
5272
d6a3cc15
RS
5273 UNGCPRO;
5274 return annotations;
5275}
ec7adf26 5276\f
ce51c54c
KH
5277/* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5278 If STRING is nil, POS is the character position in the current buffer.
d6a3cc15 5279 Intersperse with them the annotations from *ANNOT
ce51c54c 5280 which fall within the range of POS to POS + NCHARS,
d6a3cc15
RS
5281 each at its appropriate position.
5282
ec7adf26
RS
5283 We modify *ANNOT by discarding elements as we use them up.
5284
d6a3cc15
RS
5285 The return value is negative in case of system call failure. */
5286
ec7adf26 5287static int
ce51c54c 5288a_write (desc, string, pos, nchars, annot, coding)
d6a3cc15 5289 int desc;
ce51c54c
KH
5290 Lisp_Object string;
5291 register int nchars;
5292 int pos;
d6a3cc15 5293 Lisp_Object *annot;
6fdaa9a0 5294 struct coding_system *coding;
d6a3cc15
RS
5295{
5296 Lisp_Object tem;
5297 int nextpos;
ce51c54c 5298 int lastpos = pos + nchars;
d6a3cc15 5299
eb15aa18 5300 while (NILP (*annot) || CONSP (*annot))
d6a3cc15
RS
5301 {
5302 tem = Fcar_safe (Fcar (*annot));
ce51c54c 5303 nextpos = pos - 1;
ec7adf26 5304 if (INTEGERP (tem))
ce51c54c 5305 nextpos = XFASTINT (tem);
ec7adf26
RS
5306
5307 /* If there are no more annotations in this range,
5308 output the rest of the range all at once. */
ce51c54c
KH
5309 if (! (nextpos >= pos && nextpos <= lastpos))
5310 return e_write (desc, string, pos, lastpos, coding);
ec7adf26
RS
5311
5312 /* Output buffer text up to the next annotation's position. */
ce51c54c 5313 if (nextpos > pos)
d6a3cc15 5314 {
055a28c9 5315 if (0 > e_write (desc, string, pos, nextpos, coding))
d6a3cc15 5316 return -1;
ce51c54c 5317 pos = nextpos;
d6a3cc15 5318 }
ec7adf26 5319 /* Output the annotation. */
d6a3cc15
RS
5320 tem = Fcdr (Fcar (*annot));
5321 if (STRINGP (tem))
5322 {
d5db4077 5323 if (0 > e_write (desc, tem, 0, SCHARS (tem), coding))
d6a3cc15
RS
5324 return -1;
5325 }
5326 *annot = Fcdr (*annot);
5327 }
dfcf069d 5328 return 0;
d6a3cc15
RS
5329}
5330
6fdaa9a0
KH
5331#ifndef WRITE_BUF_SIZE
5332#define WRITE_BUF_SIZE (16 * 1024)
5333#endif
5334
ce51c54c
KH
5335/* Write text in the range START and END into descriptor DESC,
5336 encoding them with coding system CODING. If STRING is nil, START
5337 and END are character positions of the current buffer, else they
5338 are indexes to the string STRING. */
ec7adf26
RS
5339
5340static int
ce51c54c 5341e_write (desc, string, start, end, coding)
570d7624 5342 int desc;
ce51c54c
KH
5343 Lisp_Object string;
5344 int start, end;
6fdaa9a0 5345 struct coding_system *coding;
570d7624 5346{
ce51c54c
KH
5347 register char *addr;
5348 register int nbytes;
6fdaa9a0 5349 char buf[WRITE_BUF_SIZE];
ce51c54c
KH
5350 int return_val = 0;
5351
5352 if (start >= end)
5353 coding->composing = COMPOSITION_DISABLED;
5354 if (coding->composing != COMPOSITION_DISABLED)
5355 coding_save_composition (coding, start, end, string);
5356
5357 if (STRINGP (string))
5358 {
d5db4077
KR
5359 addr = SDATA (string);
5360 nbytes = SBYTES (string);
8c3b9441 5361 coding->src_multibyte = STRING_MULTIBYTE (string);
ce51c54c
KH
5362 }
5363 else if (start < end)
5364 {
5365 /* It is assured that the gap is not in the range START and END-1. */
5366 addr = CHAR_POS_ADDR (start);
5367 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
8c3b9441
KH
5368 coding->src_multibyte
5369 = !NILP (current_buffer->enable_multibyte_characters);
ce51c54c
KH
5370 }
5371 else
5372 {
5373 addr = "";
5374 nbytes = 0;
8c3b9441 5375 coding->src_multibyte = 1;
ce51c54c 5376 }
570d7624 5377
6fdaa9a0
KH
5378 /* We used to have a code for handling selective display here. But,
5379 now it is handled within encode_coding. */
5380 while (1)
570d7624 5381 {
b4132433
KH
5382 int result;
5383
5384 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
c8a6d68a 5385 if (coding->produced > 0)
6fdaa9a0 5386 {
68c45bf0 5387 coding->produced -= emacs_write (desc, buf, coding->produced);
ce51c54c
KH
5388 if (coding->produced)
5389 {
5390 return_val = -1;
5391 break;
5392 }
570d7624 5393 }
ca91fb26
KH
5394 nbytes -= coding->consumed;
5395 addr += coding->consumed;
5396 if (result == CODING_FINISH_INSUFFICIENT_SRC
5397 && nbytes > 0)
b4132433
KH
5398 {
5399 /* The source text ends by an incomplete multibyte form.
5400 There's no way other than write it out as is. */
68c45bf0 5401 nbytes -= emacs_write (desc, addr, nbytes);
ce51c54c
KH
5402 if (nbytes)
5403 {
5404 return_val = -1;
5405 break;
5406 }
b4132433 5407 }
ec7adf26 5408 if (nbytes <= 0)
6fdaa9a0 5409 break;
ce51c54c
KH
5410 start += coding->consumed_char;
5411 if (coding->cmp_data)
5412 coding_adjust_composition_offset (coding, start);
570d7624 5413 }
0c41a39c
KH
5414
5415 if (coding->cmp_data)
5416 coding_free_composition_data (coding);
5417
055a28c9 5418 return return_val;
570d7624 5419}
ec7adf26 5420\f
570d7624 5421DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
8c1a1077
PJ
5422 Sverify_visited_file_modtime, 1, 1, 0,
5423 doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
5424This means that the file has not been changed since it was visited or saved. */)
5425 (buf)
570d7624
JB
5426 Lisp_Object buf;
5427{
5428 struct buffer *b;
5429 struct stat st;
32f4334d 5430 Lisp_Object handler;
b1d1b865 5431 Lisp_Object filename;
570d7624 5432
b7826503 5433 CHECK_BUFFER (buf);
570d7624
JB
5434 b = XBUFFER (buf);
5435
93c30b5f 5436 if (!STRINGP (b->filename)) return Qt;
570d7624
JB
5437 if (b->modtime == 0) return Qt;
5438
32f4334d
RS
5439 /* If the file name has special constructs in it,
5440 call the corresponding file handler. */
49307295
KH
5441 handler = Ffind_file_name_handler (b->filename,
5442 Qverify_visited_file_modtime);
32f4334d 5443 if (!NILP (handler))
09121adc 5444 return call2 (handler, Qverify_visited_file_modtime, buf);
32f4334d 5445
b1d1b865
RS
5446 filename = ENCODE_FILE (b->filename);
5447
d5db4077 5448 if (stat (SDATA (filename), &st) < 0)
570d7624
JB
5449 {
5450 /* If the file doesn't exist now and didn't exist before,
5451 we say that it isn't modified, provided the error is a tame one. */
5452 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
5453 st.st_mtime = -1;
5454 else
5455 st.st_mtime = 0;
5456 }
5457 if (st.st_mtime == b->modtime
5458 /* If both are positive, accept them if they are off by one second. */
5459 || (st.st_mtime > 0 && b->modtime > 0
5460 && (st.st_mtime == b->modtime + 1
5461 || st.st_mtime == b->modtime - 1)))
5462 return Qt;
5463 return Qnil;
5464}
5465
5466DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
8c1a1077
PJ
5467 Sclear_visited_file_modtime, 0, 0, 0,
5468 doc: /* Clear out records of last mod time of visited file.
5469Next attempt to save will certainly not complain of a discrepancy. */)
5470 ()
570d7624
JB
5471{
5472 current_buffer->modtime = 0;
5473 return Qnil;
5474}
5475
f5d5eccf 5476DEFUN ("visited-file-modtime", Fvisited_file_modtime,
8c1a1077
PJ
5477 Svisited_file_modtime, 0, 0, 0,
5478 doc: /* Return the current buffer's recorded visited file modification time.
5479The value is a list of the form (HIGH . LOW), like the time values
5480that `file-attributes' returns. */)
5481 ()
f5d5eccf 5482{
b50536bb 5483 return long_to_cons ((unsigned long) current_buffer->modtime);
f5d5eccf
RS
5484}
5485
570d7624 5486DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
8c1a1077
PJ
5487 Sset_visited_file_modtime, 0, 1, 0,
5488 doc: /* Update buffer's recorded modification time from the visited file's time.
5489Useful if the buffer was not read from the file normally
5490or if the file itself has been changed for some known benign reason.
5491An argument specifies the modification time value to use
5492\(instead of that of the visited file), in the form of a list
5493\(HIGH . LOW) or (HIGH LOW). */)
5494 (time_list)
f5d5eccf 5495 Lisp_Object time_list;
570d7624 5496{
f5d5eccf
RS
5497 if (!NILP (time_list))
5498 current_buffer->modtime = cons_to_long (time_list);
5499 else
5500 {
5501 register Lisp_Object filename;
5502 struct stat st;
5503 Lisp_Object handler;
570d7624 5504
f5d5eccf 5505 filename = Fexpand_file_name (current_buffer->filename, Qnil);
32f4334d 5506
f5d5eccf
RS
5507 /* If the file name has special constructs in it,
5508 call the corresponding file handler. */
49307295 5509 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
f5d5eccf 5510 if (!NILP (handler))
caf3c431 5511 /* The handler can find the file name the same way we did. */
76c881b0 5512 return call2 (handler, Qset_visited_file_modtime, Qnil);
b1d1b865
RS
5513
5514 filename = ENCODE_FILE (filename);
5515
d5db4077 5516 if (stat (SDATA (filename), &st) >= 0)
f5d5eccf
RS
5517 current_buffer->modtime = st.st_mtime;
5518 }
570d7624
JB
5519
5520 return Qnil;
5521}
5522\f
5523Lisp_Object
d7f31e22
GM
5524auto_save_error (error)
5525 Lisp_Object error;
570d7624 5526{
d7f31e22
GM
5527 Lisp_Object args[3], msg;
5528 int i, nbytes;
5529 struct gcpro gcpro1;
efdc16c9 5530
570d7624 5531 ring_bell ();
efdc16c9 5532
d7f31e22
GM
5533 args[0] = build_string ("Auto-saving %s: %s");
5534 args[1] = current_buffer->name;
5535 args[2] = Ferror_message_string (error);
5536 msg = Fformat (3, args);
5537 GCPRO1 (msg);
d5db4077 5538 nbytes = SBYTES (msg);
d7f31e22
GM
5539
5540 for (i = 0; i < 3; ++i)
5541 {
5542 if (i == 0)
d5db4077 5543 message2 (SDATA (msg), nbytes, STRING_MULTIBYTE (msg));
d7f31e22 5544 else
d5db4077 5545 message2_nolog (SDATA (msg), nbytes, STRING_MULTIBYTE (msg));
d7f31e22
GM
5546 Fsleep_for (make_number (1), Qnil);
5547 }
5548
5549 UNGCPRO;
570d7624
JB
5550 return Qnil;
5551}
5552
5553Lisp_Object
5554auto_save_1 ()
5555{
570d7624
JB
5556 struct stat st;
5557
5558 /* Get visited file's mode to become the auto save file's mode. */
8801a864 5559 if (! NILP (current_buffer->filename)
d5db4077 5560 && stat (SDATA (current_buffer->filename), &st) >= 0)
570d7624
JB
5561 /* But make sure we can overwrite it later! */
5562 auto_save_mode_bits = st.st_mode | 0600;
5563 else
5564 auto_save_mode_bits = 0666;
5565
5566 return
5567 Fwrite_region (Qnil, Qnil,
5568 current_buffer->auto_save_file_name,
de1d0127 5569 Qnil, Qlambda, Qnil, Qnil);
570d7624
JB
5570}
5571
e54d3b5d 5572static Lisp_Object
1b335d29
RS
5573do_auto_save_unwind (stream) /* used as unwind-protect function */
5574 Lisp_Object stream;
e54d3b5d 5575{
3be3c08e 5576 auto_saving = 0;
1b335d29 5577 if (!NILP (stream))
03699b14
KR
5578 fclose ((FILE *) (XFASTINT (XCAR (stream)) << 16
5579 | XFASTINT (XCDR (stream))));
e54d3b5d
RS
5580 return Qnil;
5581}
5582
a8c828be
RS
5583static Lisp_Object
5584do_auto_save_unwind_1 (value) /* used as unwind-protect function */
5585 Lisp_Object value;
5586{
5587 minibuffer_auto_raise = XINT (value);
5588 return Qnil;
5589}
5590
5794dd61
RS
5591static Lisp_Object
5592do_auto_save_make_dir (dir)
5593 Lisp_Object dir;
5594{
5595 return call2 (Qmake_directory, dir, Qt);
5596}
5597
5598static Lisp_Object
5599do_auto_save_eh (ignore)
5600 Lisp_Object ignore;
5601{
5602 return Qnil;
5603}
5604
570d7624 5605DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
8c1a1077
PJ
5606 doc: /* Auto-save all buffers that need it.
5607This is all buffers that have auto-saving enabled
5608and are changed since last auto-saved.
5609Auto-saving writes the buffer into a file
5610so that your editing is not lost if the system crashes.
5611This file is not the file you visited; that changes only when you save.
5612Normally we run the normal hook `auto-save-hook' before saving.
5613
5614A non-nil NO-MESSAGE argument means do not print any message if successful.
5615A non-nil CURRENT-ONLY argument means save only current buffer. */)
5616 (no_message, current_only)
17857782 5617 Lisp_Object no_message, current_only;
570d7624
JB
5618{
5619 struct buffer *old = current_buffer, *b;
5620 Lisp_Object tail, buf;
5621 int auto_saved = 0;
f14b1c68 5622 int do_handled_files;
ff4c9993 5623 Lisp_Object oquit;
1b335d29
RS
5624 FILE *stream;
5625 Lisp_Object lispstream;
aed13378 5626 int count = SPECPDL_INDEX ();
a8c828be 5627 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
5794dd61 5628 int old_message_p = 0;
d57563b6 5629 struct gcpro gcpro1, gcpro2;
38da540d
RS
5630
5631 if (max_specpdl_size < specpdl_size + 40)
5632 max_specpdl_size = specpdl_size + 40;
5633
5634 if (minibuf_level)
5635 no_message = Qt;
5636
5794dd61
RS
5637 if (NILP (no_message))
5638 {
5639 old_message_p = push_message ();
5640 record_unwind_protect (pop_message_unwind, Qnil);
5641 }
efdc16c9 5642
ff4c9993
RS
5643 /* Ordinarily don't quit within this function,
5644 but don't make it impossible to quit (in case we get hung in I/O). */
5645 oquit = Vquit_flag;
5646 Vquit_flag = Qnil;
570d7624
JB
5647
5648 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
5649 point to non-strings reached from Vbuffer_alist. */
5650
265a9e55 5651 if (!NILP (Vrun_hooks))
570d7624
JB
5652 call1 (Vrun_hooks, intern ("auto-save-hook"));
5653
e54d3b5d
RS
5654 if (STRINGP (Vauto_save_list_file_name))
5655 {
0894672f 5656 Lisp_Object listfile;
efdc16c9 5657
258fd2cb 5658 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
0894672f
GM
5659
5660 /* Don't try to create the directory when shutting down Emacs,
5661 because creating the directory might signal an error, and
5662 that would leave Emacs in a strange state. */
5663 if (!NILP (Vrun_hooks))
5664 {
5665 Lisp_Object dir;
d57563b6
RS
5666 dir = Qnil;
5667 GCPRO2 (dir, listfile);
0894672f
GM
5668 dir = Ffile_name_directory (listfile);
5669 if (NILP (Ffile_directory_p (dir)))
5794dd61
RS
5670 internal_condition_case_1 (do_auto_save_make_dir,
5671 dir, Fcons (Fcons (Qfile_error, Qnil), Qnil),
5672 do_auto_save_eh);
d57563b6 5673 UNGCPRO;
0894672f 5674 }
efdc16c9 5675
d5db4077 5676 stream = fopen (SDATA (listfile), "w");
0eff1f85
RS
5677 if (stream != NULL)
5678 {
5679 /* Arrange to close that file whether or not we get an error.
5680 Also reset auto_saving to 0. */
5681 lispstream = Fcons (Qnil, Qnil);
f3fbd155
KR
5682 XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
5683 XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
0eff1f85
RS
5684 }
5685 else
5686 lispstream = Qnil;
e54d3b5d
RS
5687 }
5688 else
1b335d29
RS
5689 {
5690 stream = NULL;
5691 lispstream = Qnil;
5692 }
199607e4 5693
1b335d29 5694 record_unwind_protect (do_auto_save_unwind, lispstream);
a8c828be
RS
5695 record_unwind_protect (do_auto_save_unwind_1,
5696 make_number (minibuffer_auto_raise));
5697 minibuffer_auto_raise = 0;
3be3c08e
RS
5698 auto_saving = 1;
5699
f14b1c68
JB
5700 /* First, save all files which don't have handlers. If Emacs is
5701 crashing, the handlers may tweak what is causing Emacs to crash
5702 in the first place, and it would be a shame if Emacs failed to
5703 autosave perfectly ordinary files because it couldn't handle some
5704 ange-ftp'd file. */
5705 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
03699b14 5706 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCDR (tail))
f14b1c68 5707 {
03699b14 5708 buf = XCDR (XCAR (tail));
f14b1c68 5709 b = XBUFFER (buf);
199607e4 5710
e54d3b5d 5711 /* Record all the buffers that have auto save mode
258fd2cb
RS
5712 in the special file that lists them. For each of these buffers,
5713 Record visited name (if any) and auto save name. */
93c30b5f 5714 if (STRINGP (b->auto_save_file_name)
1b335d29 5715 && stream != NULL && do_handled_files == 0)
e54d3b5d 5716 {
258fd2cb
RS
5717 if (!NILP (b->filename))
5718 {
d5db4077
KR
5719 fwrite (SDATA (b->filename), 1,
5720 SBYTES (b->filename), stream);
258fd2cb 5721 }
1b335d29 5722 putc ('\n', stream);
d5db4077
KR
5723 fwrite (SDATA (b->auto_save_file_name), 1,
5724 SBYTES (b->auto_save_file_name), stream);
1b335d29 5725 putc ('\n', stream);
e54d3b5d 5726 }
17857782 5727
f14b1c68
JB
5728 if (!NILP (current_only)
5729 && b != current_buffer)
5730 continue;
e54d3b5d 5731
95385625
RS
5732 /* Don't auto-save indirect buffers.
5733 The base buffer takes care of it. */
5734 if (b->base_buffer)
5735 continue;
5736
f14b1c68
JB
5737 /* Check for auto save enabled
5738 and file changed since last auto save
5739 and file changed since last real save. */
93c30b5f 5740 if (STRINGP (b->auto_save_file_name)
95385625 5741 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
f14b1c68 5742 && b->auto_save_modified < BUF_MODIFF (b)
82c2d839
RS
5743 /* -1 means we've turned off autosaving for a while--see below. */
5744 && XINT (b->save_length) >= 0
f14b1c68 5745 && (do_handled_files
49307295
KH
5746 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
5747 Qwrite_region))))
f14b1c68 5748 {
b60247d9
RS
5749 EMACS_TIME before_time, after_time;
5750
5751 EMACS_GET_TIME (before_time);
5752
5753 /* If we had a failure, don't try again for 20 minutes. */
5754 if (b->auto_save_failure_time >= 0
5755 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
5756 continue;
5757
f14b1c68
JB
5758 if ((XFASTINT (b->save_length) * 10
5759 > (BUF_Z (b) - BUF_BEG (b)) * 13)
5760 /* A short file is likely to change a large fraction;
5761 spare the user annoying messages. */
5762 && XFASTINT (b->save_length) > 5000
5763 /* These messages are frequent and annoying for `*mail*'. */
5764 && !EQ (b->filename, Qnil)
5765 && NILP (no_message))
5766 {
5767 /* It has shrunk too much; turn off auto-saving here. */
a8c828be 5768 minibuffer_auto_raise = orig_minibuffer_auto_raise;
fd91d0d4 5769 message_with_string ("Buffer %s has shrunk a lot; auto save disabled in that buffer until next real save",
60d67b83 5770 b->name, 1);
a8c828be 5771 minibuffer_auto_raise = 0;
82c2d839
RS
5772 /* Turn off auto-saving until there's a real save,
5773 and prevent any more warnings. */
46283abe 5774 XSETINT (b->save_length, -1);
f14b1c68
JB
5775 Fsleep_for (make_number (1), Qnil);
5776 continue;
5777 }
5778 set_buffer_internal (b);
5779 if (!auto_saved && NILP (no_message))
5780 message1 ("Auto-saving...");
5781 internal_condition_case (auto_save_1, Qt, auto_save_error);
5782 auto_saved++;
5783 b->auto_save_modified = BUF_MODIFF (b);
2acfd7ae 5784 XSETFASTINT (current_buffer->save_length, Z - BEG);
f14b1c68 5785 set_buffer_internal (old);
b60247d9
RS
5786
5787 EMACS_GET_TIME (after_time);
5788
5789 /* If auto-save took more than 60 seconds,
5790 assume it was an NFS failure that got a timeout. */
5791 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
5792 b->auto_save_failure_time = EMACS_SECS (after_time);
f14b1c68
JB
5793 }
5794 }
570d7624 5795
b67f2ca5
RS
5796 /* Prevent another auto save till enough input events come in. */
5797 record_auto_save ();
570d7624 5798
17857782 5799 if (auto_saved && NILP (no_message))
f05b275b 5800 {
5794dd61 5801 if (old_message_p)
31f3d831 5802 {
5794dd61
RS
5803 /* If we are going to restore an old message,
5804 give time to read ours. */
22e59fa7 5805 sit_for (1, 0, 0, 0, 0);
c71106e5 5806 restore_message ();
31f3d831 5807 }
f05b275b 5808 else
5794dd61
RS
5809 /* If we displayed a message and then restored a state
5810 with no message, leave a "done" message on the screen. */
f05b275b
KH
5811 message1 ("Auto-saving...done");
5812 }
570d7624 5813
ff4c9993
RS
5814 Vquit_flag = oquit;
5815
5794dd61 5816 /* This restores the message-stack status. */
e54d3b5d 5817 unbind_to (count, Qnil);
570d7624
JB
5818 return Qnil;
5819}
5820
5821DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
8c1a1077
PJ
5822 Sset_buffer_auto_saved, 0, 0, 0,
5823 doc: /* Mark current buffer as auto-saved with its current text.
5824No auto-save file will be written until the buffer changes again. */)
5825 ()
570d7624
JB
5826{
5827 current_buffer->auto_save_modified = MODIFF;
2acfd7ae 5828 XSETFASTINT (current_buffer->save_length, Z - BEG);
b60247d9
RS
5829 current_buffer->auto_save_failure_time = -1;
5830 return Qnil;
5831}
5832
5833DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
8c1a1077
PJ
5834 Sclear_buffer_auto_save_failure, 0, 0, 0,
5835 doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
5836 ()
b60247d9
RS
5837{
5838 current_buffer->auto_save_failure_time = -1;
570d7624
JB
5839 return Qnil;
5840}
5841
5842DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
8c1a1077
PJ
5843 0, 0, 0,
5844 doc: /* Return t if buffer has been auto-saved since last read in or saved. */)
5845 ()
570d7624 5846{
95385625 5847 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
570d7624
JB
5848}
5849\f
5850/* Reading and completing file names */
5851extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
5852
6e710ae5
RS
5853/* In the string VAL, change each $ to $$ and return the result. */
5854
5855static Lisp_Object
5856double_dollars (val)
5857 Lisp_Object val;
5858{
19290c65
KR
5859 register const unsigned char *old;
5860 register unsigned char *new;
6e710ae5
RS
5861 register int n;
5862 int osize, count;
5863
d5db4077 5864 osize = SBYTES (val);
60d67b83
RS
5865
5866 /* Count the number of $ characters. */
d5db4077 5867 for (n = osize, count = 0, old = SDATA (val); n > 0; n--)
6e710ae5
RS
5868 if (*old++ == '$') count++;
5869 if (count > 0)
5870 {
d5db4077
KR
5871 old = SDATA (val);
5872 val = make_uninit_multibyte_string (SCHARS (val) + count,
60d67b83 5873 osize + count);
d5db4077 5874 new = SDATA (val);
6e710ae5
RS
5875 for (n = osize; n > 0; n--)
5876 if (*old != '$')
5877 *new++ = *old++;
5878 else
5879 {
5880 *new++ = '$';
5881 *new++ = '$';
5882 old++;
5883 }
5884 }
5885 return val;
5886}
5887
59ffe07d
KS
5888static Lisp_Object
5889read_file_name_cleanup (arg)
5890 Lisp_Object arg;
5891{
c4174fbb 5892 return (current_buffer->directory = arg);
59ffe07d
KS
5893}
5894
570d7624 5895DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
8c1a1077
PJ
5896 3, 3, 0,
5897 doc: /* Internal subroutine for read-file-name. Do not call this. */)
5898 (string, dir, action)
570d7624
JB
5899 Lisp_Object string, dir, action;
5900 /* action is nil for complete, t for return list of completions,
5901 lambda for verify final value */
5902{
5903 Lisp_Object name, specdir, realdir, val, orig_string;
09121adc 5904 int changed;
8ce069f5 5905 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
09121adc 5906
b7826503 5907 CHECK_STRING (string);
58cc3710 5908
09121adc
RS
5909 realdir = dir;
5910 name = string;
5911 orig_string = Qnil;
5912 specdir = Qnil;
5913 changed = 0;
5914 /* No need to protect ACTION--we only compare it with t and nil. */
8ce069f5 5915 GCPRO5 (string, realdir, name, specdir, orig_string);
570d7624 5916
d5db4077 5917 if (SCHARS (string) == 0)
570d7624 5918 {
570d7624 5919 if (EQ (action, Qlambda))
09121adc
RS
5920 {
5921 UNGCPRO;
5922 return Qnil;
5923 }
570d7624
JB
5924 }
5925 else
5926 {
5927 orig_string = string;
5928 string = Fsubstitute_in_file_name (string);
09121adc 5929 changed = NILP (Fstring_equal (string, orig_string));
570d7624 5930 name = Ffile_name_nondirectory (string);
09121adc
RS
5931 val = Ffile_name_directory (string);
5932 if (! NILP (val))
5933 realdir = Fexpand_file_name (val, realdir);
570d7624
JB
5934 }
5935
265a9e55 5936 if (NILP (action))
570d7624
JB
5937 {
5938 specdir = Ffile_name_directory (string);
5939 val = Ffile_name_completion (name, realdir);
09121adc 5940 UNGCPRO;
93c30b5f 5941 if (!STRINGP (val))
570d7624 5942 {
09121adc 5943 if (changed)
dbd04e01 5944 return double_dollars (string);
09121adc 5945 return val;
570d7624
JB
5946 }
5947
265a9e55 5948 if (!NILP (specdir))
570d7624
JB
5949 val = concat2 (specdir, val);
5950#ifndef VMS
6e710ae5
RS
5951 return double_dollars (val);
5952#else /* not VMS */
09121adc 5953 return val;
6e710ae5 5954#endif /* not VMS */
570d7624 5955 }
09121adc 5956 UNGCPRO;
570d7624
JB
5957
5958 if (EQ (action, Qt))
59ffe07d
KS
5959 {
5960 Lisp_Object all = Ffile_name_all_completions (name, realdir);
5961 Lisp_Object comp;
5962 int count;
5963
5964 if (NILP (Vread_file_name_predicate)
5965 || EQ (Vread_file_name_predicate, Qfile_exists_p))
5966 return all;
da46f04f
KS
5967
5968#ifndef VMS
5969 if (EQ (Vread_file_name_predicate, Qfile_directory_p))
5970 {
efdc16c9 5971 /* Brute-force speed up for directory checking:
da46f04f
KS
5972 Discard strings which don't end in a slash. */
5973 for (comp = Qnil; CONSP (all); all = XCDR (all))
5974 {
5975 Lisp_Object tem = XCAR (all);
5976 int len;
5977 if (STRINGP (tem) &&
d5db4077
KR
5978 (len = SCHARS (tem), len > 0) &&
5979 IS_DIRECTORY_SEP (SREF (tem, len-1)))
da46f04f
KS
5980 comp = Fcons (tem, comp);
5981 }
5982 }
5983 else
5984#endif
5985 {
5986 /* Must do it the hard (and slow) way. */
5987 GCPRO3 (all, comp, specdir);
aed13378 5988 count = SPECPDL_INDEX ();
da46f04f
KS
5989 record_unwind_protect (read_file_name_cleanup, current_buffer->directory);
5990 current_buffer->directory = realdir;
5991 for (comp = Qnil; CONSP (all); all = XCDR (all))
5992 if (!NILP (call1 (Vread_file_name_predicate, XCAR (all))))
5993 comp = Fcons (XCAR (all), comp);
5994 unbind_to (count, Qnil);
5995 UNGCPRO;
5996 }
59ffe07d
KS
5997 return Fnreverse (comp);
5998 }
5999
570d7624
JB
6000 /* Only other case actually used is ACTION = lambda */
6001#ifdef VMS
6002 /* Supposedly this helps commands such as `cd' that read directory names,
6003 but can someone explain how it helps them? -- RMS */
d5db4077 6004 if (SCHARS (name) == 0)
570d7624
JB
6005 return Qt;
6006#endif /* VMS */
59ffe07d
KS
6007 if (!NILP (Vread_file_name_predicate))
6008 return call1 (Vread_file_name_predicate, string);
570d7624
JB
6009 return Ffile_exists_p (string);
6010}
6011
59ffe07d 6012DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0,
8c1a1077
PJ
6013 doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
6014Value is not expanded---you must call `expand-file-name' yourself.
6015Default name to DEFAULT-FILENAME if user enters a null string.
6016 (If DEFAULT-FILENAME is omitted, the visited file name is used,
6017 except that if INITIAL is specified, that combined with DIR is used.)
6018Fourth arg MUSTMATCH non-nil means require existing file's name.
6019 Non-nil and non-t means also require confirmation after completion.
6020Fifth arg INITIAL specifies text to start with.
efdc16c9 6021If optional sixth arg PREDICATE is non-nil, possible completions and the
59ffe07d 6022resulting file name must satisfy (funcall PREDICATE NAME).
8c1a1077
PJ
6023DIR defaults to current buffer's directory default.
6024
6025If this command was invoked with the mouse, use a file dialog box if
6026`use-dialog-box' is non-nil, and the window system or X toolkit in use
6027provides a file dialog box. */)
59ffe07d
KS
6028 (prompt, dir, default_filename, mustmatch, initial, predicate)
6029 Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate;
570d7624 6030{
8d6d9fef 6031 Lisp_Object val, insdef, tem;
570d7624
JB
6032 struct gcpro gcpro1, gcpro2;
6033 register char *homedir;
d7231f93 6034 Lisp_Object decoded_homedir;
62f555a5
RS
6035 int replace_in_history = 0;
6036 int add_to_history = 0;
570d7624
JB
6037 int count;
6038
265a9e55 6039 if (NILP (dir))
570d7624 6040 dir = current_buffer->directory;
3b7f6e60 6041 if (NILP (default_filename))
4a9f0fae
SM
6042 default_filename = !NILP (initial)
6043 ? Fexpand_file_name (initial, dir)
6044 : current_buffer->filename;
570d7624
JB
6045
6046 /* If dir starts with user's homedir, change that to ~. */
6047 homedir = (char *) egetenv ("HOME");
199607e4 6048#ifdef DOS_NT
417c884a
EZ
6049 /* homedir can be NULL in temacs, since Vprocess_environment is not
6050 yet set up. We shouldn't crash in that case. */
6051 if (homedir != 0)
6052 {
6053 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
6054 CORRECT_DIR_SEPS (homedir);
6055 }
199607e4 6056#endif
d7231f93
KH
6057 if (homedir != 0)
6058 decoded_homedir
6059 = DECODE_FILE (make_unibyte_string (homedir, strlen (homedir)));
570d7624 6060 if (homedir != 0
93c30b5f 6061 && STRINGP (dir)
d7231f93
KH
6062 && !strncmp (SDATA (decoded_homedir), SDATA (dir),
6063 SBYTES (decoded_homedir))
6064 && IS_DIRECTORY_SEP (SREF (dir, SBYTES (decoded_homedir))))
570d7624 6065 {
d7231f93
KH
6066 dir = Fsubstring (dir, make_number (SCHARS (decoded_homedir) + 1), Qnil);
6067 dir = concat2 (build_string ("~"), dir);
570d7624 6068 }
8d6d9fef
AS
6069 /* Likewise for default_filename. */
6070 if (homedir != 0
6071 && STRINGP (default_filename)
d7231f93
KH
6072 && !strncmp (SDATA (decoded_homedir), SDATA (default_filename),
6073 SBYTES (decoded_homedir))
6074 && IS_DIRECTORY_SEP (SREF (default_filename, SBYTES (decoded_homedir))))
8d6d9fef
AS
6075 {
6076 default_filename
d7231f93
KH
6077 = Fsubstring (default_filename,
6078 make_number (SCHARS (decoded_homedir) + 1), Qnil);
6079 default_filename = concat2 (build_string ("~"), default_filename);
8d6d9fef
AS
6080 }
6081 if (!NILP (default_filename))
b537a6c7 6082 {
b7826503 6083 CHECK_STRING (default_filename);
b537a6c7
RS
6084 default_filename = double_dollars (default_filename);
6085 }
570d7624 6086
58cc3710 6087 if (insert_default_directory && STRINGP (dir))
570d7624
JB
6088 {
6089 insdef = dir;
265a9e55 6090 if (!NILP (initial))
570d7624 6091 {
15c65264 6092 Lisp_Object args[2], pos;
570d7624
JB
6093
6094 args[0] = insdef;
6095 args[1] = initial;
6096 insdef = Fconcat (2, args);
d5db4077 6097 pos = make_number (SCHARS (double_dollars (dir)));
8d6d9fef 6098 insdef = Fcons (double_dollars (insdef), pos);
570d7624 6099 }
6e710ae5 6100 else
8d6d9fef 6101 insdef = double_dollars (insdef);
570d7624 6102 }
58cc3710 6103 else if (STRINGP (initial))
8d6d9fef 6104 insdef = Fcons (double_dollars (initial), make_number (0));
570d7624 6105 else
8d6d9fef 6106 insdef = Qnil;
570d7624 6107
59ffe07d
KS
6108 if (!NILP (Vread_file_name_function))
6109 {
6110 Lisp_Object args[7];
6111
6112 GCPRO2 (insdef, default_filename);
6113 args[0] = Vread_file_name_function;
6114 args[1] = prompt;
6115 args[2] = dir;
6116 args[3] = default_filename;
6117 args[4] = mustmatch;
6118 args[5] = initial;
6119 args[6] = predicate;
6120 RETURN_UNGCPRO (Ffuncall (7, args));
6121 }
6122
aed13378 6123 count = SPECPDL_INDEX ();
a79485af 6124#ifdef VMS
570d7624
JB
6125 specbind (intern ("completion-ignore-case"), Qt);
6126#endif
6127
a79485af 6128 specbind (intern ("minibuffer-completing-file-name"), Qt);
efdc16c9 6129 specbind (intern ("read-file-name-predicate"),
59ffe07d 6130 (NILP (predicate) ? Qfile_exists_p : predicate));
a79485af 6131
3b7f6e60 6132 GCPRO2 (insdef, default_filename);
c60ee5e7 6133
488dd4c4 6134#if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK)
9c856db9
GM
6135 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
6136 && use_dialog_box
6137 && have_menus_p ())
6138 {
9172b88d
GM
6139 /* If DIR contains a file name, split it. */
6140 Lisp_Object file;
6141 file = Ffile_name_nondirectory (dir);
d5db4077 6142 if (SCHARS (file) && NILP (default_filename))
9172b88d
GM
6143 {
6144 default_filename = file;
6145 dir = Ffile_name_directory (dir);
6146 }
f73f57bd
JR
6147 if (!NILP(default_filename))
6148 default_filename = Fexpand_file_name (default_filename, dir);
9c856db9
GM
6149 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch);
6150 add_to_history = 1;
6151 }
6152 else
6153#endif
6154 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
6155 dir, mustmatch, insdef,
6156 Qfile_name_history, default_filename, Qnil);
62f555a5
RS
6157
6158 tem = Fsymbol_value (Qfile_name_history);
03699b14 6159 if (CONSP (tem) && EQ (XCAR (tem), val))
62f555a5
RS
6160 replace_in_history = 1;
6161
6162 /* If Fcompleting_read returned the inserted default string itself
a8c828be
RS
6163 (rather than a new string with the same contents),
6164 it has to mean that the user typed RET with the minibuffer empty.
6165 In that case, we really want to return ""
6166 so that commands such as set-visited-file-name can distinguish. */
6167 if (EQ (val, default_filename))
62f555a5
RS
6168 {
6169 /* In this case, Fcompleting_read has not added an element
6170 to the history. Maybe we should. */
6171 if (! replace_in_history)
6172 add_to_history = 1;
6173
4a9f0fae 6174 val = empty_string;
62f555a5 6175 }
570d7624 6176
570d7624 6177 unbind_to (count, Qnil);
570d7624 6178 UNGCPRO;
265a9e55 6179 if (NILP (val))
570d7624 6180 error ("No file name specified");
62f555a5 6181
8d6d9fef 6182 tem = Fstring_equal (val, CONSP (insdef) ? XCAR (insdef) : insdef);
62f555a5 6183
3b7f6e60 6184 if (!NILP (tem) && !NILP (default_filename))
62f555a5 6185 val = default_filename;
d5db4077 6186 else if (SCHARS (val) == 0 && NILP (insdef))
d9bc1c99 6187 {
3b7f6e60 6188 if (!NILP (default_filename))
62f555a5 6189 val = default_filename;
d9bc1c99
RS
6190 else
6191 error ("No default file name");
6192 }
62f555a5 6193 val = Fsubstitute_in_file_name (val);
570d7624 6194
62f555a5
RS
6195 if (replace_in_history)
6196 /* Replace what Fcompleting_read added to the history
6197 with what we will actually return. */
f3fbd155 6198 XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val));
62f555a5 6199 else if (add_to_history)
570d7624 6200 {
62f555a5
RS
6201 /* Add the value to the history--but not if it matches
6202 the last value already there. */
8d6d9fef 6203 Lisp_Object val1 = double_dollars (val);
62f555a5 6204 tem = Fsymbol_value (Qfile_name_history);
03699b14 6205 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
62f555a5 6206 Fset (Qfile_name_history,
8d6d9fef 6207 Fcons (val1, tem));
570d7624 6208 }
efdc16c9 6209
62f555a5 6210 return val;
570d7624 6211}
9c856db9 6212
570d7624 6213\f
dbda5089
GV
6214void
6215init_fileio_once ()
6216{
6217 /* Must be set before any path manipulation is performed. */
6218 XSETFASTINT (Vdirectory_sep_char, '/');
6219}
6220
9c856db9 6221\f
dfcf069d 6222void
570d7624
JB
6223syms_of_fileio ()
6224{
0bf2eed2 6225 Qexpand_file_name = intern ("expand-file-name");
273e0829 6226 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
0bf2eed2
RS
6227 Qdirectory_file_name = intern ("directory-file-name");
6228 Qfile_name_directory = intern ("file-name-directory");
6229 Qfile_name_nondirectory = intern ("file-name-nondirectory");
642ef245 6230 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
0bf2eed2 6231 Qfile_name_as_directory = intern ("file-name-as-directory");
32f4334d 6232 Qcopy_file = intern ("copy-file");
a6e6e718 6233 Qmake_directory_internal = intern ("make-directory-internal");
b272d624 6234 Qmake_directory = intern ("make-directory");
32f4334d
RS
6235 Qdelete_directory = intern ("delete-directory");
6236 Qdelete_file = intern ("delete-file");
6237 Qrename_file = intern ("rename-file");
6238 Qadd_name_to_file = intern ("add-name-to-file");
6239 Qmake_symbolic_link = intern ("make-symbolic-link");
6240 Qfile_exists_p = intern ("file-exists-p");
6241 Qfile_executable_p = intern ("file-executable-p");
6242 Qfile_readable_p = intern ("file-readable-p");
32f4334d 6243 Qfile_writable_p = intern ("file-writable-p");
1f8653eb
RS
6244 Qfile_symlink_p = intern ("file-symlink-p");
6245 Qaccess_file = intern ("access-file");
32f4334d 6246 Qfile_directory_p = intern ("file-directory-p");
adedc71d 6247 Qfile_regular_p = intern ("file-regular-p");
32f4334d
RS
6248 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
6249 Qfile_modes = intern ("file-modes");
6250 Qset_file_modes = intern ("set-file-modes");
6251 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
6252 Qinsert_file_contents = intern ("insert-file-contents");
6253 Qwrite_region = intern ("write-region");
6254 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
3ec46acd 6255 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
32f4334d 6256
642ef245 6257 staticpro (&Qexpand_file_name);
273e0829 6258 staticpro (&Qsubstitute_in_file_name);
642ef245
JB
6259 staticpro (&Qdirectory_file_name);
6260 staticpro (&Qfile_name_directory);
6261 staticpro (&Qfile_name_nondirectory);
6262 staticpro (&Qunhandled_file_name_directory);
6263 staticpro (&Qfile_name_as_directory);
15c65264 6264 staticpro (&Qcopy_file);
c34b559d 6265 staticpro (&Qmake_directory_internal);
b272d624 6266 staticpro (&Qmake_directory);
15c65264
RS
6267 staticpro (&Qdelete_directory);
6268 staticpro (&Qdelete_file);
6269 staticpro (&Qrename_file);
6270 staticpro (&Qadd_name_to_file);
6271 staticpro (&Qmake_symbolic_link);
6272 staticpro (&Qfile_exists_p);
6273 staticpro (&Qfile_executable_p);
6274 staticpro (&Qfile_readable_p);
15c65264 6275 staticpro (&Qfile_writable_p);
1f8653eb
RS
6276 staticpro (&Qaccess_file);
6277 staticpro (&Qfile_symlink_p);
15c65264 6278 staticpro (&Qfile_directory_p);
adedc71d 6279 staticpro (&Qfile_regular_p);
15c65264
RS
6280 staticpro (&Qfile_accessible_directory_p);
6281 staticpro (&Qfile_modes);
6282 staticpro (&Qset_file_modes);
6283 staticpro (&Qfile_newer_than_file_p);
6284 staticpro (&Qinsert_file_contents);
6285 staticpro (&Qwrite_region);
6286 staticpro (&Qverify_visited_file_modtime);
0a61794b 6287 staticpro (&Qset_visited_file_modtime);
642ef245
JB
6288
6289 Qfile_name_history = intern ("file-name-history");
6290 Fset (Qfile_name_history, Qnil);
15c65264
RS
6291 staticpro (&Qfile_name_history);
6292
570d7624
JB
6293 Qfile_error = intern ("file-error");
6294 staticpro (&Qfile_error);
199607e4 6295 Qfile_already_exists = intern ("file-already-exists");
570d7624 6296 staticpro (&Qfile_already_exists);
c0b7b21c
RS
6297 Qfile_date_error = intern ("file-date-error");
6298 staticpro (&Qfile_date_error);
505ab9bc
RS
6299 Qexcl = intern ("excl");
6300 staticpro (&Qexcl);
570d7624 6301
5e570b75 6302#ifdef DOS_NT
4c3c22f3
RS
6303 Qfind_buffer_file_type = intern ("find-buffer-file-type");
6304 staticpro (&Qfind_buffer_file_type);
5e570b75 6305#endif /* DOS_NT */
4c3c22f3 6306
b1d1b865 6307 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
8c1a1077 6308 doc: /* *Coding system for encoding file names.
346ebf53 6309If it is nil, `default-file-name-coding-system' (which see) is used. */);
b1d1b865
RS
6310 Vfile_name_coding_system = Qnil;
6311
cd913586
KH
6312 DEFVAR_LISP ("default-file-name-coding-system",
6313 &Vdefault_file_name_coding_system,
8c1a1077 6314 doc: /* Default coding system for encoding file names.
346ebf53 6315This variable is used only when `file-name-coding-system' is nil.
8c1a1077 6316
346ebf53 6317This variable is set/changed by the command `set-language-environment'.
8c1a1077 6318User should not set this variable manually,
346ebf53 6319instead use `file-name-coding-system' to get a constant encoding
8c1a1077 6320of file names regardless of the current language environment. */);
cd913586
KH
6321 Vdefault_file_name_coding_system = Qnil;
6322
0d420e88 6323 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
8c1a1077
PJ
6324 doc: /* *Format in which to write auto-save files.
6325Should be a list of symbols naming formats that are defined in `format-alist'.
6326If it is t, which is the default, auto-save files are written in the
6327same format as a regular save would use. */);
0d420e88
BG
6328 Vauto_save_file_format = Qt;
6329
6330 Qformat_decode = intern ("format-decode");
6331 staticpro (&Qformat_decode);
6332 Qformat_annotate_function = intern ("format-annotate-function");
6333 staticpro (&Qformat_annotate_function);
efdc16c9 6334
d6a3cc15
RS
6335 Qcar_less_than_car = intern ("car-less-than-car");
6336 staticpro (&Qcar_less_than_car);
6337
570d7624
JB
6338 Fput (Qfile_error, Qerror_conditions,
6339 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
6340 Fput (Qfile_error, Qerror_message,
6341 build_string ("File error"));
6342
6343 Fput (Qfile_already_exists, Qerror_conditions,
6344 Fcons (Qfile_already_exists,
6345 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
6346 Fput (Qfile_already_exists, Qerror_message,
6347 build_string ("File already exists"));
6348
c0b7b21c
RS
6349 Fput (Qfile_date_error, Qerror_conditions,
6350 Fcons (Qfile_date_error,
6351 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
6352 Fput (Qfile_date_error, Qerror_message,
6353 build_string ("Cannot set file date"));
6354
59ffe07d
KS
6355 DEFVAR_LISP ("read-file-name-function", &Vread_file_name_function,
6356 doc: /* If this is non-nil, `read-file-name' does its work by calling this function. */);
6357 Vread_file_name_function = Qnil;
6358
6359 DEFVAR_LISP ("read-file-name-predicate", &Vread_file_name_predicate,
6360 doc: /* Current predicate used by `read-file-name-internal'. */);
6361 Vread_file_name_predicate = Qnil;
6362
570d7624 6363 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
8c1a1077 6364 doc: /* *Non-nil means when reading a filename start with default dir in minibuffer. */);
570d7624
JB
6365 insert_default_directory = 1;
6366
6367 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
8c1a1077
PJ
6368 doc: /* *Non-nil means write new files with record format `stmlf'.
6369nil means use format `var'. This variable is meaningful only on VMS. */);
570d7624
JB
6370 vms_stmlf_recfm = 0;
6371
199607e4 6372 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
8c1a1077 6373 doc: /* Directory separator character for built-in functions that return file names.
d57563b6 6374The value is always ?/. Don't use this variable, just use `/'. */);
199607e4 6375
1d1826db 6376 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
8c1a1077
PJ
6377 doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
6378If a file name matches REGEXP, then all I/O on that file is done by calling
6379HANDLER.
6380
6381The first argument given to HANDLER is the name of the I/O primitive
6382to be handled; the remaining arguments are the arguments that were
6383passed to that primitive. For example, if you do
6384 (file-exists-p FILENAME)
6385and FILENAME is handled by HANDLER, then HANDLER is called like this:
6386 (funcall HANDLER 'file-exists-p FILENAME)
6387The function `find-file-name-handler' checks this list for a handler
6388for its argument. */);
09121adc
RS
6389 Vfile_name_handler_alist = Qnil;
6390
0414b394
KH
6391 DEFVAR_LISP ("set-auto-coding-function",
6392 &Vset_auto_coding_function,
8c1a1077
PJ
6393 doc: /* If non-nil, a function to call to decide a coding system of file.
6394Two arguments are passed to this function: the file name
6395and the length of a file contents following the point.
6396This function should return a coding system to decode the file contents.
6397It should check the file name against `auto-coding-alist'.
6398If no coding system is decided, it should check a coding system
6399specified in the heading lines with the format:
6400 -*- ... coding: CODING-SYSTEM; ... -*-
6401or local variable spec of the tailing lines with `coding:' tag. */);
0414b394 6402 Vset_auto_coding_function = Qnil;
c9e82392 6403
d6a3cc15 6404 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
8c1a1077
PJ
6405 doc: /* A list of functions to be called at the end of `insert-file-contents'.
6406Each is passed one argument, the number of bytes inserted. It should return
6407the new byte count, and leave point the same. If `insert-file-contents' is
6408intercepted by a handler from `file-name-handler-alist', that handler is
6409responsible for calling the after-insert-file-functions if appropriate. */);
d6a3cc15
RS
6410 Vafter_insert_file_functions = Qnil;
6411
6412 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
8c1a1077
PJ
6413 doc: /* A list of functions to be called at the start of `write-region'.
6414Each is passed two arguments, START and END as for `write-region'.
6415These are usually two numbers but not always; see the documentation
6416for `write-region'. The function should return a list of pairs
6417of the form (POSITION . STRING), consisting of strings to be effectively
6418inserted at the specified positions of the file being written (1 means to
6419insert before the first byte written). The POSITIONs must be sorted into
6420increasing order. If there are several functions in the list, the several
28c3eb5a
SM
6421lists are merged destructively. Alternatively, the function can return
6422with a different buffer current and value nil.*/);
d6a3cc15
RS
6423 Vwrite_region_annotate_functions = Qnil;
6424
6fc6f94b
RS
6425 DEFVAR_LISP ("write-region-annotations-so-far",
6426 &Vwrite_region_annotations_so_far,
8c1a1077
PJ
6427 doc: /* When an annotation function is called, this holds the previous annotations.
6428These are the annotations made by other annotation functions
6429that were already called. See also `write-region-annotate-functions'. */);
6fc6f94b
RS
6430 Vwrite_region_annotations_so_far = Qnil;
6431
82c2d839 6432 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
8c1a1077
PJ
6433 doc: /* A list of file name handlers that temporarily should not be used.
6434This applies only to the operation `inhibit-file-name-operation'. */);
82c2d839
RS
6435 Vinhibit_file_name_handlers = Qnil;
6436
a65970a0 6437 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
8c1a1077 6438 doc: /* The operation for which `inhibit-file-name-handlers' is applicable. */);
a65970a0
RS
6439 Vinhibit_file_name_operation = Qnil;
6440
e54d3b5d 6441 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
8c1a1077
PJ
6442 doc: /* File name in which we write a list of all auto save file names.
6443This variable is initialized automatically from `auto-save-list-file-prefix'
6444shortly after Emacs reads your `.emacs' file, if you have not yet given it
6445a non-nil value. */);
e54d3b5d
RS
6446 Vauto_save_list_file_name = Qnil;
6447
642ef245 6448 defsubr (&Sfind_file_name_handler);
570d7624
JB
6449 defsubr (&Sfile_name_directory);
6450 defsubr (&Sfile_name_nondirectory);
642ef245 6451 defsubr (&Sunhandled_file_name_directory);
570d7624
JB
6452 defsubr (&Sfile_name_as_directory);
6453 defsubr (&Sdirectory_file_name);
6454 defsubr (&Smake_temp_name);
6455 defsubr (&Sexpand_file_name);
6456 defsubr (&Ssubstitute_in_file_name);
6457 defsubr (&Scopy_file);
9bbe01fb 6458 defsubr (&Smake_directory_internal);
aa734e17 6459 defsubr (&Sdelete_directory);
570d7624
JB
6460 defsubr (&Sdelete_file);
6461 defsubr (&Srename_file);
6462 defsubr (&Sadd_name_to_file);
6463#ifdef S_IFLNK
6464 defsubr (&Smake_symbolic_link);
6465#endif /* S_IFLNK */
6466#ifdef VMS
6467 defsubr (&Sdefine_logical_name);
6468#endif /* VMS */
6469#ifdef HPUX_NET
6470 defsubr (&Ssysnetunam);
6471#endif /* HPUX_NET */
6472 defsubr (&Sfile_name_absolute_p);
6473 defsubr (&Sfile_exists_p);
6474 defsubr (&Sfile_executable_p);
6475 defsubr (&Sfile_readable_p);
6476 defsubr (&Sfile_writable_p);
1f8653eb 6477 defsubr (&Saccess_file);
570d7624
JB
6478 defsubr (&Sfile_symlink_p);
6479 defsubr (&Sfile_directory_p);
b72dea2a 6480 defsubr (&Sfile_accessible_directory_p);
f793dc6c 6481 defsubr (&Sfile_regular_p);
570d7624
JB
6482 defsubr (&Sfile_modes);
6483 defsubr (&Sset_file_modes);
c24e9a53
RS
6484 defsubr (&Sset_default_file_modes);
6485 defsubr (&Sdefault_file_modes);
570d7624
JB
6486 defsubr (&Sfile_newer_than_file_p);
6487 defsubr (&Sinsert_file_contents);
6488 defsubr (&Swrite_region);
d6a3cc15 6489 defsubr (&Scar_less_than_car);
570d7624
JB
6490 defsubr (&Sverify_visited_file_modtime);
6491 defsubr (&Sclear_visited_file_modtime);
f5d5eccf 6492 defsubr (&Svisited_file_modtime);
570d7624
JB
6493 defsubr (&Sset_visited_file_modtime);
6494 defsubr (&Sdo_auto_save);
6495 defsubr (&Sset_buffer_auto_saved);
b60247d9 6496 defsubr (&Sclear_buffer_auto_save_failure);
570d7624
JB
6497 defsubr (&Srecent_auto_save_p);
6498
6499 defsubr (&Sread_file_name_internal);
6500 defsubr (&Sread_file_name);
85ffea93 6501
483a2e10 6502#ifdef unix
85ffea93 6503 defsubr (&Sunix_sync);
483a2e10 6504#endif
570d7624 6505}