(file_name_as_directory): For empty arg, return `./'.
[bpt/emacs.git] / src / fileio.c
1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96,97,1998 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include <config.h>
22
23 #if defined (USG5) || defined (BSD_SYSTEM) || defined (LINUX)
24 #include <fcntl.h>
25 #endif
26
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #if !defined (S_ISLNK) && defined (S_IFLNK)
36 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
37 #endif
38
39 #if !defined (S_ISFIFO) && defined (S_IFIFO)
40 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
41 #endif
42
43 #if !defined (S_ISREG) && defined (S_IFREG)
44 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
45 #endif
46
47 #ifdef VMS
48 #include "vms-pwd.h"
49 #else
50 #include <pwd.h>
51 #endif
52
53 #ifdef MSDOS
54 #include "msdos.h"
55 #include <sys/param.h>
56 #if __DJGPP__ >= 2
57 #include <fcntl.h>
58 #include <string.h>
59 #endif
60 #endif
61
62 #include <ctype.h>
63
64 #ifdef VMS
65 #include "vmsdir.h"
66 #include <perror.h>
67 #include <stddef.h>
68 #include <string.h>
69 #endif
70
71 #include <errno.h>
72
73 #ifndef vax11c
74 extern int errno;
75 #endif
76
77 extern char *strerror ();
78
79 #ifdef APOLLO
80 #include <sys/time.h>
81 #endif
82
83 #ifndef USG
84 #ifndef VMS
85 #ifndef BSD4_1
86 #ifndef WINDOWSNT
87 #define HAVE_FSYNC
88 #endif
89 #endif
90 #endif
91 #endif
92
93 #include "lisp.h"
94 #include "intervals.h"
95 #include "buffer.h"
96 #include "charset.h"
97 #include "coding.h"
98 #include "window.h"
99
100 #ifdef WINDOWSNT
101 #define NOMINMAX 1
102 #include <windows.h>
103 #include <stdlib.h>
104 #include <fcntl.h>
105 #endif /* not WINDOWSNT */
106
107 #ifdef DOS_NT
108 #define CORRECT_DIR_SEPS(s) \
109 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
110 else unixtodos_filename (s); \
111 } while (0)
112 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
113 redirector allows the six letters between 'Z' and 'a' as well. */
114 #ifdef MSDOS
115 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
116 #endif
117 #ifdef WINDOWSNT
118 #define IS_DRIVE(x) isalpha (x)
119 #endif
120 /* Need to lower-case the drive letter, or else expanded
121 filenames will sometimes compare inequal, because
122 `expand-file-name' doesn't always down-case the drive letter. */
123 #define DRIVE_LETTER(x) (tolower (x))
124 #endif
125
126 #ifdef VMS
127 #include <file.h>
128 #include <rmsdef.h>
129 #include <fab.h>
130 #include <nam.h>
131 #endif
132
133 #include "systime.h"
134
135 #ifdef HPUX
136 #include <netio.h>
137 #ifndef HPUX8
138 #ifndef HPUX9
139 #include <errnet.h>
140 #endif
141 #endif
142 #endif
143
144 #ifndef O_WRONLY
145 #define O_WRONLY 1
146 #endif
147
148 #ifndef O_RDONLY
149 #define O_RDONLY 0
150 #endif
151
152 #define min(a, b) ((a) < (b) ? (a) : (b))
153 #define max(a, b) ((a) > (b) ? (a) : (b))
154
155 /* Nonzero during writing of auto-save files */
156 int auto_saving;
157
158 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
159 a new file with the same mode as the original */
160 int auto_save_mode_bits;
161
162 /* Coding system for file names, or nil if none. */
163 Lisp_Object Vfile_name_coding_system;
164
165 /* Coding system for file names used only when
166 Vfile_name_coding_system is nil. */
167 Lisp_Object Vdefault_file_name_coding_system;
168
169 /* Alist of elements (REGEXP . HANDLER) for file names
170 whose I/O is done with a special handler. */
171 Lisp_Object Vfile_name_handler_alist;
172
173 /* Format for auto-save files */
174 Lisp_Object Vauto_save_file_format;
175
176 /* Lisp functions for translating file formats */
177 Lisp_Object Qformat_decode, Qformat_annotate_function;
178
179 /* Function to be called to decide a coding system of a reading file. */
180 Lisp_Object Vset_auto_coding_function;
181
182 /* Functions to be called to process text properties in inserted file. */
183 Lisp_Object Vafter_insert_file_functions;
184
185 /* Functions to be called to create text property annotations for file. */
186 Lisp_Object Vwrite_region_annotate_functions;
187
188 /* During build_annotations, each time an annotation function is called,
189 this holds the annotations made by the previous functions. */
190 Lisp_Object Vwrite_region_annotations_so_far;
191
192 /* File name in which we write a list of all our auto save files. */
193 Lisp_Object Vauto_save_list_file_name;
194
195 /* Nonzero means, when reading a filename in the minibuffer,
196 start out by inserting the default directory into the minibuffer. */
197 int insert_default_directory;
198
199 /* On VMS, nonzero means write new files with record format stmlf.
200 Zero means use var format. */
201 int vms_stmlf_recfm;
202
203 /* On NT, specifies the directory separator character, used (eg.) when
204 expanding file names. This can be bound to / or \. */
205 Lisp_Object Vdirectory_sep_char;
206
207 extern Lisp_Object Vuser_login_name;
208
209 extern int minibuf_level;
210
211 extern int minibuffer_auto_raise;
212
213 /* These variables describe handlers that have "already" had a chance
214 to handle the current operation.
215
216 Vinhibit_file_name_handlers is a list of file name handlers.
217 Vinhibit_file_name_operation is the operation being handled.
218 If we try to handle that operation, we ignore those handlers. */
219
220 static Lisp_Object Vinhibit_file_name_handlers;
221 static Lisp_Object Vinhibit_file_name_operation;
222
223 Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
224
225 Lisp_Object Qfile_name_history;
226
227 Lisp_Object Qcar_less_than_car;
228
229 static int a_write P_ ((int, char *, int, int,
230 Lisp_Object *, struct coding_system *));
231 static int e_write P_ ((int, char *, int, struct coding_system *));
232 \f
233 void
234 report_file_error (string, data)
235 char *string;
236 Lisp_Object data;
237 {
238 Lisp_Object errstring;
239
240 errstring = build_string (strerror (errno));
241
242 /* System error messages are capitalized. Downcase the initial
243 unless it is followed by a slash. */
244 if (XSTRING (errstring)->data[1] != '/')
245 XSTRING (errstring)->data[0] = DOWNCASE (XSTRING (errstring)->data[0]);
246
247 while (1)
248 Fsignal (Qfile_error,
249 Fcons (build_string (string), Fcons (errstring, data)));
250 }
251
252 Lisp_Object
253 close_file_unwind (fd)
254 Lisp_Object fd;
255 {
256 close (XFASTINT (fd));
257 return Qnil;
258 }
259
260 /* Restore point, having saved it as a marker. */
261
262 static Lisp_Object
263 restore_point_unwind (location)
264 Lisp_Object location;
265 {
266 Fgoto_char (location);
267 Fset_marker (location, Qnil, Qnil);
268 return Qnil;
269 }
270 \f
271 Lisp_Object Qexpand_file_name;
272 Lisp_Object Qsubstitute_in_file_name;
273 Lisp_Object Qdirectory_file_name;
274 Lisp_Object Qfile_name_directory;
275 Lisp_Object Qfile_name_nondirectory;
276 Lisp_Object Qunhandled_file_name_directory;
277 Lisp_Object Qfile_name_as_directory;
278 Lisp_Object Qcopy_file;
279 Lisp_Object Qmake_directory_internal;
280 Lisp_Object Qdelete_directory;
281 Lisp_Object Qdelete_file;
282 Lisp_Object Qrename_file;
283 Lisp_Object Qadd_name_to_file;
284 Lisp_Object Qmake_symbolic_link;
285 Lisp_Object Qfile_exists_p;
286 Lisp_Object Qfile_executable_p;
287 Lisp_Object Qfile_readable_p;
288 Lisp_Object Qfile_writable_p;
289 Lisp_Object Qfile_symlink_p;
290 Lisp_Object Qaccess_file;
291 Lisp_Object Qfile_directory_p;
292 Lisp_Object Qfile_regular_p;
293 Lisp_Object Qfile_accessible_directory_p;
294 Lisp_Object Qfile_modes;
295 Lisp_Object Qset_file_modes;
296 Lisp_Object Qfile_newer_than_file_p;
297 Lisp_Object Qinsert_file_contents;
298 Lisp_Object Qwrite_region;
299 Lisp_Object Qverify_visited_file_modtime;
300 Lisp_Object Qset_visited_file_modtime;
301
302 DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
303 "Return FILENAME's handler function for OPERATION, if it has one.\n\
304 Otherwise, return nil.\n\
305 A file name is handled if one of the regular expressions in\n\
306 `file-name-handler-alist' matches it.\n\n\
307 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
308 any handlers that are members of `inhibit-file-name-handlers',\n\
309 but we still do run any other handlers. This lets handlers\n\
310 use the standard functions without calling themselves recursively.")
311 (filename, operation)
312 Lisp_Object filename, operation;
313 {
314 /* This function must not munge the match data. */
315 Lisp_Object chain, inhibited_handlers;
316
317 CHECK_STRING (filename, 0);
318
319 if (EQ (operation, Vinhibit_file_name_operation))
320 inhibited_handlers = Vinhibit_file_name_handlers;
321 else
322 inhibited_handlers = Qnil;
323
324 for (chain = Vfile_name_handler_alist; CONSP (chain);
325 chain = XCONS (chain)->cdr)
326 {
327 Lisp_Object elt;
328 elt = XCONS (chain)->car;
329 if (CONSP (elt))
330 {
331 Lisp_Object string;
332 string = XCONS (elt)->car;
333 if (STRINGP (string) && fast_string_match (string, filename) >= 0)
334 {
335 Lisp_Object handler, tem;
336
337 handler = XCONS (elt)->cdr;
338 tem = Fmemq (handler, inhibited_handlers);
339 if (NILP (tem))
340 return handler;
341 }
342 }
343
344 QUIT;
345 }
346 return Qnil;
347 }
348 \f
349 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
350 1, 1, 0,
351 "Return the directory component in file name FILENAME.\n\
352 Return nil if FILENAME does not include a directory.\n\
353 Otherwise return a directory spec.\n\
354 Given a Unix syntax file name, returns a string ending in slash;\n\
355 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
356 (filename)
357 Lisp_Object filename;
358 {
359 register unsigned char *beg;
360 register unsigned char *p;
361 Lisp_Object handler;
362
363 CHECK_STRING (filename, 0);
364
365 /* If the file name has special constructs in it,
366 call the corresponding file handler. */
367 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
368 if (!NILP (handler))
369 return call2 (handler, Qfile_name_directory, filename);
370
371 #ifdef FILE_SYSTEM_CASE
372 filename = FILE_SYSTEM_CASE (filename);
373 #endif
374 beg = XSTRING (filename)->data;
375 #ifdef DOS_NT
376 beg = strcpy (alloca (strlen (beg) + 1), beg);
377 #endif
378 p = beg + STRING_BYTES (XSTRING (filename));
379
380 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
381 #ifdef VMS
382 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
383 #endif /* VMS */
384 #ifdef DOS_NT
385 /* only recognise drive specifier at beginning */
386 && !(p[-1] == ':' && p == beg + 2)
387 #endif
388 ) p--;
389
390 if (p == beg)
391 return Qnil;
392 #ifdef DOS_NT
393 /* Expansion of "c:" to drive and default directory. */
394 if (p == beg + 2 && beg[1] == ':')
395 {
396 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
397 unsigned char *res = alloca (MAXPATHLEN + 1);
398 if (getdefdir (toupper (*beg) - 'A' + 1, res))
399 {
400 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
401 strcat (res, "/");
402 beg = res;
403 p = beg + strlen (beg);
404 }
405 }
406 CORRECT_DIR_SEPS (beg);
407 #endif /* DOS_NT */
408
409 if (STRING_MULTIBYTE (filename))
410 return make_string (beg, p - beg);
411 return make_unibyte_string (beg, p - beg);
412 }
413
414 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
415 Sfile_name_nondirectory, 1, 1, 0,
416 "Return file name FILENAME sans its directory.\n\
417 For example, in a Unix-syntax file name,\n\
418 this is everything after the last slash,\n\
419 or the entire name if it contains no slash.")
420 (filename)
421 Lisp_Object filename;
422 {
423 register unsigned char *beg, *p, *end;
424 Lisp_Object handler;
425
426 CHECK_STRING (filename, 0);
427
428 /* If the file name has special constructs in it,
429 call the corresponding file handler. */
430 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
431 if (!NILP (handler))
432 return call2 (handler, Qfile_name_nondirectory, filename);
433
434 beg = XSTRING (filename)->data;
435 end = p = beg + STRING_BYTES (XSTRING (filename));
436
437 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
438 #ifdef VMS
439 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
440 #endif /* VMS */
441 #ifdef DOS_NT
442 /* only recognise drive specifier at beginning */
443 && !(p[-1] == ':' && p == beg + 2)
444 #endif
445 )
446 p--;
447
448 if (STRING_MULTIBYTE (filename))
449 return make_string (p, end - p);
450 return make_unibyte_string (p, end - p);
451 }
452
453 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory,
454 Sunhandled_file_name_directory, 1, 1, 0,
455 "Return a directly usable directory name somehow associated with FILENAME.\n\
456 A `directly usable' directory name is one that may be used without the\n\
457 intervention of any file handler.\n\
458 If FILENAME is a directly usable file itself, return\n\
459 \(file-name-directory FILENAME).\n\
460 The `call-process' and `start-process' functions use this function to\n\
461 get a current directory to run processes in.")
462 (filename)
463 Lisp_Object filename;
464 {
465 Lisp_Object handler;
466
467 /* If the file name has special constructs in it,
468 call the corresponding file handler. */
469 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
470 if (!NILP (handler))
471 return call2 (handler, Qunhandled_file_name_directory, filename);
472
473 return Ffile_name_directory (filename);
474 }
475
476 \f
477 char *
478 file_name_as_directory (out, in)
479 char *out, *in;
480 {
481 int size = strlen (in) - 1;
482
483 strcpy (out, in);
484
485 if (size < 0)
486 {
487 out[0] = '.';
488 out[1] = '/';
489 out[2] = 0;
490 return out;
491 }
492
493 #ifdef VMS
494 /* Is it already a directory string? */
495 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
496 return out;
497 /* Is it a VMS directory file name? If so, hack VMS syntax. */
498 else if (! index (in, '/')
499 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
500 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
501 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
502 || ! strncmp (&in[size - 5], ".dir", 4))
503 && (in[size - 1] == '.' || in[size - 1] == ';')
504 && in[size] == '1')))
505 {
506 register char *p, *dot;
507 char brack;
508
509 /* x.dir -> [.x]
510 dir:x.dir --> dir:[x]
511 dir:[x]y.dir --> dir:[x.y] */
512 p = in + size;
513 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
514 if (p != in)
515 {
516 strncpy (out, in, p - in);
517 out[p - in] = '\0';
518 if (*p == ':')
519 {
520 brack = ']';
521 strcat (out, ":[");
522 }
523 else
524 {
525 brack = *p;
526 strcat (out, ".");
527 }
528 p++;
529 }
530 else
531 {
532 brack = ']';
533 strcpy (out, "[.");
534 }
535 dot = index (p, '.');
536 if (dot)
537 {
538 /* blindly remove any extension */
539 size = strlen (out) + (dot - p);
540 strncat (out, p, dot - p);
541 }
542 else
543 {
544 strcat (out, p);
545 size = strlen (out);
546 }
547 out[size++] = brack;
548 out[size] = '\0';
549 }
550 #else /* not VMS */
551 /* For Unix syntax, Append a slash if necessary */
552 if (!IS_DIRECTORY_SEP (out[size]))
553 {
554 out[size + 1] = DIRECTORY_SEP;
555 out[size + 2] = '\0';
556 }
557 #ifdef DOS_NT
558 CORRECT_DIR_SEPS (out);
559 #endif
560 #endif /* not VMS */
561 return out;
562 }
563
564 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
565 Sfile_name_as_directory, 1, 1, 0,
566 "Return a string representing file FILENAME interpreted as a directory.\n\
567 This operation exists because a directory is also a file, but its name as\n\
568 a directory is different from its name as a file.\n\
569 The result can be used as the value of `default-directory'\n\
570 or passed as second argument to `expand-file-name'.\n\
571 For a Unix-syntax file name, just appends a slash.\n\
572 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
573 (file)
574 Lisp_Object file;
575 {
576 char *buf;
577 Lisp_Object handler;
578
579 CHECK_STRING (file, 0);
580 if (NILP (file))
581 return Qnil;
582
583 /* If the file name has special constructs in it,
584 call the corresponding file handler. */
585 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
586 if (!NILP (handler))
587 return call2 (handler, Qfile_name_as_directory, file);
588
589 buf = (char *) alloca (STRING_BYTES (XSTRING (file)) + 10);
590 return build_string (file_name_as_directory (buf, XSTRING (file)->data));
591 }
592 \f
593 /*
594 * Convert from directory name to filename.
595 * On VMS:
596 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
597 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
598 * On UNIX, it's simple: just make sure there isn't a terminating /
599
600 * Value is nonzero if the string output is different from the input.
601 */
602
603 int
604 directory_file_name (src, dst)
605 char *src, *dst;
606 {
607 long slen;
608 #ifdef VMS
609 long rlen;
610 char * ptr, * rptr;
611 char bracket;
612 struct FAB fab = cc$rms_fab;
613 struct NAM nam = cc$rms_nam;
614 char esa[NAM$C_MAXRSS];
615 #endif /* VMS */
616
617 slen = strlen (src);
618 #ifdef VMS
619 if (! index (src, '/')
620 && (src[slen - 1] == ']'
621 || src[slen - 1] == ':'
622 || src[slen - 1] == '>'))
623 {
624 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
625 fab.fab$l_fna = src;
626 fab.fab$b_fns = slen;
627 fab.fab$l_nam = &nam;
628 fab.fab$l_fop = FAB$M_NAM;
629
630 nam.nam$l_esa = esa;
631 nam.nam$b_ess = sizeof esa;
632 nam.nam$b_nop |= NAM$M_SYNCHK;
633
634 /* We call SYS$PARSE to handle such things as [--] for us. */
635 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
636 {
637 slen = nam.nam$b_esl;
638 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
639 slen -= 2;
640 esa[slen] = '\0';
641 src = esa;
642 }
643 if (src[slen - 1] != ']' && src[slen - 1] != '>')
644 {
645 /* what about when we have logical_name:???? */
646 if (src[slen - 1] == ':')
647 { /* Xlate logical name and see what we get */
648 ptr = strcpy (dst, src); /* upper case for getenv */
649 while (*ptr)
650 {
651 if ('a' <= *ptr && *ptr <= 'z')
652 *ptr -= 040;
653 ptr++;
654 }
655 dst[slen - 1] = 0; /* remove colon */
656 if (!(src = egetenv (dst)))
657 return 0;
658 /* should we jump to the beginning of this procedure?
659 Good points: allows us to use logical names that xlate
660 to Unix names,
661 Bad points: can be a problem if we just translated to a device
662 name...
663 For now, I'll punt and always expect VMS names, and hope for
664 the best! */
665 slen = strlen (src);
666 if (src[slen - 1] != ']' && src[slen - 1] != '>')
667 { /* no recursion here! */
668 strcpy (dst, src);
669 return 0;
670 }
671 }
672 else
673 { /* not a directory spec */
674 strcpy (dst, src);
675 return 0;
676 }
677 }
678 bracket = src[slen - 1];
679
680 /* If bracket is ']' or '>', bracket - 2 is the corresponding
681 opening bracket. */
682 ptr = index (src, bracket - 2);
683 if (ptr == 0)
684 { /* no opening bracket */
685 strcpy (dst, src);
686 return 0;
687 }
688 if (!(rptr = rindex (src, '.')))
689 rptr = ptr;
690 slen = rptr - src;
691 strncpy (dst, src, slen);
692 dst[slen] = '\0';
693 if (*rptr == '.')
694 {
695 dst[slen++] = bracket;
696 dst[slen] = '\0';
697 }
698 else
699 {
700 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
701 then translate the device and recurse. */
702 if (dst[slen - 1] == ':'
703 && dst[slen - 2] != ':' /* skip decnet nodes */
704 && strcmp (src + slen, "[000000]") == 0)
705 {
706 dst[slen - 1] = '\0';
707 if ((ptr = egetenv (dst))
708 && (rlen = strlen (ptr) - 1) > 0
709 && (ptr[rlen] == ']' || ptr[rlen] == '>')
710 && ptr[rlen - 1] == '.')
711 {
712 char * buf = (char *) alloca (strlen (ptr) + 1);
713 strcpy (buf, ptr);
714 buf[rlen - 1] = ']';
715 buf[rlen] = '\0';
716 return directory_file_name (buf, dst);
717 }
718 else
719 dst[slen - 1] = ':';
720 }
721 strcat (dst, "[000000]");
722 slen += 8;
723 }
724 rptr++;
725 rlen = strlen (rptr) - 1;
726 strncat (dst, rptr, rlen);
727 dst[slen + rlen] = '\0';
728 strcat (dst, ".DIR.1");
729 return 1;
730 }
731 #endif /* VMS */
732 /* Process as Unix format: just remove any final slash.
733 But leave "/" unchanged; do not change it to "". */
734 strcpy (dst, src);
735 #ifdef APOLLO
736 /* Handle // as root for apollo's. */
737 if ((slen > 2 && dst[slen - 1] == '/')
738 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
739 dst[slen - 1] = 0;
740 #else
741 if (slen > 1
742 && IS_DIRECTORY_SEP (dst[slen - 1])
743 #ifdef DOS_NT
744 && !IS_ANY_SEP (dst[slen - 2])
745 #endif
746 )
747 dst[slen - 1] = 0;
748 #endif
749 #ifdef DOS_NT
750 CORRECT_DIR_SEPS (dst);
751 #endif
752 return 1;
753 }
754
755 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
756 1, 1, 0,
757 "Returns the file name of the directory named DIRECTORY.\n\
758 This is the name of the file that holds the data for the directory DIRECTORY.\n\
759 This operation exists because a directory is also a file, but its name as\n\
760 a directory is different from its name as a file.\n\
761 In Unix-syntax, this function just removes the final slash.\n\
762 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
763 it returns a file name such as \"[X]Y.DIR.1\".")
764 (directory)
765 Lisp_Object directory;
766 {
767 char *buf;
768 Lisp_Object handler;
769
770 CHECK_STRING (directory, 0);
771
772 if (NILP (directory))
773 return Qnil;
774
775 /* If the file name has special constructs in it,
776 call the corresponding file handler. */
777 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
778 if (!NILP (handler))
779 return call2 (handler, Qdirectory_file_name, directory);
780
781 #ifdef VMS
782 /* 20 extra chars is insufficient for VMS, since we might perform a
783 logical name translation. an equivalence string can be up to 255
784 chars long, so grab that much extra space... - sss */
785 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20 + 255);
786 #else
787 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20);
788 #endif
789 directory_file_name (XSTRING (directory)->data, buf);
790 return build_string (buf);
791 }
792
793 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
794 "Generate temporary file name (string) starting with PREFIX (a string).\n\
795 The Emacs process number forms part of the result,\n\
796 so there is no danger of generating a name being used by another process.\n\
797 In addition, this function makes an attempt to choose a name\n\
798 which has no existing file.")
799 (prefix)
800 Lisp_Object prefix;
801 {
802 char *temp;
803 Lisp_Object val;
804 #ifdef MSDOS
805 /* Don't use too many characters of the restricted 8+3 DOS
806 filename space. */
807 val = concat2 (prefix, build_string ("a.XXX"));
808 #else
809 val = concat2 (prefix, build_string ("XXXXXX"));
810 #endif
811 temp = mktemp (XSTRING (val)->data);
812 if (! temp)
813 error ("No temporary file names based on %s are available",
814 XSTRING (prefix)->data);
815 #ifdef DOS_NT
816 CORRECT_DIR_SEPS (XSTRING (val)->data);
817 #endif
818 return val;
819 }
820 \f
821 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
822 "Convert filename NAME to absolute, and canonicalize it.\n\
823 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
824 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
825 the current buffer's value of default-directory is used.\n\
826 File name components that are `.' are removed, and \n\
827 so are file name components followed by `..', along with the `..' itself;\n\
828 note that these simplifications are done without checking the resulting\n\
829 file names in the file system.\n\
830 An initial `~/' expands to your home directory.\n\
831 An initial `~USER/' expands to USER's home directory.\n\
832 See also the function `substitute-in-file-name'.")
833 (name, default_directory)
834 Lisp_Object name, default_directory;
835 {
836 unsigned char *nm;
837
838 register unsigned char *newdir, *p, *o;
839 int tlen;
840 unsigned char *target;
841 struct passwd *pw;
842 #ifdef VMS
843 unsigned char * colon = 0;
844 unsigned char * close = 0;
845 unsigned char * slash = 0;
846 unsigned char * brack = 0;
847 int lbrack = 0, rbrack = 0;
848 int dots = 0;
849 #endif /* VMS */
850 #ifdef DOS_NT
851 int drive = 0;
852 int collapse_newdir = 1;
853 #endif /* DOS_NT */
854 int length;
855 Lisp_Object handler;
856
857 CHECK_STRING (name, 0);
858
859 /* If the file name has special constructs in it,
860 call the corresponding file handler. */
861 handler = Ffind_file_name_handler (name, Qexpand_file_name);
862 if (!NILP (handler))
863 return call3 (handler, Qexpand_file_name, name, default_directory);
864
865 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
866 if (NILP (default_directory))
867 default_directory = current_buffer->directory;
868 if (! STRINGP (default_directory))
869 default_directory = build_string ("/");
870
871 if (!NILP (default_directory))
872 {
873 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
874 if (!NILP (handler))
875 return call3 (handler, Qexpand_file_name, name, default_directory);
876 }
877
878 o = XSTRING (default_directory)->data;
879
880 /* Make sure DEFAULT_DIRECTORY is properly expanded.
881 It would be better to do this down below where we actually use
882 default_directory. Unfortunately, calling Fexpand_file_name recursively
883 could invoke GC, and the strings might be relocated. This would
884 be annoying because we have pointers into strings lying around
885 that would need adjusting, and people would add new pointers to
886 the code and forget to adjust them, resulting in intermittent bugs.
887 Putting this call here avoids all that crud.
888
889 The EQ test avoids infinite recursion. */
890 if (! NILP (default_directory) && !EQ (default_directory, name)
891 /* Save time in some common cases - as long as default_directory
892 is not relative, it can be canonicalized with name below (if it
893 is needed at all) without requiring it to be expanded now. */
894 #ifdef DOS_NT
895 /* Detect MSDOS file names with drive specifiers. */
896 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
897 #ifdef WINDOWSNT
898 /* Detect Windows file names in UNC format. */
899 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
900 #endif
901 #else /* not DOS_NT */
902 /* Detect Unix absolute file names (/... alone is not absolute on
903 DOS or Windows). */
904 && ! (IS_DIRECTORY_SEP (o[0]))
905 #endif /* not DOS_NT */
906 )
907 {
908 struct gcpro gcpro1;
909
910 GCPRO1 (name);
911 default_directory = Fexpand_file_name (default_directory, Qnil);
912 UNGCPRO;
913 }
914
915 #ifdef VMS
916 /* Filenames on VMS are always upper case. */
917 name = Fupcase (name);
918 #endif
919 #ifdef FILE_SYSTEM_CASE
920 name = FILE_SYSTEM_CASE (name);
921 #endif
922
923 nm = XSTRING (name)->data;
924
925 #ifdef DOS_NT
926 /* We will force directory separators to be either all \ or /, so make
927 a local copy to modify, even if there ends up being no change. */
928 nm = strcpy (alloca (strlen (nm) + 1), nm);
929
930 /* Find and remove drive specifier if present; this makes nm absolute
931 even if the rest of the name appears to be relative. */
932 {
933 unsigned char *colon = rindex (nm, ':');
934
935 if (colon)
936 /* Only recognize colon as part of drive specifier if there is a
937 single alphabetic character preceeding the colon (and if the
938 character before the drive letter, if present, is a directory
939 separator); this is to support the remote system syntax used by
940 ange-ftp, and the "po:username" syntax for POP mailboxes. */
941 look_again:
942 if (nm == colon)
943 nm++;
944 else if (IS_DRIVE (colon[-1])
945 && (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2])))
946 {
947 drive = colon[-1];
948 nm = colon + 1;
949 }
950 else
951 {
952 while (--colon >= nm)
953 if (colon[0] == ':')
954 goto look_again;
955 }
956 }
957
958 #ifdef WINDOWSNT
959 /* If we see "c://somedir", we want to strip the first slash after the
960 colon when stripping the drive letter. Otherwise, this expands to
961 "//somedir". */
962 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
963 nm++;
964 #endif /* WINDOWSNT */
965 #endif /* DOS_NT */
966
967 #ifdef WINDOWSNT
968 /* Discard any previous drive specifier if nm is now in UNC format. */
969 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
970 {
971 drive = 0;
972 }
973 #endif
974
975 /* If nm is absolute, look for /./ or /../ sequences; if none are
976 found, we can probably return right away. We will avoid allocating
977 a new string if name is already fully expanded. */
978 if (
979 IS_DIRECTORY_SEP (nm[0])
980 #ifdef MSDOS
981 && drive
982 #endif
983 #ifdef WINDOWSNT
984 && (drive || IS_DIRECTORY_SEP (nm[1]))
985 #endif
986 #ifdef VMS
987 || index (nm, ':')
988 #endif /* VMS */
989 )
990 {
991 /* If it turns out that the filename we want to return is just a
992 suffix of FILENAME, we don't need to go through and edit
993 things; we just need to construct a new string using data
994 starting at the middle of FILENAME. If we set lose to a
995 non-zero value, that means we've discovered that we can't do
996 that cool trick. */
997 int lose = 0;
998
999 p = nm;
1000 while (*p)
1001 {
1002 /* Since we know the name is absolute, we can assume that each
1003 element starts with a "/". */
1004
1005 /* "." and ".." are hairy. */
1006 if (IS_DIRECTORY_SEP (p[0])
1007 && p[1] == '.'
1008 && (IS_DIRECTORY_SEP (p[2])
1009 || p[2] == 0
1010 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
1011 || p[3] == 0))))
1012 lose = 1;
1013 #ifdef VMS
1014 if (p[0] == '\\')
1015 lose = 1;
1016 if (p[0] == '/') {
1017 /* if dev:[dir]/, move nm to / */
1018 if (!slash && p > nm && (brack || colon)) {
1019 nm = (brack ? brack + 1 : colon + 1);
1020 lbrack = rbrack = 0;
1021 brack = 0;
1022 colon = 0;
1023 }
1024 slash = p;
1025 }
1026 if (p[0] == '-')
1027 #ifndef VMS4_4
1028 /* VMS pre V4.4,convert '-'s in filenames. */
1029 if (lbrack == rbrack)
1030 {
1031 if (dots < 2) /* this is to allow negative version numbers */
1032 p[0] = '_';
1033 }
1034 else
1035 #endif /* VMS4_4 */
1036 if (lbrack > rbrack &&
1037 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1038 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1039 lose = 1;
1040 #ifndef VMS4_4
1041 else
1042 p[0] = '_';
1043 #endif /* VMS4_4 */
1044 /* count open brackets, reset close bracket pointer */
1045 if (p[0] == '[' || p[0] == '<')
1046 lbrack++, brack = 0;
1047 /* count close brackets, set close bracket pointer */
1048 if (p[0] == ']' || p[0] == '>')
1049 rbrack++, brack = p;
1050 /* detect ][ or >< */
1051 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1052 lose = 1;
1053 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1054 nm = p + 1, lose = 1;
1055 if (p[0] == ':' && (colon || slash))
1056 /* if dev1:[dir]dev2:, move nm to dev2: */
1057 if (brack)
1058 {
1059 nm = brack + 1;
1060 brack = 0;
1061 }
1062 /* if /name/dev:, move nm to dev: */
1063 else if (slash)
1064 nm = slash + 1;
1065 /* if node::dev:, move colon following dev */
1066 else if (colon && colon[-1] == ':')
1067 colon = p;
1068 /* if dev1:dev2:, move nm to dev2: */
1069 else if (colon && colon[-1] != ':')
1070 {
1071 nm = colon + 1;
1072 colon = 0;
1073 }
1074 if (p[0] == ':' && !colon)
1075 {
1076 if (p[1] == ':')
1077 p++;
1078 colon = p;
1079 }
1080 if (lbrack == rbrack)
1081 if (p[0] == ';')
1082 dots = 2;
1083 else if (p[0] == '.')
1084 dots++;
1085 #endif /* VMS */
1086 p++;
1087 }
1088 if (!lose)
1089 {
1090 #ifdef VMS
1091 if (index (nm, '/'))
1092 return build_string (sys_translate_unix (nm));
1093 #endif /* VMS */
1094 #ifdef DOS_NT
1095 /* Make sure directories are all separated with / or \ as
1096 desired, but avoid allocation of a new string when not
1097 required. */
1098 CORRECT_DIR_SEPS (nm);
1099 #ifdef WINDOWSNT
1100 if (IS_DIRECTORY_SEP (nm[1]))
1101 {
1102 if (strcmp (nm, XSTRING (name)->data) != 0)
1103 name = build_string (nm);
1104 }
1105 else
1106 #endif
1107 /* drive must be set, so this is okay */
1108 if (strcmp (nm - 2, XSTRING (name)->data) != 0)
1109 {
1110 name = make_string (nm - 2, p - nm + 2);
1111 XSTRING (name)->data[0] = DRIVE_LETTER (drive);
1112 XSTRING (name)->data[1] = ':';
1113 }
1114 return name;
1115 #else /* not DOS_NT */
1116 if (nm == XSTRING (name)->data)
1117 return name;
1118 return build_string (nm);
1119 #endif /* not DOS_NT */
1120 }
1121 }
1122
1123 /* At this point, nm might or might not be an absolute file name. We
1124 need to expand ~ or ~user if present, otherwise prefix nm with
1125 default_directory if nm is not absolute, and finally collapse /./
1126 and /foo/../ sequences.
1127
1128 We set newdir to be the appropriate prefix if one is needed:
1129 - the relevant user directory if nm starts with ~ or ~user
1130 - the specified drive's working dir (DOS/NT only) if nm does not
1131 start with /
1132 - the value of default_directory.
1133
1134 Note that these prefixes are not guaranteed to be absolute (except
1135 for the working dir of a drive). Therefore, to ensure we always
1136 return an absolute name, if the final prefix is not absolute we
1137 append it to the current working directory. */
1138
1139 newdir = 0;
1140
1141 if (nm[0] == '~') /* prefix ~ */
1142 {
1143 if (IS_DIRECTORY_SEP (nm[1])
1144 #ifdef VMS
1145 || nm[1] == ':'
1146 #endif /* VMS */
1147 || nm[1] == 0) /* ~ by itself */
1148 {
1149 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1150 newdir = (unsigned char *) "";
1151 nm++;
1152 #ifdef DOS_NT
1153 collapse_newdir = 0;
1154 #endif
1155 #ifdef VMS
1156 nm++; /* Don't leave the slash in nm. */
1157 #endif /* VMS */
1158 }
1159 else /* ~user/filename */
1160 {
1161 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
1162 #ifdef VMS
1163 && *p != ':'
1164 #endif /* VMS */
1165 ); p++);
1166 o = (unsigned char *) alloca (p - nm + 1);
1167 bcopy ((char *) nm, o, p - nm);
1168 o [p - nm] = 0;
1169
1170 pw = (struct passwd *) getpwnam (o + 1);
1171 if (pw)
1172 {
1173 newdir = (unsigned char *) pw -> pw_dir;
1174 #ifdef VMS
1175 nm = p + 1; /* skip the terminator */
1176 #else
1177 nm = p;
1178 #ifdef DOS_NT
1179 collapse_newdir = 0;
1180 #endif
1181 #endif /* VMS */
1182 }
1183
1184 /* If we don't find a user of that name, leave the name
1185 unchanged; don't move nm forward to p. */
1186 }
1187 }
1188
1189 #ifdef DOS_NT
1190 /* On DOS and Windows, nm is absolute if a drive name was specified;
1191 use the drive's current directory as the prefix if needed. */
1192 if (!newdir && drive)
1193 {
1194 /* Get default directory if needed to make nm absolute. */
1195 if (!IS_DIRECTORY_SEP (nm[0]))
1196 {
1197 newdir = alloca (MAXPATHLEN + 1);
1198 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1199 newdir = NULL;
1200 }
1201 if (!newdir)
1202 {
1203 /* Either nm starts with /, or drive isn't mounted. */
1204 newdir = alloca (4);
1205 newdir[0] = DRIVE_LETTER (drive);
1206 newdir[1] = ':';
1207 newdir[2] = '/';
1208 newdir[3] = 0;
1209 }
1210 }
1211 #endif /* DOS_NT */
1212
1213 /* Finally, if no prefix has been specified and nm is not absolute,
1214 then it must be expanded relative to default_directory. */
1215
1216 if (1
1217 #ifndef DOS_NT
1218 /* /... alone is not absolute on DOS and Windows. */
1219 && !IS_DIRECTORY_SEP (nm[0])
1220 #endif
1221 #ifdef WINDOWSNT
1222 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1223 #endif
1224 #ifdef VMS
1225 && !index (nm, ':')
1226 #endif
1227 && !newdir)
1228 {
1229 newdir = XSTRING (default_directory)->data;
1230 }
1231
1232 #ifdef DOS_NT
1233 if (newdir)
1234 {
1235 /* First ensure newdir is an absolute name. */
1236 if (
1237 /* Detect MSDOS file names with drive specifiers. */
1238 ! (IS_DRIVE (newdir[0])
1239 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1240 #ifdef WINDOWSNT
1241 /* Detect Windows file names in UNC format. */
1242 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1243 #endif
1244 )
1245 {
1246 /* Effectively, let newdir be (expand-file-name newdir cwd).
1247 Because of the admonition against calling expand-file-name
1248 when we have pointers into lisp strings, we accomplish this
1249 indirectly by prepending newdir to nm if necessary, and using
1250 cwd (or the wd of newdir's drive) as the new newdir. */
1251
1252 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1253 {
1254 drive = newdir[0];
1255 newdir += 2;
1256 }
1257 if (!IS_DIRECTORY_SEP (nm[0]))
1258 {
1259 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1260 file_name_as_directory (tmp, newdir);
1261 strcat (tmp, nm);
1262 nm = tmp;
1263 }
1264 newdir = alloca (MAXPATHLEN + 1);
1265 if (drive)
1266 {
1267 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1268 newdir = "/";
1269 }
1270 else
1271 getwd (newdir);
1272 }
1273
1274 /* Strip off drive name from prefix, if present. */
1275 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1276 {
1277 drive = newdir[0];
1278 newdir += 2;
1279 }
1280
1281 /* Keep only a prefix from newdir if nm starts with slash
1282 (//server/share for UNC, nothing otherwise). */
1283 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1284 {
1285 #ifdef WINDOWSNT
1286 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1287 {
1288 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1289 p = newdir + 2;
1290 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1291 p++;
1292 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1293 *p = 0;
1294 }
1295 else
1296 #endif
1297 newdir = "";
1298 }
1299 }
1300 #endif /* DOS_NT */
1301
1302 if (newdir)
1303 {
1304 /* Get rid of any slash at the end of newdir, unless newdir is
1305 just // (an incomplete UNC name). */
1306 length = strlen (newdir);
1307 if (length > 0 && IS_DIRECTORY_SEP (newdir[length - 1])
1308 #ifdef WINDOWSNT
1309 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1310 #endif
1311 )
1312 {
1313 unsigned char *temp = (unsigned char *) alloca (length);
1314 bcopy (newdir, temp, length - 1);
1315 temp[length - 1] = 0;
1316 newdir = temp;
1317 }
1318 tlen = length + 1;
1319 }
1320 else
1321 tlen = 0;
1322
1323 /* Now concatenate the directory and name to new space in the stack frame */
1324 tlen += strlen (nm) + 1;
1325 #ifdef DOS_NT
1326 /* Add reserved space for drive name. (The Microsoft x86 compiler
1327 produces incorrect code if the following two lines are combined.) */
1328 target = (unsigned char *) alloca (tlen + 2);
1329 target += 2;
1330 #else /* not DOS_NT */
1331 target = (unsigned char *) alloca (tlen);
1332 #endif /* not DOS_NT */
1333 *target = 0;
1334
1335 if (newdir)
1336 {
1337 #ifndef VMS
1338 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1339 strcpy (target, newdir);
1340 else
1341 #endif
1342 file_name_as_directory (target, newdir);
1343 }
1344
1345 strcat (target, nm);
1346 #ifdef VMS
1347 if (index (target, '/'))
1348 strcpy (target, sys_translate_unix (target));
1349 #endif /* VMS */
1350
1351 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1352
1353 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1354
1355 p = target;
1356 o = target;
1357
1358 while (*p)
1359 {
1360 #ifdef VMS
1361 if (*p != ']' && *p != '>' && *p != '-')
1362 {
1363 if (*p == '\\')
1364 p++;
1365 *o++ = *p++;
1366 }
1367 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1368 /* brackets are offset from each other by 2 */
1369 {
1370 p += 2;
1371 if (*p != '.' && *p != '-' && o[-1] != '.')
1372 /* convert [foo][bar] to [bar] */
1373 while (o[-1] != '[' && o[-1] != '<')
1374 o--;
1375 else if (*p == '-' && *o != '.')
1376 *--p = '.';
1377 }
1378 else if (p[0] == '-' && o[-1] == '.' &&
1379 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1380 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1381 {
1382 do
1383 o--;
1384 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1385 if (p[1] == '.') /* foo.-.bar ==> bar. */
1386 p += 2;
1387 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1388 p++, o--;
1389 /* else [foo.-] ==> [-] */
1390 }
1391 else
1392 {
1393 #ifndef VMS4_4
1394 if (*p == '-' &&
1395 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1396 p[1] != ']' && p[1] != '>' && p[1] != '.')
1397 *p = '_';
1398 #endif /* VMS4_4 */
1399 *o++ = *p++;
1400 }
1401 #else /* not VMS */
1402 if (!IS_DIRECTORY_SEP (*p))
1403 {
1404 *o++ = *p++;
1405 }
1406 else if (IS_DIRECTORY_SEP (p[0])
1407 && p[1] == '.'
1408 && (IS_DIRECTORY_SEP (p[2])
1409 || p[2] == 0))
1410 {
1411 /* If "/." is the entire filename, keep the "/". Otherwise,
1412 just delete the whole "/.". */
1413 if (o == target && p[2] == '\0')
1414 *o++ = *p;
1415 p += 2;
1416 }
1417 else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1418 /* `/../' is the "superroot" on certain file systems. */
1419 && o != target
1420 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1421 {
1422 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1423 ;
1424 /* Keep initial / only if this is the whole name. */
1425 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1426 ++o;
1427 p += 3;
1428 }
1429 else
1430 {
1431 *o++ = *p++;
1432 }
1433 #endif /* not VMS */
1434 }
1435
1436 #ifdef DOS_NT
1437 /* At last, set drive name. */
1438 #ifdef WINDOWSNT
1439 /* Except for network file name. */
1440 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1441 #endif /* WINDOWSNT */
1442 {
1443 if (!drive) abort ();
1444 target -= 2;
1445 target[0] = DRIVE_LETTER (drive);
1446 target[1] = ':';
1447 }
1448 CORRECT_DIR_SEPS (target);
1449 #endif /* DOS_NT */
1450
1451 return make_string (target, o - target);
1452 }
1453
1454 #if 0
1455 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1456 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1457 "Convert FILENAME to absolute, and canonicalize it.\n\
1458 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1459 (does not start with slash); if DEFAULT is nil or missing,\n\
1460 the current buffer's value of default-directory is used.\n\
1461 Filenames containing `.' or `..' as components are simplified;\n\
1462 initial `~/' expands to your home directory.\n\
1463 See also the function `substitute-in-file-name'.")
1464 (name, defalt)
1465 Lisp_Object name, defalt;
1466 {
1467 unsigned char *nm;
1468
1469 register unsigned char *newdir, *p, *o;
1470 int tlen;
1471 unsigned char *target;
1472 struct passwd *pw;
1473 int lose;
1474 #ifdef VMS
1475 unsigned char * colon = 0;
1476 unsigned char * close = 0;
1477 unsigned char * slash = 0;
1478 unsigned char * brack = 0;
1479 int lbrack = 0, rbrack = 0;
1480 int dots = 0;
1481 #endif /* VMS */
1482
1483 CHECK_STRING (name, 0);
1484
1485 #ifdef VMS
1486 /* Filenames on VMS are always upper case. */
1487 name = Fupcase (name);
1488 #endif
1489
1490 nm = XSTRING (name)->data;
1491
1492 /* If nm is absolute, flush ...// and detect /./ and /../.
1493 If no /./ or /../ we can return right away. */
1494 if (
1495 nm[0] == '/'
1496 #ifdef VMS
1497 || index (nm, ':')
1498 #endif /* VMS */
1499 )
1500 {
1501 p = nm;
1502 lose = 0;
1503 while (*p)
1504 {
1505 if (p[0] == '/' && p[1] == '/'
1506 #ifdef APOLLO
1507 /* // at start of filename is meaningful on Apollo system. */
1508 && nm != p
1509 #endif /* APOLLO */
1510 )
1511 nm = p + 1;
1512 if (p[0] == '/' && p[1] == '~')
1513 nm = p + 1, lose = 1;
1514 if (p[0] == '/' && p[1] == '.'
1515 && (p[2] == '/' || p[2] == 0
1516 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1517 lose = 1;
1518 #ifdef VMS
1519 if (p[0] == '\\')
1520 lose = 1;
1521 if (p[0] == '/') {
1522 /* if dev:[dir]/, move nm to / */
1523 if (!slash && p > nm && (brack || colon)) {
1524 nm = (brack ? brack + 1 : colon + 1);
1525 lbrack = rbrack = 0;
1526 brack = 0;
1527 colon = 0;
1528 }
1529 slash = p;
1530 }
1531 if (p[0] == '-')
1532 #ifndef VMS4_4
1533 /* VMS pre V4.4,convert '-'s in filenames. */
1534 if (lbrack == rbrack)
1535 {
1536 if (dots < 2) /* this is to allow negative version numbers */
1537 p[0] = '_';
1538 }
1539 else
1540 #endif /* VMS4_4 */
1541 if (lbrack > rbrack &&
1542 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1543 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1544 lose = 1;
1545 #ifndef VMS4_4
1546 else
1547 p[0] = '_';
1548 #endif /* VMS4_4 */
1549 /* count open brackets, reset close bracket pointer */
1550 if (p[0] == '[' || p[0] == '<')
1551 lbrack++, brack = 0;
1552 /* count close brackets, set close bracket pointer */
1553 if (p[0] == ']' || p[0] == '>')
1554 rbrack++, brack = p;
1555 /* detect ][ or >< */
1556 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1557 lose = 1;
1558 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1559 nm = p + 1, lose = 1;
1560 if (p[0] == ':' && (colon || slash))
1561 /* if dev1:[dir]dev2:, move nm to dev2: */
1562 if (brack)
1563 {
1564 nm = brack + 1;
1565 brack = 0;
1566 }
1567 /* If /name/dev:, move nm to dev: */
1568 else if (slash)
1569 nm = slash + 1;
1570 /* If node::dev:, move colon following dev */
1571 else if (colon && colon[-1] == ':')
1572 colon = p;
1573 /* If dev1:dev2:, move nm to dev2: */
1574 else if (colon && colon[-1] != ':')
1575 {
1576 nm = colon + 1;
1577 colon = 0;
1578 }
1579 if (p[0] == ':' && !colon)
1580 {
1581 if (p[1] == ':')
1582 p++;
1583 colon = p;
1584 }
1585 if (lbrack == rbrack)
1586 if (p[0] == ';')
1587 dots = 2;
1588 else if (p[0] == '.')
1589 dots++;
1590 #endif /* VMS */
1591 p++;
1592 }
1593 if (!lose)
1594 {
1595 #ifdef VMS
1596 if (index (nm, '/'))
1597 return build_string (sys_translate_unix (nm));
1598 #endif /* VMS */
1599 if (nm == XSTRING (name)->data)
1600 return name;
1601 return build_string (nm);
1602 }
1603 }
1604
1605 /* Now determine directory to start with and put it in NEWDIR */
1606
1607 newdir = 0;
1608
1609 if (nm[0] == '~') /* prefix ~ */
1610 if (nm[1] == '/'
1611 #ifdef VMS
1612 || nm[1] == ':'
1613 #endif /* VMS */
1614 || nm[1] == 0)/* ~/filename */
1615 {
1616 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1617 newdir = (unsigned char *) "";
1618 nm++;
1619 #ifdef VMS
1620 nm++; /* Don't leave the slash in nm. */
1621 #endif /* VMS */
1622 }
1623 else /* ~user/filename */
1624 {
1625 /* Get past ~ to user */
1626 unsigned char *user = nm + 1;
1627 /* Find end of name. */
1628 unsigned char *ptr = (unsigned char *) index (user, '/');
1629 int len = ptr ? ptr - user : strlen (user);
1630 #ifdef VMS
1631 unsigned char *ptr1 = index (user, ':');
1632 if (ptr1 != 0 && ptr1 - user < len)
1633 len = ptr1 - user;
1634 #endif /* VMS */
1635 /* Copy the user name into temp storage. */
1636 o = (unsigned char *) alloca (len + 1);
1637 bcopy ((char *) user, o, len);
1638 o[len] = 0;
1639
1640 /* Look up the user name. */
1641 pw = (struct passwd *) getpwnam (o + 1);
1642 if (!pw)
1643 error ("\"%s\" isn't a registered user", o + 1);
1644
1645 newdir = (unsigned char *) pw->pw_dir;
1646
1647 /* Discard the user name from NM. */
1648 nm += len;
1649 }
1650
1651 if (nm[0] != '/'
1652 #ifdef VMS
1653 && !index (nm, ':')
1654 #endif /* not VMS */
1655 && !newdir)
1656 {
1657 if (NILP (defalt))
1658 defalt = current_buffer->directory;
1659 CHECK_STRING (defalt, 1);
1660 newdir = XSTRING (defalt)->data;
1661 }
1662
1663 /* Now concatenate the directory and name to new space in the stack frame */
1664
1665 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1666 target = (unsigned char *) alloca (tlen);
1667 *target = 0;
1668
1669 if (newdir)
1670 {
1671 #ifndef VMS
1672 if (nm[0] == 0 || nm[0] == '/')
1673 strcpy (target, newdir);
1674 else
1675 #endif
1676 file_name_as_directory (target, newdir);
1677 }
1678
1679 strcat (target, nm);
1680 #ifdef VMS
1681 if (index (target, '/'))
1682 strcpy (target, sys_translate_unix (target));
1683 #endif /* VMS */
1684
1685 /* Now canonicalize by removing /. and /foo/.. if they appear */
1686
1687 p = target;
1688 o = target;
1689
1690 while (*p)
1691 {
1692 #ifdef VMS
1693 if (*p != ']' && *p != '>' && *p != '-')
1694 {
1695 if (*p == '\\')
1696 p++;
1697 *o++ = *p++;
1698 }
1699 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1700 /* brackets are offset from each other by 2 */
1701 {
1702 p += 2;
1703 if (*p != '.' && *p != '-' && o[-1] != '.')
1704 /* convert [foo][bar] to [bar] */
1705 while (o[-1] != '[' && o[-1] != '<')
1706 o--;
1707 else if (*p == '-' && *o != '.')
1708 *--p = '.';
1709 }
1710 else if (p[0] == '-' && o[-1] == '.' &&
1711 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1712 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1713 {
1714 do
1715 o--;
1716 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1717 if (p[1] == '.') /* foo.-.bar ==> bar. */
1718 p += 2;
1719 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1720 p++, o--;
1721 /* else [foo.-] ==> [-] */
1722 }
1723 else
1724 {
1725 #ifndef VMS4_4
1726 if (*p == '-' &&
1727 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1728 p[1] != ']' && p[1] != '>' && p[1] != '.')
1729 *p = '_';
1730 #endif /* VMS4_4 */
1731 *o++ = *p++;
1732 }
1733 #else /* not VMS */
1734 if (*p != '/')
1735 {
1736 *o++ = *p++;
1737 }
1738 else if (!strncmp (p, "//", 2)
1739 #ifdef APOLLO
1740 /* // at start of filename is meaningful in Apollo system. */
1741 && o != target
1742 #endif /* APOLLO */
1743 )
1744 {
1745 o = target;
1746 p++;
1747 }
1748 else if (p[0] == '/' && p[1] == '.' &&
1749 (p[2] == '/' || p[2] == 0))
1750 p += 2;
1751 else if (!strncmp (p, "/..", 3)
1752 /* `/../' is the "superroot" on certain file systems. */
1753 && o != target
1754 && (p[3] == '/' || p[3] == 0))
1755 {
1756 while (o != target && *--o != '/')
1757 ;
1758 #ifdef APOLLO
1759 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1760 ++o;
1761 else
1762 #endif /* APOLLO */
1763 if (o == target && *o == '/')
1764 ++o;
1765 p += 3;
1766 }
1767 else
1768 {
1769 *o++ = *p++;
1770 }
1771 #endif /* not VMS */
1772 }
1773
1774 return make_string (target, o - target);
1775 }
1776 #endif
1777 \f
1778 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1779 Ssubstitute_in_file_name, 1, 1, 0,
1780 "Substitute environment variables referred to in FILENAME.\n\
1781 `$FOO' where FOO is an environment variable name means to substitute\n\
1782 the value of that variable. The variable name should be terminated\n\
1783 with a character not a letter, digit or underscore; otherwise, enclose\n\
1784 the entire variable name in braces.\n\
1785 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1786 On VMS, `$' substitution is not done; this function does little and only\n\
1787 duplicates what `expand-file-name' does.")
1788 (filename)
1789 Lisp_Object filename;
1790 {
1791 unsigned char *nm;
1792
1793 register unsigned char *s, *p, *o, *x, *endp;
1794 unsigned char *target;
1795 int total = 0;
1796 int substituted = 0;
1797 unsigned char *xnm;
1798 Lisp_Object handler;
1799
1800 CHECK_STRING (filename, 0);
1801
1802 /* If the file name has special constructs in it,
1803 call the corresponding file handler. */
1804 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1805 if (!NILP (handler))
1806 return call2 (handler, Qsubstitute_in_file_name, filename);
1807
1808 nm = XSTRING (filename)->data;
1809 #ifdef DOS_NT
1810 nm = strcpy (alloca (strlen (nm) + 1), nm);
1811 CORRECT_DIR_SEPS (nm);
1812 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
1813 #endif
1814 endp = nm + STRING_BYTES (XSTRING (filename));
1815
1816 /* If /~ or // appears, discard everything through first slash. */
1817
1818 for (p = nm; p != endp; p++)
1819 {
1820 if ((p[0] == '~'
1821 #if defined (APOLLO) || defined (WINDOWSNT)
1822 /* // at start of file name is meaningful in Apollo and
1823 WindowsNT systems. */
1824 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1825 #else /* not (APOLLO || WINDOWSNT) */
1826 || IS_DIRECTORY_SEP (p[0])
1827 #endif /* not (APOLLO || WINDOWSNT) */
1828 )
1829 && p != nm
1830 && (0
1831 #ifdef VMS
1832 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
1833 #endif /* VMS */
1834 || IS_DIRECTORY_SEP (p[-1])))
1835 {
1836 nm = p;
1837 substituted = 1;
1838 }
1839 #ifdef DOS_NT
1840 /* see comment in expand-file-name about drive specifiers */
1841 else if (IS_DRIVE (p[0]) && p[1] == ':'
1842 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1843 {
1844 nm = p;
1845 substituted = 1;
1846 }
1847 #endif /* DOS_NT */
1848 }
1849
1850 #ifdef VMS
1851 return build_string (nm);
1852 #else
1853
1854 /* See if any variables are substituted into the string
1855 and find the total length of their values in `total' */
1856
1857 for (p = nm; p != endp;)
1858 if (*p != '$')
1859 p++;
1860 else
1861 {
1862 p++;
1863 if (p == endp)
1864 goto badsubst;
1865 else if (*p == '$')
1866 {
1867 /* "$$" means a single "$" */
1868 p++;
1869 total -= 1;
1870 substituted = 1;
1871 continue;
1872 }
1873 else if (*p == '{')
1874 {
1875 o = ++p;
1876 while (p != endp && *p != '}') p++;
1877 if (*p != '}') goto missingclose;
1878 s = p;
1879 }
1880 else
1881 {
1882 o = p;
1883 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1884 s = p;
1885 }
1886
1887 /* Copy out the variable name */
1888 target = (unsigned char *) alloca (s - o + 1);
1889 strncpy (target, o, s - o);
1890 target[s - o] = 0;
1891 #ifdef DOS_NT
1892 strupr (target); /* $home == $HOME etc. */
1893 #endif /* DOS_NT */
1894
1895 /* Get variable value */
1896 o = (unsigned char *) egetenv (target);
1897 if (!o) goto badvar;
1898 total += strlen (o);
1899 substituted = 1;
1900 }
1901
1902 if (!substituted)
1903 return filename;
1904
1905 /* If substitution required, recopy the string and do it */
1906 /* Make space in stack frame for the new copy */
1907 xnm = (unsigned char *) alloca (STRING_BYTES (XSTRING (filename)) + total + 1);
1908 x = xnm;
1909
1910 /* Copy the rest of the name through, replacing $ constructs with values */
1911 for (p = nm; *p;)
1912 if (*p != '$')
1913 *x++ = *p++;
1914 else
1915 {
1916 p++;
1917 if (p == endp)
1918 goto badsubst;
1919 else if (*p == '$')
1920 {
1921 *x++ = *p++;
1922 continue;
1923 }
1924 else if (*p == '{')
1925 {
1926 o = ++p;
1927 while (p != endp && *p != '}') p++;
1928 if (*p != '}') goto missingclose;
1929 s = p++;
1930 }
1931 else
1932 {
1933 o = p;
1934 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1935 s = p;
1936 }
1937
1938 /* Copy out the variable name */
1939 target = (unsigned char *) alloca (s - o + 1);
1940 strncpy (target, o, s - o);
1941 target[s - o] = 0;
1942 #ifdef DOS_NT
1943 strupr (target); /* $home == $HOME etc. */
1944 #endif /* DOS_NT */
1945
1946 /* Get variable value */
1947 o = (unsigned char *) egetenv (target);
1948 if (!o)
1949 goto badvar;
1950
1951 if (STRING_MULTIBYTE (filename))
1952 {
1953 /* If the original string is multibyte,
1954 convert what we substitute into multibyte. */
1955 unsigned char workbuf[4], *str;
1956 int len;
1957
1958 while (*o)
1959 {
1960 int c = *o++;
1961 c = unibyte_char_to_multibyte (c);
1962 if (! SINGLE_BYTE_CHAR_P (c))
1963 {
1964 len = CHAR_STRING (c, workbuf, str);
1965 bcopy (str, x, len);
1966 x += len;
1967 }
1968 else
1969 *x++ = c;
1970 }
1971 }
1972 else
1973 {
1974 strcpy (x, o);
1975 x += strlen (o);
1976 }
1977 }
1978
1979 *x = 0;
1980
1981 /* If /~ or // appears, discard everything through first slash. */
1982
1983 for (p = xnm; p != x; p++)
1984 if ((p[0] == '~'
1985 #if defined (APOLLO) || defined (WINDOWSNT)
1986 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1987 #else /* not (APOLLO || WINDOWSNT) */
1988 || IS_DIRECTORY_SEP (p[0])
1989 #endif /* not (APOLLO || WINDOWSNT) */
1990 )
1991 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
1992 xnm = p;
1993 #ifdef DOS_NT
1994 else if (IS_DRIVE (p[0]) && p[1] == ':'
1995 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1996 xnm = p;
1997 #endif
1998
1999 if (STRING_MULTIBYTE (filename))
2000 return make_string (xnm, x - xnm);
2001 return make_unibyte_string (xnm, x - xnm);
2002
2003 badsubst:
2004 error ("Bad format environment-variable substitution");
2005 missingclose:
2006 error ("Missing \"}\" in environment-variable substitution");
2007 badvar:
2008 error ("Substituting nonexistent environment variable \"%s\"", target);
2009
2010 /* NOTREACHED */
2011 #endif /* not VMS */
2012 }
2013 \f
2014 /* A slightly faster and more convenient way to get
2015 (directory-file-name (expand-file-name FOO)). */
2016
2017 Lisp_Object
2018 expand_and_dir_to_file (filename, defdir)
2019 Lisp_Object filename, defdir;
2020 {
2021 register Lisp_Object absname;
2022
2023 absname = Fexpand_file_name (filename, defdir);
2024 #ifdef VMS
2025 {
2026 register int c = XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1];
2027 if (c == ':' || c == ']' || c == '>')
2028 absname = Fdirectory_file_name (absname);
2029 }
2030 #else
2031 /* Remove final slash, if any (unless this is the root dir).
2032 stat behaves differently depending! */
2033 if (XSTRING (absname)->size > 1
2034 && IS_DIRECTORY_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1])
2035 && !IS_DEVICE_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname))-2]))
2036 /* We cannot take shortcuts; they might be wrong for magic file names. */
2037 absname = Fdirectory_file_name (absname);
2038 #endif
2039 return absname;
2040 }
2041 \f
2042 /* Signal an error if the file ABSNAME already exists.
2043 If INTERACTIVE is nonzero, ask the user whether to proceed,
2044 and bypass the error if the user says to go ahead.
2045 QUERYSTRING is a name for the action that is being considered
2046 to alter the file.
2047
2048 *STATPTR is used to store the stat information if the file exists.
2049 If the file does not exist, STATPTR->st_mode is set to 0.
2050 If STATPTR is null, we don't store into it.
2051
2052 If QUICK is nonzero, we ask for y or n, not yes or no. */
2053
2054 void
2055 barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
2056 Lisp_Object absname;
2057 unsigned char *querystring;
2058 int interactive;
2059 struct stat *statptr;
2060 int quick;
2061 {
2062 register Lisp_Object tem;
2063 struct stat statbuf;
2064 struct gcpro gcpro1;
2065
2066 /* stat is a good way to tell whether the file exists,
2067 regardless of what access permissions it has. */
2068 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
2069 {
2070 if (! interactive)
2071 Fsignal (Qfile_already_exists,
2072 Fcons (build_string ("File already exists"),
2073 Fcons (absname, Qnil)));
2074 GCPRO1 (absname);
2075 tem = format1 ("File %s already exists; %s anyway? ",
2076 XSTRING (absname)->data, querystring);
2077 if (quick)
2078 tem = Fy_or_n_p (tem);
2079 else
2080 tem = do_yes_or_no_p (tem);
2081 UNGCPRO;
2082 if (NILP (tem))
2083 Fsignal (Qfile_already_exists,
2084 Fcons (build_string ("File already exists"),
2085 Fcons (absname, Qnil)));
2086 if (statptr)
2087 *statptr = statbuf;
2088 }
2089 else
2090 {
2091 if (statptr)
2092 statptr->st_mode = 0;
2093 }
2094 return;
2095 }
2096
2097 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2098 "fCopy file: \nFCopy %s to file: \np\nP",
2099 "Copy FILE to NEWNAME. Both args must be strings.\n\
2100 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2101 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2102 A number as third arg means request confirmation if NEWNAME already exists.\n\
2103 This is what happens in interactive use with M-x.\n\
2104 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2105 last-modified time as the old one. (This works on only some systems.)\n\
2106 A prefix arg makes KEEP-TIME non-nil.")
2107 (file, newname, ok_if_already_exists, keep_date)
2108 Lisp_Object file, newname, ok_if_already_exists, keep_date;
2109 {
2110 int ifd, ofd, n;
2111 char buf[16 * 1024];
2112 struct stat st, out_st;
2113 Lisp_Object handler;
2114 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2115 int count = specpdl_ptr - specpdl;
2116 int input_file_statable_p;
2117 Lisp_Object encoded_file, encoded_newname;
2118
2119 encoded_file = encoded_newname = Qnil;
2120 GCPRO4 (file, newname, encoded_file, encoded_newname);
2121 CHECK_STRING (file, 0);
2122 CHECK_STRING (newname, 1);
2123
2124 file = Fexpand_file_name (file, Qnil);
2125 newname = Fexpand_file_name (newname, Qnil);
2126
2127 /* If the input file name has special constructs in it,
2128 call the corresponding file handler. */
2129 handler = Ffind_file_name_handler (file, Qcopy_file);
2130 /* Likewise for output file name. */
2131 if (NILP (handler))
2132 handler = Ffind_file_name_handler (newname, Qcopy_file);
2133 if (!NILP (handler))
2134 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2135 ok_if_already_exists, keep_date));
2136
2137 encoded_file = ENCODE_FILE (file);
2138 encoded_newname = ENCODE_FILE (newname);
2139
2140 if (NILP (ok_if_already_exists)
2141 || INTEGERP (ok_if_already_exists))
2142 barf_or_query_if_file_exists (encoded_newname, "copy to it",
2143 INTEGERP (ok_if_already_exists), &out_st, 0);
2144 else if (stat (XSTRING (encoded_newname)->data, &out_st) < 0)
2145 out_st.st_mode = 0;
2146
2147 ifd = open (XSTRING (encoded_file)->data, O_RDONLY);
2148 if (ifd < 0)
2149 report_file_error ("Opening input file", Fcons (file, Qnil));
2150
2151 record_unwind_protect (close_file_unwind, make_number (ifd));
2152
2153 /* We can only copy regular files and symbolic links. Other files are not
2154 copyable by us. */
2155 input_file_statable_p = (fstat (ifd, &st) >= 0);
2156
2157 #if !defined (MSDOS) || __DJGPP__ > 1
2158 if (out_st.st_mode != 0
2159 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2160 {
2161 errno = 0;
2162 report_file_error ("Input and output files are the same",
2163 Fcons (file, Fcons (newname, Qnil)));
2164 }
2165 #endif
2166
2167 #if defined (S_ISREG) && defined (S_ISLNK)
2168 if (input_file_statable_p)
2169 {
2170 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2171 {
2172 #if defined (EISDIR)
2173 /* Get a better looking error message. */
2174 errno = EISDIR;
2175 #endif /* EISDIR */
2176 report_file_error ("Non-regular file", Fcons (file, Qnil));
2177 }
2178 }
2179 #endif /* S_ISREG && S_ISLNK */
2180
2181 #ifdef VMS
2182 /* Create the copy file with the same record format as the input file */
2183 ofd = sys_creat (XSTRING (encoded_newname)->data, 0666, ifd);
2184 #else
2185 #ifdef MSDOS
2186 /* System's default file type was set to binary by _fmode in emacs.c. */
2187 ofd = creat (XSTRING (encoded_newname)->data, S_IREAD | S_IWRITE);
2188 #else /* not MSDOS */
2189 ofd = creat (XSTRING (encoded_newname)->data, 0666);
2190 #endif /* not MSDOS */
2191 #endif /* VMS */
2192 if (ofd < 0)
2193 report_file_error ("Opening output file", Fcons (newname, Qnil));
2194
2195 record_unwind_protect (close_file_unwind, make_number (ofd));
2196
2197 immediate_quit = 1;
2198 QUIT;
2199 while ((n = read (ifd, buf, sizeof buf)) > 0)
2200 if (write (ofd, buf, n) != n)
2201 report_file_error ("I/O error", Fcons (newname, Qnil));
2202 immediate_quit = 0;
2203
2204 /* Closing the output clobbers the file times on some systems. */
2205 if (close (ofd) < 0)
2206 report_file_error ("I/O error", Fcons (newname, Qnil));
2207
2208 if (input_file_statable_p)
2209 {
2210 if (!NILP (keep_date))
2211 {
2212 EMACS_TIME atime, mtime;
2213 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2214 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2215 if (set_file_times (XSTRING (encoded_newname)->data,
2216 atime, mtime))
2217 Fsignal (Qfile_date_error,
2218 Fcons (build_string ("Cannot set file date"),
2219 Fcons (newname, Qnil)));
2220 }
2221 #ifndef MSDOS
2222 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2223 #else /* MSDOS */
2224 #if defined (__DJGPP__) && __DJGPP__ > 1
2225 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2226 and if it can't, it tells so. Otherwise, under MSDOS we usually
2227 get only the READ bit, which will make the copied file read-only,
2228 so it's better not to chmod at all. */
2229 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2230 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2231 #endif /* DJGPP version 2 or newer */
2232 #endif /* MSDOS */
2233 }
2234
2235 close (ifd);
2236
2237 /* Discard the unwind protects. */
2238 specpdl_ptr = specpdl + count;
2239
2240 UNGCPRO;
2241 return Qnil;
2242 }
2243 \f
2244 DEFUN ("make-directory-internal", Fmake_directory_internal,
2245 Smake_directory_internal, 1, 1, 0,
2246 "Create a new directory named DIRECTORY.")
2247 (directory)
2248 Lisp_Object directory;
2249 {
2250 unsigned char *dir;
2251 Lisp_Object handler;
2252 Lisp_Object encoded_dir;
2253
2254 CHECK_STRING (directory, 0);
2255 directory = Fexpand_file_name (directory, Qnil);
2256
2257 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2258 if (!NILP (handler))
2259 return call2 (handler, Qmake_directory_internal, directory);
2260
2261 encoded_dir = ENCODE_FILE (directory);
2262
2263 dir = XSTRING (encoded_dir)->data;
2264
2265 #ifdef WINDOWSNT
2266 if (mkdir (dir) != 0)
2267 #else
2268 if (mkdir (dir, 0777) != 0)
2269 #endif
2270 report_file_error ("Creating directory", Flist (1, &directory));
2271
2272 return Qnil;
2273 }
2274
2275 DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2276 "Delete the directory named DIRECTORY.")
2277 (directory)
2278 Lisp_Object directory;
2279 {
2280 unsigned char *dir;
2281 Lisp_Object handler;
2282 Lisp_Object encoded_dir;
2283
2284 CHECK_STRING (directory, 0);
2285 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2286
2287 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2288 if (!NILP (handler))
2289 return call2 (handler, Qdelete_directory, directory);
2290
2291 encoded_dir = ENCODE_FILE (directory);
2292
2293 dir = XSTRING (encoded_dir)->data;
2294
2295 if (rmdir (dir) != 0)
2296 report_file_error ("Removing directory", Flist (1, &directory));
2297
2298 return Qnil;
2299 }
2300
2301 DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2302 "Delete file named FILENAME.\n\
2303 If file has multiple names, it continues to exist with the other names.")
2304 (filename)
2305 Lisp_Object filename;
2306 {
2307 Lisp_Object handler;
2308 Lisp_Object encoded_file;
2309
2310 CHECK_STRING (filename, 0);
2311 filename = Fexpand_file_name (filename, Qnil);
2312
2313 handler = Ffind_file_name_handler (filename, Qdelete_file);
2314 if (!NILP (handler))
2315 return call2 (handler, Qdelete_file, filename);
2316
2317 encoded_file = ENCODE_FILE (filename);
2318
2319 if (0 > unlink (XSTRING (encoded_file)->data))
2320 report_file_error ("Removing old name", Flist (1, &filename));
2321 return Qnil;
2322 }
2323
2324 static Lisp_Object
2325 internal_delete_file_1 (ignore)
2326 Lisp_Object ignore;
2327 {
2328 return Qt;
2329 }
2330
2331 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2332
2333 int
2334 internal_delete_file (filename)
2335 Lisp_Object filename;
2336 {
2337 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2338 Qt, internal_delete_file_1));
2339 }
2340 \f
2341 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2342 "fRename file: \nFRename %s to file: \np",
2343 "Rename FILE as NEWNAME. Both args strings.\n\
2344 If file has names other than FILE, it continues to have those names.\n\
2345 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2346 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2347 A number as third arg means request confirmation if NEWNAME already exists.\n\
2348 This is what happens in interactive use with M-x.")
2349 (file, newname, ok_if_already_exists)
2350 Lisp_Object file, newname, ok_if_already_exists;
2351 {
2352 #ifdef NO_ARG_ARRAY
2353 Lisp_Object args[2];
2354 #endif
2355 Lisp_Object handler;
2356 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2357 Lisp_Object encoded_file, encoded_newname;
2358
2359 encoded_file = encoded_newname = Qnil;
2360 GCPRO4 (file, newname, encoded_file, encoded_newname);
2361 CHECK_STRING (file, 0);
2362 CHECK_STRING (newname, 1);
2363 file = Fexpand_file_name (file, Qnil);
2364 newname = Fexpand_file_name (newname, Qnil);
2365
2366 /* If the file name has special constructs in it,
2367 call the corresponding file handler. */
2368 handler = Ffind_file_name_handler (file, Qrename_file);
2369 if (NILP (handler))
2370 handler = Ffind_file_name_handler (newname, Qrename_file);
2371 if (!NILP (handler))
2372 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2373 file, newname, ok_if_already_exists));
2374
2375 encoded_file = ENCODE_FILE (file);
2376 encoded_newname = ENCODE_FILE (newname);
2377
2378 if (NILP (ok_if_already_exists)
2379 || INTEGERP (ok_if_already_exists))
2380 barf_or_query_if_file_exists (encoded_newname, "rename to it",
2381 INTEGERP (ok_if_already_exists), 0, 0);
2382 #ifndef BSD4_1
2383 if (0 > rename (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2384 #else
2385 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)
2386 || 0 > unlink (XSTRING (encoded_file)->data))
2387 #endif
2388 {
2389 if (errno == EXDEV)
2390 {
2391 Fcopy_file (file, newname,
2392 /* We have already prompted if it was an integer,
2393 so don't have copy-file prompt again. */
2394 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2395 Fdelete_file (file);
2396 }
2397 else
2398 #ifdef NO_ARG_ARRAY
2399 {
2400 args[0] = file;
2401 args[1] = newname;
2402 report_file_error ("Renaming", Flist (2, args));
2403 }
2404 #else
2405 report_file_error ("Renaming", Flist (2, &file));
2406 #endif
2407 }
2408 UNGCPRO;
2409 return Qnil;
2410 }
2411
2412 DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2413 "fAdd name to file: \nFName to add to %s: \np",
2414 "Give FILE additional name NEWNAME. Both args strings.\n\
2415 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2416 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2417 A number as third arg means request confirmation if NEWNAME already exists.\n\
2418 This is what happens in interactive use with M-x.")
2419 (file, newname, ok_if_already_exists)
2420 Lisp_Object file, newname, ok_if_already_exists;
2421 {
2422 #ifdef NO_ARG_ARRAY
2423 Lisp_Object args[2];
2424 #endif
2425 Lisp_Object handler;
2426 Lisp_Object encoded_file, encoded_newname;
2427 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2428
2429 GCPRO4 (file, newname, encoded_file, encoded_newname);
2430 encoded_file = encoded_newname = Qnil;
2431 CHECK_STRING (file, 0);
2432 CHECK_STRING (newname, 1);
2433 file = Fexpand_file_name (file, Qnil);
2434 newname = Fexpand_file_name (newname, Qnil);
2435
2436 /* If the file name has special constructs in it,
2437 call the corresponding file handler. */
2438 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2439 if (!NILP (handler))
2440 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2441 newname, ok_if_already_exists));
2442
2443 /* If the new name has special constructs in it,
2444 call the corresponding file handler. */
2445 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2446 if (!NILP (handler))
2447 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2448 newname, ok_if_already_exists));
2449
2450 encoded_file = ENCODE_FILE (file);
2451 encoded_newname = ENCODE_FILE (newname);
2452
2453 if (NILP (ok_if_already_exists)
2454 || INTEGERP (ok_if_already_exists))
2455 barf_or_query_if_file_exists (encoded_newname, "make it a new name",
2456 INTEGERP (ok_if_already_exists), 0, 0);
2457
2458 unlink (XSTRING (newname)->data);
2459 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2460 {
2461 #ifdef NO_ARG_ARRAY
2462 args[0] = file;
2463 args[1] = newname;
2464 report_file_error ("Adding new name", Flist (2, args));
2465 #else
2466 report_file_error ("Adding new name", Flist (2, &file));
2467 #endif
2468 }
2469
2470 UNGCPRO;
2471 return Qnil;
2472 }
2473
2474 #ifdef S_IFLNK
2475 DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2476 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2477 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2478 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2479 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2480 A number as third arg means request confirmation if LINKNAME already exists.\n\
2481 This happens for interactive use with M-x.")
2482 (filename, linkname, ok_if_already_exists)
2483 Lisp_Object filename, linkname, ok_if_already_exists;
2484 {
2485 #ifdef NO_ARG_ARRAY
2486 Lisp_Object args[2];
2487 #endif
2488 Lisp_Object handler;
2489 Lisp_Object encoded_filename, encoded_linkname;
2490 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2491
2492 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2493 encoded_filename = encoded_linkname = Qnil;
2494 CHECK_STRING (filename, 0);
2495 CHECK_STRING (linkname, 1);
2496 /* If the link target has a ~, we must expand it to get
2497 a truly valid file name. Otherwise, do not expand;
2498 we want to permit links to relative file names. */
2499 if (XSTRING (filename)->data[0] == '~')
2500 filename = Fexpand_file_name (filename, Qnil);
2501 linkname = Fexpand_file_name (linkname, Qnil);
2502
2503 /* If the file name has special constructs in it,
2504 call the corresponding file handler. */
2505 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2506 if (!NILP (handler))
2507 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2508 linkname, ok_if_already_exists));
2509
2510 /* If the new link name has special constructs in it,
2511 call the corresponding file handler. */
2512 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2513 if (!NILP (handler))
2514 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2515 linkname, ok_if_already_exists));
2516
2517 encoded_filename = ENCODE_FILE (filename);
2518 encoded_linkname = ENCODE_FILE (linkname);
2519
2520 if (NILP (ok_if_already_exists)
2521 || INTEGERP (ok_if_already_exists))
2522 barf_or_query_if_file_exists (encoded_linkname, "make it a link",
2523 INTEGERP (ok_if_already_exists), 0, 0);
2524 if (0 > symlink (XSTRING (encoded_filename)->data,
2525 XSTRING (encoded_linkname)->data))
2526 {
2527 /* If we didn't complain already, silently delete existing file. */
2528 if (errno == EEXIST)
2529 {
2530 unlink (XSTRING (encoded_linkname)->data);
2531 if (0 <= symlink (XSTRING (encoded_filename)->data,
2532 XSTRING (encoded_linkname)->data))
2533 {
2534 UNGCPRO;
2535 return Qnil;
2536 }
2537 }
2538
2539 #ifdef NO_ARG_ARRAY
2540 args[0] = filename;
2541 args[1] = linkname;
2542 report_file_error ("Making symbolic link", Flist (2, args));
2543 #else
2544 report_file_error ("Making symbolic link", Flist (2, &filename));
2545 #endif
2546 }
2547 UNGCPRO;
2548 return Qnil;
2549 }
2550 #endif /* S_IFLNK */
2551
2552 #ifdef VMS
2553
2554 DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2555 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2556 "Define the job-wide logical name NAME to have the value STRING.\n\
2557 If STRING is nil or a null string, the logical name NAME is deleted.")
2558 (name, string)
2559 Lisp_Object name;
2560 Lisp_Object string;
2561 {
2562 CHECK_STRING (name, 0);
2563 if (NILP (string))
2564 delete_logical_name (XSTRING (name)->data);
2565 else
2566 {
2567 CHECK_STRING (string, 1);
2568
2569 if (XSTRING (string)->size == 0)
2570 delete_logical_name (XSTRING (name)->data);
2571 else
2572 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2573 }
2574
2575 return string;
2576 }
2577 #endif /* VMS */
2578
2579 #ifdef HPUX_NET
2580
2581 DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2582 "Open a network connection to PATH using LOGIN as the login string.")
2583 (path, login)
2584 Lisp_Object path, login;
2585 {
2586 int netresult;
2587
2588 CHECK_STRING (path, 0);
2589 CHECK_STRING (login, 0);
2590
2591 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2592
2593 if (netresult == -1)
2594 return Qnil;
2595 else
2596 return Qt;
2597 }
2598 #endif /* HPUX_NET */
2599 \f
2600 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2601 1, 1, 0,
2602 "Return t if file FILENAME specifies an absolute file name.\n\
2603 On Unix, this is a name starting with a `/' or a `~'.")
2604 (filename)
2605 Lisp_Object filename;
2606 {
2607 unsigned char *ptr;
2608
2609 CHECK_STRING (filename, 0);
2610 ptr = XSTRING (filename)->data;
2611 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2612 #ifdef VMS
2613 /* ??? This criterion is probably wrong for '<'. */
2614 || index (ptr, ':') || index (ptr, '<')
2615 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2616 && ptr[1] != '.')
2617 #endif /* VMS */
2618 #ifdef DOS_NT
2619 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2620 #endif
2621 )
2622 return Qt;
2623 else
2624 return Qnil;
2625 }
2626 \f
2627 /* Return nonzero if file FILENAME exists and can be executed. */
2628
2629 static int
2630 check_executable (filename)
2631 char *filename;
2632 {
2633 #ifdef DOS_NT
2634 int len = strlen (filename);
2635 char *suffix;
2636 struct stat st;
2637 if (stat (filename, &st) < 0)
2638 return 0;
2639 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2640 return ((st.st_mode & S_IEXEC) != 0);
2641 #else
2642 return (S_ISREG (st.st_mode)
2643 && len >= 5
2644 && (stricmp ((suffix = filename + len-4), ".com") == 0
2645 || stricmp (suffix, ".exe") == 0
2646 || stricmp (suffix, ".bat") == 0)
2647 || (st.st_mode & S_IFMT) == S_IFDIR);
2648 #endif /* not WINDOWSNT */
2649 #else /* not DOS_NT */
2650 #ifdef HAVE_EUIDACCESS
2651 return (euidaccess (filename, 1) >= 0);
2652 #else
2653 /* Access isn't quite right because it uses the real uid
2654 and we really want to test with the effective uid.
2655 But Unix doesn't give us a right way to do it. */
2656 return (access (filename, 1) >= 0);
2657 #endif
2658 #endif /* not DOS_NT */
2659 }
2660
2661 /* Return nonzero if file FILENAME exists and can be written. */
2662
2663 static int
2664 check_writable (filename)
2665 char *filename;
2666 {
2667 #ifdef MSDOS
2668 struct stat st;
2669 if (stat (filename, &st) < 0)
2670 return 0;
2671 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2672 #else /* not MSDOS */
2673 #ifdef HAVE_EUIDACCESS
2674 return (euidaccess (filename, 2) >= 0);
2675 #else
2676 /* Access isn't quite right because it uses the real uid
2677 and we really want to test with the effective uid.
2678 But Unix doesn't give us a right way to do it.
2679 Opening with O_WRONLY could work for an ordinary file,
2680 but would lose for directories. */
2681 return (access (filename, 2) >= 0);
2682 #endif
2683 #endif /* not MSDOS */
2684 }
2685
2686 DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2687 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2688 See also `file-readable-p' and `file-attributes'.")
2689 (filename)
2690 Lisp_Object filename;
2691 {
2692 Lisp_Object absname;
2693 Lisp_Object handler;
2694 struct stat statbuf;
2695
2696 CHECK_STRING (filename, 0);
2697 absname = Fexpand_file_name (filename, Qnil);
2698
2699 /* If the file name has special constructs in it,
2700 call the corresponding file handler. */
2701 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2702 if (!NILP (handler))
2703 return call2 (handler, Qfile_exists_p, absname);
2704
2705 absname = ENCODE_FILE (absname);
2706
2707 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2708 }
2709
2710 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2711 "Return t if FILENAME can be executed by you.\n\
2712 For a directory, this means you can access files in that directory.")
2713 (filename)
2714 Lisp_Object filename;
2715
2716 {
2717 Lisp_Object absname;
2718 Lisp_Object handler;
2719
2720 CHECK_STRING (filename, 0);
2721 absname = Fexpand_file_name (filename, Qnil);
2722
2723 /* If the file name has special constructs in it,
2724 call the corresponding file handler. */
2725 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
2726 if (!NILP (handler))
2727 return call2 (handler, Qfile_executable_p, absname);
2728
2729 absname = ENCODE_FILE (absname);
2730
2731 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
2732 }
2733
2734 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
2735 "Return t if file FILENAME exists and you can read it.\n\
2736 See also `file-exists-p' and `file-attributes'.")
2737 (filename)
2738 Lisp_Object filename;
2739 {
2740 Lisp_Object absname;
2741 Lisp_Object handler;
2742 int desc;
2743 int flags;
2744 struct stat statbuf;
2745
2746 CHECK_STRING (filename, 0);
2747 absname = Fexpand_file_name (filename, Qnil);
2748
2749 /* If the file name has special constructs in it,
2750 call the corresponding file handler. */
2751 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
2752 if (!NILP (handler))
2753 return call2 (handler, Qfile_readable_p, absname);
2754
2755 absname = ENCODE_FILE (absname);
2756
2757 #ifdef DOS_NT
2758 /* Under MS-DOS and Windows, open does not work for directories. */
2759 if (access (XSTRING (absname)->data, 0) == 0)
2760 return Qt;
2761 return Qnil;
2762 #else /* not DOS_NT */
2763 flags = O_RDONLY;
2764 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
2765 /* Opening a fifo without O_NONBLOCK can wait.
2766 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2767 except in the case of a fifo, on a system which handles it. */
2768 desc = stat (XSTRING (absname)->data, &statbuf);
2769 if (desc < 0)
2770 return Qnil;
2771 if (S_ISFIFO (statbuf.st_mode))
2772 flags |= O_NONBLOCK;
2773 #endif
2774 desc = open (XSTRING (absname)->data, flags);
2775 if (desc < 0)
2776 return Qnil;
2777 close (desc);
2778 return Qt;
2779 #endif /* not DOS_NT */
2780 }
2781
2782 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2783 on the RT/PC. */
2784 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2785 "Return t if file FILENAME can be written or created by you.")
2786 (filename)
2787 Lisp_Object filename;
2788 {
2789 Lisp_Object absname, dir, encoded;
2790 Lisp_Object handler;
2791 struct stat statbuf;
2792
2793 CHECK_STRING (filename, 0);
2794 absname = Fexpand_file_name (filename, Qnil);
2795
2796 /* If the file name has special constructs in it,
2797 call the corresponding file handler. */
2798 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
2799 if (!NILP (handler))
2800 return call2 (handler, Qfile_writable_p, absname);
2801
2802 encoded = ENCODE_FILE (absname);
2803 if (stat (XSTRING (encoded)->data, &statbuf) >= 0)
2804 return (check_writable (XSTRING (encoded)->data)
2805 ? Qt : Qnil);
2806
2807 dir = Ffile_name_directory (absname);
2808 #ifdef VMS
2809 if (!NILP (dir))
2810 dir = Fdirectory_file_name (dir);
2811 #endif /* VMS */
2812 #ifdef MSDOS
2813 if (!NILP (dir))
2814 dir = Fdirectory_file_name (dir);
2815 #endif /* MSDOS */
2816
2817 dir = ENCODE_FILE (dir);
2818 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
2819 ? Qt : Qnil);
2820 }
2821 \f
2822 DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
2823 "Access file FILENAME, and get an error if that does not work.\n\
2824 The second argument STRING is used in the error message.\n\
2825 If there is no error, we return nil.")
2826 (filename, string)
2827 Lisp_Object filename, string;
2828 {
2829 Lisp_Object handler, encoded_filename;
2830 int fd;
2831
2832 CHECK_STRING (filename, 0);
2833
2834 /* If the file name has special constructs in it,
2835 call the corresponding file handler. */
2836 handler = Ffind_file_name_handler (filename, Qaccess_file);
2837 if (!NILP (handler))
2838 return call3 (handler, Qaccess_file, filename, string);
2839
2840 encoded_filename = ENCODE_FILE (filename);
2841
2842 fd = open (XSTRING (encoded_filename)->data, O_RDONLY);
2843 if (fd < 0)
2844 report_file_error (XSTRING (string)->data, Fcons (filename, Qnil));
2845 close (fd);
2846
2847 return Qnil;
2848 }
2849 \f
2850 DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2851 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2852 The value is the name of the file to which it is linked.\n\
2853 Otherwise returns nil.")
2854 (filename)
2855 Lisp_Object filename;
2856 {
2857 #ifdef S_IFLNK
2858 char *buf;
2859 int bufsize;
2860 int valsize;
2861 Lisp_Object val;
2862 Lisp_Object handler;
2863
2864 CHECK_STRING (filename, 0);
2865 filename = Fexpand_file_name (filename, Qnil);
2866
2867 /* If the file name has special constructs in it,
2868 call the corresponding file handler. */
2869 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2870 if (!NILP (handler))
2871 return call2 (handler, Qfile_symlink_p, filename);
2872
2873 filename = ENCODE_FILE (filename);
2874
2875 bufsize = 100;
2876 while (1)
2877 {
2878 buf = (char *) xmalloc (bufsize);
2879 bzero (buf, bufsize);
2880 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
2881 if (valsize < bufsize) break;
2882 /* Buffer was not long enough */
2883 xfree (buf);
2884 bufsize *= 2;
2885 }
2886 if (valsize == -1)
2887 {
2888 xfree (buf);
2889 return Qnil;
2890 }
2891 val = make_string (buf, valsize);
2892 xfree (buf);
2893 val = DECODE_FILE (val);
2894 return val;
2895 #else /* not S_IFLNK */
2896 return Qnil;
2897 #endif /* not S_IFLNK */
2898 }
2899
2900 DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
2901 "Return t if FILENAME names an existing directory.")
2902 (filename)
2903 Lisp_Object filename;
2904 {
2905 register Lisp_Object absname;
2906 struct stat st;
2907 Lisp_Object handler;
2908
2909 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2910
2911 /* If the file name has special constructs in it,
2912 call the corresponding file handler. */
2913 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
2914 if (!NILP (handler))
2915 return call2 (handler, Qfile_directory_p, absname);
2916
2917 absname = ENCODE_FILE (absname);
2918
2919 if (stat (XSTRING (absname)->data, &st) < 0)
2920 return Qnil;
2921 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2922 }
2923
2924 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
2925 "Return t if file FILENAME is the name of a directory as a file,\n\
2926 and files in that directory can be opened by you. In order to use a\n\
2927 directory as a buffer's current directory, this predicate must return true.\n\
2928 A directory name spec may be given instead; then the value is t\n\
2929 if the directory so specified exists and really is a readable and\n\
2930 searchable directory.")
2931 (filename)
2932 Lisp_Object filename;
2933 {
2934 Lisp_Object handler;
2935 int tem;
2936 struct gcpro gcpro1;
2937
2938 /* If the file name has special constructs in it,
2939 call the corresponding file handler. */
2940 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2941 if (!NILP (handler))
2942 return call2 (handler, Qfile_accessible_directory_p, filename);
2943
2944 /* It's an unlikely combination, but yes we really do need to gcpro:
2945 Suppose that file-accessible-directory-p has no handler, but
2946 file-directory-p does have a handler; this handler causes a GC which
2947 relocates the string in `filename'; and finally file-directory-p
2948 returns non-nil. Then we would end up passing a garbaged string
2949 to file-executable-p. */
2950 GCPRO1 (filename);
2951 tem = (NILP (Ffile_directory_p (filename))
2952 || NILP (Ffile_executable_p (filename)));
2953 UNGCPRO;
2954 return tem ? Qnil : Qt;
2955 }
2956
2957 DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
2958 "Return t if file FILENAME is the name of a regular file.\n\
2959 This is the sort of file that holds an ordinary stream of data bytes.")
2960 (filename)
2961 Lisp_Object filename;
2962 {
2963 register Lisp_Object absname;
2964 struct stat st;
2965 Lisp_Object handler;
2966
2967 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2968
2969 /* If the file name has special constructs in it,
2970 call the corresponding file handler. */
2971 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
2972 if (!NILP (handler))
2973 return call2 (handler, Qfile_regular_p, absname);
2974
2975 absname = ENCODE_FILE (absname);
2976
2977 if (stat (XSTRING (absname)->data, &st) < 0)
2978 return Qnil;
2979 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2980 }
2981 \f
2982 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
2983 "Return mode bits of file named FILENAME, as an integer.")
2984 (filename)
2985 Lisp_Object filename;
2986 {
2987 Lisp_Object absname;
2988 struct stat st;
2989 Lisp_Object handler;
2990
2991 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2992
2993 /* If the file name has special constructs in it,
2994 call the corresponding file handler. */
2995 handler = Ffind_file_name_handler (absname, Qfile_modes);
2996 if (!NILP (handler))
2997 return call2 (handler, Qfile_modes, absname);
2998
2999 absname = ENCODE_FILE (absname);
3000
3001 if (stat (XSTRING (absname)->data, &st) < 0)
3002 return Qnil;
3003 #if defined (MSDOS) && __DJGPP__ < 2
3004 if (check_executable (XSTRING (absname)->data))
3005 st.st_mode |= S_IEXEC;
3006 #endif /* MSDOS && __DJGPP__ < 2 */
3007
3008 return make_number (st.st_mode & 07777);
3009 }
3010
3011 DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
3012 "Set mode bits of file named FILENAME to MODE (an integer).\n\
3013 Only the 12 low bits of MODE are used.")
3014 (filename, mode)
3015 Lisp_Object filename, mode;
3016 {
3017 Lisp_Object absname, encoded_absname;
3018 Lisp_Object handler;
3019
3020 absname = Fexpand_file_name (filename, current_buffer->directory);
3021 CHECK_NUMBER (mode, 1);
3022
3023 /* If the file name has special constructs in it,
3024 call the corresponding file handler. */
3025 handler = Ffind_file_name_handler (absname, Qset_file_modes);
3026 if (!NILP (handler))
3027 return call3 (handler, Qset_file_modes, absname, mode);
3028
3029 encoded_absname = ENCODE_FILE (absname);
3030
3031 if (chmod (XSTRING (encoded_absname)->data, XINT (mode)) < 0)
3032 report_file_error ("Doing chmod", Fcons (absname, Qnil));
3033
3034 return Qnil;
3035 }
3036
3037 DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
3038 "Set the file permission bits for newly created files.\n\
3039 The argument MODE should be an integer; only the low 9 bits are used.\n\
3040 This setting is inherited by subprocesses.")
3041 (mode)
3042 Lisp_Object mode;
3043 {
3044 CHECK_NUMBER (mode, 0);
3045
3046 umask ((~ XINT (mode)) & 0777);
3047
3048 return Qnil;
3049 }
3050
3051 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
3052 "Return the default file protection for created files.\n\
3053 The value is an integer.")
3054 ()
3055 {
3056 int realmask;
3057 Lisp_Object value;
3058
3059 realmask = umask (0);
3060 umask (realmask);
3061
3062 XSETINT (value, (~ realmask) & 0777);
3063 return value;
3064 }
3065 \f
3066 #ifdef unix
3067
3068 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
3069 "Tell Unix to finish all pending disk updates.")
3070 ()
3071 {
3072 sync ();
3073 return Qnil;
3074 }
3075
3076 #endif /* unix */
3077
3078 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
3079 "Return t if file FILE1 is newer than file FILE2.\n\
3080 If FILE1 does not exist, the answer is nil;\n\
3081 otherwise, if FILE2 does not exist, the answer is t.")
3082 (file1, file2)
3083 Lisp_Object file1, file2;
3084 {
3085 Lisp_Object absname1, absname2;
3086 struct stat st;
3087 int mtime1;
3088 Lisp_Object handler;
3089 struct gcpro gcpro1, gcpro2;
3090
3091 CHECK_STRING (file1, 0);
3092 CHECK_STRING (file2, 0);
3093
3094 absname1 = Qnil;
3095 GCPRO2 (absname1, file2);
3096 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3097 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
3098 UNGCPRO;
3099
3100 /* If the file name has special constructs in it,
3101 call the corresponding file handler. */
3102 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
3103 if (NILP (handler))
3104 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
3105 if (!NILP (handler))
3106 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
3107
3108 GCPRO2 (absname1, absname2);
3109 absname1 = ENCODE_FILE (absname1);
3110 absname2 = ENCODE_FILE (absname2);
3111 UNGCPRO;
3112
3113 if (stat (XSTRING (absname1)->data, &st) < 0)
3114 return Qnil;
3115
3116 mtime1 = st.st_mtime;
3117
3118 if (stat (XSTRING (absname2)->data, &st) < 0)
3119 return Qt;
3120
3121 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3122 }
3123 \f
3124 #ifdef DOS_NT
3125 Lisp_Object Qfind_buffer_file_type;
3126 #endif /* DOS_NT */
3127
3128 #ifndef READ_BUF_SIZE
3129 #define READ_BUF_SIZE (64 << 10)
3130 #endif
3131
3132 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3133 1, 5, 0,
3134 "Insert contents of file FILENAME after point.\n\
3135 Returns list of absolute file name and number of bytes inserted.\n\
3136 If second argument VISIT is non-nil, the buffer's visited filename\n\
3137 and last save file modtime are set, and it is marked unmodified.\n\
3138 If visiting and the file does not exist, visiting is completed\n\
3139 before the error is signaled.\n\
3140 The optional third and fourth arguments BEG and END\n\
3141 specify what portion of the file to insert.\n\
3142 These arguments count bytes in the file, not characters in the buffer.\n\
3143 If VISIT is non-nil, BEG and END must be nil.\n\
3144 \n\
3145 If optional fifth argument REPLACE is non-nil,\n\
3146 it means replace the current buffer contents (in the accessible portion)\n\
3147 with the file contents. This is better than simply deleting and inserting\n\
3148 the whole thing because (1) it preserves some marker positions\n\
3149 and (2) it puts less data in the undo list.\n\
3150 When REPLACE is non-nil, the value is the number of characters actually read,\n\
3151 which is often less than the number of characters to be read.\n\
3152 This does code conversion according to the value of\n\
3153 `coding-system-for-read' or `file-coding-system-alist',\n\
3154 and sets the variable `last-coding-system-used' to the coding system\n\
3155 actually used.")
3156 (filename, visit, beg, end, replace)
3157 Lisp_Object filename, visit, beg, end, replace;
3158 {
3159 struct stat st;
3160 register int fd;
3161 int inserted = 0;
3162 register int how_much;
3163 register int unprocessed;
3164 int count = specpdl_ptr - specpdl;
3165 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3166 Lisp_Object handler, val, insval, orig_filename;
3167 Lisp_Object p;
3168 int total;
3169 int not_regular = 0;
3170 char read_buf[READ_BUF_SIZE];
3171 struct coding_system coding;
3172 unsigned char buffer[1 << 14];
3173 int replace_handled = 0;
3174 int set_coding_system = 0;
3175
3176 if (current_buffer->base_buffer && ! NILP (visit))
3177 error ("Cannot do file visiting in an indirect buffer");
3178
3179 if (!NILP (current_buffer->read_only))
3180 Fbarf_if_buffer_read_only ();
3181
3182 val = Qnil;
3183 p = Qnil;
3184 orig_filename = Qnil;
3185
3186 GCPRO4 (filename, val, p, orig_filename);
3187
3188 CHECK_STRING (filename, 0);
3189 filename = Fexpand_file_name (filename, Qnil);
3190
3191 /* If the file name has special constructs in it,
3192 call the corresponding file handler. */
3193 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3194 if (!NILP (handler))
3195 {
3196 val = call6 (handler, Qinsert_file_contents, filename,
3197 visit, beg, end, replace);
3198 goto handled;
3199 }
3200
3201 orig_filename = filename;
3202 filename = ENCODE_FILE (filename);
3203
3204 fd = -1;
3205
3206 #ifndef APOLLO
3207 if (stat (XSTRING (filename)->data, &st) < 0)
3208 #else
3209 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0
3210 || fstat (fd, &st) < 0)
3211 #endif /* not APOLLO */
3212 {
3213 if (fd >= 0) close (fd);
3214 badopen:
3215 if (NILP (visit))
3216 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3217 st.st_mtime = -1;
3218 how_much = 0;
3219 if (!NILP (Vcoding_system_for_read))
3220 current_buffer->buffer_file_coding_system = Vcoding_system_for_read;
3221 goto notfound;
3222 }
3223
3224 #ifdef S_IFREG
3225 /* This code will need to be changed in order to work on named
3226 pipes, and it's probably just not worth it. So we should at
3227 least signal an error. */
3228 if (!S_ISREG (st.st_mode))
3229 {
3230 not_regular = 1;
3231
3232 if (! NILP (visit))
3233 goto notfound;
3234
3235 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
3236 Fsignal (Qfile_error,
3237 Fcons (build_string ("not a regular file"),
3238 Fcons (orig_filename, Qnil)));
3239 }
3240 #endif
3241
3242 if (fd < 0)
3243 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0)
3244 goto badopen;
3245
3246 /* Replacement should preserve point as it preserves markers. */
3247 if (!NILP (replace))
3248 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3249
3250 record_unwind_protect (close_file_unwind, make_number (fd));
3251
3252 /* Supposedly happens on VMS. */
3253 if (! not_regular && st.st_size < 0)
3254 error ("File size is negative");
3255
3256 if (!NILP (beg) || !NILP (end))
3257 if (!NILP (visit))
3258 error ("Attempt to visit less than an entire file");
3259
3260 if (!NILP (beg))
3261 CHECK_NUMBER (beg, 0);
3262 else
3263 XSETFASTINT (beg, 0);
3264
3265 if (!NILP (end))
3266 CHECK_NUMBER (end, 0);
3267 else
3268 {
3269 if (! not_regular)
3270 {
3271 XSETINT (end, st.st_size);
3272 if (XINT (end) != st.st_size)
3273 error ("Maximum buffer size exceeded");
3274 }
3275 }
3276
3277 /* Decide the coding-system of the file. */
3278 {
3279 Lisp_Object val = Qnil;
3280
3281 if (!NILP (Vcoding_system_for_read))
3282 val = Vcoding_system_for_read;
3283 else
3284 {
3285 if (! NILP (Vset_auto_coding_function))
3286 {
3287 /* Find a coding system specified in the heading two lines
3288 or in the tailing several lines of the file. We assume
3289 that the 1K-byte and 3K-byte for heading and tailing
3290 respectively are sufficient fot this purpose. */
3291 int how_many, nread;
3292
3293 if (st.st_size <= (1024 * 4))
3294 nread = read (fd, read_buf, 1024 * 4);
3295 else
3296 {
3297 nread = read (fd, read_buf, 1024);
3298 if (nread >= 0)
3299 {
3300 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3301 report_file_error ("Setting file position",
3302 Fcons (orig_filename, Qnil));
3303 nread += read (fd, read_buf + nread, 1024 * 3);
3304 }
3305 }
3306
3307 if (nread < 0)
3308 error ("IO error reading %s: %s",
3309 XSTRING (orig_filename)->data, strerror (errno));
3310 else if (nread > 0)
3311 {
3312 Lisp_Object tem;
3313 /* Always make this a unibyte string
3314 because we have not yet decoded it. */
3315 tem = make_unibyte_string (read_buf, nread);
3316 val = call1 (Vset_auto_coding_function, tem);
3317 /* Rewind the file for the actual read done later. */
3318 if (lseek (fd, 0, 0) < 0)
3319 report_file_error ("Setting file position",
3320 Fcons (orig_filename, Qnil));
3321 }
3322 }
3323 if (NILP (val))
3324 {
3325 Lisp_Object args[6], coding_systems;
3326
3327 args[0] = Qinsert_file_contents, args[1] = orig_filename,
3328 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3329 coding_systems = Ffind_operation_coding_system (6, args);
3330 if (CONSP (coding_systems)) val = XCONS (coding_systems)->car;
3331 }
3332 }
3333
3334 if (NILP (Vcoding_system_for_read)
3335 && NILP (current_buffer->enable_multibyte_characters))
3336 {
3337 /* We must suppress all text conversion except for end-of-line
3338 conversion. */
3339 struct coding_system coding_temp;
3340
3341 setup_coding_system (Fcheck_coding_system (val), &coding_temp);
3342 setup_coding_system (Qraw_text, &coding);
3343 coding.eol_type = coding_temp.eol_type;
3344 }
3345 else
3346 setup_coding_system (Fcheck_coding_system (val), &coding);
3347 }
3348
3349 /* If requested, replace the accessible part of the buffer
3350 with the file contents. Avoid replacing text at the
3351 beginning or end of the buffer that matches the file contents;
3352 that preserves markers pointing to the unchanged parts.
3353
3354 Here we implement this feature in an optimized way
3355 for the case where code conversion is NOT needed.
3356 The following if-statement handles the case of conversion
3357 in a less optimal way.
3358
3359 If the code conversion is "automatic" then we try using this
3360 method and hope for the best.
3361 But if we discover the need for conversion, we give up on this method
3362 and let the following if-statement handle the replace job. */
3363 if (!NILP (replace)
3364 && ! CODING_REQUIRE_DECODING (&coding))
3365 {
3366 /* same_at_start and same_at_end count bytes,
3367 because file access counts bytes
3368 and BEG and END count bytes. */
3369 int same_at_start = BEGV_BYTE;
3370 int same_at_end = ZV_BYTE;
3371 int overlap;
3372 /* There is still a possibility we will find the need to do code
3373 conversion. If that happens, we set this variable to 1 to
3374 give up on handling REPLACE in the optimized way. */
3375 int giveup_match_end = 0;
3376
3377 if (XINT (beg) != 0)
3378 {
3379 if (lseek (fd, XINT (beg), 0) < 0)
3380 report_file_error ("Setting file position",
3381 Fcons (orig_filename, Qnil));
3382 }
3383
3384 immediate_quit = 1;
3385 QUIT;
3386 /* Count how many chars at the start of the file
3387 match the text at the beginning of the buffer. */
3388 while (1)
3389 {
3390 int nread, bufpos;
3391
3392 nread = read (fd, buffer, sizeof buffer);
3393 if (nread < 0)
3394 error ("IO error reading %s: %s",
3395 XSTRING (orig_filename)->data, strerror (errno));
3396 else if (nread == 0)
3397 break;
3398
3399 if (coding.type == coding_type_undecided)
3400 detect_coding (&coding, buffer, nread);
3401 if (CODING_REQUIRE_DECODING (&coding))
3402 /* We found that the file should be decoded somehow.
3403 Let's give up here. */
3404 {
3405 giveup_match_end = 1;
3406 break;
3407 }
3408
3409 if (coding.eol_type == CODING_EOL_UNDECIDED)
3410 detect_eol (&coding, buffer, nread);
3411 if (coding.eol_type != CODING_EOL_UNDECIDED
3412 && coding.eol_type != CODING_EOL_LF)
3413 /* We found that the format of eol should be decoded.
3414 Let's give up here. */
3415 {
3416 giveup_match_end = 1;
3417 break;
3418 }
3419
3420 bufpos = 0;
3421 while (bufpos < nread && same_at_start < ZV_BYTE
3422 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3423 same_at_start++, bufpos++;
3424 /* If we found a discrepancy, stop the scan.
3425 Otherwise loop around and scan the next bufferful. */
3426 if (bufpos != nread)
3427 break;
3428 }
3429 immediate_quit = 0;
3430 /* If the file matches the buffer completely,
3431 there's no need to replace anything. */
3432 if (same_at_start - BEGV_BYTE == XINT (end))
3433 {
3434 close (fd);
3435 specpdl_ptr--;
3436 /* Truncate the buffer to the size of the file. */
3437 del_range_1 (same_at_start, same_at_end, 0);
3438 goto handled;
3439 }
3440 immediate_quit = 1;
3441 QUIT;
3442 /* Count how many chars at the end of the file
3443 match the text at the end of the buffer. But, if we have
3444 already found that decoding is necessary, don't waste time. */
3445 while (!giveup_match_end)
3446 {
3447 int total_read, nread, bufpos, curpos, trial;
3448
3449 /* At what file position are we now scanning? */
3450 curpos = XINT (end) - (ZV_BYTE - same_at_end);
3451 /* If the entire file matches the buffer tail, stop the scan. */
3452 if (curpos == 0)
3453 break;
3454 /* How much can we scan in the next step? */
3455 trial = min (curpos, sizeof buffer);
3456 if (lseek (fd, curpos - trial, 0) < 0)
3457 report_file_error ("Setting file position",
3458 Fcons (orig_filename, Qnil));
3459
3460 total_read = 0;
3461 while (total_read < trial)
3462 {
3463 nread = read (fd, buffer + total_read, trial - total_read);
3464 if (nread <= 0)
3465 error ("IO error reading %s: %s",
3466 XSTRING (orig_filename)->data, strerror (errno));
3467 total_read += nread;
3468 }
3469 /* Scan this bufferful from the end, comparing with
3470 the Emacs buffer. */
3471 bufpos = total_read;
3472 /* Compare with same_at_start to avoid counting some buffer text
3473 as matching both at the file's beginning and at the end. */
3474 while (bufpos > 0 && same_at_end > same_at_start
3475 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3476 same_at_end--, bufpos--;
3477
3478 /* If we found a discrepancy, stop the scan.
3479 Otherwise loop around and scan the preceding bufferful. */
3480 if (bufpos != 0)
3481 {
3482 /* If this discrepancy is because of code conversion,
3483 we cannot use this method; giveup and try the other. */
3484 if (same_at_end > same_at_start
3485 && FETCH_BYTE (same_at_end - 1) >= 0200
3486 && ! NILP (current_buffer->enable_multibyte_characters)
3487 && (CODING_MAY_REQUIRE_DECODING (&coding)))
3488 giveup_match_end = 1;
3489 break;
3490 }
3491 }
3492 immediate_quit = 0;
3493
3494 if (! giveup_match_end)
3495 {
3496 int temp;
3497
3498 /* We win! We can handle REPLACE the optimized way. */
3499
3500 /* Extends the end of non-matching text area to multibyte
3501 character boundary. */
3502 if (! NILP (current_buffer->enable_multibyte_characters))
3503 while (same_at_end < ZV_BYTE
3504 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3505 same_at_end++;
3506
3507 /* Don't try to reuse the same piece of text twice. */
3508 overlap = (same_at_start - BEGV_BYTE
3509 - (same_at_end + st.st_size - ZV));
3510 if (overlap > 0)
3511 same_at_end += overlap;
3512
3513 /* Arrange to read only the nonmatching middle part of the file. */
3514 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
3515 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3516
3517 del_range_byte (same_at_start, same_at_end, 0);
3518 /* Insert from the file at the proper position. */
3519 temp = BYTE_TO_CHAR (same_at_start);
3520 SET_PT_BOTH (temp, same_at_start);
3521
3522 /* If display currently starts at beginning of line,
3523 keep it that way. */
3524 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3525 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3526
3527 replace_handled = 1;
3528 }
3529 }
3530
3531 /* If requested, replace the accessible part of the buffer
3532 with the file contents. Avoid replacing text at the
3533 beginning or end of the buffer that matches the file contents;
3534 that preserves markers pointing to the unchanged parts.
3535
3536 Here we implement this feature for the case where code conversion
3537 is needed, in a simple way that needs a lot of memory.
3538 The preceding if-statement handles the case of no conversion
3539 in a more optimized way. */
3540 if (!NILP (replace) && ! replace_handled)
3541 {
3542 int same_at_start = BEGV_BYTE;
3543 int same_at_end = ZV_BYTE;
3544 int overlap;
3545 int bufpos;
3546 /* Make sure that the gap is large enough. */
3547 int bufsize = 2 * st.st_size;
3548 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
3549 int temp;
3550
3551 /* First read the whole file, performing code conversion into
3552 CONVERSION_BUFFER. */
3553
3554 if (lseek (fd, XINT (beg), 0) < 0)
3555 {
3556 free (conversion_buffer);
3557 report_file_error ("Setting file position",
3558 Fcons (orig_filename, Qnil));
3559 }
3560
3561 total = st.st_size; /* Total bytes in the file. */
3562 how_much = 0; /* Bytes read from file so far. */
3563 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3564 unprocessed = 0; /* Bytes not processed in previous loop. */
3565
3566 while (how_much < total)
3567 {
3568 /* try is reserved in some compilers (Microsoft C) */
3569 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
3570 char *destination = read_buf + unprocessed;
3571 int this;
3572
3573 /* Allow quitting out of the actual I/O. */
3574 immediate_quit = 1;
3575 QUIT;
3576 this = read (fd, destination, trytry);
3577 immediate_quit = 0;
3578
3579 if (this < 0 || this + unprocessed == 0)
3580 {
3581 how_much = this;
3582 break;
3583 }
3584
3585 how_much += this;
3586
3587 if (CODING_MAY_REQUIRE_DECODING (&coding))
3588 {
3589 int require, result;
3590
3591 this += unprocessed;
3592
3593 /* If we are using more space than estimated,
3594 make CONVERSION_BUFFER bigger. */
3595 require = decoding_buffer_size (&coding, this);
3596 if (inserted + require + 2 * (total - how_much) > bufsize)
3597 {
3598 bufsize = inserted + require + 2 * (total - how_much);
3599 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
3600 }
3601
3602 /* Convert this batch with results in CONVERSION_BUFFER. */
3603 if (how_much >= total) /* This is the last block. */
3604 coding.mode |= CODING_MODE_LAST_BLOCK;
3605 result = decode_coding (&coding, read_buf,
3606 conversion_buffer + inserted,
3607 this, bufsize - inserted);
3608
3609 /* Save for next iteration whatever we didn't convert. */
3610 unprocessed = this - coding.consumed;
3611 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
3612 this = coding.produced;
3613 }
3614
3615 inserted += this;
3616 }
3617
3618 /* At this point, INSERTED is how many characters (i.e. bytes)
3619 are present in CONVERSION_BUFFER.
3620 HOW_MUCH should equal TOTAL,
3621 or should be <= 0 if we couldn't read the file. */
3622
3623 if (how_much < 0)
3624 {
3625 free (conversion_buffer);
3626
3627 if (how_much == -1)
3628 error ("IO error reading %s: %s",
3629 XSTRING (orig_filename)->data, strerror (errno));
3630 else if (how_much == -2)
3631 error ("maximum buffer size exceeded");
3632 }
3633
3634 /* Compare the beginning of the converted file
3635 with the buffer text. */
3636
3637 bufpos = 0;
3638 while (bufpos < inserted && same_at_start < same_at_end
3639 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
3640 same_at_start++, bufpos++;
3641
3642 /* If the file matches the buffer completely,
3643 there's no need to replace anything. */
3644
3645 if (bufpos == inserted)
3646 {
3647 free (conversion_buffer);
3648 close (fd);
3649 specpdl_ptr--;
3650 /* Truncate the buffer to the size of the file. */
3651 del_range_1 (same_at_start, same_at_end, 0);
3652 goto handled;
3653 }
3654
3655 /* Scan this bufferful from the end, comparing with
3656 the Emacs buffer. */
3657 bufpos = inserted;
3658
3659 /* Compare with same_at_start to avoid counting some buffer text
3660 as matching both at the file's beginning and at the end. */
3661 while (bufpos > 0 && same_at_end > same_at_start
3662 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
3663 same_at_end--, bufpos--;
3664
3665 /* Don't try to reuse the same piece of text twice. */
3666 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3667 if (overlap > 0)
3668 same_at_end += overlap;
3669
3670 /* If display currently starts at beginning of line,
3671 keep it that way. */
3672 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3673 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3674
3675 /* Replace the chars that we need to replace,
3676 and update INSERTED to equal the number of bytes
3677 we are taking from the file. */
3678 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
3679 del_range_byte (same_at_start, same_at_end, 0);
3680 SET_PT_BOTH (GPT, GPT_BYTE);
3681
3682 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,
3683 0, 0, 0);
3684
3685 free (conversion_buffer);
3686 close (fd);
3687 specpdl_ptr--;
3688
3689 goto handled;
3690 }
3691
3692 if (! not_regular)
3693 {
3694 register Lisp_Object temp;
3695
3696 total = XINT (end) - XINT (beg);
3697
3698 /* Make sure point-max won't overflow after this insertion. */
3699 XSETINT (temp, total);
3700 if (total != XINT (temp))
3701 error ("Maximum buffer size exceeded");
3702 }
3703 else
3704 /* For a special file, all we can do is guess. */
3705 total = READ_BUF_SIZE;
3706
3707 if (NILP (visit) && total > 0)
3708 prepare_to_modify_buffer (PT, PT, NULL);
3709
3710 move_gap (PT);
3711 if (GAP_SIZE < total)
3712 make_gap (total - GAP_SIZE);
3713
3714 if (XINT (beg) != 0 || !NILP (replace))
3715 {
3716 if (lseek (fd, XINT (beg), 0) < 0)
3717 report_file_error ("Setting file position",
3718 Fcons (orig_filename, Qnil));
3719 }
3720
3721 /* In the following loop, HOW_MUCH contains the total bytes read so
3722 far for a regular file, and not changed for a special file. But,
3723 before exiting the loop, it is set to a negative value if I/O
3724 error occurs. */
3725 how_much = 0;
3726 /* Total bytes inserted. */
3727 inserted = 0;
3728 /* Here, we don't do code conversion in the loop. It is done by
3729 code_convert_region after all data are read into the buffer. */
3730 while (how_much < total)
3731 {
3732 /* try is reserved in some compilers (Microsoft C) */
3733 int trytry = min (total - how_much, READ_BUF_SIZE);
3734 int this;
3735
3736 /* For a special file, GAP_SIZE should be checked every time. */
3737 if (not_regular && GAP_SIZE < trytry)
3738 make_gap (total - GAP_SIZE);
3739
3740 /* Allow quitting out of the actual I/O. */
3741 immediate_quit = 1;
3742 QUIT;
3743 this = read (fd, BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, trytry);
3744 immediate_quit = 0;
3745
3746 if (this <= 0)
3747 {
3748 how_much = this;
3749 break;
3750 }
3751
3752 GAP_SIZE -= this;
3753 GPT_BYTE += this;
3754 ZV_BYTE += this;
3755 Z_BYTE += this;
3756 GPT += this;
3757 ZV += this;
3758 Z += this;
3759
3760 /* For a regular file, where TOTAL is the real size,
3761 count HOW_MUCH to compare with it.
3762 For a special file, where TOTAL is just a buffer size,
3763 so don't bother counting in HOW_MUCH.
3764 (INSERTED is where we count the number of characters inserted.) */
3765 if (! not_regular)
3766 how_much += this;
3767 inserted += this;
3768 }
3769
3770 if (GAP_SIZE > 0)
3771 /* Put an anchor to ensure multi-byte form ends at gap. */
3772 *GPT_ADDR = 0;
3773
3774 close (fd);
3775
3776 /* Discard the unwind protect for closing the file. */
3777 specpdl_ptr--;
3778
3779 if (how_much < 0)
3780 error ("IO error reading %s: %s",
3781 XSTRING (orig_filename)->data, strerror (errno));
3782
3783 if (inserted > 0)
3784 {
3785 if (CODING_MAY_REQUIRE_DECODING (&coding))
3786 {
3787 /* Here, we don't have to consider byte combining (see the
3788 comment below) because code_convert_region takes care of
3789 it. */
3790 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
3791 &coding, 0, 0);
3792 inserted = (NILP (current_buffer->enable_multibyte_characters)
3793 ? coding.produced : coding.produced_char);
3794 }
3795 else if (!NILP (current_buffer->enable_multibyte_characters))
3796 {
3797 int inserted_byte = inserted;
3798
3799 /* There's a possibility that we must combine bytes at the
3800 head (resp. the tail) of the just inserted text with the
3801 bytes before (resp. after) the gap to form a single
3802 character. */
3803 inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted);
3804 adjust_after_insert (PT, PT_BYTE,
3805 PT + inserted_byte, PT_BYTE + inserted_byte,
3806 inserted);
3807 }
3808 else
3809 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
3810 inserted);
3811
3812 #ifdef DOS_NT
3813 /* Use the conversion type to determine buffer-file-type
3814 (find-buffer-file-type is now used to help determine the
3815 conversion). */
3816 if (coding.eol_type != CODING_EOL_UNDECIDED
3817 && coding.eol_type != CODING_EOL_LF)
3818 current_buffer->buffer_file_type = Qnil;
3819 else
3820 current_buffer->buffer_file_type = Qt;
3821 #endif
3822 }
3823
3824 set_coding_system = 1;
3825
3826 notfound:
3827 handled:
3828
3829 if (!NILP (visit))
3830 {
3831 if (!EQ (current_buffer->undo_list, Qt))
3832 current_buffer->undo_list = Qnil;
3833 #ifdef APOLLO
3834 stat (XSTRING (filename)->data, &st);
3835 #endif
3836
3837 if (NILP (handler))
3838 {
3839 current_buffer->modtime = st.st_mtime;
3840 current_buffer->filename = orig_filename;
3841 }
3842
3843 SAVE_MODIFF = MODIFF;
3844 current_buffer->auto_save_modified = MODIFF;
3845 XSETFASTINT (current_buffer->save_length, Z - BEG);
3846 #ifdef CLASH_DETECTION
3847 if (NILP (handler))
3848 {
3849 if (!NILP (current_buffer->file_truename))
3850 unlock_file (current_buffer->file_truename);
3851 unlock_file (filename);
3852 }
3853 #endif /* CLASH_DETECTION */
3854 if (not_regular)
3855 Fsignal (Qfile_error,
3856 Fcons (build_string ("not a regular file"),
3857 Fcons (orig_filename, Qnil)));
3858
3859 /* If visiting nonexistent file, return nil. */
3860 if (current_buffer->modtime == -1)
3861 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3862 }
3863
3864 /* Decode file format */
3865 if (inserted > 0)
3866 {
3867 insval = call3 (Qformat_decode,
3868 Qnil, make_number (inserted), visit);
3869 CHECK_NUMBER (insval, 0);
3870 inserted = XFASTINT (insval);
3871 }
3872
3873 /* Call after-change hooks for the inserted text, aside from the case
3874 of normal visiting (not with REPLACE), which is done in a new buffer
3875 "before" the buffer is changed. */
3876 if (inserted > 0 && total > 0
3877 && (NILP (visit) || !NILP (replace)))
3878 signal_after_change (PT, 0, inserted);
3879
3880 if (set_coding_system)
3881 Vlast_coding_system_used = coding.symbol;
3882
3883 if (inserted > 0)
3884 {
3885 p = Vafter_insert_file_functions;
3886 while (!NILP (p))
3887 {
3888 insval = call1 (Fcar (p), make_number (inserted));
3889 if (!NILP (insval))
3890 {
3891 CHECK_NUMBER (insval, 0);
3892 inserted = XFASTINT (insval);
3893 }
3894 QUIT;
3895 p = Fcdr (p);
3896 }
3897 }
3898
3899 /* ??? Retval needs to be dealt with in all cases consistently. */
3900 if (NILP (val))
3901 val = Fcons (orig_filename,
3902 Fcons (make_number (inserted),
3903 Qnil));
3904
3905 RETURN_UNGCPRO (unbind_to (count, val));
3906 }
3907 \f
3908 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object,
3909 Lisp_Object));
3910
3911 /* If build_annotations switched buffers, switch back to BUF.
3912 Kill the temporary buffer that was selected in the meantime.
3913
3914 Since this kill only the last temporary buffer, some buffers remain
3915 not killed if build_annotations switched buffers more than once.
3916 -- K.Handa */
3917
3918 static Lisp_Object
3919 build_annotations_unwind (buf)
3920 Lisp_Object buf;
3921 {
3922 Lisp_Object tembuf;
3923
3924 if (XBUFFER (buf) == current_buffer)
3925 return Qnil;
3926 tembuf = Fcurrent_buffer ();
3927 Fset_buffer (buf);
3928 Fkill_buffer (tembuf);
3929 return Qnil;
3930 }
3931
3932 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
3933 "r\nFWrite region to file: \ni\ni\ni\np",
3934 "Write current region into specified file.\n\
3935 When called from a program, takes three arguments:\n\
3936 START, END and FILENAME. START and END are buffer positions.\n\
3937 Optional fourth argument APPEND if non-nil means\n\
3938 append to existing file contents (if any).\n\
3939 Optional fifth argument VISIT if t means\n\
3940 set the last-save-file-modtime of buffer to this file's modtime\n\
3941 and mark buffer not modified.\n\
3942 If VISIT is a string, it is a second file name;\n\
3943 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3944 VISIT is also the file name to lock and unlock for clash detection.\n\
3945 If VISIT is neither t nor nil nor a string,\n\
3946 that means do not print the \"Wrote file\" message.\n\
3947 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3948 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3949 The optional seventh arg CONFIRM, if non-nil, says ask for confirmation\n\
3950 before overwriting an existing file.\n\
3951 Kludgy feature: if START is a string, then that string is written\n\
3952 to the file, instead of any buffer contents, and END is ignored.")
3953 (start, end, filename, append, visit, lockname, confirm)
3954 Lisp_Object start, end, filename, append, visit, lockname, confirm;
3955 {
3956 register int desc;
3957 int failure;
3958 int save_errno;
3959 unsigned char *fn;
3960 struct stat st;
3961 int tem;
3962 int count = specpdl_ptr - specpdl;
3963 int count1;
3964 #ifdef VMS
3965 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
3966 #endif /* VMS */
3967 Lisp_Object handler;
3968 Lisp_Object visit_file;
3969 Lisp_Object annotations;
3970 Lisp_Object encoded_filename;
3971 int visiting, quietly;
3972 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3973 struct buffer *given_buffer;
3974 #ifdef DOS_NT
3975 int buffer_file_type = O_BINARY;
3976 #endif /* DOS_NT */
3977 struct coding_system coding;
3978
3979 if (current_buffer->base_buffer && ! NILP (visit))
3980 error ("Cannot do file visiting in an indirect buffer");
3981
3982 if (!NILP (start) && !STRINGP (start))
3983 validate_region (&start, &end);
3984
3985 GCPRO4 (start, filename, visit, lockname);
3986
3987 /* Decide the coding-system to encode the data with. */
3988 {
3989 Lisp_Object val;
3990
3991 if (auto_saving)
3992 val = Qnil;
3993 else if (!NILP (Vcoding_system_for_write))
3994 val = Vcoding_system_for_write;
3995 else if (NILP (current_buffer->enable_multibyte_characters))
3996 {
3997 /* If the variable `buffer-file-coding-system' is set locally,
3998 it means that the file was read with some kind of code
3999 conversion or the varialbe is explicitely set by users. We
4000 had better write it out with the same coding system even if
4001 `enable-multibyte-characters' is nil.
4002
4003 If it is not set locally, we anyway have to convert EOL
4004 format if the default value of `buffer-file-coding-system'
4005 tells that it is not Unix-like (LF only) format. */
4006 val = current_buffer->buffer_file_coding_system;
4007 if (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4008 {
4009 struct coding_system coding_temp;
4010
4011 setup_coding_system (Fcheck_coding_system (val), &coding_temp);
4012 if (coding_temp.eol_type == CODING_EOL_CRLF
4013 || coding_temp.eol_type == CODING_EOL_CR)
4014 {
4015 setup_coding_system (Qraw_text, &coding);
4016 coding.eol_type = coding_temp.eol_type;
4017 goto done_setup_coding;
4018 }
4019 val = Qnil;
4020 }
4021 }
4022 else
4023 {
4024 Lisp_Object args[7], coding_systems;
4025
4026 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4027 args[3] = filename; args[4] = append; args[5] = visit;
4028 args[6] = lockname;
4029 coding_systems = Ffind_operation_coding_system (7, args);
4030 val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr)
4031 ? XCONS (coding_systems)->cdr
4032 : current_buffer->buffer_file_coding_system);
4033 /* Confirm that VAL can surely encode the current region. */
4034 if (!NILP (Ffboundp (Vselect_safe_coding_system_function)))
4035 val = call3 (Vselect_safe_coding_system_function, start, end, val);
4036 }
4037 setup_coding_system (Fcheck_coding_system (val), &coding);
4038
4039 done_setup_coding:
4040 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4041 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY;
4042 }
4043
4044 Vlast_coding_system_used = coding.symbol;
4045
4046 filename = Fexpand_file_name (filename, Qnil);
4047
4048 if (! NILP (confirm))
4049 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
4050
4051 if (STRINGP (visit))
4052 visit_file = Fexpand_file_name (visit, Qnil);
4053 else
4054 visit_file = filename;
4055 UNGCPRO;
4056
4057 visiting = (EQ (visit, Qt) || STRINGP (visit));
4058 quietly = !NILP (visit);
4059
4060 annotations = Qnil;
4061
4062 if (NILP (lockname))
4063 lockname = visit_file;
4064
4065 GCPRO5 (start, filename, annotations, visit_file, lockname);
4066
4067 /* If the file name has special constructs in it,
4068 call the corresponding file handler. */
4069 handler = Ffind_file_name_handler (filename, Qwrite_region);
4070 /* If FILENAME has no handler, see if VISIT has one. */
4071 if (NILP (handler) && STRINGP (visit))
4072 handler = Ffind_file_name_handler (visit, Qwrite_region);
4073
4074 if (!NILP (handler))
4075 {
4076 Lisp_Object val;
4077 val = call6 (handler, Qwrite_region, start, end,
4078 filename, append, visit);
4079
4080 if (visiting)
4081 {
4082 SAVE_MODIFF = MODIFF;
4083 XSETFASTINT (current_buffer->save_length, Z - BEG);
4084 current_buffer->filename = visit_file;
4085 }
4086 UNGCPRO;
4087 return val;
4088 }
4089
4090 /* Special kludge to simplify auto-saving. */
4091 if (NILP (start))
4092 {
4093 XSETFASTINT (start, BEG);
4094 XSETFASTINT (end, Z);
4095 }
4096
4097 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
4098 count1 = specpdl_ptr - specpdl;
4099
4100 given_buffer = current_buffer;
4101 annotations = build_annotations (start, end, coding.pre_write_conversion);
4102 if (current_buffer != given_buffer)
4103 {
4104 XSETFASTINT (start, BEGV);
4105 XSETFASTINT (end, ZV);
4106 }
4107
4108 #ifdef CLASH_DETECTION
4109 if (!auto_saving)
4110 {
4111 #if 0 /* This causes trouble for GNUS. */
4112 /* If we've locked this file for some other buffer,
4113 query before proceeding. */
4114 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
4115 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
4116 #endif
4117
4118 lock_file (lockname);
4119 }
4120 #endif /* CLASH_DETECTION */
4121
4122 encoded_filename = ENCODE_FILE (filename);
4123
4124 fn = XSTRING (encoded_filename)->data;
4125 desc = -1;
4126 if (!NILP (append))
4127 #ifdef DOS_NT
4128 desc = open (fn, O_WRONLY | buffer_file_type);
4129 #else /* not DOS_NT */
4130 desc = open (fn, O_WRONLY);
4131 #endif /* not DOS_NT */
4132
4133 if (desc < 0 && (NILP (append) || errno == ENOENT))
4134 #ifdef VMS
4135 if (auto_saving) /* Overwrite any previous version of autosave file */
4136 {
4137 vms_truncate (fn); /* if fn exists, truncate to zero length */
4138 desc = open (fn, O_RDWR);
4139 if (desc < 0)
4140 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
4141 ? XSTRING (current_buffer->filename)->data : 0,
4142 fn);
4143 }
4144 else /* Write to temporary name and rename if no errors */
4145 {
4146 Lisp_Object temp_name;
4147 temp_name = Ffile_name_directory (filename);
4148
4149 if (!NILP (temp_name))
4150 {
4151 temp_name = Fmake_temp_name (concat2 (temp_name,
4152 build_string ("$$SAVE$$")));
4153 fname = XSTRING (filename)->data;
4154 fn = XSTRING (temp_name)->data;
4155 desc = creat_copy_attrs (fname, fn);
4156 if (desc < 0)
4157 {
4158 /* If we can't open the temporary file, try creating a new
4159 version of the original file. VMS "creat" creates a
4160 new version rather than truncating an existing file. */
4161 fn = fname;
4162 fname = 0;
4163 desc = creat (fn, 0666);
4164 #if 0 /* This can clobber an existing file and fail to replace it,
4165 if the user runs out of space. */
4166 if (desc < 0)
4167 {
4168 /* We can't make a new version;
4169 try to truncate and rewrite existing version if any. */
4170 vms_truncate (fn);
4171 desc = open (fn, O_RDWR);
4172 }
4173 #endif
4174 }
4175 }
4176 else
4177 desc = creat (fn, 0666);
4178 }
4179 #else /* not VMS */
4180 #ifdef DOS_NT
4181 desc = open (fn,
4182 O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type,
4183 S_IREAD | S_IWRITE);
4184 #else /* not DOS_NT */
4185 desc = creat (fn, auto_saving ? auto_save_mode_bits : 0666);
4186 #endif /* not DOS_NT */
4187 #endif /* not VMS */
4188
4189 UNGCPRO;
4190
4191 if (desc < 0)
4192 {
4193 #ifdef CLASH_DETECTION
4194 save_errno = errno;
4195 if (!auto_saving) unlock_file (lockname);
4196 errno = save_errno;
4197 #endif /* CLASH_DETECTION */
4198 report_file_error ("Opening output file", Fcons (filename, Qnil));
4199 }
4200
4201 record_unwind_protect (close_file_unwind, make_number (desc));
4202
4203 if (!NILP (append))
4204 if (lseek (desc, 0, 2) < 0)
4205 {
4206 #ifdef CLASH_DETECTION
4207 if (!auto_saving) unlock_file (lockname);
4208 #endif /* CLASH_DETECTION */
4209 report_file_error ("Lseek error", Fcons (filename, Qnil));
4210 }
4211
4212 #ifdef VMS
4213 /*
4214 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4215 * if we do writes that don't end with a carriage return. Furthermore
4216 * it cannot handle writes of more then 16K. The modified
4217 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4218 * this EXCEPT for the last record (iff it doesn't end with a carriage
4219 * return). This implies that if your buffer doesn't end with a carriage
4220 * return, you get one free... tough. However it also means that if
4221 * we make two calls to sys_write (a la the following code) you can
4222 * get one at the gap as well. The easiest way to fix this (honest)
4223 * is to move the gap to the next newline (or the end of the buffer).
4224 * Thus this change.
4225 *
4226 * Yech!
4227 */
4228 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4229 move_gap (find_next_newline (GPT, 1));
4230 #else
4231 /* Whether VMS or not, we must move the gap to the next of newline
4232 when we must put designation sequences at beginning of line. */
4233 if (INTEGERP (start)
4234 && coding.type == coding_type_iso2022
4235 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4236 && GPT > BEG && GPT_ADDR[-1] != '\n')
4237 {
4238 int opoint = PT, opoint_byte = PT_BYTE;
4239 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
4240 move_gap_both (PT, PT_BYTE);
4241 SET_PT_BOTH (opoint, opoint_byte);
4242 }
4243 #endif
4244
4245 failure = 0;
4246 immediate_quit = 1;
4247
4248 if (STRINGP (start))
4249 {
4250 failure = 0 > a_write (desc, XSTRING (start)->data,
4251 STRING_BYTES (XSTRING (start)), 0, &annotations,
4252 &coding);
4253 save_errno = errno;
4254 }
4255 else if (XINT (start) != XINT (end))
4256 {
4257 register int end1 = CHAR_TO_BYTE (XINT (end));
4258
4259 tem = CHAR_TO_BYTE (XINT (start));
4260
4261 if (XINT (start) < GPT)
4262 {
4263 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem),
4264 min (GPT_BYTE, end1) - tem, tem, &annotations,
4265 &coding);
4266 save_errno = errno;
4267 }
4268
4269 if (XINT (end) > GPT && !failure)
4270 {
4271 tem = max (tem, GPT_BYTE);
4272 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem,
4273 tem, &annotations, &coding);
4274 save_errno = errno;
4275 }
4276 }
4277 else
4278 {
4279 /* If file was empty, still need to write the annotations */
4280 coding.mode |= CODING_MODE_LAST_BLOCK;
4281 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding);
4282 save_errno = errno;
4283 }
4284
4285 if (CODING_REQUIRE_FLUSHING (&coding)
4286 && !(coding.mode & CODING_MODE_LAST_BLOCK)
4287 && ! failure)
4288 {
4289 /* We have to flush out a data. */
4290 coding.mode |= CODING_MODE_LAST_BLOCK;
4291 failure = 0 > e_write (desc, "", 0, &coding);
4292 save_errno = errno;
4293 }
4294
4295 immediate_quit = 0;
4296
4297 #ifdef HAVE_FSYNC
4298 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4299 Disk full in NFS may be reported here. */
4300 /* mib says that closing the file will try to write as fast as NFS can do
4301 it, and that means the fsync here is not crucial for autosave files. */
4302 if (!auto_saving && fsync (desc) < 0)
4303 {
4304 /* If fsync fails with EINTR, don't treat that as serious. */
4305 if (errno != EINTR)
4306 failure = 1, save_errno = errno;
4307 }
4308 #endif
4309
4310 /* Spurious "file has changed on disk" warnings have been
4311 observed on Suns as well.
4312 It seems that `close' can change the modtime, under nfs.
4313
4314 (This has supposedly been fixed in Sunos 4,
4315 but who knows about all the other machines with NFS?) */
4316 #if 0
4317
4318 /* On VMS and APOLLO, must do the stat after the close
4319 since closing changes the modtime. */
4320 #ifndef VMS
4321 #ifndef APOLLO
4322 /* Recall that #if defined does not work on VMS. */
4323 #define FOO
4324 fstat (desc, &st);
4325 #endif
4326 #endif
4327 #endif
4328
4329 /* NFS can report a write failure now. */
4330 if (close (desc) < 0)
4331 failure = 1, save_errno = errno;
4332
4333 #ifdef VMS
4334 /* If we wrote to a temporary name and had no errors, rename to real name. */
4335 if (fname)
4336 {
4337 if (!failure)
4338 failure = (rename (fn, fname) != 0), save_errno = errno;
4339 fn = fname;
4340 }
4341 #endif /* VMS */
4342
4343 #ifndef FOO
4344 stat (fn, &st);
4345 #endif
4346 /* Discard the unwind protect for close_file_unwind. */
4347 specpdl_ptr = specpdl + count1;
4348 /* Restore the original current buffer. */
4349 visit_file = unbind_to (count, visit_file);
4350
4351 #ifdef CLASH_DETECTION
4352 if (!auto_saving)
4353 unlock_file (lockname);
4354 #endif /* CLASH_DETECTION */
4355
4356 /* Do this before reporting IO error
4357 to avoid a "file has changed on disk" warning on
4358 next attempt to save. */
4359 if (visiting)
4360 current_buffer->modtime = st.st_mtime;
4361
4362 if (failure)
4363 error ("IO error writing %s: %s", XSTRING (filename)->data,
4364 strerror (save_errno));
4365
4366 if (visiting)
4367 {
4368 SAVE_MODIFF = MODIFF;
4369 XSETFASTINT (current_buffer->save_length, Z - BEG);
4370 current_buffer->filename = visit_file;
4371 update_mode_lines++;
4372 }
4373 else if (quietly)
4374 return Qnil;
4375
4376 if (!auto_saving)
4377 message_with_string ("Wrote %s", visit_file, 1);
4378
4379 return Qnil;
4380 }
4381 \f
4382 Lisp_Object merge ();
4383
4384 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
4385 "Return t if (car A) is numerically less than (car B).")
4386 (a, b)
4387 Lisp_Object a, b;
4388 {
4389 return Flss (Fcar (a), Fcar (b));
4390 }
4391
4392 /* Build the complete list of annotations appropriate for writing out
4393 the text between START and END, by calling all the functions in
4394 write-region-annotate-functions and merging the lists they return.
4395 If one of these functions switches to a different buffer, we assume
4396 that buffer contains altered text. Therefore, the caller must
4397 make sure to restore the current buffer in all cases,
4398 as save-excursion would do. */
4399
4400 static Lisp_Object
4401 build_annotations (start, end, pre_write_conversion)
4402 Lisp_Object start, end, pre_write_conversion;
4403 {
4404 Lisp_Object annotations;
4405 Lisp_Object p, res;
4406 struct gcpro gcpro1, gcpro2;
4407 Lisp_Object original_buffer;
4408
4409 XSETBUFFER (original_buffer, current_buffer);
4410
4411 annotations = Qnil;
4412 p = Vwrite_region_annotate_functions;
4413 GCPRO2 (annotations, p);
4414 while (!NILP (p))
4415 {
4416 struct buffer *given_buffer = current_buffer;
4417 Vwrite_region_annotations_so_far = annotations;
4418 res = call2 (Fcar (p), start, end);
4419 /* If the function makes a different buffer current,
4420 assume that means this buffer contains altered text to be output.
4421 Reset START and END from the buffer bounds
4422 and discard all previous annotations because they should have
4423 been dealt with by this function. */
4424 if (current_buffer != given_buffer)
4425 {
4426 XSETFASTINT (start, BEGV);
4427 XSETFASTINT (end, ZV);
4428 annotations = Qnil;
4429 }
4430 Flength (res); /* Check basic validity of return value */
4431 annotations = merge (annotations, res, Qcar_less_than_car);
4432 p = Fcdr (p);
4433 }
4434
4435 /* Now do the same for annotation functions implied by the file-format */
4436 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
4437 p = Vauto_save_file_format;
4438 else
4439 p = current_buffer->file_format;
4440 while (!NILP (p))
4441 {
4442 struct buffer *given_buffer = current_buffer;
4443 Vwrite_region_annotations_so_far = annotations;
4444 res = call4 (Qformat_annotate_function, Fcar (p), start, end,
4445 original_buffer);
4446 if (current_buffer != given_buffer)
4447 {
4448 XSETFASTINT (start, BEGV);
4449 XSETFASTINT (end, ZV);
4450 annotations = Qnil;
4451 }
4452 Flength (res);
4453 annotations = merge (annotations, res, Qcar_less_than_car);
4454 p = Fcdr (p);
4455 }
4456
4457 /* At last, do the same for the function PRE_WRITE_CONVERSION
4458 implied by the current coding-system. */
4459 if (!NILP (pre_write_conversion))
4460 {
4461 struct buffer *given_buffer = current_buffer;
4462 Vwrite_region_annotations_so_far = annotations;
4463 res = call2 (pre_write_conversion, start, end);
4464 Flength (res);
4465 annotations = (current_buffer != given_buffer
4466 ? res
4467 : merge (annotations, res, Qcar_less_than_car));
4468 }
4469
4470 UNGCPRO;
4471 return annotations;
4472 }
4473 \f
4474 /* Write to descriptor DESC the NBYTES bytes starting at ADDR,
4475 assuming they start at byte position BYTEPOS in the buffer.
4476 Intersperse with them the annotations from *ANNOT
4477 which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES,
4478 each at its appropriate position.
4479
4480 We modify *ANNOT by discarding elements as we use them up.
4481
4482 The return value is negative in case of system call failure. */
4483
4484 static int
4485 a_write (desc, addr, nbytes, bytepos, annot, coding)
4486 int desc;
4487 register char *addr;
4488 register int nbytes;
4489 int bytepos;
4490 Lisp_Object *annot;
4491 struct coding_system *coding;
4492 {
4493 Lisp_Object tem;
4494 int nextpos;
4495 int lastpos = bytepos + nbytes;
4496
4497 while (NILP (*annot) || CONSP (*annot))
4498 {
4499 tem = Fcar_safe (Fcar (*annot));
4500 nextpos = bytepos - 1;
4501 if (INTEGERP (tem))
4502 nextpos = CHAR_TO_BYTE (XFASTINT (tem));
4503
4504 /* If there are no more annotations in this range,
4505 output the rest of the range all at once. */
4506 if (! (nextpos >= bytepos && nextpos <= lastpos))
4507 return e_write (desc, addr, lastpos - bytepos, coding);
4508
4509 /* Output buffer text up to the next annotation's position. */
4510 if (nextpos > bytepos)
4511 {
4512 if (0 > e_write (desc, addr, nextpos - bytepos, coding))
4513 return -1;
4514 addr += nextpos - bytepos;
4515 bytepos = nextpos;
4516 }
4517 /* Output the annotation. */
4518 tem = Fcdr (Fcar (*annot));
4519 if (STRINGP (tem))
4520 {
4521 if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)),
4522 coding))
4523 return -1;
4524 }
4525 *annot = Fcdr (*annot);
4526 }
4527 return 0;
4528 }
4529
4530 #ifndef WRITE_BUF_SIZE
4531 #define WRITE_BUF_SIZE (16 * 1024)
4532 #endif
4533
4534 /* Write NBYTES bytes starting at ADDR into descriptor DESC,
4535 encoding them with coding system CODING. */
4536
4537 static int
4538 e_write (desc, addr, nbytes, coding)
4539 int desc;
4540 register char *addr;
4541 register int nbytes;
4542 struct coding_system *coding;
4543 {
4544 char buf[WRITE_BUF_SIZE];
4545
4546 /* We used to have a code for handling selective display here. But,
4547 now it is handled within encode_coding. */
4548 while (1)
4549 {
4550 encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
4551 nbytes -= coding->consumed, addr += coding->consumed;
4552 if (coding->produced > 0)
4553 {
4554 coding->produced -= write (desc, buf, coding->produced);
4555 if (coding->produced) return -1;
4556 }
4557 if (nbytes <= 0)
4558 break;
4559 }
4560 return 0;
4561 }
4562 \f
4563 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
4564 Sverify_visited_file_modtime, 1, 1, 0,
4565 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4566 This means that the file has not been changed since it was visited or saved.")
4567 (buf)
4568 Lisp_Object buf;
4569 {
4570 struct buffer *b;
4571 struct stat st;
4572 Lisp_Object handler;
4573 Lisp_Object filename;
4574
4575 CHECK_BUFFER (buf, 0);
4576 b = XBUFFER (buf);
4577
4578 if (!STRINGP (b->filename)) return Qt;
4579 if (b->modtime == 0) return Qt;
4580
4581 /* If the file name has special constructs in it,
4582 call the corresponding file handler. */
4583 handler = Ffind_file_name_handler (b->filename,
4584 Qverify_visited_file_modtime);
4585 if (!NILP (handler))
4586 return call2 (handler, Qverify_visited_file_modtime, buf);
4587
4588 filename = ENCODE_FILE (b->filename);
4589
4590 if (stat (XSTRING (filename)->data, &st) < 0)
4591 {
4592 /* If the file doesn't exist now and didn't exist before,
4593 we say that it isn't modified, provided the error is a tame one. */
4594 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
4595 st.st_mtime = -1;
4596 else
4597 st.st_mtime = 0;
4598 }
4599 if (st.st_mtime == b->modtime
4600 /* If both are positive, accept them if they are off by one second. */
4601 || (st.st_mtime > 0 && b->modtime > 0
4602 && (st.st_mtime == b->modtime + 1
4603 || st.st_mtime == b->modtime - 1)))
4604 return Qt;
4605 return Qnil;
4606 }
4607
4608 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
4609 Sclear_visited_file_modtime, 0, 0, 0,
4610 "Clear out records of last mod time of visited file.\n\
4611 Next attempt to save will certainly not complain of a discrepancy.")
4612 ()
4613 {
4614 current_buffer->modtime = 0;
4615 return Qnil;
4616 }
4617
4618 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
4619 Svisited_file_modtime, 0, 0, 0,
4620 "Return the current buffer's recorded visited file modification time.\n\
4621 The value is a list of the form (HIGH . LOW), like the time values\n\
4622 that `file-attributes' returns.")
4623 ()
4624 {
4625 return long_to_cons ((unsigned long) current_buffer->modtime);
4626 }
4627
4628 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
4629 Sset_visited_file_modtime, 0, 1, 0,
4630 "Update buffer's recorded modification time from the visited file's time.\n\
4631 Useful if the buffer was not read from the file normally\n\
4632 or if the file itself has been changed for some known benign reason.\n\
4633 An argument specifies the modification time value to use\n\
4634 \(instead of that of the visited file), in the form of a list\n\
4635 \(HIGH . LOW) or (HIGH LOW).")
4636 (time_list)
4637 Lisp_Object time_list;
4638 {
4639 if (!NILP (time_list))
4640 current_buffer->modtime = cons_to_long (time_list);
4641 else
4642 {
4643 register Lisp_Object filename;
4644 struct stat st;
4645 Lisp_Object handler;
4646
4647 filename = Fexpand_file_name (current_buffer->filename, Qnil);
4648
4649 /* If the file name has special constructs in it,
4650 call the corresponding file handler. */
4651 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
4652 if (!NILP (handler))
4653 /* The handler can find the file name the same way we did. */
4654 return call2 (handler, Qset_visited_file_modtime, Qnil);
4655
4656 filename = ENCODE_FILE (filename);
4657
4658 if (stat (XSTRING (filename)->data, &st) >= 0)
4659 current_buffer->modtime = st.st_mtime;
4660 }
4661
4662 return Qnil;
4663 }
4664 \f
4665 Lisp_Object
4666 auto_save_error ()
4667 {
4668 ring_bell ();
4669 message_with_string ("Autosaving...error for %s", current_buffer->name, 1);
4670 Fsleep_for (make_number (1), Qnil);
4671 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
4672 Fsleep_for (make_number (1), Qnil);
4673 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
4674 Fsleep_for (make_number (1), Qnil);
4675 return Qnil;
4676 }
4677
4678 Lisp_Object
4679 auto_save_1 ()
4680 {
4681 unsigned char *fn;
4682 struct stat st;
4683
4684 /* Get visited file's mode to become the auto save file's mode. */
4685 if (stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
4686 /* But make sure we can overwrite it later! */
4687 auto_save_mode_bits = st.st_mode | 0600;
4688 else
4689 auto_save_mode_bits = 0666;
4690
4691 return
4692 Fwrite_region (Qnil, Qnil,
4693 current_buffer->auto_save_file_name,
4694 Qnil, Qlambda, Qnil, Qnil);
4695 }
4696
4697 static Lisp_Object
4698 do_auto_save_unwind (stream) /* used as unwind-protect function */
4699 Lisp_Object stream;
4700 {
4701 auto_saving = 0;
4702 if (!NILP (stream))
4703 fclose ((FILE *) (XFASTINT (XCONS (stream)->car) << 16
4704 | XFASTINT (XCONS (stream)->cdr)));
4705 return Qnil;
4706 }
4707
4708 static Lisp_Object
4709 do_auto_save_unwind_1 (value) /* used as unwind-protect function */
4710 Lisp_Object value;
4711 {
4712 minibuffer_auto_raise = XINT (value);
4713 return Qnil;
4714 }
4715
4716 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
4717 "Auto-save all buffers that need it.\n\
4718 This is all buffers that have auto-saving enabled\n\
4719 and are changed since last auto-saved.\n\
4720 Auto-saving writes the buffer into a file\n\
4721 so that your editing is not lost if the system crashes.\n\
4722 This file is not the file you visited; that changes only when you save.\n\
4723 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4724 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4725 A non-nil CURRENT-ONLY argument means save only current buffer.")
4726 (no_message, current_only)
4727 Lisp_Object no_message, current_only;
4728 {
4729 struct buffer *old = current_buffer, *b;
4730 Lisp_Object tail, buf;
4731 int auto_saved = 0;
4732 char *omessage = echo_area_glyphs;
4733 int omessage_length = echo_area_glyphs_length;
4734 int oldmultibyte = message_enable_multibyte;
4735 int do_handled_files;
4736 Lisp_Object oquit;
4737 FILE *stream;
4738 Lisp_Object lispstream;
4739 int count = specpdl_ptr - specpdl;
4740 int *ptr;
4741 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
4742
4743 /* Ordinarily don't quit within this function,
4744 but don't make it impossible to quit (in case we get hung in I/O). */
4745 oquit = Vquit_flag;
4746 Vquit_flag = Qnil;
4747
4748 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4749 point to non-strings reached from Vbuffer_alist. */
4750
4751 if (minibuf_level)
4752 no_message = Qt;
4753
4754 if (!NILP (Vrun_hooks))
4755 call1 (Vrun_hooks, intern ("auto-save-hook"));
4756
4757 if (STRINGP (Vauto_save_list_file_name))
4758 {
4759 Lisp_Object listfile;
4760 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
4761 stream = fopen (XSTRING (listfile)->data, "w");
4762 if (stream != NULL)
4763 {
4764 /* Arrange to close that file whether or not we get an error.
4765 Also reset auto_saving to 0. */
4766 lispstream = Fcons (Qnil, Qnil);
4767 XSETFASTINT (XCONS (lispstream)->car, (EMACS_UINT)stream >> 16);
4768 XSETFASTINT (XCONS (lispstream)->cdr, (EMACS_UINT)stream & 0xffff);
4769 }
4770 else
4771 lispstream = Qnil;
4772 }
4773 else
4774 {
4775 stream = NULL;
4776 lispstream = Qnil;
4777 }
4778
4779 record_unwind_protect (do_auto_save_unwind, lispstream);
4780 record_unwind_protect (do_auto_save_unwind_1,
4781 make_number (minibuffer_auto_raise));
4782 minibuffer_auto_raise = 0;
4783 auto_saving = 1;
4784
4785 /* First, save all files which don't have handlers. If Emacs is
4786 crashing, the handlers may tweak what is causing Emacs to crash
4787 in the first place, and it would be a shame if Emacs failed to
4788 autosave perfectly ordinary files because it couldn't handle some
4789 ange-ftp'd file. */
4790 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
4791 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
4792 {
4793 buf = XCONS (XCONS (tail)->car)->cdr;
4794 b = XBUFFER (buf);
4795
4796 /* Record all the buffers that have auto save mode
4797 in the special file that lists them. For each of these buffers,
4798 Record visited name (if any) and auto save name. */
4799 if (STRINGP (b->auto_save_file_name)
4800 && stream != NULL && do_handled_files == 0)
4801 {
4802 if (!NILP (b->filename))
4803 {
4804 fwrite (XSTRING (b->filename)->data, 1,
4805 STRING_BYTES (XSTRING (b->filename)), stream);
4806 }
4807 putc ('\n', stream);
4808 fwrite (XSTRING (b->auto_save_file_name)->data, 1,
4809 STRING_BYTES (XSTRING (b->auto_save_file_name)), stream);
4810 putc ('\n', stream);
4811 }
4812
4813 if (!NILP (current_only)
4814 && b != current_buffer)
4815 continue;
4816
4817 /* Don't auto-save indirect buffers.
4818 The base buffer takes care of it. */
4819 if (b->base_buffer)
4820 continue;
4821
4822 /* Check for auto save enabled
4823 and file changed since last auto save
4824 and file changed since last real save. */
4825 if (STRINGP (b->auto_save_file_name)
4826 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
4827 && b->auto_save_modified < BUF_MODIFF (b)
4828 /* -1 means we've turned off autosaving for a while--see below. */
4829 && XINT (b->save_length) >= 0
4830 && (do_handled_files
4831 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
4832 Qwrite_region))))
4833 {
4834 EMACS_TIME before_time, after_time;
4835
4836 EMACS_GET_TIME (before_time);
4837
4838 /* If we had a failure, don't try again for 20 minutes. */
4839 if (b->auto_save_failure_time >= 0
4840 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
4841 continue;
4842
4843 if ((XFASTINT (b->save_length) * 10
4844 > (BUF_Z (b) - BUF_BEG (b)) * 13)
4845 /* A short file is likely to change a large fraction;
4846 spare the user annoying messages. */
4847 && XFASTINT (b->save_length) > 5000
4848 /* These messages are frequent and annoying for `*mail*'. */
4849 && !EQ (b->filename, Qnil)
4850 && NILP (no_message))
4851 {
4852 /* It has shrunk too much; turn off auto-saving here. */
4853 minibuffer_auto_raise = orig_minibuffer_auto_raise;
4854 message_with_string ("Buffer %s has shrunk a lot; auto save turned off there",
4855 b->name, 1);
4856 minibuffer_auto_raise = 0;
4857 /* Turn off auto-saving until there's a real save,
4858 and prevent any more warnings. */
4859 XSETINT (b->save_length, -1);
4860 Fsleep_for (make_number (1), Qnil);
4861 continue;
4862 }
4863 set_buffer_internal (b);
4864 if (!auto_saved && NILP (no_message))
4865 message1 ("Auto-saving...");
4866 internal_condition_case (auto_save_1, Qt, auto_save_error);
4867 auto_saved++;
4868 b->auto_save_modified = BUF_MODIFF (b);
4869 XSETFASTINT (current_buffer->save_length, Z - BEG);
4870 set_buffer_internal (old);
4871
4872 EMACS_GET_TIME (after_time);
4873
4874 /* If auto-save took more than 60 seconds,
4875 assume it was an NFS failure that got a timeout. */
4876 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
4877 b->auto_save_failure_time = EMACS_SECS (after_time);
4878 }
4879 }
4880
4881 /* Prevent another auto save till enough input events come in. */
4882 record_auto_save ();
4883
4884 if (auto_saved && NILP (no_message))
4885 {
4886 if (omessage)
4887 {
4888 sit_for (1, 0, 0, 0, 0);
4889 message2 (omessage, omessage_length, oldmultibyte);
4890 }
4891 else
4892 message1 ("Auto-saving...done");
4893 }
4894
4895 Vquit_flag = oquit;
4896
4897 unbind_to (count, Qnil);
4898 return Qnil;
4899 }
4900
4901 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
4902 Sset_buffer_auto_saved, 0, 0, 0,
4903 "Mark current buffer as auto-saved with its current text.\n\
4904 No auto-save file will be written until the buffer changes again.")
4905 ()
4906 {
4907 current_buffer->auto_save_modified = MODIFF;
4908 XSETFASTINT (current_buffer->save_length, Z - BEG);
4909 current_buffer->auto_save_failure_time = -1;
4910 return Qnil;
4911 }
4912
4913 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
4914 Sclear_buffer_auto_save_failure, 0, 0, 0,
4915 "Clear any record of a recent auto-save failure in the current buffer.")
4916 ()
4917 {
4918 current_buffer->auto_save_failure_time = -1;
4919 return Qnil;
4920 }
4921
4922 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
4923 0, 0, 0,
4924 "Return t if buffer has been auto-saved since last read in or saved.")
4925 ()
4926 {
4927 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
4928 }
4929 \f
4930 /* Reading and completing file names */
4931 extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
4932
4933 /* In the string VAL, change each $ to $$ and return the result. */
4934
4935 static Lisp_Object
4936 double_dollars (val)
4937 Lisp_Object val;
4938 {
4939 register unsigned char *old, *new;
4940 register int n;
4941 int osize, count;
4942
4943 osize = STRING_BYTES (XSTRING (val));
4944
4945 /* Count the number of $ characters. */
4946 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
4947 if (*old++ == '$') count++;
4948 if (count > 0)
4949 {
4950 old = XSTRING (val)->data;
4951 val = make_uninit_multibyte_string (XSTRING (val)->size + count,
4952 osize + count);
4953 new = XSTRING (val)->data;
4954 for (n = osize; n > 0; n--)
4955 if (*old != '$')
4956 *new++ = *old++;
4957 else
4958 {
4959 *new++ = '$';
4960 *new++ = '$';
4961 old++;
4962 }
4963 }
4964 return val;
4965 }
4966
4967 DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
4968 3, 3, 0,
4969 "Internal subroutine for read-file-name. Do not call this.")
4970 (string, dir, action)
4971 Lisp_Object string, dir, action;
4972 /* action is nil for complete, t for return list of completions,
4973 lambda for verify final value */
4974 {
4975 Lisp_Object name, specdir, realdir, val, orig_string;
4976 int changed;
4977 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4978
4979 CHECK_STRING (string, 0);
4980
4981 realdir = dir;
4982 name = string;
4983 orig_string = Qnil;
4984 specdir = Qnil;
4985 changed = 0;
4986 /* No need to protect ACTION--we only compare it with t and nil. */
4987 GCPRO5 (string, realdir, name, specdir, orig_string);
4988
4989 if (XSTRING (string)->size == 0)
4990 {
4991 if (EQ (action, Qlambda))
4992 {
4993 UNGCPRO;
4994 return Qnil;
4995 }
4996 }
4997 else
4998 {
4999 orig_string = string;
5000 string = Fsubstitute_in_file_name (string);
5001 changed = NILP (Fstring_equal (string, orig_string));
5002 name = Ffile_name_nondirectory (string);
5003 val = Ffile_name_directory (string);
5004 if (! NILP (val))
5005 realdir = Fexpand_file_name (val, realdir);
5006 }
5007
5008 if (NILP (action))
5009 {
5010 specdir = Ffile_name_directory (string);
5011 val = Ffile_name_completion (name, realdir);
5012 UNGCPRO;
5013 if (!STRINGP (val))
5014 {
5015 if (changed)
5016 return double_dollars (string);
5017 return val;
5018 }
5019
5020 if (!NILP (specdir))
5021 val = concat2 (specdir, val);
5022 #ifndef VMS
5023 return double_dollars (val);
5024 #else /* not VMS */
5025 return val;
5026 #endif /* not VMS */
5027 }
5028 UNGCPRO;
5029
5030 if (EQ (action, Qt))
5031 return Ffile_name_all_completions (name, realdir);
5032 /* Only other case actually used is ACTION = lambda */
5033 #ifdef VMS
5034 /* Supposedly this helps commands such as `cd' that read directory names,
5035 but can someone explain how it helps them? -- RMS */
5036 if (XSTRING (name)->size == 0)
5037 return Qt;
5038 #endif /* VMS */
5039 return Ffile_exists_p (string);
5040 }
5041
5042 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
5043 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
5044 Value is not expanded---you must call `expand-file-name' yourself.\n\
5045 Default name to DEFAULT-FILENAME if user enters a null string.\n\
5046 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
5047 except that if INITIAL is specified, that combined with DIR is used.)\n\
5048 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
5049 Non-nil and non-t means also require confirmation after completion.\n\
5050 Fifth arg INITIAL specifies text to start with.\n\
5051 DIR defaults to current buffer's directory default.")
5052 (prompt, dir, default_filename, mustmatch, initial)
5053 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
5054 {
5055 Lisp_Object val, insdef, insdef1, tem;
5056 struct gcpro gcpro1, gcpro2;
5057 register char *homedir;
5058 int replace_in_history = 0;
5059 int add_to_history = 0;
5060 int count;
5061
5062 if (NILP (dir))
5063 dir = current_buffer->directory;
5064 if (NILP (default_filename))
5065 {
5066 if (! NILP (initial))
5067 default_filename = Fexpand_file_name (initial, dir);
5068 else
5069 default_filename = current_buffer->filename;
5070 }
5071
5072 /* If dir starts with user's homedir, change that to ~. */
5073 homedir = (char *) egetenv ("HOME");
5074 #ifdef DOS_NT
5075 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
5076 CORRECT_DIR_SEPS (homedir);
5077 #endif
5078 if (homedir != 0
5079 && STRINGP (dir)
5080 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
5081 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
5082 {
5083 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
5084 STRING_BYTES (XSTRING (dir)) - strlen (homedir) + 1);
5085 XSTRING (dir)->data[0] = '~';
5086 }
5087
5088 if (insert_default_directory && STRINGP (dir))
5089 {
5090 insdef = dir;
5091 if (!NILP (initial))
5092 {
5093 Lisp_Object args[2], pos;
5094
5095 args[0] = insdef;
5096 args[1] = initial;
5097 insdef = Fconcat (2, args);
5098 pos = make_number (XSTRING (double_dollars (dir))->size);
5099 insdef1 = Fcons (double_dollars (insdef), pos);
5100 }
5101 else
5102 insdef1 = double_dollars (insdef);
5103 }
5104 else if (STRINGP (initial))
5105 {
5106 insdef = initial;
5107 insdef1 = Fcons (double_dollars (insdef), make_number (0));
5108 }
5109 else
5110 insdef = Qnil, insdef1 = Qnil;
5111
5112 #ifdef VMS
5113 count = specpdl_ptr - specpdl;
5114 specbind (intern ("completion-ignore-case"), Qt);
5115 #endif
5116
5117 GCPRO2 (insdef, default_filename);
5118 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
5119 dir, mustmatch, insdef1,
5120 Qfile_name_history, default_filename, Qnil);
5121
5122 tem = Fsymbol_value (Qfile_name_history);
5123 if (CONSP (tem) && EQ (XCONS (tem)->car, val))
5124 replace_in_history = 1;
5125
5126 /* If Fcompleting_read returned the inserted default string itself
5127 (rather than a new string with the same contents),
5128 it has to mean that the user typed RET with the minibuffer empty.
5129 In that case, we really want to return ""
5130 so that commands such as set-visited-file-name can distinguish. */
5131 if (EQ (val, default_filename))
5132 {
5133 /* In this case, Fcompleting_read has not added an element
5134 to the history. Maybe we should. */
5135 if (! replace_in_history)
5136 add_to_history = 1;
5137
5138 val = build_string ("");
5139 }
5140
5141 #ifdef VMS
5142 unbind_to (count, Qnil);
5143 #endif
5144
5145 UNGCPRO;
5146 if (NILP (val))
5147 error ("No file name specified");
5148
5149 tem = Fstring_equal (val, insdef);
5150
5151 if (!NILP (tem) && !NILP (default_filename))
5152 val = default_filename;
5153 else if (XSTRING (val)->size == 0 && NILP (insdef))
5154 {
5155 if (!NILP (default_filename))
5156 val = default_filename;
5157 else
5158 error ("No default file name");
5159 }
5160 val = Fsubstitute_in_file_name (val);
5161
5162 if (replace_in_history)
5163 /* Replace what Fcompleting_read added to the history
5164 with what we will actually return. */
5165 XCONS (Fsymbol_value (Qfile_name_history))->car = val;
5166 else if (add_to_history)
5167 {
5168 /* Add the value to the history--but not if it matches
5169 the last value already there. */
5170 tem = Fsymbol_value (Qfile_name_history);
5171 if (! CONSP (tem) || NILP (Fequal (XCONS (tem)->car, val)))
5172 Fset (Qfile_name_history,
5173 Fcons (val, tem));
5174 }
5175 return val;
5176 }
5177 \f
5178 void
5179 syms_of_fileio ()
5180 {
5181 Qexpand_file_name = intern ("expand-file-name");
5182 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
5183 Qdirectory_file_name = intern ("directory-file-name");
5184 Qfile_name_directory = intern ("file-name-directory");
5185 Qfile_name_nondirectory = intern ("file-name-nondirectory");
5186 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
5187 Qfile_name_as_directory = intern ("file-name-as-directory");
5188 Qcopy_file = intern ("copy-file");
5189 Qmake_directory_internal = intern ("make-directory-internal");
5190 Qdelete_directory = intern ("delete-directory");
5191 Qdelete_file = intern ("delete-file");
5192 Qrename_file = intern ("rename-file");
5193 Qadd_name_to_file = intern ("add-name-to-file");
5194 Qmake_symbolic_link = intern ("make-symbolic-link");
5195 Qfile_exists_p = intern ("file-exists-p");
5196 Qfile_executable_p = intern ("file-executable-p");
5197 Qfile_readable_p = intern ("file-readable-p");
5198 Qfile_writable_p = intern ("file-writable-p");
5199 Qfile_symlink_p = intern ("file-symlink-p");
5200 Qaccess_file = intern ("access-file");
5201 Qfile_directory_p = intern ("file-directory-p");
5202 Qfile_regular_p = intern ("file-regular-p");
5203 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
5204 Qfile_modes = intern ("file-modes");
5205 Qset_file_modes = intern ("set-file-modes");
5206 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
5207 Qinsert_file_contents = intern ("insert-file-contents");
5208 Qwrite_region = intern ("write-region");
5209 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
5210 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
5211
5212 staticpro (&Qexpand_file_name);
5213 staticpro (&Qsubstitute_in_file_name);
5214 staticpro (&Qdirectory_file_name);
5215 staticpro (&Qfile_name_directory);
5216 staticpro (&Qfile_name_nondirectory);
5217 staticpro (&Qunhandled_file_name_directory);
5218 staticpro (&Qfile_name_as_directory);
5219 staticpro (&Qcopy_file);
5220 staticpro (&Qmake_directory_internal);
5221 staticpro (&Qdelete_directory);
5222 staticpro (&Qdelete_file);
5223 staticpro (&Qrename_file);
5224 staticpro (&Qadd_name_to_file);
5225 staticpro (&Qmake_symbolic_link);
5226 staticpro (&Qfile_exists_p);
5227 staticpro (&Qfile_executable_p);
5228 staticpro (&Qfile_readable_p);
5229 staticpro (&Qfile_writable_p);
5230 staticpro (&Qaccess_file);
5231 staticpro (&Qfile_symlink_p);
5232 staticpro (&Qfile_directory_p);
5233 staticpro (&Qfile_regular_p);
5234 staticpro (&Qfile_accessible_directory_p);
5235 staticpro (&Qfile_modes);
5236 staticpro (&Qset_file_modes);
5237 staticpro (&Qfile_newer_than_file_p);
5238 staticpro (&Qinsert_file_contents);
5239 staticpro (&Qwrite_region);
5240 staticpro (&Qverify_visited_file_modtime);
5241 staticpro (&Qset_visited_file_modtime);
5242
5243 Qfile_name_history = intern ("file-name-history");
5244 Fset (Qfile_name_history, Qnil);
5245 staticpro (&Qfile_name_history);
5246
5247 Qfile_error = intern ("file-error");
5248 staticpro (&Qfile_error);
5249 Qfile_already_exists = intern ("file-already-exists");
5250 staticpro (&Qfile_already_exists);
5251 Qfile_date_error = intern ("file-date-error");
5252 staticpro (&Qfile_date_error);
5253
5254 #ifdef DOS_NT
5255 Qfind_buffer_file_type = intern ("find-buffer-file-type");
5256 staticpro (&Qfind_buffer_file_type);
5257 #endif /* DOS_NT */
5258
5259 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
5260 "*Coding system for encoding file names.\n\
5261 If it is nil, default-file-name-coding-system (which see) is used.");
5262 Vfile_name_coding_system = Qnil;
5263
5264 DEFVAR_LISP ("default-file-name-coding-system",
5265 &Vdefault_file_name_coding_system,
5266 "Default coding system for encoding file names.\n\
5267 This variable is used only when file-name-coding-system is nil.\n\
5268 \n\
5269 This variable is set/changed by the command set-language-environment.\n\
5270 User should not set this variable manually,\n\
5271 instead use file-name-coding-system to get a constant encoding\n\
5272 of file names regardless of the current language environment.");
5273 Vdefault_file_name_coding_system = Qnil;
5274
5275 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
5276 "*Format in which to write auto-save files.\n\
5277 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5278 If it is t, which is the default, auto-save files are written in the\n\
5279 same format as a regular save would use.");
5280 Vauto_save_file_format = Qt;
5281
5282 Qformat_decode = intern ("format-decode");
5283 staticpro (&Qformat_decode);
5284 Qformat_annotate_function = intern ("format-annotate-function");
5285 staticpro (&Qformat_annotate_function);
5286
5287 Qcar_less_than_car = intern ("car-less-than-car");
5288 staticpro (&Qcar_less_than_car);
5289
5290 Fput (Qfile_error, Qerror_conditions,
5291 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
5292 Fput (Qfile_error, Qerror_message,
5293 build_string ("File error"));
5294
5295 Fput (Qfile_already_exists, Qerror_conditions,
5296 Fcons (Qfile_already_exists,
5297 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5298 Fput (Qfile_already_exists, Qerror_message,
5299 build_string ("File already exists"));
5300
5301 Fput (Qfile_date_error, Qerror_conditions,
5302 Fcons (Qfile_date_error,
5303 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5304 Fput (Qfile_date_error, Qerror_message,
5305 build_string ("Cannot set file date"));
5306
5307 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
5308 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5309 insert_default_directory = 1;
5310
5311 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
5312 "*Non-nil means write new files with record format `stmlf'.\n\
5313 nil means use format `var'. This variable is meaningful only on VMS.");
5314 vms_stmlf_recfm = 0;
5315
5316 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
5317 "Directory separator character for built-in functions that return file names.\n\
5318 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5319 This variable affects the built-in functions only on Windows,\n\
5320 on other platforms, it is initialized so that Lisp code can find out\n\
5321 what the normal separator is.");
5322 XSETFASTINT (Vdirectory_sep_char, '/');
5323
5324 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
5325 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5326 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5327 HANDLER.\n\
5328 \n\
5329 The first argument given to HANDLER is the name of the I/O primitive\n\
5330 to be handled; the remaining arguments are the arguments that were\n\
5331 passed to that primitive. For example, if you do\n\
5332 (file-exists-p FILENAME)\n\
5333 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5334 (funcall HANDLER 'file-exists-p FILENAME)\n\
5335 The function `find-file-name-handler' checks this list for a handler\n\
5336 for its argument.");
5337 Vfile_name_handler_alist = Qnil;
5338
5339 DEFVAR_LISP ("set-auto-coding-function",
5340 &Vset_auto_coding_function,
5341 "If non-nil, a function to call to decide a coding system of file.\n\
5342 One argument is passed to this function: the string of concatination\n\
5343 or the heading 1K-byte and the tailing 3K-byte of a file to be read.\n\
5344 This function should return a coding system to decode the file contents\n\
5345 specified in the heading lines with the format:\n\
5346 -*- ... coding: CODING-SYSTEM; ... -*-\n\
5347 or local variable spec of the tailing lines with `coding:' tag.");
5348 Vset_auto_coding_function = Qnil;
5349
5350 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
5351 "A list of functions to be called at the end of `insert-file-contents'.\n\
5352 Each is passed one argument, the number of bytes inserted. It should return\n\
5353 the new byte count, and leave point the same. If `insert-file-contents' is\n\
5354 intercepted by a handler from `file-name-handler-alist', that handler is\n\
5355 responsible for calling the after-insert-file-functions if appropriate.");
5356 Vafter_insert_file_functions = Qnil;
5357
5358 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
5359 "A list of functions to be called at the start of `write-region'.\n\
5360 Each is passed two arguments, START and END as for `write-region'.\n\
5361 These are usually two numbers but not always; see the documentation\n\
5362 for `write-region'. The function should return a list of pairs\n\
5363 of the form (POSITION . STRING), consisting of strings to be effectively\n\
5364 inserted at the specified positions of the file being written (1 means to\n\
5365 insert before the first byte written). The POSITIONs must be sorted into\n\
5366 increasing order. If there are several functions in the list, the several\n\
5367 lists are merged destructively.");
5368 Vwrite_region_annotate_functions = Qnil;
5369
5370 DEFVAR_LISP ("write-region-annotations-so-far",
5371 &Vwrite_region_annotations_so_far,
5372 "When an annotation function is called, this holds the previous annotations.\n\
5373 These are the annotations made by other annotation functions\n\
5374 that were already called. See also `write-region-annotate-functions'.");
5375 Vwrite_region_annotations_so_far = Qnil;
5376
5377 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
5378 "A list of file name handlers that temporarily should not be used.\n\
5379 This applies only to the operation `inhibit-file-name-operation'.");
5380 Vinhibit_file_name_handlers = Qnil;
5381
5382 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
5383 "The operation for which `inhibit-file-name-handlers' is applicable.");
5384 Vinhibit_file_name_operation = Qnil;
5385
5386 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
5387 "File name in which we write a list of all auto save file names.\n\
5388 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5389 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5390 a non-nil value.");
5391 Vauto_save_list_file_name = Qnil;
5392
5393 defsubr (&Sfind_file_name_handler);
5394 defsubr (&Sfile_name_directory);
5395 defsubr (&Sfile_name_nondirectory);
5396 defsubr (&Sunhandled_file_name_directory);
5397 defsubr (&Sfile_name_as_directory);
5398 defsubr (&Sdirectory_file_name);
5399 defsubr (&Smake_temp_name);
5400 defsubr (&Sexpand_file_name);
5401 defsubr (&Ssubstitute_in_file_name);
5402 defsubr (&Scopy_file);
5403 defsubr (&Smake_directory_internal);
5404 defsubr (&Sdelete_directory);
5405 defsubr (&Sdelete_file);
5406 defsubr (&Srename_file);
5407 defsubr (&Sadd_name_to_file);
5408 #ifdef S_IFLNK
5409 defsubr (&Smake_symbolic_link);
5410 #endif /* S_IFLNK */
5411 #ifdef VMS
5412 defsubr (&Sdefine_logical_name);
5413 #endif /* VMS */
5414 #ifdef HPUX_NET
5415 defsubr (&Ssysnetunam);
5416 #endif /* HPUX_NET */
5417 defsubr (&Sfile_name_absolute_p);
5418 defsubr (&Sfile_exists_p);
5419 defsubr (&Sfile_executable_p);
5420 defsubr (&Sfile_readable_p);
5421 defsubr (&Sfile_writable_p);
5422 defsubr (&Saccess_file);
5423 defsubr (&Sfile_symlink_p);
5424 defsubr (&Sfile_directory_p);
5425 defsubr (&Sfile_accessible_directory_p);
5426 defsubr (&Sfile_regular_p);
5427 defsubr (&Sfile_modes);
5428 defsubr (&Sset_file_modes);
5429 defsubr (&Sset_default_file_modes);
5430 defsubr (&Sdefault_file_modes);
5431 defsubr (&Sfile_newer_than_file_p);
5432 defsubr (&Sinsert_file_contents);
5433 defsubr (&Swrite_region);
5434 defsubr (&Scar_less_than_car);
5435 defsubr (&Sverify_visited_file_modtime);
5436 defsubr (&Sclear_visited_file_modtime);
5437 defsubr (&Svisited_file_modtime);
5438 defsubr (&Sset_visited_file_modtime);
5439 defsubr (&Sdo_auto_save);
5440 defsubr (&Sset_buffer_auto_saved);
5441 defsubr (&Sclear_buffer_auto_save_failure);
5442 defsubr (&Srecent_auto_save_p);
5443
5444 defsubr (&Sread_file_name_internal);
5445 defsubr (&Sread_file_name);
5446
5447 #ifdef unix
5448 defsubr (&Sunix_sync);
5449 #endif
5450 }