(x_window): Don't add ibw to menubar_size.
[emacs.git] / src / fileio.c
bloba9d2b95e09ad8eda8c66049666f9292c7227613d
1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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.
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.
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. */
21 #include <config.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
30 #if !defined (S_ISLNK) && defined (S_IFLNK)
31 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
32 #endif
34 #if !defined (S_ISREG) && defined (S_IFREG)
35 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
36 #endif
38 #ifdef VMS
39 #include "vms-pwd.h"
40 #else
41 #include <pwd.h>
42 #endif
44 #ifdef MSDOS
45 #include "msdos.h"
46 #include <sys/param.h>
47 #if __DJGPP__ >= 2
48 #include <fcntl.h>
49 #include <string.h>
50 #endif
51 #endif
53 #include <ctype.h>
55 #ifdef VMS
56 #include "vmsdir.h"
57 #include <perror.h>
58 #include <stddef.h>
59 #include <string.h>
60 #endif
62 #include <errno.h>
64 #ifndef vax11c
65 extern int errno;
66 #endif
68 extern char *strerror ();
70 #ifdef APOLLO
71 #include <sys/time.h>
72 #endif
74 #ifndef USG
75 #ifndef VMS
76 #ifndef BSD4_1
77 #ifndef WINDOWSNT
78 #define HAVE_FSYNC
79 #endif
80 #endif
81 #endif
82 #endif
84 #include "lisp.h"
85 #include "intervals.h"
86 #include "buffer.h"
87 #include "window.h"
89 #ifdef WINDOWSNT
90 #define NOMINMAX 1
91 #include <windows.h>
92 #include <stdlib.h>
93 #include <fcntl.h>
94 #endif /* not WINDOWSNT */
96 #ifdef DOS_NT
97 #define CORRECT_DIR_SEPS(s) \
98 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
99 else unixtodos_filename (s); \
100 } while (0)
101 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
102 redirector allows the six letters between 'Z' and 'a' as well. */
103 #ifdef MSDOS
104 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
105 #endif
106 #ifdef WINDOWSNT
107 #define IS_DRIVE(x) isalpha (x)
108 #endif
109 /* Need to lower-case the drive letter, or else expanded
110 filenames will sometimes compare inequal, because
111 `expand-file-name' doesn't always down-case the drive letter. */
112 #define DRIVE_LETTER(x) (tolower (x))
113 #endif
115 #ifdef VMS
116 #include <file.h>
117 #include <rmsdef.h>
118 #include <fab.h>
119 #include <nam.h>
120 #endif
122 #include "systime.h"
124 #ifdef HPUX
125 #include <netio.h>
126 #ifndef HPUX8
127 #ifndef HPUX9
128 #include <errnet.h>
129 #endif
130 #endif
131 #endif
133 #ifndef O_WRONLY
134 #define O_WRONLY 1
135 #endif
137 #ifndef O_RDONLY
138 #define O_RDONLY 0
139 #endif
141 #define min(a, b) ((a) < (b) ? (a) : (b))
142 #define max(a, b) ((a) > (b) ? (a) : (b))
144 /* Nonzero during writing of auto-save files */
145 int auto_saving;
147 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
148 a new file with the same mode as the original */
149 int auto_save_mode_bits;
151 /* Alist of elements (REGEXP . HANDLER) for file names
152 whose I/O is done with a special handler. */
153 Lisp_Object Vfile_name_handler_alist;
155 /* Format for auto-save files */
156 Lisp_Object Vauto_save_file_format;
158 /* Lisp functions for translating file formats */
159 Lisp_Object Qformat_decode, Qformat_annotate_function;
161 /* Functions to be called to process text properties in inserted file. */
162 Lisp_Object Vafter_insert_file_functions;
164 /* Functions to be called to create text property annotations for file. */
165 Lisp_Object Vwrite_region_annotate_functions;
167 /* During build_annotations, each time an annotation function is called,
168 this holds the annotations made by the previous functions. */
169 Lisp_Object Vwrite_region_annotations_so_far;
171 /* File name in which we write a list of all our auto save files. */
172 Lisp_Object Vauto_save_list_file_name;
174 /* Nonzero means, when reading a filename in the minibuffer,
175 start out by inserting the default directory into the minibuffer. */
176 int insert_default_directory;
178 /* On VMS, nonzero means write new files with record format stmlf.
179 Zero means use var format. */
180 int vms_stmlf_recfm;
182 /* On NT, specifies the directory separator character, used (eg.) when
183 expanding file names. This can be bound to / or \. */
184 Lisp_Object Vdirectory_sep_char;
186 /* These variables describe handlers that have "already" had a chance
187 to handle the current operation.
189 Vinhibit_file_name_handlers is a list of file name handlers.
190 Vinhibit_file_name_operation is the operation being handled.
191 If we try to handle that operation, we ignore those handlers. */
193 static Lisp_Object Vinhibit_file_name_handlers;
194 static Lisp_Object Vinhibit_file_name_operation;
196 Lisp_Object Qfile_error, Qfile_already_exists;
198 Lisp_Object Qfile_name_history;
200 Lisp_Object Qcar_less_than_car;
202 report_file_error (string, data)
203 char *string;
204 Lisp_Object data;
206 Lisp_Object errstring;
208 errstring = build_string (strerror (errno));
210 /* System error messages are capitalized. Downcase the initial
211 unless it is followed by a slash. */
212 if (XSTRING (errstring)->data[1] != '/')
213 XSTRING (errstring)->data[0] = DOWNCASE (XSTRING (errstring)->data[0]);
215 while (1)
216 Fsignal (Qfile_error,
217 Fcons (build_string (string), Fcons (errstring, data)));
220 close_file_unwind (fd)
221 Lisp_Object fd;
223 close (XFASTINT (fd));
226 /* Restore point, having saved it as a marker. */
228 restore_point_unwind (location)
229 Lisp_Object location;
231 SET_PT (marker_position (location));
232 Fset_marker (location, Qnil, Qnil);
235 Lisp_Object Qexpand_file_name;
236 Lisp_Object Qsubstitute_in_file_name;
237 Lisp_Object Qdirectory_file_name;
238 Lisp_Object Qfile_name_directory;
239 Lisp_Object Qfile_name_nondirectory;
240 Lisp_Object Qunhandled_file_name_directory;
241 Lisp_Object Qfile_name_as_directory;
242 Lisp_Object Qcopy_file;
243 Lisp_Object Qmake_directory_internal;
244 Lisp_Object Qdelete_directory;
245 Lisp_Object Qdelete_file;
246 Lisp_Object Qrename_file;
247 Lisp_Object Qadd_name_to_file;
248 Lisp_Object Qmake_symbolic_link;
249 Lisp_Object Qfile_exists_p;
250 Lisp_Object Qfile_executable_p;
251 Lisp_Object Qfile_readable_p;
252 Lisp_Object Qfile_symlink_p;
253 Lisp_Object Qfile_writable_p;
254 Lisp_Object Qfile_directory_p;
255 Lisp_Object Qfile_regular_p;
256 Lisp_Object Qfile_accessible_directory_p;
257 Lisp_Object Qfile_modes;
258 Lisp_Object Qset_file_modes;
259 Lisp_Object Qfile_newer_than_file_p;
260 Lisp_Object Qinsert_file_contents;
261 Lisp_Object Qwrite_region;
262 Lisp_Object Qverify_visited_file_modtime;
263 Lisp_Object Qset_visited_file_modtime;
265 DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
266 "Return FILENAME's handler function for OPERATION, if it has one.\n\
267 Otherwise, return nil.\n\
268 A file name is handled if one of the regular expressions in\n\
269 `file-name-handler-alist' matches it.\n\n\
270 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
271 any handlers that are members of `inhibit-file-name-handlers',\n\
272 but we still do run any other handlers. This lets handlers\n\
273 use the standard functions without calling themselves recursively.")
274 (filename, operation)
275 Lisp_Object filename, operation;
277 /* This function must not munge the match data. */
278 Lisp_Object chain, inhibited_handlers;
280 CHECK_STRING (filename, 0);
282 if (EQ (operation, Vinhibit_file_name_operation))
283 inhibited_handlers = Vinhibit_file_name_handlers;
284 else
285 inhibited_handlers = Qnil;
287 for (chain = Vfile_name_handler_alist; CONSP (chain);
288 chain = XCONS (chain)->cdr)
290 Lisp_Object elt;
291 elt = XCONS (chain)->car;
292 if (CONSP (elt))
294 Lisp_Object string;
295 string = XCONS (elt)->car;
296 if (STRINGP (string) && fast_string_match (string, filename) >= 0)
298 Lisp_Object handler, tem;
300 handler = XCONS (elt)->cdr;
301 tem = Fmemq (handler, inhibited_handlers);
302 if (NILP (tem))
303 return handler;
307 QUIT;
309 return Qnil;
312 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
313 1, 1, 0,
314 "Return the directory component in file name FILENAME.\n\
315 Return nil if FILENAME does not include a directory.\n\
316 Otherwise return a directory spec.\n\
317 Given a Unix syntax file name, returns a string ending in slash;\n\
318 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
319 (filename)
320 Lisp_Object filename;
322 register unsigned char *beg;
323 register unsigned char *p;
324 Lisp_Object handler;
326 CHECK_STRING (filename, 0);
328 /* If the file name has special constructs in it,
329 call the corresponding file handler. */
330 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
331 if (!NILP (handler))
332 return call2 (handler, Qfile_name_directory, filename);
334 #ifdef FILE_SYSTEM_CASE
335 filename = FILE_SYSTEM_CASE (filename);
336 #endif
337 beg = XSTRING (filename)->data;
338 #ifdef DOS_NT
339 beg = strcpy (alloca (strlen (beg) + 1), beg);
340 #endif
341 p = beg + XSTRING (filename)->size;
343 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
344 #ifdef VMS
345 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
346 #endif /* VMS */
347 #ifdef DOS_NT
348 /* only recognise drive specifier at beginning */
349 && !(p[-1] == ':' && p == beg + 2)
350 #endif
351 ) p--;
353 if (p == beg)
354 return Qnil;
355 #ifdef DOS_NT
356 /* Expansion of "c:" to drive and default directory. */
357 if (p == beg + 2 && beg[1] == ':')
359 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
360 unsigned char *res = alloca (MAXPATHLEN + 1);
361 if (getdefdir (toupper (*beg) - 'A' + 1, res))
363 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
364 strcat (res, "/");
365 beg = res;
366 p = beg + strlen (beg);
369 CORRECT_DIR_SEPS (beg);
370 #endif /* DOS_NT */
371 return make_string (beg, p - beg);
374 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, Sfile_name_nondirectory,
375 1, 1, 0,
376 "Return file name FILENAME sans its directory.\n\
377 For example, in a Unix-syntax file name,\n\
378 this is everything after the last slash,\n\
379 or the entire name if it contains no slash.")
380 (filename)
381 Lisp_Object filename;
383 register unsigned char *beg, *p, *end;
384 Lisp_Object handler;
386 CHECK_STRING (filename, 0);
388 /* If the file name has special constructs in it,
389 call the corresponding file handler. */
390 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
391 if (!NILP (handler))
392 return call2 (handler, Qfile_name_nondirectory, filename);
394 beg = XSTRING (filename)->data;
395 end = p = beg + XSTRING (filename)->size;
397 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
398 #ifdef VMS
399 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
400 #endif /* VMS */
401 #ifdef DOS_NT
402 /* only recognise drive specifier at beginning */
403 && !(p[-1] == ':' && p == beg + 2)
404 #endif
405 ) p--;
407 return make_string (p, end - p);
410 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, Sunhandled_file_name_directory, 1, 1, 0,
411 "Return a directly usable directory name somehow associated with FILENAME.\n\
412 A `directly usable' directory name is one that may be used without the\n\
413 intervention of any file handler.\n\
414 If FILENAME is a directly usable file itself, return\n\
415 (file-name-directory FILENAME).\n\
416 The `call-process' and `start-process' functions use this function to\n\
417 get a current directory to run processes in.")
418 (filename)
419 Lisp_Object filename;
421 Lisp_Object handler;
423 /* If the file name has special constructs in it,
424 call the corresponding file handler. */
425 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
426 if (!NILP (handler))
427 return call2 (handler, Qunhandled_file_name_directory, filename);
429 return Ffile_name_directory (filename);
433 char *
434 file_name_as_directory (out, in)
435 char *out, *in;
437 int size = strlen (in) - 1;
439 strcpy (out, in);
441 #ifdef VMS
442 /* Is it already a directory string? */
443 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
444 return out;
445 /* Is it a VMS directory file name? If so, hack VMS syntax. */
446 else if (! index (in, '/')
447 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
448 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
449 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
450 || ! strncmp (&in[size - 5], ".dir", 4))
451 && (in[size - 1] == '.' || in[size - 1] == ';')
452 && in[size] == '1')))
454 register char *p, *dot;
455 char brack;
457 /* x.dir -> [.x]
458 dir:x.dir --> dir:[x]
459 dir:[x]y.dir --> dir:[x.y] */
460 p = in + size;
461 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
462 if (p != in)
464 strncpy (out, in, p - in);
465 out[p - in] = '\0';
466 if (*p == ':')
468 brack = ']';
469 strcat (out, ":[");
471 else
473 brack = *p;
474 strcat (out, ".");
476 p++;
478 else
480 brack = ']';
481 strcpy (out, "[.");
483 dot = index (p, '.');
484 if (dot)
486 /* blindly remove any extension */
487 size = strlen (out) + (dot - p);
488 strncat (out, p, dot - p);
490 else
492 strcat (out, p);
493 size = strlen (out);
495 out[size++] = brack;
496 out[size] = '\0';
498 #else /* not VMS */
499 /* For Unix syntax, Append a slash if necessary */
500 if (!IS_DIRECTORY_SEP (out[size]))
502 out[size + 1] = DIRECTORY_SEP;
503 out[size + 2] = '\0';
505 #ifdef DOS_NT
506 CORRECT_DIR_SEPS (out);
507 #endif
508 #endif /* not VMS */
509 return out;
512 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
513 Sfile_name_as_directory, 1, 1, 0,
514 "Return a string representing file FILENAME interpreted as a directory.\n\
515 This operation exists because a directory is also a file, but its name as\n\
516 a directory is different from its name as a file.\n\
517 The result can be used as the value of `default-directory'\n\
518 or passed as second argument to `expand-file-name'.\n\
519 For a Unix-syntax file name, just appends a slash.\n\
520 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
521 (file)
522 Lisp_Object file;
524 char *buf;
525 Lisp_Object handler;
527 CHECK_STRING (file, 0);
528 if (NILP (file))
529 return Qnil;
531 /* If the file name has special constructs in it,
532 call the corresponding file handler. */
533 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
534 if (!NILP (handler))
535 return call2 (handler, Qfile_name_as_directory, file);
537 buf = (char *) alloca (XSTRING (file)->size + 10);
538 return build_string (file_name_as_directory (buf, XSTRING (file)->data));
542 * Convert from directory name to filename.
543 * On VMS:
544 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
545 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
546 * On UNIX, it's simple: just make sure there isn't a terminating /
548 * Value is nonzero if the string output is different from the input.
551 directory_file_name (src, dst)
552 char *src, *dst;
554 long slen;
555 #ifdef VMS
556 long rlen;
557 char * ptr, * rptr;
558 char bracket;
559 struct FAB fab = cc$rms_fab;
560 struct NAM nam = cc$rms_nam;
561 char esa[NAM$C_MAXRSS];
562 #endif /* VMS */
564 slen = strlen (src);
565 #ifdef VMS
566 if (! index (src, '/')
567 && (src[slen - 1] == ']'
568 || src[slen - 1] == ':'
569 || src[slen - 1] == '>'))
571 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
572 fab.fab$l_fna = src;
573 fab.fab$b_fns = slen;
574 fab.fab$l_nam = &nam;
575 fab.fab$l_fop = FAB$M_NAM;
577 nam.nam$l_esa = esa;
578 nam.nam$b_ess = sizeof esa;
579 nam.nam$b_nop |= NAM$M_SYNCHK;
581 /* We call SYS$PARSE to handle such things as [--] for us. */
582 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
584 slen = nam.nam$b_esl;
585 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
586 slen -= 2;
587 esa[slen] = '\0';
588 src = esa;
590 if (src[slen - 1] != ']' && src[slen - 1] != '>')
592 /* what about when we have logical_name:???? */
593 if (src[slen - 1] == ':')
594 { /* Xlate logical name and see what we get */
595 ptr = strcpy (dst, src); /* upper case for getenv */
596 while (*ptr)
598 if ('a' <= *ptr && *ptr <= 'z')
599 *ptr -= 040;
600 ptr++;
602 dst[slen - 1] = 0; /* remove colon */
603 if (!(src = egetenv (dst)))
604 return 0;
605 /* should we jump to the beginning of this procedure?
606 Good points: allows us to use logical names that xlate
607 to Unix names,
608 Bad points: can be a problem if we just translated to a device
609 name...
610 For now, I'll punt and always expect VMS names, and hope for
611 the best! */
612 slen = strlen (src);
613 if (src[slen - 1] != ']' && src[slen - 1] != '>')
614 { /* no recursion here! */
615 strcpy (dst, src);
616 return 0;
619 else
620 { /* not a directory spec */
621 strcpy (dst, src);
622 return 0;
625 bracket = src[slen - 1];
627 /* If bracket is ']' or '>', bracket - 2 is the corresponding
628 opening bracket. */
629 ptr = index (src, bracket - 2);
630 if (ptr == 0)
631 { /* no opening bracket */
632 strcpy (dst, src);
633 return 0;
635 if (!(rptr = rindex (src, '.')))
636 rptr = ptr;
637 slen = rptr - src;
638 strncpy (dst, src, slen);
639 dst[slen] = '\0';
640 if (*rptr == '.')
642 dst[slen++] = bracket;
643 dst[slen] = '\0';
645 else
647 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
648 then translate the device and recurse. */
649 if (dst[slen - 1] == ':'
650 && dst[slen - 2] != ':' /* skip decnet nodes */
651 && strcmp (src + slen, "[000000]") == 0)
653 dst[slen - 1] = '\0';
654 if ((ptr = egetenv (dst))
655 && (rlen = strlen (ptr) - 1) > 0
656 && (ptr[rlen] == ']' || ptr[rlen] == '>')
657 && ptr[rlen - 1] == '.')
659 char * buf = (char *) alloca (strlen (ptr) + 1);
660 strcpy (buf, ptr);
661 buf[rlen - 1] = ']';
662 buf[rlen] = '\0';
663 return directory_file_name (buf, dst);
665 else
666 dst[slen - 1] = ':';
668 strcat (dst, "[000000]");
669 slen += 8;
671 rptr++;
672 rlen = strlen (rptr) - 1;
673 strncat (dst, rptr, rlen);
674 dst[slen + rlen] = '\0';
675 strcat (dst, ".DIR.1");
676 return 1;
678 #endif /* VMS */
679 /* Process as Unix format: just remove any final slash.
680 But leave "/" unchanged; do not change it to "". */
681 strcpy (dst, src);
682 #ifdef APOLLO
683 /* Handle // as root for apollo's. */
684 if ((slen > 2 && dst[slen - 1] == '/')
685 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
686 dst[slen - 1] = 0;
687 #else
688 if (slen > 1
689 && IS_DIRECTORY_SEP (dst[slen - 1])
690 #ifdef DOS_NT
691 && !IS_ANY_SEP (dst[slen - 2])
692 #endif
694 dst[slen - 1] = 0;
695 #endif
696 #ifdef DOS_NT
697 CORRECT_DIR_SEPS (dst);
698 #endif
699 return 1;
702 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
703 1, 1, 0,
704 "Returns the file name of the directory named DIRECTORY.\n\
705 This is the name of the file that holds the data for the directory DIRECTORY.\n\
706 This operation exists because a directory is also a file, but its name as\n\
707 a directory is different from its name as a file.\n\
708 In Unix-syntax, this function just removes the final slash.\n\
709 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
710 it returns a file name such as \"[X]Y.DIR.1\".")
711 (directory)
712 Lisp_Object directory;
714 char *buf;
715 Lisp_Object handler;
717 CHECK_STRING (directory, 0);
719 if (NILP (directory))
720 return Qnil;
722 /* If the file name has special constructs in it,
723 call the corresponding file handler. */
724 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
725 if (!NILP (handler))
726 return call2 (handler, Qdirectory_file_name, directory);
728 #ifdef VMS
729 /* 20 extra chars is insufficient for VMS, since we might perform a
730 logical name translation. an equivalence string can be up to 255
731 chars long, so grab that much extra space... - sss */
732 buf = (char *) alloca (XSTRING (directory)->size + 20 + 255);
733 #else
734 buf = (char *) alloca (XSTRING (directory)->size + 20);
735 #endif
736 directory_file_name (XSTRING (directory)->data, buf);
737 return build_string (buf);
740 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
741 "Generate temporary file name (string) starting with PREFIX (a string).\n\
742 The Emacs process number forms part of the result,\n\
743 so there is no danger of generating a name being used by another process.")
744 (prefix)
745 Lisp_Object prefix;
747 Lisp_Object val;
748 #ifdef MSDOS
749 /* Don't use too many characters of the restricted 8+3 DOS
750 filename space. */
751 val = concat2 (prefix, build_string ("a.XXX"));
752 #else
753 val = concat2 (prefix, build_string ("XXXXXX"));
754 #endif
755 mktemp (XSTRING (val)->data);
756 #ifdef DOS_NT
757 CORRECT_DIR_SEPS (XSTRING (val)->data);
758 #endif
759 return val;
762 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
763 "Convert filename NAME to absolute, and canonicalize it.\n\
764 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
765 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
766 the current buffer's value of default-directory is used.\n\
767 File name components that are `.' are removed, and \n\
768 so are file name components followed by `..', along with the `..' itself;\n\
769 note that these simplifications are done without checking the resulting\n\
770 file names in the file system.\n\
771 An initial `~/' expands to your home directory.\n\
772 An initial `~USER/' expands to USER's home directory.\n\
773 See also the function `substitute-in-file-name'.")
774 (name, default_directory)
775 Lisp_Object name, default_directory;
777 unsigned char *nm;
779 register unsigned char *newdir, *p, *o;
780 int tlen;
781 unsigned char *target;
782 struct passwd *pw;
783 #ifdef VMS
784 unsigned char * colon = 0;
785 unsigned char * close = 0;
786 unsigned char * slash = 0;
787 unsigned char * brack = 0;
788 int lbrack = 0, rbrack = 0;
789 int dots = 0;
790 #endif /* VMS */
791 #ifdef DOS_NT
792 int drive = 0;
793 int collapse_newdir = 1;
794 #endif /* DOS_NT */
795 int length;
796 Lisp_Object handler;
798 CHECK_STRING (name, 0);
800 /* If the file name has special constructs in it,
801 call the corresponding file handler. */
802 handler = Ffind_file_name_handler (name, Qexpand_file_name);
803 if (!NILP (handler))
804 return call3 (handler, Qexpand_file_name, name, default_directory);
806 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
807 if (NILP (default_directory))
808 default_directory = current_buffer->directory;
809 CHECK_STRING (default_directory, 1);
811 if (!NILP (default_directory))
813 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
814 if (!NILP (handler))
815 return call3 (handler, Qexpand_file_name, name, default_directory);
818 o = XSTRING (default_directory)->data;
820 /* Make sure DEFAULT_DIRECTORY is properly expanded.
821 It would be better to do this down below where we actually use
822 default_directory. Unfortunately, calling Fexpand_file_name recursively
823 could invoke GC, and the strings might be relocated. This would
824 be annoying because we have pointers into strings lying around
825 that would need adjusting, and people would add new pointers to
826 the code and forget to adjust them, resulting in intermittent bugs.
827 Putting this call here avoids all that crud.
829 The EQ test avoids infinite recursion. */
830 if (! NILP (default_directory) && !EQ (default_directory, name)
831 /* Save time in some common cases - as long as default_directory
832 is not relative, it can be canonicalized with name below (if it
833 is needed at all) without requiring it to be expanded now. */
834 #ifdef DOS_NT
835 /* Detect MSDOS file names with drive specifiers. */
836 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
837 #ifdef WINDOWSNT
838 /* Detect Windows file names in UNC format. */
839 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
840 #endif
841 #else /* not DOS_NT */
842 /* Detect Unix absolute file names (/... alone is not absolute on
843 DOS or Windows). */
844 && ! (IS_DIRECTORY_SEP (o[0]))
845 #endif /* not DOS_NT */
848 struct gcpro gcpro1;
850 GCPRO1 (name);
851 default_directory = Fexpand_file_name (default_directory, Qnil);
852 UNGCPRO;
855 #ifdef VMS
856 /* Filenames on VMS are always upper case. */
857 name = Fupcase (name);
858 #endif
859 #ifdef FILE_SYSTEM_CASE
860 name = FILE_SYSTEM_CASE (name);
861 #endif
863 nm = XSTRING (name)->data;
865 #ifdef DOS_NT
866 /* We will force directory separators to be either all \ or /, so make
867 a local copy to modify, even if there ends up being no change. */
868 nm = strcpy (alloca (strlen (nm) + 1), nm);
870 /* Find and remove drive specifier if present; this makes nm absolute
871 even if the rest of the name appears to be relative. */
873 unsigned char *colon = rindex (nm, ':');
875 if (colon)
876 /* Only recognize colon as part of drive specifier if there is a
877 single alphabetic character preceeding the colon (and if the
878 character before the drive letter, if present, is a directory
879 separator); this is to support the remote system syntax used by
880 ange-ftp, and the "po:username" syntax for POP mailboxes. */
881 look_again:
882 if (nm == colon)
883 nm++;
884 else if (IS_DRIVE (colon[-1])
885 && (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2])))
887 drive = colon[-1];
888 nm = colon + 1;
890 else
892 while (--colon >= nm)
893 if (colon[0] == ':')
894 goto look_again;
897 #endif /* DOS_NT */
899 /* Handle // and /~ in middle of file name
900 by discarding everything through the first / of that sequence. */
901 p = nm;
902 while (*p)
904 /* Since we are expecting the name to be absolute, we can assume
905 that each element starts with a "/". */
907 if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])
908 #if defined (APOLLO) || defined (WINDOWSNT)
909 /* // at start of filename is meaningful on Apollo
910 and WindowsNT systems */
911 && nm != p
912 #endif /* APOLLO || WINDOWSNT */
914 nm = p + 1;
916 if (IS_DIRECTORY_SEP (p[0]) && p[1] == '~')
917 nm = p + 1;
919 p++;
922 #ifdef WINDOWSNT
923 /* Discard any previous drive specifier if nm is now in UNC format. */
924 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
926 drive = 0;
928 #endif
930 /* If nm is absolute, look for /./ or /../ sequences; if none are
931 found, we can probably return right away. We will avoid allocating
932 a new string if name is already fully expanded. */
933 if (
934 IS_DIRECTORY_SEP (nm[0])
935 #ifdef MSDOS
936 && drive
937 #endif
938 #ifdef WINDOWSNT
939 && (drive || IS_DIRECTORY_SEP (nm[1]))
940 #endif
941 #ifdef VMS
942 || index (nm, ':')
943 #endif /* VMS */
946 /* If it turns out that the filename we want to return is just a
947 suffix of FILENAME, we don't need to go through and edit
948 things; we just need to construct a new string using data
949 starting at the middle of FILENAME. If we set lose to a
950 non-zero value, that means we've discovered that we can't do
951 that cool trick. */
952 int lose = 0;
954 p = nm;
955 while (*p)
957 /* Since we know the name is absolute, we can assume that each
958 element starts with a "/". */
960 /* "." and ".." are hairy. */
961 if (IS_DIRECTORY_SEP (p[0])
962 && p[1] == '.'
963 && (IS_DIRECTORY_SEP (p[2])
964 || p[2] == 0
965 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
966 || p[3] == 0))))
967 lose = 1;
968 #ifdef VMS
969 if (p[0] == '\\')
970 lose = 1;
971 if (p[0] == '/') {
972 /* if dev:[dir]/, move nm to / */
973 if (!slash && p > nm && (brack || colon)) {
974 nm = (brack ? brack + 1 : colon + 1);
975 lbrack = rbrack = 0;
976 brack = 0;
977 colon = 0;
979 slash = p;
981 if (p[0] == '-')
982 #ifndef VMS4_4
983 /* VMS pre V4.4,convert '-'s in filenames. */
984 if (lbrack == rbrack)
986 if (dots < 2) /* this is to allow negative version numbers */
987 p[0] = '_';
989 else
990 #endif /* VMS4_4 */
991 if (lbrack > rbrack &&
992 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
993 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
994 lose = 1;
995 #ifndef VMS4_4
996 else
997 p[0] = '_';
998 #endif /* VMS4_4 */
999 /* count open brackets, reset close bracket pointer */
1000 if (p[0] == '[' || p[0] == '<')
1001 lbrack++, brack = 0;
1002 /* count close brackets, set close bracket pointer */
1003 if (p[0] == ']' || p[0] == '>')
1004 rbrack++, brack = p;
1005 /* detect ][ or >< */
1006 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1007 lose = 1;
1008 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1009 nm = p + 1, lose = 1;
1010 if (p[0] == ':' && (colon || slash))
1011 /* if dev1:[dir]dev2:, move nm to dev2: */
1012 if (brack)
1014 nm = brack + 1;
1015 brack = 0;
1017 /* if /name/dev:, move nm to dev: */
1018 else if (slash)
1019 nm = slash + 1;
1020 /* if node::dev:, move colon following dev */
1021 else if (colon && colon[-1] == ':')
1022 colon = p;
1023 /* if dev1:dev2:, move nm to dev2: */
1024 else if (colon && colon[-1] != ':')
1026 nm = colon + 1;
1027 colon = 0;
1029 if (p[0] == ':' && !colon)
1031 if (p[1] == ':')
1032 p++;
1033 colon = p;
1035 if (lbrack == rbrack)
1036 if (p[0] == ';')
1037 dots = 2;
1038 else if (p[0] == '.')
1039 dots++;
1040 #endif /* VMS */
1041 p++;
1043 if (!lose)
1045 #ifdef VMS
1046 if (index (nm, '/'))
1047 return build_string (sys_translate_unix (nm));
1048 #endif /* VMS */
1049 #ifdef DOS_NT
1050 /* Make sure directories are all separated with / or \ as
1051 desired, but avoid allocation of a new string when not
1052 required. */
1053 CORRECT_DIR_SEPS (nm);
1054 #ifdef WINDOWSNT
1055 if (IS_DIRECTORY_SEP (nm[1]))
1057 if (strcmp (nm, XSTRING (name)->data) != 0)
1058 name = build_string (nm);
1060 else
1061 #endif
1062 /* drive must be set, so this is okay */
1063 if (strcmp (nm - 2, XSTRING (name)->data) != 0)
1065 name = make_string (nm - 2, p - nm + 2);
1066 XSTRING (name)->data[0] = DRIVE_LETTER (drive);
1067 XSTRING (name)->data[1] = ':';
1069 return name;
1070 #else /* not DOS_NT */
1071 if (nm == XSTRING (name)->data)
1072 return name;
1073 return build_string (nm);
1074 #endif /* not DOS_NT */
1078 /* At this point, nm might or might not be an absolute file name. We
1079 need to expand ~ or ~user if present, otherwise prefix nm with
1080 default_directory if nm is not absolute, and finally collapse /./
1081 and /foo/../ sequences.
1083 We set newdir to be the appropriate prefix if one is needed:
1084 - the relevant user directory if nm starts with ~ or ~user
1085 - the specified drive's working dir (DOS/NT only) if nm does not
1086 start with /
1087 - the value of default_directory.
1089 Note that these prefixes are not guaranteed to be absolute (except
1090 for the working dir of a drive). Therefore, to ensure we always
1091 return an absolute name, if the final prefix is not absolute we
1092 append it to the current working directory. */
1094 newdir = 0;
1096 if (nm[0] == '~') /* prefix ~ */
1098 if (IS_DIRECTORY_SEP (nm[1])
1099 #ifdef VMS
1100 || nm[1] == ':'
1101 #endif /* VMS */
1102 || nm[1] == 0) /* ~ by itself */
1104 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1105 newdir = (unsigned char *) "";
1106 nm++;
1107 #ifdef DOS_NT
1108 collapse_newdir = 0;
1109 #endif
1110 #ifdef VMS
1111 nm++; /* Don't leave the slash in nm. */
1112 #endif /* VMS */
1114 else /* ~user/filename */
1116 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
1117 #ifdef VMS
1118 && *p != ':'
1119 #endif /* VMS */
1120 ); p++);
1121 o = (unsigned char *) alloca (p - nm + 1);
1122 bcopy ((char *) nm, o, p - nm);
1123 o [p - nm] = 0;
1125 pw = (struct passwd *) getpwnam (o + 1);
1126 if (pw)
1128 newdir = (unsigned char *) pw -> pw_dir;
1129 #ifdef VMS
1130 nm = p + 1; /* skip the terminator */
1131 #else
1132 nm = p;
1133 #ifdef DOS_NT
1134 collapse_newdir = 0;
1135 #endif
1136 #endif /* VMS */
1139 /* If we don't find a user of that name, leave the name
1140 unchanged; don't move nm forward to p. */
1144 #ifdef DOS_NT
1145 /* On DOS and Windows, nm is absolute if a drive name was specified;
1146 use the drive's current directory as the prefix if needed. */
1147 if (!newdir && drive)
1149 /* Get default directory if needed to make nm absolute. */
1150 if (!IS_DIRECTORY_SEP (nm[0]))
1152 newdir = alloca (MAXPATHLEN + 1);
1153 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1154 newdir = NULL;
1156 if (!newdir)
1158 /* Either nm starts with /, or drive isn't mounted. */
1159 newdir = alloca (4);
1160 newdir[0] = DRIVE_LETTER (drive);
1161 newdir[1] = ':';
1162 newdir[2] = '/';
1163 newdir[3] = 0;
1166 #endif /* DOS_NT */
1168 /* Finally, if no prefix has been specified and nm is not absolute,
1169 then it must be expanded relative to default_directory. */
1171 if (1
1172 #ifndef DOS_NT
1173 /* /... alone is not absolute on DOS and Windows. */
1174 && !IS_DIRECTORY_SEP (nm[0])
1175 #endif
1176 #ifdef WINDOWSNT
1177 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1178 #endif
1179 #ifdef VMS
1180 && !index (nm, ':')
1181 #endif
1182 && !newdir)
1184 newdir = XSTRING (default_directory)->data;
1187 #ifdef DOS_NT
1188 if (newdir)
1190 /* First ensure newdir is an absolute name. */
1191 if (
1192 /* Detect MSDOS file names with drive specifiers. */
1193 ! (IS_DRIVE (newdir[0])
1194 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1195 #ifdef WINDOWSNT
1196 /* Detect Windows file names in UNC format. */
1197 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1198 #endif
1201 /* Effectively, let newdir be (expand-file-name newdir cwd).
1202 Because of the admonition against calling expand-file-name
1203 when we have pointers into lisp strings, we accomplish this
1204 indirectly by prepending newdir to nm if necessary, and using
1205 cwd (or the wd of newdir's drive) as the new newdir. */
1207 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1209 drive = newdir[0];
1210 newdir += 2;
1212 if (!IS_DIRECTORY_SEP (nm[0]))
1214 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1215 file_name_as_directory (tmp, newdir);
1216 strcat (tmp, nm);
1217 nm = tmp;
1219 newdir = alloca (MAXPATHLEN + 1);
1220 if (drive)
1222 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1223 newdir = "/";
1225 else
1226 getwd (newdir);
1229 /* Strip off drive name from prefix, if present. */
1230 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1232 drive = newdir[0];
1233 newdir += 2;
1236 /* Keep only a prefix from newdir if nm starts with slash
1237 (//server/share for UNC, nothing otherwise). */
1238 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1240 #ifdef WINDOWSNT
1241 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1243 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1244 p = newdir + 2;
1245 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1246 p++;
1247 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1248 *p = 0;
1250 else
1251 #endif
1252 newdir = "";
1255 #endif /* DOS_NT */
1257 if (newdir)
1259 /* Get rid of any slash at the end of newdir, unless newdir is
1260 just // (an incomplete UNC name). */
1261 length = strlen (newdir);
1262 if (IS_DIRECTORY_SEP (newdir[length - 1])
1263 #ifdef WINDOWSNT
1264 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1265 #endif
1268 unsigned char *temp = (unsigned char *) alloca (length);
1269 bcopy (newdir, temp, length - 1);
1270 temp[length - 1] = 0;
1271 newdir = temp;
1273 tlen = length + 1;
1275 else
1276 tlen = 0;
1278 /* Now concatenate the directory and name to new space in the stack frame */
1279 tlen += strlen (nm) + 1;
1280 #ifdef DOS_NT
1281 /* Add reserved space for drive name. (The Microsoft x86 compiler
1282 produces incorrect code if the following two lines are combined.) */
1283 target = (unsigned char *) alloca (tlen + 2);
1284 target += 2;
1285 #else /* not DOS_NT */
1286 target = (unsigned char *) alloca (tlen);
1287 #endif /* not DOS_NT */
1288 *target = 0;
1290 if (newdir)
1292 #ifndef VMS
1293 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1294 strcpy (target, newdir);
1295 else
1296 #endif
1297 file_name_as_directory (target, newdir);
1300 strcat (target, nm);
1301 #ifdef VMS
1302 if (index (target, '/'))
1303 strcpy (target, sys_translate_unix (target));
1304 #endif /* VMS */
1306 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1308 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1310 p = target;
1311 o = target;
1313 while (*p)
1315 #ifdef VMS
1316 if (*p != ']' && *p != '>' && *p != '-')
1318 if (*p == '\\')
1319 p++;
1320 *o++ = *p++;
1322 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1323 /* brackets are offset from each other by 2 */
1325 p += 2;
1326 if (*p != '.' && *p != '-' && o[-1] != '.')
1327 /* convert [foo][bar] to [bar] */
1328 while (o[-1] != '[' && o[-1] != '<')
1329 o--;
1330 else if (*p == '-' && *o != '.')
1331 *--p = '.';
1333 else if (p[0] == '-' && o[-1] == '.' &&
1334 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1335 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1338 o--;
1339 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1340 if (p[1] == '.') /* foo.-.bar ==> bar. */
1341 p += 2;
1342 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1343 p++, o--;
1344 /* else [foo.-] ==> [-] */
1346 else
1348 #ifndef VMS4_4
1349 if (*p == '-' &&
1350 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1351 p[1] != ']' && p[1] != '>' && p[1] != '.')
1352 *p = '_';
1353 #endif /* VMS4_4 */
1354 *o++ = *p++;
1356 #else /* not VMS */
1357 if (!IS_DIRECTORY_SEP (*p))
1359 *o++ = *p++;
1361 else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])
1362 #if defined (APOLLO) || defined (WINDOWSNT)
1363 /* // at start of filename is meaningful in Apollo
1364 and WindowsNT systems */
1365 && o != target
1366 #endif /* APOLLO || WINDOWSNT */
1369 o = target;
1370 p++;
1372 else if (IS_DIRECTORY_SEP (p[0])
1373 && p[1] == '.'
1374 && (IS_DIRECTORY_SEP (p[2])
1375 || p[2] == 0))
1377 /* If "/." is the entire filename, keep the "/". Otherwise,
1378 just delete the whole "/.". */
1379 if (o == target && p[2] == '\0')
1380 *o++ = *p;
1381 p += 2;
1383 else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1384 /* `/../' is the "superroot" on certain file systems. */
1385 && o != target
1386 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1388 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1390 if (o == target && IS_ANY_SEP (*o))
1391 ++o;
1392 p += 3;
1394 else
1396 *o++ = *p++;
1398 #endif /* not VMS */
1401 #ifdef DOS_NT
1402 /* At last, set drive name. */
1403 #ifdef WINDOWSNT
1404 /* Except for network file name. */
1405 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1406 #endif /* WINDOWSNT */
1408 if (!drive) abort ();
1409 target -= 2;
1410 target[0] = DRIVE_LETTER (drive);
1411 target[1] = ':';
1413 CORRECT_DIR_SEPS (target);
1414 #endif /* DOS_NT */
1416 return make_string (target, o - target);
1419 #if 0
1420 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1421 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1422 "Convert FILENAME to absolute, and canonicalize it.\n\
1423 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1424 (does not start with slash); if DEFAULT is nil or missing,\n\
1425 the current buffer's value of default-directory is used.\n\
1426 Filenames containing `.' or `..' as components are simplified;\n\
1427 initial `~/' expands to your home directory.\n\
1428 See also the function `substitute-in-file-name'.")
1429 (name, defalt)
1430 Lisp_Object name, defalt;
1432 unsigned char *nm;
1434 register unsigned char *newdir, *p, *o;
1435 int tlen;
1436 unsigned char *target;
1437 struct passwd *pw;
1438 int lose;
1439 #ifdef VMS
1440 unsigned char * colon = 0;
1441 unsigned char * close = 0;
1442 unsigned char * slash = 0;
1443 unsigned char * brack = 0;
1444 int lbrack = 0, rbrack = 0;
1445 int dots = 0;
1446 #endif /* VMS */
1448 CHECK_STRING (name, 0);
1450 #ifdef VMS
1451 /* Filenames on VMS are always upper case. */
1452 name = Fupcase (name);
1453 #endif
1455 nm = XSTRING (name)->data;
1457 /* If nm is absolute, flush ...// and detect /./ and /../.
1458 If no /./ or /../ we can return right away. */
1459 if (
1460 nm[0] == '/'
1461 #ifdef VMS
1462 || index (nm, ':')
1463 #endif /* VMS */
1466 p = nm;
1467 lose = 0;
1468 while (*p)
1470 if (p[0] == '/' && p[1] == '/'
1471 #ifdef APOLLO
1472 /* // at start of filename is meaningful on Apollo system */
1473 && nm != p
1474 #endif /* APOLLO */
1476 nm = p + 1;
1477 if (p[0] == '/' && p[1] == '~')
1478 nm = p + 1, lose = 1;
1479 if (p[0] == '/' && p[1] == '.'
1480 && (p[2] == '/' || p[2] == 0
1481 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1482 lose = 1;
1483 #ifdef VMS
1484 if (p[0] == '\\')
1485 lose = 1;
1486 if (p[0] == '/') {
1487 /* if dev:[dir]/, move nm to / */
1488 if (!slash && p > nm && (brack || colon)) {
1489 nm = (brack ? brack + 1 : colon + 1);
1490 lbrack = rbrack = 0;
1491 brack = 0;
1492 colon = 0;
1494 slash = p;
1496 if (p[0] == '-')
1497 #ifndef VMS4_4
1498 /* VMS pre V4.4,convert '-'s in filenames. */
1499 if (lbrack == rbrack)
1501 if (dots < 2) /* this is to allow negative version numbers */
1502 p[0] = '_';
1504 else
1505 #endif /* VMS4_4 */
1506 if (lbrack > rbrack &&
1507 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1508 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1509 lose = 1;
1510 #ifndef VMS4_4
1511 else
1512 p[0] = '_';
1513 #endif /* VMS4_4 */
1514 /* count open brackets, reset close bracket pointer */
1515 if (p[0] == '[' || p[0] == '<')
1516 lbrack++, brack = 0;
1517 /* count close brackets, set close bracket pointer */
1518 if (p[0] == ']' || p[0] == '>')
1519 rbrack++, brack = p;
1520 /* detect ][ or >< */
1521 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1522 lose = 1;
1523 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1524 nm = p + 1, lose = 1;
1525 if (p[0] == ':' && (colon || slash))
1526 /* if dev1:[dir]dev2:, move nm to dev2: */
1527 if (brack)
1529 nm = brack + 1;
1530 brack = 0;
1532 /* If /name/dev:, move nm to dev: */
1533 else if (slash)
1534 nm = slash + 1;
1535 /* If node::dev:, move colon following dev */
1536 else if (colon && colon[-1] == ':')
1537 colon = p;
1538 /* If dev1:dev2:, move nm to dev2: */
1539 else if (colon && colon[-1] != ':')
1541 nm = colon + 1;
1542 colon = 0;
1544 if (p[0] == ':' && !colon)
1546 if (p[1] == ':')
1547 p++;
1548 colon = p;
1550 if (lbrack == rbrack)
1551 if (p[0] == ';')
1552 dots = 2;
1553 else if (p[0] == '.')
1554 dots++;
1555 #endif /* VMS */
1556 p++;
1558 if (!lose)
1560 #ifdef VMS
1561 if (index (nm, '/'))
1562 return build_string (sys_translate_unix (nm));
1563 #endif /* VMS */
1564 if (nm == XSTRING (name)->data)
1565 return name;
1566 return build_string (nm);
1570 /* Now determine directory to start with and put it in NEWDIR */
1572 newdir = 0;
1574 if (nm[0] == '~') /* prefix ~ */
1575 if (nm[1] == '/'
1576 #ifdef VMS
1577 || nm[1] == ':'
1578 #endif /* VMS */
1579 || nm[1] == 0)/* ~/filename */
1581 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1582 newdir = (unsigned char *) "";
1583 nm++;
1584 #ifdef VMS
1585 nm++; /* Don't leave the slash in nm. */
1586 #endif /* VMS */
1588 else /* ~user/filename */
1590 /* Get past ~ to user */
1591 unsigned char *user = nm + 1;
1592 /* Find end of name. */
1593 unsigned char *ptr = (unsigned char *) index (user, '/');
1594 int len = ptr ? ptr - user : strlen (user);
1595 #ifdef VMS
1596 unsigned char *ptr1 = index (user, ':');
1597 if (ptr1 != 0 && ptr1 - user < len)
1598 len = ptr1 - user;
1599 #endif /* VMS */
1600 /* Copy the user name into temp storage. */
1601 o = (unsigned char *) alloca (len + 1);
1602 bcopy ((char *) user, o, len);
1603 o[len] = 0;
1605 /* Look up the user name. */
1606 pw = (struct passwd *) getpwnam (o + 1);
1607 if (!pw)
1608 error ("\"%s\" isn't a registered user", o + 1);
1610 newdir = (unsigned char *) pw->pw_dir;
1612 /* Discard the user name from NM. */
1613 nm += len;
1616 if (nm[0] != '/'
1617 #ifdef VMS
1618 && !index (nm, ':')
1619 #endif /* not VMS */
1620 && !newdir)
1622 if (NILP (defalt))
1623 defalt = current_buffer->directory;
1624 CHECK_STRING (defalt, 1);
1625 newdir = XSTRING (defalt)->data;
1628 /* Now concatenate the directory and name to new space in the stack frame */
1630 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1631 target = (unsigned char *) alloca (tlen);
1632 *target = 0;
1634 if (newdir)
1636 #ifndef VMS
1637 if (nm[0] == 0 || nm[0] == '/')
1638 strcpy (target, newdir);
1639 else
1640 #endif
1641 file_name_as_directory (target, newdir);
1644 strcat (target, nm);
1645 #ifdef VMS
1646 if (index (target, '/'))
1647 strcpy (target, sys_translate_unix (target));
1648 #endif /* VMS */
1650 /* Now canonicalize by removing /. and /foo/.. if they appear */
1652 p = target;
1653 o = target;
1655 while (*p)
1657 #ifdef VMS
1658 if (*p != ']' && *p != '>' && *p != '-')
1660 if (*p == '\\')
1661 p++;
1662 *o++ = *p++;
1664 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1665 /* brackets are offset from each other by 2 */
1667 p += 2;
1668 if (*p != '.' && *p != '-' && o[-1] != '.')
1669 /* convert [foo][bar] to [bar] */
1670 while (o[-1] != '[' && o[-1] != '<')
1671 o--;
1672 else if (*p == '-' && *o != '.')
1673 *--p = '.';
1675 else if (p[0] == '-' && o[-1] == '.' &&
1676 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1677 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1680 o--;
1681 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1682 if (p[1] == '.') /* foo.-.bar ==> bar. */
1683 p += 2;
1684 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1685 p++, o--;
1686 /* else [foo.-] ==> [-] */
1688 else
1690 #ifndef VMS4_4
1691 if (*p == '-' &&
1692 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1693 p[1] != ']' && p[1] != '>' && p[1] != '.')
1694 *p = '_';
1695 #endif /* VMS4_4 */
1696 *o++ = *p++;
1698 #else /* not VMS */
1699 if (*p != '/')
1701 *o++ = *p++;
1703 else if (!strncmp (p, "//", 2)
1704 #ifdef APOLLO
1705 /* // at start of filename is meaningful in Apollo system */
1706 && o != target
1707 #endif /* APOLLO */
1710 o = target;
1711 p++;
1713 else if (p[0] == '/' && p[1] == '.' &&
1714 (p[2] == '/' || p[2] == 0))
1715 p += 2;
1716 else if (!strncmp (p, "/..", 3)
1717 /* `/../' is the "superroot" on certain file systems. */
1718 && o != target
1719 && (p[3] == '/' || p[3] == 0))
1721 while (o != target && *--o != '/')
1723 #ifdef APOLLO
1724 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1725 ++o;
1726 else
1727 #endif /* APOLLO */
1728 if (o == target && *o == '/')
1729 ++o;
1730 p += 3;
1732 else
1734 *o++ = *p++;
1736 #endif /* not VMS */
1739 return make_string (target, o - target);
1741 #endif
1743 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1744 Ssubstitute_in_file_name, 1, 1, 0,
1745 "Substitute environment variables referred to in FILENAME.\n\
1746 `$FOO' where FOO is an environment variable name means to substitute\n\
1747 the value of that variable. The variable name should be terminated\n\
1748 with a character not a letter, digit or underscore; otherwise, enclose\n\
1749 the entire variable name in braces.\n\
1750 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1751 On VMS, `$' substitution is not done; this function does little and only\n\
1752 duplicates what `expand-file-name' does.")
1753 (filename)
1754 Lisp_Object filename;
1756 unsigned char *nm;
1758 register unsigned char *s, *p, *o, *x, *endp;
1759 unsigned char *target;
1760 int total = 0;
1761 int substituted = 0;
1762 unsigned char *xnm;
1763 Lisp_Object handler;
1765 CHECK_STRING (filename, 0);
1767 /* If the file name has special constructs in it,
1768 call the corresponding file handler. */
1769 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1770 if (!NILP (handler))
1771 return call2 (handler, Qsubstitute_in_file_name, filename);
1773 nm = XSTRING (filename)->data;
1774 #ifdef DOS_NT
1775 nm = strcpy (alloca (strlen (nm) + 1), nm);
1776 CORRECT_DIR_SEPS (nm);
1777 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
1778 #endif
1779 endp = nm + XSTRING (filename)->size;
1781 /* If /~ or // appears, discard everything through first slash. */
1783 for (p = nm; p != endp; p++)
1785 if ((p[0] == '~'
1786 #if defined (APOLLO) || defined (WINDOWSNT)
1787 /* // at start of file name is meaningful in Apollo and
1788 WindowsNT systems */
1789 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1790 #else /* not (APOLLO || WINDOWSNT) */
1791 || IS_DIRECTORY_SEP (p[0])
1792 #endif /* not (APOLLO || WINDOWSNT) */
1794 && p != nm
1795 && (0
1796 #ifdef VMS
1797 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
1798 #endif /* VMS */
1799 || IS_DIRECTORY_SEP (p[-1])))
1801 nm = p;
1802 substituted = 1;
1804 #ifdef DOS_NT
1805 /* see comment in expand-file-name about drive specifiers */
1806 else if (IS_DRIVE (p[0]) && p[1] == ':'
1807 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1809 nm = p;
1810 substituted = 1;
1812 #endif /* DOS_NT */
1815 #ifdef VMS
1816 return build_string (nm);
1817 #else
1819 /* See if any variables are substituted into the string
1820 and find the total length of their values in `total' */
1822 for (p = nm; p != endp;)
1823 if (*p != '$')
1824 p++;
1825 else
1827 p++;
1828 if (p == endp)
1829 goto badsubst;
1830 else if (*p == '$')
1832 /* "$$" means a single "$" */
1833 p++;
1834 total -= 1;
1835 substituted = 1;
1836 continue;
1838 else if (*p == '{')
1840 o = ++p;
1841 while (p != endp && *p != '}') p++;
1842 if (*p != '}') goto missingclose;
1843 s = p;
1845 else
1847 o = p;
1848 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1849 s = p;
1852 /* Copy out the variable name */
1853 target = (unsigned char *) alloca (s - o + 1);
1854 strncpy (target, o, s - o);
1855 target[s - o] = 0;
1856 #ifdef DOS_NT
1857 strupr (target); /* $home == $HOME etc. */
1858 #endif /* DOS_NT */
1860 /* Get variable value */
1861 o = (unsigned char *) egetenv (target);
1862 if (!o) goto badvar;
1863 total += strlen (o);
1864 substituted = 1;
1867 if (!substituted)
1868 return filename;
1870 /* If substitution required, recopy the string and do it */
1871 /* Make space in stack frame for the new copy */
1872 xnm = (unsigned char *) alloca (XSTRING (filename)->size + total + 1);
1873 x = xnm;
1875 /* Copy the rest of the name through, replacing $ constructs with values */
1876 for (p = nm; *p;)
1877 if (*p != '$')
1878 *x++ = *p++;
1879 else
1881 p++;
1882 if (p == endp)
1883 goto badsubst;
1884 else if (*p == '$')
1886 *x++ = *p++;
1887 continue;
1889 else if (*p == '{')
1891 o = ++p;
1892 while (p != endp && *p != '}') p++;
1893 if (*p != '}') goto missingclose;
1894 s = p++;
1896 else
1898 o = p;
1899 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1900 s = p;
1903 /* Copy out the variable name */
1904 target = (unsigned char *) alloca (s - o + 1);
1905 strncpy (target, o, s - o);
1906 target[s - o] = 0;
1907 #ifdef DOS_NT
1908 strupr (target); /* $home == $HOME etc. */
1909 #endif /* DOS_NT */
1911 /* Get variable value */
1912 o = (unsigned char *) egetenv (target);
1913 if (!o)
1914 goto badvar;
1916 strcpy (x, o);
1917 x += strlen (o);
1920 *x = 0;
1922 /* If /~ or // appears, discard everything through first slash. */
1924 for (p = xnm; p != x; p++)
1925 if ((p[0] == '~'
1926 #if defined (APOLLO) || defined (WINDOWSNT)
1927 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1928 #else /* not (APOLLO || WINDOWSNT) */
1929 || IS_DIRECTORY_SEP (p[0])
1930 #endif /* not (APOLLO || WINDOWSNT) */
1932 && p != nm && IS_DIRECTORY_SEP (p[-1]))
1933 xnm = p;
1934 #ifdef DOS_NT
1935 else if (IS_DRIVE (p[0]) && p[1] == ':'
1936 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1937 xnm = p;
1938 #endif
1940 return make_string (xnm, x - xnm);
1942 badsubst:
1943 error ("Bad format environment-variable substitution");
1944 missingclose:
1945 error ("Missing \"}\" in environment-variable substitution");
1946 badvar:
1947 error ("Substituting nonexistent environment variable \"%s\"", target);
1949 /* NOTREACHED */
1950 #endif /* not VMS */
1953 /* A slightly faster and more convenient way to get
1954 (directory-file-name (expand-file-name FOO)). */
1956 Lisp_Object
1957 expand_and_dir_to_file (filename, defdir)
1958 Lisp_Object filename, defdir;
1960 register Lisp_Object absname;
1962 absname = Fexpand_file_name (filename, defdir);
1963 #ifdef VMS
1965 register int c = XSTRING (absname)->data[XSTRING (absname)->size - 1];
1966 if (c == ':' || c == ']' || c == '>')
1967 absname = Fdirectory_file_name (absname);
1969 #else
1970 /* Remove final slash, if any (unless this is the root dir).
1971 stat behaves differently depending! */
1972 if (XSTRING (absname)->size > 1
1973 && IS_DIRECTORY_SEP (XSTRING (absname)->data[XSTRING (absname)->size - 1])
1974 && !IS_DEVICE_SEP (XSTRING (absname)->data[XSTRING (absname)->size-2]))
1975 /* We cannot take shortcuts; they might be wrong for magic file names. */
1976 absname = Fdirectory_file_name (absname);
1977 #endif
1978 return absname;
1981 /* Signal an error if the file ABSNAME already exists.
1982 If INTERACTIVE is nonzero, ask the user whether to proceed,
1983 and bypass the error if the user says to go ahead.
1984 QUERYSTRING is a name for the action that is being considered
1985 to alter the file.
1986 *STATPTR is used to store the stat information if the file exists.
1987 If the file does not exist, STATPTR->st_mode is set to 0. */
1989 void
1990 barf_or_query_if_file_exists (absname, querystring, interactive, statptr)
1991 Lisp_Object absname;
1992 unsigned char *querystring;
1993 int interactive;
1994 struct stat *statptr;
1996 register Lisp_Object tem;
1997 struct stat statbuf;
1998 struct gcpro gcpro1;
2000 /* stat is a good way to tell whether the file exists,
2001 regardless of what access permissions it has. */
2002 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
2004 if (! interactive)
2005 Fsignal (Qfile_already_exists,
2006 Fcons (build_string ("File already exists"),
2007 Fcons (absname, Qnil)));
2008 GCPRO1 (absname);
2009 tem = do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
2010 XSTRING (absname)->data, querystring));
2011 UNGCPRO;
2012 if (NILP (tem))
2013 Fsignal (Qfile_already_exists,
2014 Fcons (build_string ("File already exists"),
2015 Fcons (absname, Qnil)));
2016 if (statptr)
2017 *statptr = statbuf;
2019 else
2021 if (statptr)
2022 statptr->st_mode = 0;
2024 return;
2027 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2028 "fCopy file: \nFCopy %s to file: \np\nP",
2029 "Copy FILE to NEWNAME. Both args must be strings.\n\
2030 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2031 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2032 A number as third arg means request confirmation if NEWNAME already exists.\n\
2033 This is what happens in interactive use with M-x.\n\
2034 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2035 last-modified time as the old one. (This works on only some systems.)\n\
2036 A prefix arg makes KEEP-TIME non-nil.")
2037 (file, newname, ok_if_already_exists, keep_date)
2038 Lisp_Object file, newname, ok_if_already_exists, keep_date;
2040 int ifd, ofd, n;
2041 char buf[16 * 1024];
2042 struct stat st, out_st;
2043 Lisp_Object handler;
2044 struct gcpro gcpro1, gcpro2;
2045 int count = specpdl_ptr - specpdl;
2046 int input_file_statable_p;
2048 GCPRO2 (file, newname);
2049 CHECK_STRING (file, 0);
2050 CHECK_STRING (newname, 1);
2051 file = Fexpand_file_name (file, Qnil);
2052 newname = Fexpand_file_name (newname, Qnil);
2054 /* If the input file name has special constructs in it,
2055 call the corresponding file handler. */
2056 handler = Ffind_file_name_handler (file, Qcopy_file);
2057 /* Likewise for output file name. */
2058 if (NILP (handler))
2059 handler = Ffind_file_name_handler (newname, Qcopy_file);
2060 if (!NILP (handler))
2061 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2062 ok_if_already_exists, keep_date));
2064 if (NILP (ok_if_already_exists)
2065 || INTEGERP (ok_if_already_exists))
2066 barf_or_query_if_file_exists (newname, "copy to it",
2067 INTEGERP (ok_if_already_exists), &out_st);
2068 else if (stat (XSTRING (newname)->data, &out_st) < 0)
2069 out_st.st_mode = 0;
2071 ifd = open (XSTRING (file)->data, O_RDONLY);
2072 if (ifd < 0)
2073 report_file_error ("Opening input file", Fcons (file, Qnil));
2075 record_unwind_protect (close_file_unwind, make_number (ifd));
2077 /* We can only copy regular files and symbolic links. Other files are not
2078 copyable by us. */
2079 input_file_statable_p = (fstat (ifd, &st) >= 0);
2081 #if !defined (MSDOS) || __DJGPP__ > 1
2082 if (out_st.st_mode != 0
2083 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2085 errno = 0;
2086 report_file_error ("Input and output files are the same",
2087 Fcons (file, Fcons (newname, Qnil)));
2089 #endif
2091 #if defined (S_ISREG) && defined (S_ISLNK)
2092 if (input_file_statable_p)
2094 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2096 #if defined (EISDIR)
2097 /* Get a better looking error message. */
2098 errno = EISDIR;
2099 #endif /* EISDIR */
2100 report_file_error ("Non-regular file", Fcons (file, Qnil));
2103 #endif /* S_ISREG && S_ISLNK */
2105 #ifdef VMS
2106 /* Create the copy file with the same record format as the input file */
2107 ofd = sys_creat (XSTRING (newname)->data, 0666, ifd);
2108 #else
2109 #ifdef MSDOS
2110 /* System's default file type was set to binary by _fmode in emacs.c. */
2111 ofd = creat (XSTRING (newname)->data, S_IREAD | S_IWRITE);
2112 #else /* not MSDOS */
2113 ofd = creat (XSTRING (newname)->data, 0666);
2114 #endif /* not MSDOS */
2115 #endif /* VMS */
2116 if (ofd < 0)
2117 report_file_error ("Opening output file", Fcons (newname, Qnil));
2119 record_unwind_protect (close_file_unwind, make_number (ofd));
2121 immediate_quit = 1;
2122 QUIT;
2123 while ((n = read (ifd, buf, sizeof buf)) > 0)
2124 if (write (ofd, buf, n) != n)
2125 report_file_error ("I/O error", Fcons (newname, Qnil));
2126 immediate_quit = 0;
2128 /* Closing the output clobbers the file times on some systems. */
2129 if (close (ofd) < 0)
2130 report_file_error ("I/O error", Fcons (newname, Qnil));
2132 if (input_file_statable_p)
2134 if (!NILP (keep_date))
2136 EMACS_TIME atime, mtime;
2137 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2138 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2139 if (set_file_times (XSTRING (newname)->data, atime, mtime))
2140 report_file_error ("I/O error", Fcons (newname, Qnil));
2142 #ifndef MSDOS
2143 chmod (XSTRING (newname)->data, st.st_mode & 07777);
2144 #else /* MSDOS */
2145 #if defined (__DJGPP__) && __DJGPP__ > 1
2146 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2147 and if it can't, it tells so. Otherwise, under MSDOS we usually
2148 get only the READ bit, which will make the copied file read-only,
2149 so it's better not to chmod at all. */
2150 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2151 chmod (XSTRING (newname)->data, st.st_mode & 07777);
2152 #endif /* DJGPP version 2 or newer */
2153 #endif /* MSDOS */
2156 close (ifd);
2158 /* Discard the unwind protects. */
2159 specpdl_ptr = specpdl + count;
2161 UNGCPRO;
2162 return Qnil;
2165 DEFUN ("make-directory-internal", Fmake_directory_internal,
2166 Smake_directory_internal, 1, 1, 0,
2167 "Create a new directory named DIRECTORY.")
2168 (directory)
2169 Lisp_Object directory;
2171 unsigned char *dir;
2172 Lisp_Object handler;
2174 CHECK_STRING (directory, 0);
2175 directory = Fexpand_file_name (directory, Qnil);
2177 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2178 if (!NILP (handler))
2179 return call2 (handler, Qmake_directory_internal, directory);
2181 dir = XSTRING (directory)->data;
2183 #ifdef WINDOWSNT
2184 if (mkdir (dir) != 0)
2185 #else
2186 if (mkdir (dir, 0777) != 0)
2187 #endif
2188 report_file_error ("Creating directory", Flist (1, &directory));
2190 return Qnil;
2193 DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2194 "Delete the directory named DIRECTORY.")
2195 (directory)
2196 Lisp_Object directory;
2198 unsigned char *dir;
2199 Lisp_Object handler;
2201 CHECK_STRING (directory, 0);
2202 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2203 dir = XSTRING (directory)->data;
2205 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2206 if (!NILP (handler))
2207 return call2 (handler, Qdelete_directory, directory);
2209 if (rmdir (dir) != 0)
2210 report_file_error ("Removing directory", Flist (1, &directory));
2212 return Qnil;
2215 DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2216 "Delete file named FILENAME.\n\
2217 If file has multiple names, it continues to exist with the other names.")
2218 (filename)
2219 Lisp_Object filename;
2221 Lisp_Object handler;
2222 CHECK_STRING (filename, 0);
2223 filename = Fexpand_file_name (filename, Qnil);
2225 handler = Ffind_file_name_handler (filename, Qdelete_file);
2226 if (!NILP (handler))
2227 return call2 (handler, Qdelete_file, filename);
2229 if (0 > unlink (XSTRING (filename)->data))
2230 report_file_error ("Removing old name", Flist (1, &filename));
2231 return Qnil;
2234 static Lisp_Object
2235 internal_delete_file_1 (ignore)
2236 Lisp_Object ignore;
2238 return Qt;
2241 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2244 internal_delete_file (filename)
2245 Lisp_Object filename;
2247 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2248 Qt, internal_delete_file_1));
2251 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2252 "fRename file: \nFRename %s to file: \np",
2253 "Rename FILE as NEWNAME. Both args strings.\n\
2254 If file has names other than FILE, it continues to have those names.\n\
2255 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2256 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2257 A number as third arg means request confirmation if NEWNAME already exists.\n\
2258 This is what happens in interactive use with M-x.")
2259 (file, newname, ok_if_already_exists)
2260 Lisp_Object file, newname, ok_if_already_exists;
2262 #ifdef NO_ARG_ARRAY
2263 Lisp_Object args[2];
2264 #endif
2265 Lisp_Object handler;
2266 struct gcpro gcpro1, gcpro2;
2268 GCPRO2 (file, newname);
2269 CHECK_STRING (file, 0);
2270 CHECK_STRING (newname, 1);
2271 file = Fexpand_file_name (file, Qnil);
2272 newname = Fexpand_file_name (newname, Qnil);
2274 /* If the file name has special constructs in it,
2275 call the corresponding file handler. */
2276 handler = Ffind_file_name_handler (file, Qrename_file);
2277 if (NILP (handler))
2278 handler = Ffind_file_name_handler (newname, Qrename_file);
2279 if (!NILP (handler))
2280 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2281 file, newname, ok_if_already_exists));
2283 if (NILP (ok_if_already_exists)
2284 || INTEGERP (ok_if_already_exists))
2285 barf_or_query_if_file_exists (newname, "rename to it",
2286 INTEGERP (ok_if_already_exists), 0);
2287 #ifndef BSD4_1
2288 if (0 > rename (XSTRING (file)->data, XSTRING (newname)->data))
2289 #else
2290 if (0 > link (XSTRING (file)->data, XSTRING (newname)->data)
2291 || 0 > unlink (XSTRING (file)->data))
2292 #endif
2294 if (errno == EXDEV)
2296 Fcopy_file (file, newname,
2297 /* We have already prompted if it was an integer,
2298 so don't have copy-file prompt again. */
2299 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2300 Fdelete_file (file);
2302 else
2303 #ifdef NO_ARG_ARRAY
2305 args[0] = file;
2306 args[1] = newname;
2307 report_file_error ("Renaming", Flist (2, args));
2309 #else
2310 report_file_error ("Renaming", Flist (2, &file));
2311 #endif
2313 UNGCPRO;
2314 return Qnil;
2317 DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2318 "fAdd name to file: \nFName to add to %s: \np",
2319 "Give FILE additional name NEWNAME. Both args strings.\n\
2320 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2321 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2322 A number as third arg means request confirmation if NEWNAME already exists.\n\
2323 This is what happens in interactive use with M-x.")
2324 (file, newname, ok_if_already_exists)
2325 Lisp_Object file, newname, ok_if_already_exists;
2327 #ifdef NO_ARG_ARRAY
2328 Lisp_Object args[2];
2329 #endif
2330 Lisp_Object handler;
2331 struct gcpro gcpro1, gcpro2;
2333 GCPRO2 (file, newname);
2334 CHECK_STRING (file, 0);
2335 CHECK_STRING (newname, 1);
2336 file = Fexpand_file_name (file, Qnil);
2337 newname = Fexpand_file_name (newname, Qnil);
2339 /* If the file name has special constructs in it,
2340 call the corresponding file handler. */
2341 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2342 if (!NILP (handler))
2343 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2344 newname, ok_if_already_exists));
2346 /* If the new name has special constructs in it,
2347 call the corresponding file handler. */
2348 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2349 if (!NILP (handler))
2350 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2351 newname, ok_if_already_exists));
2353 if (NILP (ok_if_already_exists)
2354 || INTEGERP (ok_if_already_exists))
2355 barf_or_query_if_file_exists (newname, "make it a new name",
2356 INTEGERP (ok_if_already_exists), 0);
2357 #ifdef WINDOWSNT
2358 /* Windows does not support this operation. */
2359 report_file_error ("Adding new name", Flist (2, &file));
2360 #else /* not WINDOWSNT */
2362 unlink (XSTRING (newname)->data);
2363 if (0 > link (XSTRING (file)->data, XSTRING (newname)->data))
2365 #ifdef NO_ARG_ARRAY
2366 args[0] = file;
2367 args[1] = newname;
2368 report_file_error ("Adding new name", Flist (2, args));
2369 #else
2370 report_file_error ("Adding new name", Flist (2, &file));
2371 #endif
2373 #endif /* not WINDOWSNT */
2375 UNGCPRO;
2376 return Qnil;
2379 #ifdef S_IFLNK
2380 DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2381 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2382 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2383 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2384 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2385 A number as third arg means request confirmation if LINKNAME already exists.\n\
2386 This happens for interactive use with M-x.")
2387 (filename, linkname, ok_if_already_exists)
2388 Lisp_Object filename, linkname, ok_if_already_exists;
2390 #ifdef NO_ARG_ARRAY
2391 Lisp_Object args[2];
2392 #endif
2393 Lisp_Object handler;
2394 struct gcpro gcpro1, gcpro2;
2396 GCPRO2 (filename, linkname);
2397 CHECK_STRING (filename, 0);
2398 CHECK_STRING (linkname, 1);
2399 /* If the link target has a ~, we must expand it to get
2400 a truly valid file name. Otherwise, do not expand;
2401 we want to permit links to relative file names. */
2402 if (XSTRING (filename)->data[0] == '~')
2403 filename = Fexpand_file_name (filename, Qnil);
2404 linkname = Fexpand_file_name (linkname, Qnil);
2406 /* If the file name has special constructs in it,
2407 call the corresponding file handler. */
2408 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2409 if (!NILP (handler))
2410 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2411 linkname, ok_if_already_exists));
2413 /* If the new link name has special constructs in it,
2414 call the corresponding file handler. */
2415 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2416 if (!NILP (handler))
2417 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2418 linkname, ok_if_already_exists));
2420 if (NILP (ok_if_already_exists)
2421 || INTEGERP (ok_if_already_exists))
2422 barf_or_query_if_file_exists (linkname, "make it a link",
2423 INTEGERP (ok_if_already_exists), 0);
2424 if (0 > symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
2426 /* If we didn't complain already, silently delete existing file. */
2427 if (errno == EEXIST)
2429 unlink (XSTRING (linkname)->data);
2430 if (0 <= symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
2432 UNGCPRO;
2433 return Qnil;
2437 #ifdef NO_ARG_ARRAY
2438 args[0] = filename;
2439 args[1] = linkname;
2440 report_file_error ("Making symbolic link", Flist (2, args));
2441 #else
2442 report_file_error ("Making symbolic link", Flist (2, &filename));
2443 #endif
2445 UNGCPRO;
2446 return Qnil;
2448 #endif /* S_IFLNK */
2450 #ifdef VMS
2452 DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2453 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2454 "Define the job-wide logical name NAME to have the value STRING.\n\
2455 If STRING is nil or a null string, the logical name NAME is deleted.")
2456 (name, string)
2457 Lisp_Object name;
2458 Lisp_Object string;
2460 CHECK_STRING (name, 0);
2461 if (NILP (string))
2462 delete_logical_name (XSTRING (name)->data);
2463 else
2465 CHECK_STRING (string, 1);
2467 if (XSTRING (string)->size == 0)
2468 delete_logical_name (XSTRING (name)->data);
2469 else
2470 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2473 return string;
2475 #endif /* VMS */
2477 #ifdef HPUX_NET
2479 DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2480 "Open a network connection to PATH using LOGIN as the login string.")
2481 (path, login)
2482 Lisp_Object path, login;
2484 int netresult;
2486 CHECK_STRING (path, 0);
2487 CHECK_STRING (login, 0);
2489 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2491 if (netresult == -1)
2492 return Qnil;
2493 else
2494 return Qt;
2496 #endif /* HPUX_NET */
2498 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2499 1, 1, 0,
2500 "Return t if file FILENAME specifies an absolute file name.\n\
2501 On Unix, this is a name starting with a `/' or a `~'.")
2502 (filename)
2503 Lisp_Object filename;
2505 unsigned char *ptr;
2507 CHECK_STRING (filename, 0);
2508 ptr = XSTRING (filename)->data;
2509 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2510 #ifdef VMS
2511 /* ??? This criterion is probably wrong for '<'. */
2512 || index (ptr, ':') || index (ptr, '<')
2513 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2514 && ptr[1] != '.')
2515 #endif /* VMS */
2516 #ifdef DOS_NT
2517 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2518 #endif
2520 return Qt;
2521 else
2522 return Qnil;
2525 /* Return nonzero if file FILENAME exists and can be executed. */
2527 static int
2528 check_executable (filename)
2529 char *filename;
2531 #ifdef DOS_NT
2532 int len = strlen (filename);
2533 char *suffix;
2534 struct stat st;
2535 if (stat (filename, &st) < 0)
2536 return 0;
2537 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2538 return ((st.st_mode & S_IEXEC) != 0);
2539 #else
2540 return (S_ISREG (st.st_mode)
2541 && len >= 5
2542 && (stricmp ((suffix = filename + len-4), ".com") == 0
2543 || stricmp (suffix, ".exe") == 0
2544 || stricmp (suffix, ".bat") == 0)
2545 || (st.st_mode & S_IFMT) == S_IFDIR);
2546 #endif /* not WINDOWSNT */
2547 #else /* not DOS_NT */
2548 #ifdef HAVE_EUIDACCESS
2549 return (euidaccess (filename, 1) >= 0);
2550 #else
2551 /* Access isn't quite right because it uses the real uid
2552 and we really want to test with the effective uid.
2553 But Unix doesn't give us a right way to do it. */
2554 return (access (filename, 1) >= 0);
2555 #endif
2556 #endif /* not DOS_NT */
2559 /* Return nonzero if file FILENAME exists and can be written. */
2561 static int
2562 check_writable (filename)
2563 char *filename;
2565 #ifdef MSDOS
2566 struct stat st;
2567 if (stat (filename, &st) < 0)
2568 return 0;
2569 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2570 #else /* not MSDOS */
2571 #ifdef HAVE_EUIDACCESS
2572 return (euidaccess (filename, 2) >= 0);
2573 #else
2574 /* Access isn't quite right because it uses the real uid
2575 and we really want to test with the effective uid.
2576 But Unix doesn't give us a right way to do it.
2577 Opening with O_WRONLY could work for an ordinary file,
2578 but would lose for directories. */
2579 return (access (filename, 2) >= 0);
2580 #endif
2581 #endif /* not MSDOS */
2584 DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2585 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2586 See also `file-readable-p' and `file-attributes'.")
2587 (filename)
2588 Lisp_Object filename;
2590 Lisp_Object absname;
2591 Lisp_Object handler;
2592 struct stat statbuf;
2594 CHECK_STRING (filename, 0);
2595 absname = Fexpand_file_name (filename, Qnil);
2597 /* If the file name has special constructs in it,
2598 call the corresponding file handler. */
2599 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2600 if (!NILP (handler))
2601 return call2 (handler, Qfile_exists_p, absname);
2603 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2606 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2607 "Return t if FILENAME can be executed by you.\n\
2608 For a directory, this means you can access files in that directory.")
2609 (filename)
2610 Lisp_Object filename;
2613 Lisp_Object absname;
2614 Lisp_Object handler;
2616 CHECK_STRING (filename, 0);
2617 absname = Fexpand_file_name (filename, Qnil);
2619 /* If the file name has special constructs in it,
2620 call the corresponding file handler. */
2621 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
2622 if (!NILP (handler))
2623 return call2 (handler, Qfile_executable_p, absname);
2625 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
2628 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
2629 "Return t if file FILENAME exists and you can read it.\n\
2630 See also `file-exists-p' and `file-attributes'.")
2631 (filename)
2632 Lisp_Object filename;
2634 Lisp_Object absname;
2635 Lisp_Object handler;
2636 int desc;
2638 CHECK_STRING (filename, 0);
2639 absname = Fexpand_file_name (filename, Qnil);
2641 /* If the file name has special constructs in it,
2642 call the corresponding file handler. */
2643 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
2644 if (!NILP (handler))
2645 return call2 (handler, Qfile_readable_p, absname);
2647 #ifdef DOS_NT
2648 /* Under MS-DOS and Windows, open does not work for directories. */
2649 if (access (XSTRING (absname)->data, 0) == 0)
2650 return Qt;
2651 return Qnil;
2652 #else /* not DOS_NT */
2653 desc = open (XSTRING (absname)->data, O_RDONLY);
2654 if (desc < 0)
2655 return Qnil;
2656 close (desc);
2657 return Qt;
2658 #endif /* not DOS_NT */
2661 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2662 on the RT/PC. */
2663 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2664 "Return t if file FILENAME can be written or created by you.")
2665 (filename)
2666 Lisp_Object filename;
2668 Lisp_Object absname, dir;
2669 Lisp_Object handler;
2670 struct stat statbuf;
2672 CHECK_STRING (filename, 0);
2673 absname = Fexpand_file_name (filename, Qnil);
2675 /* If the file name has special constructs in it,
2676 call the corresponding file handler. */
2677 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
2678 if (!NILP (handler))
2679 return call2 (handler, Qfile_writable_p, absname);
2681 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
2682 return (check_writable (XSTRING (absname)->data)
2683 ? Qt : Qnil);
2684 dir = Ffile_name_directory (absname);
2685 #ifdef VMS
2686 if (!NILP (dir))
2687 dir = Fdirectory_file_name (dir);
2688 #endif /* VMS */
2689 #ifdef MSDOS
2690 if (!NILP (dir))
2691 dir = Fdirectory_file_name (dir);
2692 #endif /* MSDOS */
2693 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
2694 ? Qt : Qnil);
2697 DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2698 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2699 The value is the name of the file to which it is linked.\n\
2700 Otherwise returns nil.")
2701 (filename)
2702 Lisp_Object filename;
2704 #ifdef S_IFLNK
2705 char *buf;
2706 int bufsize;
2707 int valsize;
2708 Lisp_Object val;
2709 Lisp_Object handler;
2711 CHECK_STRING (filename, 0);
2712 filename = Fexpand_file_name (filename, Qnil);
2714 /* If the file name has special constructs in it,
2715 call the corresponding file handler. */
2716 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2717 if (!NILP (handler))
2718 return call2 (handler, Qfile_symlink_p, filename);
2720 bufsize = 100;
2721 while (1)
2723 buf = (char *) xmalloc (bufsize);
2724 bzero (buf, bufsize);
2725 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
2726 if (valsize < bufsize) break;
2727 /* Buffer was not long enough */
2728 xfree (buf);
2729 bufsize *= 2;
2731 if (valsize == -1)
2733 xfree (buf);
2734 return Qnil;
2736 val = make_string (buf, valsize);
2737 xfree (buf);
2738 return val;
2739 #else /* not S_IFLNK */
2740 return Qnil;
2741 #endif /* not S_IFLNK */
2744 DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
2745 "Return t if file FILENAME is the name of a directory as a file.\n\
2746 A directory name spec may be given instead; then the value is t\n\
2747 if the directory so specified exists and really is a directory.")
2748 (filename)
2749 Lisp_Object filename;
2751 register Lisp_Object absname;
2752 struct stat st;
2753 Lisp_Object handler;
2755 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2757 /* If the file name has special constructs in it,
2758 call the corresponding file handler. */
2759 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
2760 if (!NILP (handler))
2761 return call2 (handler, Qfile_directory_p, absname);
2763 if (stat (XSTRING (absname)->data, &st) < 0)
2764 return Qnil;
2765 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2768 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
2769 "Return t if file FILENAME is the name of a directory as a file,\n\
2770 and files in that directory can be opened by you. In order to use a\n\
2771 directory as a buffer's current directory, this predicate must return true.\n\
2772 A directory name spec may be given instead; then the value is t\n\
2773 if the directory so specified exists and really is a readable and\n\
2774 searchable directory.")
2775 (filename)
2776 Lisp_Object filename;
2778 Lisp_Object handler;
2779 int tem;
2780 struct gcpro gcpro1;
2782 /* If the file name has special constructs in it,
2783 call the corresponding file handler. */
2784 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2785 if (!NILP (handler))
2786 return call2 (handler, Qfile_accessible_directory_p, filename);
2788 /* It's an unlikely combination, but yes we really do need to gcpro:
2789 Suppose that file-accessible-directory-p has no handler, but
2790 file-directory-p does have a handler; this handler causes a GC which
2791 relocates the string in `filename'; and finally file-directory-p
2792 returns non-nil. Then we would end up passing a garbaged string
2793 to file-executable-p. */
2794 GCPRO1 (filename);
2795 tem = (NILP (Ffile_directory_p (filename))
2796 || NILP (Ffile_executable_p (filename)));
2797 UNGCPRO;
2798 return tem ? Qnil : Qt;
2801 DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
2802 "Return t if file FILENAME is the name of a regular file.\n\
2803 This is the sort of file that holds an ordinary stream of data bytes.")
2804 (filename)
2805 Lisp_Object filename;
2807 register Lisp_Object absname;
2808 struct stat st;
2809 Lisp_Object handler;
2811 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2813 /* If the file name has special constructs in it,
2814 call the corresponding file handler. */
2815 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
2816 if (!NILP (handler))
2817 return call2 (handler, Qfile_regular_p, absname);
2819 if (stat (XSTRING (absname)->data, &st) < 0)
2820 return Qnil;
2821 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2824 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
2825 "Return mode bits of file named FILENAME, as an integer.")
2826 (filename)
2827 Lisp_Object filename;
2829 Lisp_Object absname;
2830 struct stat st;
2831 Lisp_Object handler;
2833 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2835 /* If the file name has special constructs in it,
2836 call the corresponding file handler. */
2837 handler = Ffind_file_name_handler (absname, Qfile_modes);
2838 if (!NILP (handler))
2839 return call2 (handler, Qfile_modes, absname);
2841 if (stat (XSTRING (absname)->data, &st) < 0)
2842 return Qnil;
2843 #if defined (MSDOS) && __DJGPP__ < 2
2844 if (check_executable (XSTRING (absname)->data))
2845 st.st_mode |= S_IEXEC;
2846 #endif /* MSDOS && __DJGPP__ < 2 */
2848 return make_number (st.st_mode & 07777);
2851 DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
2852 "Set mode bits of file named FILENAME to MODE (an integer).\n\
2853 Only the 12 low bits of MODE are used.")
2854 (filename, mode)
2855 Lisp_Object filename, mode;
2857 Lisp_Object absname;
2858 Lisp_Object handler;
2860 absname = Fexpand_file_name (filename, current_buffer->directory);
2861 CHECK_NUMBER (mode, 1);
2863 /* If the file name has special constructs in it,
2864 call the corresponding file handler. */
2865 handler = Ffind_file_name_handler (absname, Qset_file_modes);
2866 if (!NILP (handler))
2867 return call3 (handler, Qset_file_modes, absname, mode);
2869 if (chmod (XSTRING (absname)->data, XINT (mode)) < 0)
2870 report_file_error ("Doing chmod", Fcons (absname, Qnil));
2872 return Qnil;
2875 DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
2876 "Set the file permission bits for newly created files.\n\
2877 The argument MODE should be an integer; only the low 9 bits are used.\n\
2878 This setting is inherited by subprocesses.")
2879 (mode)
2880 Lisp_Object mode;
2882 CHECK_NUMBER (mode, 0);
2884 umask ((~ XINT (mode)) & 0777);
2886 return Qnil;
2889 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
2890 "Return the default file protection for created files.\n\
2891 The value is an integer.")
2894 int realmask;
2895 Lisp_Object value;
2897 realmask = umask (0);
2898 umask (realmask);
2900 XSETINT (value, (~ realmask) & 0777);
2901 return value;
2904 #ifdef unix
2906 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
2907 "Tell Unix to finish all pending disk updates.")
2910 sync ();
2911 return Qnil;
2914 #endif /* unix */
2916 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
2917 "Return t if file FILE1 is newer than file FILE2.\n\
2918 If FILE1 does not exist, the answer is nil;\n\
2919 otherwise, if FILE2 does not exist, the answer is t.")
2920 (file1, file2)
2921 Lisp_Object file1, file2;
2923 Lisp_Object absname1, absname2;
2924 struct stat st;
2925 int mtime1;
2926 Lisp_Object handler;
2927 struct gcpro gcpro1, gcpro2;
2929 CHECK_STRING (file1, 0);
2930 CHECK_STRING (file2, 0);
2932 absname1 = Qnil;
2933 GCPRO2 (absname1, file2);
2934 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
2935 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
2936 UNGCPRO;
2938 /* If the file name has special constructs in it,
2939 call the corresponding file handler. */
2940 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
2941 if (NILP (handler))
2942 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
2943 if (!NILP (handler))
2944 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
2946 if (stat (XSTRING (absname1)->data, &st) < 0)
2947 return Qnil;
2949 mtime1 = st.st_mtime;
2951 if (stat (XSTRING (absname2)->data, &st) < 0)
2952 return Qt;
2954 return (mtime1 > st.st_mtime) ? Qt : Qnil;
2957 #ifdef DOS_NT
2958 Lisp_Object Qfind_buffer_file_type;
2959 #endif /* DOS_NT */
2961 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
2962 1, 5, 0,
2963 "Insert contents of file FILENAME after point.\n\
2964 Returns list of absolute file name and length of data inserted.\n\
2965 If second argument VISIT is non-nil, the buffer's visited filename\n\
2966 and last save file modtime are set, and it is marked unmodified.\n\
2967 If visiting and the file does not exist, visiting is completed\n\
2968 before the error is signaled.\n\n\
2969 The optional third and fourth arguments BEG and END\n\
2970 specify what portion of the file to insert.\n\
2971 If VISIT is non-nil, BEG and END must be nil.\n\
2972 If optional fifth argument REPLACE is non-nil,\n\
2973 it means replace the current buffer contents (in the accessible portion)\n\
2974 with the file contents. This is better than simply deleting and inserting\n\
2975 the whole thing because (1) it preserves some marker positions\n\
2976 and (2) it puts less data in the undo list.")
2977 (filename, visit, beg, end, replace)
2978 Lisp_Object filename, visit, beg, end, replace;
2980 struct stat st;
2981 register int fd;
2982 register int inserted = 0;
2983 register int how_much;
2984 int count = specpdl_ptr - specpdl;
2985 struct gcpro gcpro1, gcpro2, gcpro3;
2986 Lisp_Object handler, val, insval;
2987 Lisp_Object p;
2988 int total;
2989 int not_regular = 0;
2991 if (current_buffer->base_buffer && ! NILP (visit))
2992 error ("Cannot do file visiting in an indirect buffer");
2994 if (!NILP (current_buffer->read_only))
2995 Fbarf_if_buffer_read_only ();
2997 val = Qnil;
2998 p = Qnil;
3000 GCPRO3 (filename, val, p);
3002 CHECK_STRING (filename, 0);
3003 filename = Fexpand_file_name (filename, Qnil);
3005 /* If the file name has special constructs in it,
3006 call the corresponding file handler. */
3007 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3008 if (!NILP (handler))
3010 val = call6 (handler, Qinsert_file_contents, filename,
3011 visit, beg, end, replace);
3012 goto handled;
3015 fd = -1;
3017 #ifndef APOLLO
3018 if (stat (XSTRING (filename)->data, &st) < 0)
3019 #else
3020 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0
3021 || fstat (fd, &st) < 0)
3022 #endif /* not APOLLO */
3024 if (fd >= 0) close (fd);
3025 badopen:
3026 if (NILP (visit))
3027 report_file_error ("Opening input file", Fcons (filename, Qnil));
3028 st.st_mtime = -1;
3029 how_much = 0;
3030 goto notfound;
3033 #ifdef S_IFREG
3034 /* This code will need to be changed in order to work on named
3035 pipes, and it's probably just not worth it. So we should at
3036 least signal an error. */
3037 if (!S_ISREG (st.st_mode))
3039 if (NILP (visit))
3040 Fsignal (Qfile_error,
3041 Fcons (build_string ("not a regular file"),
3042 Fcons (filename, Qnil)));
3044 not_regular = 1;
3045 goto notfound;
3047 #endif
3049 if (fd < 0)
3050 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0)
3051 goto badopen;
3053 /* Replacement should preserve point as it preserves markers. */
3054 if (!NILP (replace))
3055 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3057 record_unwind_protect (close_file_unwind, make_number (fd));
3059 /* Supposedly happens on VMS. */
3060 if (st.st_size < 0)
3061 error ("File size is negative");
3063 if (!NILP (beg) || !NILP (end))
3064 if (!NILP (visit))
3065 error ("Attempt to visit less than an entire file");
3067 if (!NILP (beg))
3068 CHECK_NUMBER (beg, 0);
3069 else
3070 XSETFASTINT (beg, 0);
3072 if (!NILP (end))
3073 CHECK_NUMBER (end, 0);
3074 else
3076 XSETINT (end, st.st_size);
3077 if (XINT (end) != st.st_size)
3078 error ("maximum buffer size exceeded");
3081 /* If requested, replace the accessible part of the buffer
3082 with the file contents. Avoid replacing text at the
3083 beginning or end of the buffer that matches the file contents;
3084 that preserves markers pointing to the unchanged parts. */
3085 #ifdef DOS_NT
3086 /* On MSDOS, replace mode doesn't really work, except for binary files,
3087 and it's not worth supporting just for them. */
3088 if (!NILP (replace))
3090 replace = Qnil;
3091 XSETFASTINT (beg, 0);
3092 XSETFASTINT (end, st.st_size);
3093 del_range_1 (BEGV, ZV, 0);
3095 #else /* not DOS_NT */
3096 if (!NILP (replace))
3098 unsigned char buffer[1 << 14];
3099 int same_at_start = BEGV;
3100 int same_at_end = ZV;
3101 int overlap;
3103 immediate_quit = 1;
3104 QUIT;
3105 /* Count how many chars at the start of the file
3106 match the text at the beginning of the buffer. */
3107 while (1)
3109 int nread, bufpos;
3111 nread = read (fd, buffer, sizeof buffer);
3112 if (nread < 0)
3113 error ("IO error reading %s: %s",
3114 XSTRING (filename)->data, strerror (errno));
3115 else if (nread == 0)
3116 break;
3117 bufpos = 0;
3118 while (bufpos < nread && same_at_start < ZV
3119 && FETCH_CHAR (same_at_start) == buffer[bufpos])
3120 same_at_start++, bufpos++;
3121 /* If we found a discrepancy, stop the scan.
3122 Otherwise loop around and scan the next bufferful. */
3123 if (bufpos != nread)
3124 break;
3126 immediate_quit = 0;
3127 /* If the file matches the buffer completely,
3128 there's no need to replace anything. */
3129 if (same_at_start - BEGV == st.st_size)
3131 close (fd);
3132 specpdl_ptr--;
3133 /* Truncate the buffer to the size of the file. */
3134 del_range_1 (same_at_start, same_at_end, 0);
3135 goto handled;
3137 immediate_quit = 1;
3138 QUIT;
3139 /* Count how many chars at the end of the file
3140 match the text at the end of the buffer. */
3141 while (1)
3143 int total_read, nread, bufpos, curpos, trial;
3145 /* At what file position are we now scanning? */
3146 curpos = st.st_size - (ZV - same_at_end);
3147 /* If the entire file matches the buffer tail, stop the scan. */
3148 if (curpos == 0)
3149 break;
3150 /* How much can we scan in the next step? */
3151 trial = min (curpos, sizeof buffer);
3152 if (lseek (fd, curpos - trial, 0) < 0)
3153 report_file_error ("Setting file position",
3154 Fcons (filename, Qnil));
3156 total_read = 0;
3157 while (total_read < trial)
3159 nread = read (fd, buffer + total_read, trial - total_read);
3160 if (nread <= 0)
3161 error ("IO error reading %s: %s",
3162 XSTRING (filename)->data, strerror (errno));
3163 total_read += nread;
3165 /* Scan this bufferful from the end, comparing with
3166 the Emacs buffer. */
3167 bufpos = total_read;
3168 /* Compare with same_at_start to avoid counting some buffer text
3169 as matching both at the file's beginning and at the end. */
3170 while (bufpos > 0 && same_at_end > same_at_start
3171 && FETCH_CHAR (same_at_end - 1) == buffer[bufpos - 1])
3172 same_at_end--, bufpos--;
3173 /* If we found a discrepancy, stop the scan.
3174 Otherwise loop around and scan the preceding bufferful. */
3175 if (bufpos != 0)
3176 break;
3177 /* If display current starts at beginning of line,
3178 keep it that way. */
3179 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3180 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3182 immediate_quit = 0;
3184 /* Don't try to reuse the same piece of text twice. */
3185 overlap = same_at_start - BEGV - (same_at_end + st.st_size - ZV);
3186 if (overlap > 0)
3187 same_at_end += overlap;
3189 /* Arrange to read only the nonmatching middle part of the file. */
3190 XSETFASTINT (beg, same_at_start - BEGV);
3191 XSETFASTINT (end, st.st_size - (ZV - same_at_end));
3193 del_range_1 (same_at_start, same_at_end, 0);
3194 /* Insert from the file at the proper position. */
3195 SET_PT (same_at_start);
3197 #endif /* not DOS_NT */
3199 total = XINT (end) - XINT (beg);
3202 register Lisp_Object temp;
3204 /* Make sure point-max won't overflow after this insertion. */
3205 XSETINT (temp, total);
3206 if (total != XINT (temp))
3207 error ("maximum buffer size exceeded");
3210 if (NILP (visit) && total > 0)
3211 prepare_to_modify_buffer (point, point);
3213 move_gap (point);
3214 if (GAP_SIZE < total)
3215 make_gap (total - GAP_SIZE);
3217 if (XINT (beg) != 0 || !NILP (replace))
3219 if (lseek (fd, XINT (beg), 0) < 0)
3220 report_file_error ("Setting file position", Fcons (filename, Qnil));
3223 how_much = 0;
3224 while (inserted < total)
3226 /* try is reserved in some compilers (Microsoft C) */
3227 int trytry = min (total - inserted, 64 << 10);
3228 int this;
3230 /* Allow quitting out of the actual I/O. */
3231 immediate_quit = 1;
3232 QUIT;
3233 this = read (fd, &FETCH_CHAR (point + inserted - 1) + 1, trytry);
3234 immediate_quit = 0;
3236 if (this <= 0)
3238 how_much = this;
3239 break;
3242 GPT += this;
3243 GAP_SIZE -= this;
3244 ZV += this;
3245 Z += this;
3246 inserted += this;
3249 #ifdef DOS_NT
3250 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3251 /* Determine file type from name and remove LFs from CR-LFs if the file
3252 is deemed to be a text file. */
3254 current_buffer->buffer_file_type
3255 = call1 (Qfind_buffer_file_type, filename);
3256 if (NILP (current_buffer->buffer_file_type))
3258 int reduced_size
3259 = inserted - crlf_to_lf (inserted, &FETCH_CHAR (point - 1) + 1);
3260 ZV -= reduced_size;
3261 Z -= reduced_size;
3262 GPT -= reduced_size;
3263 GAP_SIZE += reduced_size;
3264 inserted -= reduced_size;
3267 #endif /* DOS_NT */
3269 if (inserted > 0)
3271 record_insert (point, inserted);
3273 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
3274 offset_intervals (current_buffer, point, inserted);
3275 MODIFF++;
3278 close (fd);
3280 /* Discard the unwind protect for closing the file. */
3281 specpdl_ptr--;
3283 if (how_much < 0)
3284 error ("IO error reading %s: %s",
3285 XSTRING (filename)->data, strerror (errno));
3287 notfound:
3288 handled:
3290 if (!NILP (visit))
3292 if (!EQ (current_buffer->undo_list, Qt))
3293 current_buffer->undo_list = Qnil;
3294 #ifdef APOLLO
3295 stat (XSTRING (filename)->data, &st);
3296 #endif
3298 if (NILP (handler))
3300 current_buffer->modtime = st.st_mtime;
3301 current_buffer->filename = filename;
3304 SAVE_MODIFF = MODIFF;
3305 current_buffer->auto_save_modified = MODIFF;
3306 XSETFASTINT (current_buffer->save_length, Z - BEG);
3307 #ifdef CLASH_DETECTION
3308 if (NILP (handler))
3310 if (!NILP (current_buffer->file_truename))
3311 unlock_file (current_buffer->file_truename);
3312 unlock_file (filename);
3314 #endif /* CLASH_DETECTION */
3315 if (not_regular)
3316 Fsignal (Qfile_error,
3317 Fcons (build_string ("not a regular file"),
3318 Fcons (filename, Qnil)));
3320 /* If visiting nonexistent file, return nil. */
3321 if (current_buffer->modtime == -1)
3322 report_file_error ("Opening input file", Fcons (filename, Qnil));
3325 /* Decode file format */
3326 if (inserted > 0)
3328 insval = call3 (Qformat_decode,
3329 Qnil, make_number (inserted), visit);
3330 CHECK_NUMBER (insval, 0);
3331 inserted = XFASTINT (insval);
3334 if (inserted > 0 && NILP (visit) && total > 0)
3335 signal_after_change (point, 0, inserted);
3337 if (inserted > 0)
3339 p = Vafter_insert_file_functions;
3340 while (!NILP (p))
3342 insval = call1 (Fcar (p), make_number (inserted));
3343 if (!NILP (insval))
3345 CHECK_NUMBER (insval, 0);
3346 inserted = XFASTINT (insval);
3348 QUIT;
3349 p = Fcdr (p);
3353 if (NILP (val))
3354 val = Fcons (filename,
3355 Fcons (make_number (inserted),
3356 Qnil));
3358 RETURN_UNGCPRO (unbind_to (count, val));
3361 static Lisp_Object build_annotations ();
3363 /* If build_annotations switched buffers, switch back to BUF.
3364 Kill the temporary buffer that was selected in the meantime. */
3366 static Lisp_Object
3367 build_annotations_unwind (buf)
3368 Lisp_Object buf;
3370 Lisp_Object tembuf;
3372 if (XBUFFER (buf) == current_buffer)
3373 return Qnil;
3374 tembuf = Fcurrent_buffer ();
3375 Fset_buffer (buf);
3376 Fkill_buffer (tembuf);
3377 return Qnil;
3380 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 6,
3381 "r\nFWrite region to file: ",
3382 "Write current region into specified file.\n\
3383 When called from a program, takes three arguments:\n\
3384 START, END and FILENAME. START and END are buffer positions.\n\
3385 Optional fourth argument APPEND if non-nil means\n\
3386 append to existing file contents (if any).\n\
3387 Optional fifth argument VISIT if t means\n\
3388 set the last-save-file-modtime of buffer to this file's modtime\n\
3389 and mark buffer not modified.\n\
3390 If VISIT is a string, it is a second file name;\n\
3391 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3392 VISIT is also the file name to lock and unlock for clash detection.\n\
3393 If VISIT is neither t nor nil nor a string,\n\
3394 that means do not print the \"Wrote file\" message.\n\
3395 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3396 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3397 Kludgy feature: if START is a string, then that string is written\n\
3398 to the file, instead of any buffer contents, and END is ignored.")
3399 (start, end, filename, append, visit, lockname)
3400 Lisp_Object start, end, filename, append, visit, lockname;
3402 register int desc;
3403 int failure;
3404 int save_errno;
3405 unsigned char *fn;
3406 struct stat st;
3407 int tem;
3408 int count = specpdl_ptr - specpdl;
3409 int count1;
3410 #ifdef VMS
3411 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
3412 #endif /* VMS */
3413 Lisp_Object handler;
3414 Lisp_Object visit_file;
3415 Lisp_Object annotations;
3416 int visiting, quietly;
3417 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3418 struct buffer *given_buffer;
3419 #ifdef DOS_NT
3420 int buffer_file_type
3421 = NILP (current_buffer->buffer_file_type) ? O_TEXT : O_BINARY;
3422 #endif /* DOS_NT */
3424 if (current_buffer->base_buffer && ! NILP (visit))
3425 error ("Cannot do file visiting in an indirect buffer");
3427 if (!NILP (start) && !STRINGP (start))
3428 validate_region (&start, &end);
3430 GCPRO3 (filename, visit, lockname);
3431 filename = Fexpand_file_name (filename, Qnil);
3432 if (STRINGP (visit))
3433 visit_file = Fexpand_file_name (visit, Qnil);
3434 else
3435 visit_file = filename;
3436 UNGCPRO;
3438 visiting = (EQ (visit, Qt) || STRINGP (visit));
3439 quietly = !NILP (visit);
3441 annotations = Qnil;
3443 if (NILP (lockname))
3444 lockname = visit_file;
3446 GCPRO5 (start, filename, annotations, visit_file, lockname);
3448 /* If the file name has special constructs in it,
3449 call the corresponding file handler. */
3450 handler = Ffind_file_name_handler (filename, Qwrite_region);
3451 /* If FILENAME has no handler, see if VISIT has one. */
3452 if (NILP (handler) && STRINGP (visit))
3453 handler = Ffind_file_name_handler (visit, Qwrite_region);
3455 if (!NILP (handler))
3457 Lisp_Object val;
3458 val = call6 (handler, Qwrite_region, start, end,
3459 filename, append, visit);
3461 if (visiting)
3463 SAVE_MODIFF = MODIFF;
3464 XSETFASTINT (current_buffer->save_length, Z - BEG);
3465 current_buffer->filename = visit_file;
3467 UNGCPRO;
3468 return val;
3471 /* Special kludge to simplify auto-saving. */
3472 if (NILP (start))
3474 XSETFASTINT (start, BEG);
3475 XSETFASTINT (end, Z);
3478 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
3479 count1 = specpdl_ptr - specpdl;
3481 given_buffer = current_buffer;
3482 annotations = build_annotations (start, end);
3483 if (current_buffer != given_buffer)
3485 start = BEGV;
3486 end = ZV;
3489 #ifdef CLASH_DETECTION
3490 if (!auto_saving)
3491 lock_file (lockname);
3492 #endif /* CLASH_DETECTION */
3494 fn = XSTRING (filename)->data;
3495 desc = -1;
3496 if (!NILP (append))
3497 #ifdef DOS_NT
3498 desc = open (fn, O_WRONLY | buffer_file_type);
3499 #else /* not DOS_NT */
3500 desc = open (fn, O_WRONLY);
3501 #endif /* not DOS_NT */
3503 if (desc < 0)
3504 #ifdef VMS
3505 if (auto_saving) /* Overwrite any previous version of autosave file */
3507 vms_truncate (fn); /* if fn exists, truncate to zero length */
3508 desc = open (fn, O_RDWR);
3509 if (desc < 0)
3510 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
3511 ? XSTRING (current_buffer->filename)->data : 0,
3512 fn);
3514 else /* Write to temporary name and rename if no errors */
3516 Lisp_Object temp_name;
3517 temp_name = Ffile_name_directory (filename);
3519 if (!NILP (temp_name))
3521 temp_name = Fmake_temp_name (concat2 (temp_name,
3522 build_string ("$$SAVE$$")));
3523 fname = XSTRING (filename)->data;
3524 fn = XSTRING (temp_name)->data;
3525 desc = creat_copy_attrs (fname, fn);
3526 if (desc < 0)
3528 /* If we can't open the temporary file, try creating a new
3529 version of the original file. VMS "creat" creates a
3530 new version rather than truncating an existing file. */
3531 fn = fname;
3532 fname = 0;
3533 desc = creat (fn, 0666);
3534 #if 0 /* This can clobber an existing file and fail to replace it,
3535 if the user runs out of space. */
3536 if (desc < 0)
3538 /* We can't make a new version;
3539 try to truncate and rewrite existing version if any. */
3540 vms_truncate (fn);
3541 desc = open (fn, O_RDWR);
3543 #endif
3546 else
3547 desc = creat (fn, 0666);
3549 #else /* not VMS */
3550 #ifdef DOS_NT
3551 desc = open (fn,
3552 O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type,
3553 S_IREAD | S_IWRITE);
3554 #else /* not DOS_NT */
3555 desc = creat (fn, auto_saving ? auto_save_mode_bits : 0666);
3556 #endif /* not DOS_NT */
3557 #endif /* not VMS */
3559 UNGCPRO;
3561 if (desc < 0)
3563 #ifdef CLASH_DETECTION
3564 save_errno = errno;
3565 if (!auto_saving) unlock_file (lockname);
3566 errno = save_errno;
3567 #endif /* CLASH_DETECTION */
3568 report_file_error ("Opening output file", Fcons (filename, Qnil));
3571 record_unwind_protect (close_file_unwind, make_number (desc));
3573 if (!NILP (append))
3574 if (lseek (desc, 0, 2) < 0)
3576 #ifdef CLASH_DETECTION
3577 if (!auto_saving) unlock_file (lockname);
3578 #endif /* CLASH_DETECTION */
3579 report_file_error ("Lseek error", Fcons (filename, Qnil));
3582 #ifdef VMS
3584 * Kludge Warning: The VMS C RTL likes to insert carriage returns
3585 * if we do writes that don't end with a carriage return. Furthermore
3586 * it cannot handle writes of more then 16K. The modified
3587 * version of "sys_write" in SYSDEP.C (see comment there) copes with
3588 * this EXCEPT for the last record (iff it doesn't end with a carriage
3589 * return). This implies that if your buffer doesn't end with a carriage
3590 * return, you get one free... tough. However it also means that if
3591 * we make two calls to sys_write (a la the following code) you can
3592 * get one at the gap as well. The easiest way to fix this (honest)
3593 * is to move the gap to the next newline (or the end of the buffer).
3594 * Thus this change.
3596 * Yech!
3598 if (GPT > BEG && GPT_ADDR[-1] != '\n')
3599 move_gap (find_next_newline (GPT, 1));
3600 #endif
3602 failure = 0;
3603 immediate_quit = 1;
3605 if (STRINGP (start))
3607 failure = 0 > a_write (desc, XSTRING (start)->data,
3608 XSTRING (start)->size, 0, &annotations);
3609 save_errno = errno;
3611 else if (XINT (start) != XINT (end))
3613 int nwritten = 0;
3614 if (XINT (start) < GPT)
3616 register int end1 = XINT (end);
3617 tem = XINT (start);
3618 failure = 0 > a_write (desc, &FETCH_CHAR (tem),
3619 min (GPT, end1) - tem, tem, &annotations);
3620 nwritten += min (GPT, end1) - tem;
3621 save_errno = errno;
3624 if (XINT (end) > GPT && !failure)
3626 tem = XINT (start);
3627 tem = max (tem, GPT);
3628 failure = 0 > a_write (desc, &FETCH_CHAR (tem), XINT (end) - tem,
3629 tem, &annotations);
3630 nwritten += XINT (end) - tem;
3631 save_errno = errno;
3634 else
3636 /* If file was empty, still need to write the annotations */
3637 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations);
3638 save_errno = errno;
3641 immediate_quit = 0;
3643 #ifdef HAVE_FSYNC
3644 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
3645 Disk full in NFS may be reported here. */
3646 /* mib says that closing the file will try to write as fast as NFS can do
3647 it, and that means the fsync here is not crucial for autosave files. */
3648 if (!auto_saving && fsync (desc) < 0)
3650 /* If fsync fails with EINTR, don't treat that as serious. */
3651 if (errno != EINTR)
3652 failure = 1, save_errno = errno;
3654 #endif
3656 /* Spurious "file has changed on disk" warnings have been
3657 observed on Suns as well.
3658 It seems that `close' can change the modtime, under nfs.
3660 (This has supposedly been fixed in Sunos 4,
3661 but who knows about all the other machines with NFS?) */
3662 #if 0
3664 /* On VMS and APOLLO, must do the stat after the close
3665 since closing changes the modtime. */
3666 #ifndef VMS
3667 #ifndef APOLLO
3668 /* Recall that #if defined does not work on VMS. */
3669 #define FOO
3670 fstat (desc, &st);
3671 #endif
3672 #endif
3673 #endif
3675 /* NFS can report a write failure now. */
3676 if (close (desc) < 0)
3677 failure = 1, save_errno = errno;
3679 #ifdef VMS
3680 /* If we wrote to a temporary name and had no errors, rename to real name. */
3681 if (fname)
3683 if (!failure)
3684 failure = (rename (fn, fname) != 0), save_errno = errno;
3685 fn = fname;
3687 #endif /* VMS */
3689 #ifndef FOO
3690 stat (fn, &st);
3691 #endif
3692 /* Discard the unwind protect for close_file_unwind. */
3693 specpdl_ptr = specpdl + count1;
3694 /* Restore the original current buffer. */
3695 visit_file = unbind_to (count, visit_file);
3697 #ifdef CLASH_DETECTION
3698 if (!auto_saving)
3699 unlock_file (lockname);
3700 #endif /* CLASH_DETECTION */
3702 /* Do this before reporting IO error
3703 to avoid a "file has changed on disk" warning on
3704 next attempt to save. */
3705 if (visiting)
3706 current_buffer->modtime = st.st_mtime;
3708 if (failure)
3709 error ("IO error writing %s: %s", fn, strerror (save_errno));
3711 if (visiting)
3713 SAVE_MODIFF = MODIFF;
3714 XSETFASTINT (current_buffer->save_length, Z - BEG);
3715 current_buffer->filename = visit_file;
3716 update_mode_lines++;
3718 else if (quietly)
3719 return Qnil;
3721 if (!auto_saving)
3722 message ("Wrote %s", XSTRING (visit_file)->data);
3724 return Qnil;
3727 Lisp_Object merge ();
3729 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
3730 "Return t if (car A) is numerically less than (car B).")
3731 (a, b)
3732 Lisp_Object a, b;
3734 return Flss (Fcar (a), Fcar (b));
3737 /* Build the complete list of annotations appropriate for writing out
3738 the text between START and END, by calling all the functions in
3739 write-region-annotate-functions and merging the lists they return.
3740 If one of these functions switches to a different buffer, we assume
3741 that buffer contains altered text. Therefore, the caller must
3742 make sure to restore the current buffer in all cases,
3743 as save-excursion would do. */
3745 static Lisp_Object
3746 build_annotations (start, end)
3747 Lisp_Object start, end;
3749 Lisp_Object annotations;
3750 Lisp_Object p, res;
3751 struct gcpro gcpro1, gcpro2;
3753 annotations = Qnil;
3754 p = Vwrite_region_annotate_functions;
3755 GCPRO2 (annotations, p);
3756 while (!NILP (p))
3758 struct buffer *given_buffer = current_buffer;
3759 Vwrite_region_annotations_so_far = annotations;
3760 res = call2 (Fcar (p), start, end);
3761 /* If the function makes a different buffer current,
3762 assume that means this buffer contains altered text to be output.
3763 Reset START and END from the buffer bounds
3764 and discard all previous annotations because they should have
3765 been dealt with by this function. */
3766 if (current_buffer != given_buffer)
3768 start = BEGV;
3769 end = ZV;
3770 annotations = Qnil;
3772 Flength (res); /* Check basic validity of return value */
3773 annotations = merge (annotations, res, Qcar_less_than_car);
3774 p = Fcdr (p);
3777 /* Now do the same for annotation functions implied by the file-format */
3778 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
3779 p = Vauto_save_file_format;
3780 else
3781 p = current_buffer->file_format;
3782 while (!NILP (p))
3784 struct buffer *given_buffer = current_buffer;
3785 Vwrite_region_annotations_so_far = annotations;
3786 res = call3 (Qformat_annotate_function, Fcar (p), start, end);
3787 if (current_buffer != given_buffer)
3789 start = BEGV;
3790 end = ZV;
3791 annotations = Qnil;
3793 Flength (res);
3794 annotations = merge (annotations, res, Qcar_less_than_car);
3795 p = Fcdr (p);
3797 UNGCPRO;
3798 return annotations;
3801 /* Write to descriptor DESC the LEN characters starting at ADDR,
3802 assuming they start at position POS in the buffer.
3803 Intersperse with them the annotations from *ANNOT
3804 (those which fall within the range of positions POS to POS + LEN),
3805 each at its appropriate position.
3807 Modify *ANNOT by discarding elements as we output them.
3808 The return value is negative in case of system call failure. */
3811 a_write (desc, addr, len, pos, annot)
3812 int desc;
3813 register char *addr;
3814 register int len;
3815 int pos;
3816 Lisp_Object *annot;
3818 Lisp_Object tem;
3819 int nextpos;
3820 int lastpos = pos + len;
3822 while (NILP (*annot) || CONSP (*annot))
3824 tem = Fcar_safe (Fcar (*annot));
3825 if (INTEGERP (tem) && XINT (tem) >= pos && XFASTINT (tem) <= lastpos)
3826 nextpos = XFASTINT (tem);
3827 else
3828 return e_write (desc, addr, lastpos - pos);
3829 if (nextpos > pos)
3831 if (0 > e_write (desc, addr, nextpos - pos))
3832 return -1;
3833 addr += nextpos - pos;
3834 pos = nextpos;
3836 tem = Fcdr (Fcar (*annot));
3837 if (STRINGP (tem))
3839 if (0 > e_write (desc, XSTRING (tem)->data, XSTRING (tem)->size))
3840 return -1;
3842 *annot = Fcdr (*annot);
3847 e_write (desc, addr, len)
3848 int desc;
3849 register char *addr;
3850 register int len;
3852 char buf[16 * 1024];
3853 register char *p, *end;
3855 if (!EQ (current_buffer->selective_display, Qt))
3856 return write (desc, addr, len) - len;
3857 else
3859 p = buf;
3860 end = p + sizeof buf;
3861 while (len--)
3863 if (p == end)
3865 if (write (desc, buf, sizeof buf) != sizeof buf)
3866 return -1;
3867 p = buf;
3869 *p = *addr++;
3870 if (*p++ == '\015')
3871 p[-1] = '\n';
3873 if (p != buf)
3874 if (write (desc, buf, p - buf) != p - buf)
3875 return -1;
3877 return 0;
3880 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
3881 Sverify_visited_file_modtime, 1, 1, 0,
3882 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
3883 This means that the file has not been changed since it was visited or saved.")
3884 (buf)
3885 Lisp_Object buf;
3887 struct buffer *b;
3888 struct stat st;
3889 Lisp_Object handler;
3891 CHECK_BUFFER (buf, 0);
3892 b = XBUFFER (buf);
3894 if (!STRINGP (b->filename)) return Qt;
3895 if (b->modtime == 0) return Qt;
3897 /* If the file name has special constructs in it,
3898 call the corresponding file handler. */
3899 handler = Ffind_file_name_handler (b->filename,
3900 Qverify_visited_file_modtime);
3901 if (!NILP (handler))
3902 return call2 (handler, Qverify_visited_file_modtime, buf);
3904 if (stat (XSTRING (b->filename)->data, &st) < 0)
3906 /* If the file doesn't exist now and didn't exist before,
3907 we say that it isn't modified, provided the error is a tame one. */
3908 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
3909 st.st_mtime = -1;
3910 else
3911 st.st_mtime = 0;
3913 if (st.st_mtime == b->modtime
3914 /* If both are positive, accept them if they are off by one second. */
3915 || (st.st_mtime > 0 && b->modtime > 0
3916 && (st.st_mtime == b->modtime + 1
3917 || st.st_mtime == b->modtime - 1)))
3918 return Qt;
3919 return Qnil;
3922 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
3923 Sclear_visited_file_modtime, 0, 0, 0,
3924 "Clear out records of last mod time of visited file.\n\
3925 Next attempt to save will certainly not complain of a discrepancy.")
3928 current_buffer->modtime = 0;
3929 return Qnil;
3932 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
3933 Svisited_file_modtime, 0, 0, 0,
3934 "Return the current buffer's recorded visited file modification time.\n\
3935 The value is a list of the form (HIGH . LOW), like the time values\n\
3936 that `file-attributes' returns.")
3939 return long_to_cons ((unsigned long) current_buffer->modtime);
3942 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
3943 Sset_visited_file_modtime, 0, 1, 0,
3944 "Update buffer's recorded modification time from the visited file's time.\n\
3945 Useful if the buffer was not read from the file normally\n\
3946 or if the file itself has been changed for some known benign reason.\n\
3947 An argument specifies the modification time value to use\n\
3948 \(instead of that of the visited file), in the form of a list\n\
3949 \(HIGH . LOW) or (HIGH LOW).")
3950 (time_list)
3951 Lisp_Object time_list;
3953 if (!NILP (time_list))
3954 current_buffer->modtime = cons_to_long (time_list);
3955 else
3957 register Lisp_Object filename;
3958 struct stat st;
3959 Lisp_Object handler;
3961 filename = Fexpand_file_name (current_buffer->filename, Qnil);
3963 /* If the file name has special constructs in it,
3964 call the corresponding file handler. */
3965 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
3966 if (!NILP (handler))
3967 /* The handler can find the file name the same way we did. */
3968 return call2 (handler, Qset_visited_file_modtime, Qnil);
3969 else if (stat (XSTRING (filename)->data, &st) >= 0)
3970 current_buffer->modtime = st.st_mtime;
3973 return Qnil;
3976 Lisp_Object
3977 auto_save_error ()
3979 ring_bell ();
3980 message ("Autosaving...error for %s", XSTRING (current_buffer->name)->data);
3981 Fsleep_for (make_number (1), Qnil);
3982 message ("Autosaving...error!for %s", XSTRING (current_buffer->name)->data);
3983 Fsleep_for (make_number (1), Qnil);
3984 message ("Autosaving...error for %s", XSTRING (current_buffer->name)->data);
3985 Fsleep_for (make_number (1), Qnil);
3986 return Qnil;
3989 Lisp_Object
3990 auto_save_1 ()
3992 unsigned char *fn;
3993 struct stat st;
3995 /* Get visited file's mode to become the auto save file's mode. */
3996 if (stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
3997 /* But make sure we can overwrite it later! */
3998 auto_save_mode_bits = st.st_mode | 0600;
3999 else
4000 auto_save_mode_bits = 0666;
4002 return
4003 Fwrite_region (Qnil, Qnil,
4004 current_buffer->auto_save_file_name,
4005 Qnil, Qlambda, Qnil);
4008 static Lisp_Object
4009 do_auto_save_unwind (desc) /* used as unwind-protect function */
4010 Lisp_Object desc;
4012 auto_saving = 0;
4013 if (XINT (desc) >= 0)
4014 close (XINT (desc));
4015 return Qnil;
4018 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
4019 "Auto-save all buffers that need it.\n\
4020 This is all buffers that have auto-saving enabled\n\
4021 and are changed since last auto-saved.\n\
4022 Auto-saving writes the buffer into a file\n\
4023 so that your editing is not lost if the system crashes.\n\
4024 This file is not the file you visited; that changes only when you save.\n\
4025 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4026 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4027 A non-nil CURRENT-ONLY argument means save only current buffer.")
4028 (no_message, current_only)
4029 Lisp_Object no_message, current_only;
4031 struct buffer *old = current_buffer, *b;
4032 Lisp_Object tail, buf;
4033 int auto_saved = 0;
4034 char *omessage = echo_area_glyphs;
4035 int omessage_length = echo_area_glyphs_length;
4036 extern int minibuf_level;
4037 int do_handled_files;
4038 Lisp_Object oquit;
4039 int listdesc;
4040 int count = specpdl_ptr - specpdl;
4041 int *ptr;
4043 /* Ordinarily don't quit within this function,
4044 but don't make it impossible to quit (in case we get hung in I/O). */
4045 oquit = Vquit_flag;
4046 Vquit_flag = Qnil;
4048 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4049 point to non-strings reached from Vbuffer_alist. */
4051 if (minibuf_level)
4052 no_message = Qt;
4054 if (!NILP (Vrun_hooks))
4055 call1 (Vrun_hooks, intern ("auto-save-hook"));
4057 if (STRINGP (Vauto_save_list_file_name))
4059 Lisp_Object listfile;
4060 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
4061 #ifdef DOS_NT
4062 listdesc = open (XSTRING (listfile)->data,
4063 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
4064 S_IREAD | S_IWRITE);
4065 #else /* not DOS_NT */
4066 listdesc = creat (XSTRING (listfile)->data, 0666);
4067 #endif /* not DOS_NT */
4069 else
4070 listdesc = -1;
4072 /* Arrange to close that file whether or not we get an error.
4073 Also reset auto_saving to 0. */
4074 record_unwind_protect (do_auto_save_unwind, make_number (listdesc));
4076 auto_saving = 1;
4078 /* First, save all files which don't have handlers. If Emacs is
4079 crashing, the handlers may tweak what is causing Emacs to crash
4080 in the first place, and it would be a shame if Emacs failed to
4081 autosave perfectly ordinary files because it couldn't handle some
4082 ange-ftp'd file. */
4083 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
4084 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
4086 buf = XCONS (XCONS (tail)->car)->cdr;
4087 b = XBUFFER (buf);
4089 /* Record all the buffers that have auto save mode
4090 in the special file that lists them. For each of these buffers,
4091 Record visited name (if any) and auto save name. */
4092 if (STRINGP (b->auto_save_file_name)
4093 && listdesc >= 0 && do_handled_files == 0)
4095 if (!NILP (b->filename))
4097 write (listdesc, XSTRING (b->filename)->data,
4098 XSTRING (b->filename)->size);
4100 write (listdesc, "\n", 1);
4101 write (listdesc, XSTRING (b->auto_save_file_name)->data,
4102 XSTRING (b->auto_save_file_name)->size);
4103 write (listdesc, "\n", 1);
4106 if (!NILP (current_only)
4107 && b != current_buffer)
4108 continue;
4110 /* Don't auto-save indirect buffers.
4111 The base buffer takes care of it. */
4112 if (b->base_buffer)
4113 continue;
4115 /* Check for auto save enabled
4116 and file changed since last auto save
4117 and file changed since last real save. */
4118 if (STRINGP (b->auto_save_file_name)
4119 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
4120 && b->auto_save_modified < BUF_MODIFF (b)
4121 /* -1 means we've turned off autosaving for a while--see below. */
4122 && XINT (b->save_length) >= 0
4123 && (do_handled_files
4124 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
4125 Qwrite_region))))
4127 EMACS_TIME before_time, after_time;
4129 EMACS_GET_TIME (before_time);
4131 /* If we had a failure, don't try again for 20 minutes. */
4132 if (b->auto_save_failure_time >= 0
4133 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
4134 continue;
4136 if ((XFASTINT (b->save_length) * 10
4137 > (BUF_Z (b) - BUF_BEG (b)) * 13)
4138 /* A short file is likely to change a large fraction;
4139 spare the user annoying messages. */
4140 && XFASTINT (b->save_length) > 5000
4141 /* These messages are frequent and annoying for `*mail*'. */
4142 && !EQ (b->filename, Qnil)
4143 && NILP (no_message))
4145 /* It has shrunk too much; turn off auto-saving here. */
4146 message ("Buffer %s has shrunk a lot; auto save turned off there",
4147 XSTRING (b->name)->data);
4148 /* Turn off auto-saving until there's a real save,
4149 and prevent any more warnings. */
4150 XSETINT (b->save_length, -1);
4151 Fsleep_for (make_number (1), Qnil);
4152 continue;
4154 set_buffer_internal (b);
4155 if (!auto_saved && NILP (no_message))
4156 message1 ("Auto-saving...");
4157 internal_condition_case (auto_save_1, Qt, auto_save_error);
4158 auto_saved++;
4159 b->auto_save_modified = BUF_MODIFF (b);
4160 XSETFASTINT (current_buffer->save_length, Z - BEG);
4161 set_buffer_internal (old);
4163 EMACS_GET_TIME (after_time);
4165 /* If auto-save took more than 60 seconds,
4166 assume it was an NFS failure that got a timeout. */
4167 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
4168 b->auto_save_failure_time = EMACS_SECS (after_time);
4172 /* Prevent another auto save till enough input events come in. */
4173 record_auto_save ();
4175 if (auto_saved && NILP (no_message))
4177 if (omessage)
4179 sit_for (1, 0, 0, 0);
4180 message2 (omessage, omessage_length);
4182 else
4183 message1 ("Auto-saving...done");
4186 Vquit_flag = oquit;
4188 unbind_to (count, Qnil);
4189 return Qnil;
4192 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
4193 Sset_buffer_auto_saved, 0, 0, 0,
4194 "Mark current buffer as auto-saved with its current text.\n\
4195 No auto-save file will be written until the buffer changes again.")
4198 current_buffer->auto_save_modified = MODIFF;
4199 XSETFASTINT (current_buffer->save_length, Z - BEG);
4200 current_buffer->auto_save_failure_time = -1;
4201 return Qnil;
4204 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
4205 Sclear_buffer_auto_save_failure, 0, 0, 0,
4206 "Clear any record of a recent auto-save failure in the current buffer.")
4209 current_buffer->auto_save_failure_time = -1;
4210 return Qnil;
4213 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
4214 0, 0, 0,
4215 "Return t if buffer has been auto-saved since last read in or saved.")
4218 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
4221 /* Reading and completing file names */
4222 extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
4224 /* In the string VAL, change each $ to $$ and return the result. */
4226 static Lisp_Object
4227 double_dollars (val)
4228 Lisp_Object val;
4230 register unsigned char *old, *new;
4231 register int n;
4232 int osize, count;
4234 osize = XSTRING (val)->size;
4235 /* Quote "$" as "$$" to get it past substitute-in-file-name */
4236 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
4237 if (*old++ == '$') count++;
4238 if (count > 0)
4240 old = XSTRING (val)->data;
4241 val = Fmake_string (make_number (osize + count), make_number (0));
4242 new = XSTRING (val)->data;
4243 for (n = osize; n > 0; n--)
4244 if (*old != '$')
4245 *new++ = *old++;
4246 else
4248 *new++ = '$';
4249 *new++ = '$';
4250 old++;
4253 return val;
4256 DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
4257 3, 3, 0,
4258 "Internal subroutine for read-file-name. Do not call this.")
4259 (string, dir, action)
4260 Lisp_Object string, dir, action;
4261 /* action is nil for complete, t for return list of completions,
4262 lambda for verify final value */
4264 Lisp_Object name, specdir, realdir, val, orig_string;
4265 int changed;
4266 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4268 realdir = dir;
4269 name = string;
4270 orig_string = Qnil;
4271 specdir = Qnil;
4272 changed = 0;
4273 /* No need to protect ACTION--we only compare it with t and nil. */
4274 GCPRO5 (string, realdir, name, specdir, orig_string);
4276 if (XSTRING (string)->size == 0)
4278 if (EQ (action, Qlambda))
4280 UNGCPRO;
4281 return Qnil;
4284 else
4286 orig_string = string;
4287 string = Fsubstitute_in_file_name (string);
4288 changed = NILP (Fstring_equal (string, orig_string));
4289 name = Ffile_name_nondirectory (string);
4290 val = Ffile_name_directory (string);
4291 if (! NILP (val))
4292 realdir = Fexpand_file_name (val, realdir);
4295 if (NILP (action))
4297 specdir = Ffile_name_directory (string);
4298 val = Ffile_name_completion (name, realdir);
4299 UNGCPRO;
4300 if (!STRINGP (val))
4302 if (changed)
4303 return double_dollars (string);
4304 return val;
4307 if (!NILP (specdir))
4308 val = concat2 (specdir, val);
4309 #ifndef VMS
4310 return double_dollars (val);
4311 #else /* not VMS */
4312 return val;
4313 #endif /* not VMS */
4315 UNGCPRO;
4317 if (EQ (action, Qt))
4318 return Ffile_name_all_completions (name, realdir);
4319 /* Only other case actually used is ACTION = lambda */
4320 #ifdef VMS
4321 /* Supposedly this helps commands such as `cd' that read directory names,
4322 but can someone explain how it helps them? -- RMS */
4323 if (XSTRING (name)->size == 0)
4324 return Qt;
4325 #endif /* VMS */
4326 return Ffile_exists_p (string);
4329 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
4330 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
4331 Value is not expanded---you must call `expand-file-name' yourself.\n\
4332 Default name to DEFAULT-FILENAME if user enters a null string.\n\
4333 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
4334 except that if INITIAL is specified, that combined with DIR is used.)\n\
4335 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
4336 Non-nil and non-t means also require confirmation after completion.\n\
4337 Fifth arg INITIAL specifies text to start with.\n\
4338 DIR defaults to current buffer's directory default.")
4339 (prompt, dir, default_filename, mustmatch, initial)
4340 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
4342 Lisp_Object val, insdef, insdef1, tem;
4343 struct gcpro gcpro1, gcpro2;
4344 register char *homedir;
4345 int count;
4347 if (NILP (dir))
4348 dir = current_buffer->directory;
4349 if (NILP (default_filename))
4351 if (! NILP (initial))
4352 default_filename = Fexpand_file_name (initial, dir);
4353 else
4354 default_filename = current_buffer->filename;
4357 /* If dir starts with user's homedir, change that to ~. */
4358 homedir = (char *) egetenv ("HOME");
4359 #ifdef DOS_NT
4360 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
4361 CORRECT_DIR_SEPS (homedir);
4362 #endif
4363 if (homedir != 0
4364 && STRINGP (dir)
4365 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
4366 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
4368 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
4369 XSTRING (dir)->size - strlen (homedir) + 1);
4370 XSTRING (dir)->data[0] = '~';
4373 if (insert_default_directory)
4375 insdef = dir;
4376 if (!NILP (initial))
4378 Lisp_Object args[2], pos;
4380 args[0] = insdef;
4381 args[1] = initial;
4382 insdef = Fconcat (2, args);
4383 pos = make_number (XSTRING (double_dollars (dir))->size);
4384 insdef1 = Fcons (double_dollars (insdef), pos);
4386 else
4387 insdef1 = double_dollars (insdef);
4389 else if (!NILP (initial))
4391 insdef = initial;
4392 insdef1 = Fcons (double_dollars (insdef), 0);
4394 else
4395 insdef = Qnil, insdef1 = Qnil;
4397 #ifdef VMS
4398 count = specpdl_ptr - specpdl;
4399 specbind (intern ("completion-ignore-case"), Qt);
4400 #endif
4402 GCPRO2 (insdef, default_filename);
4403 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4404 dir, mustmatch, insdef1,
4405 Qfile_name_history);
4407 #ifdef VMS
4408 unbind_to (count, Qnil);
4409 #endif
4411 UNGCPRO;
4412 if (NILP (val))
4413 error ("No file name specified");
4414 tem = Fstring_equal (val, insdef);
4415 if (!NILP (tem) && !NILP (default_filename))
4416 return default_filename;
4417 if (XSTRING (val)->size == 0 && NILP (insdef))
4419 if (!NILP (default_filename))
4420 return default_filename;
4421 else
4422 error ("No default file name");
4424 return Fsubstitute_in_file_name (val);
4427 #if 0 /* Old version */
4428 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
4429 /* Don't confuse make-docfile by having two doc strings for this function.
4430 make-docfile does not pay attention to #if, for good reason! */
4432 (prompt, dir, defalt, mustmatch, initial)
4433 Lisp_Object prompt, dir, defalt, mustmatch, initial;
4435 Lisp_Object val, insdef, tem;
4436 struct gcpro gcpro1, gcpro2;
4437 register char *homedir;
4438 int count;
4440 if (NILP (dir))
4441 dir = current_buffer->directory;
4442 if (NILP (defalt))
4443 defalt = current_buffer->filename;
4445 /* If dir starts with user's homedir, change that to ~. */
4446 homedir = (char *) egetenv ("HOME");
4447 if (homedir != 0
4448 && STRINGP (dir)
4449 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
4450 && XSTRING (dir)->data[strlen (homedir)] == '/')
4452 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
4453 XSTRING (dir)->size - strlen (homedir) + 1);
4454 XSTRING (dir)->data[0] = '~';
4457 if (!NILP (initial))
4458 insdef = initial;
4459 else if (insert_default_directory)
4460 insdef = dir;
4461 else
4462 insdef = build_string ("");
4464 #ifdef VMS
4465 count = specpdl_ptr - specpdl;
4466 specbind (intern ("completion-ignore-case"), Qt);
4467 #endif
4469 GCPRO2 (insdef, defalt);
4470 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4471 dir, mustmatch,
4472 insert_default_directory ? insdef : Qnil,
4473 Qfile_name_history);
4475 #ifdef VMS
4476 unbind_to (count, Qnil);
4477 #endif
4479 UNGCPRO;
4480 if (NILP (val))
4481 error ("No file name specified");
4482 tem = Fstring_equal (val, insdef);
4483 if (!NILP (tem) && !NILP (defalt))
4484 return defalt;
4485 return Fsubstitute_in_file_name (val);
4487 #endif /* Old version */
4489 syms_of_fileio ()
4491 Qexpand_file_name = intern ("expand-file-name");
4492 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
4493 Qdirectory_file_name = intern ("directory-file-name");
4494 Qfile_name_directory = intern ("file-name-directory");
4495 Qfile_name_nondirectory = intern ("file-name-nondirectory");
4496 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
4497 Qfile_name_as_directory = intern ("file-name-as-directory");
4498 Qcopy_file = intern ("copy-file");
4499 Qmake_directory_internal = intern ("make-directory-internal");
4500 Qdelete_directory = intern ("delete-directory");
4501 Qdelete_file = intern ("delete-file");
4502 Qrename_file = intern ("rename-file");
4503 Qadd_name_to_file = intern ("add-name-to-file");
4504 Qmake_symbolic_link = intern ("make-symbolic-link");
4505 Qfile_exists_p = intern ("file-exists-p");
4506 Qfile_executable_p = intern ("file-executable-p");
4507 Qfile_readable_p = intern ("file-readable-p");
4508 Qfile_symlink_p = intern ("file-symlink-p");
4509 Qfile_writable_p = intern ("file-writable-p");
4510 Qfile_directory_p = intern ("file-directory-p");
4511 Qfile_regular_p = intern ("file-regular-p");
4512 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
4513 Qfile_modes = intern ("file-modes");
4514 Qset_file_modes = intern ("set-file-modes");
4515 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
4516 Qinsert_file_contents = intern ("insert-file-contents");
4517 Qwrite_region = intern ("write-region");
4518 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
4519 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
4521 staticpro (&Qexpand_file_name);
4522 staticpro (&Qsubstitute_in_file_name);
4523 staticpro (&Qdirectory_file_name);
4524 staticpro (&Qfile_name_directory);
4525 staticpro (&Qfile_name_nondirectory);
4526 staticpro (&Qunhandled_file_name_directory);
4527 staticpro (&Qfile_name_as_directory);
4528 staticpro (&Qcopy_file);
4529 staticpro (&Qmake_directory_internal);
4530 staticpro (&Qdelete_directory);
4531 staticpro (&Qdelete_file);
4532 staticpro (&Qrename_file);
4533 staticpro (&Qadd_name_to_file);
4534 staticpro (&Qmake_symbolic_link);
4535 staticpro (&Qfile_exists_p);
4536 staticpro (&Qfile_executable_p);
4537 staticpro (&Qfile_readable_p);
4538 staticpro (&Qfile_symlink_p);
4539 staticpro (&Qfile_writable_p);
4540 staticpro (&Qfile_directory_p);
4541 staticpro (&Qfile_regular_p);
4542 staticpro (&Qfile_accessible_directory_p);
4543 staticpro (&Qfile_modes);
4544 staticpro (&Qset_file_modes);
4545 staticpro (&Qfile_newer_than_file_p);
4546 staticpro (&Qinsert_file_contents);
4547 staticpro (&Qwrite_region);
4548 staticpro (&Qverify_visited_file_modtime);
4550 Qfile_name_history = intern ("file-name-history");
4551 Fset (Qfile_name_history, Qnil);
4552 staticpro (&Qfile_name_history);
4554 Qfile_error = intern ("file-error");
4555 staticpro (&Qfile_error);
4556 Qfile_already_exists = intern ("file-already-exists");
4557 staticpro (&Qfile_already_exists);
4559 #ifdef DOS_NT
4560 Qfind_buffer_file_type = intern ("find-buffer-file-type");
4561 staticpro (&Qfind_buffer_file_type);
4562 #endif /* DOS_NT */
4564 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
4565 "*Format in which to write auto-save files.\n\
4566 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
4567 If it is t, which is the default, auto-save files are written in the\n\
4568 same format as a regular save would use.");
4569 Vauto_save_file_format = Qt;
4571 Qformat_decode = intern ("format-decode");
4572 staticpro (&Qformat_decode);
4573 Qformat_annotate_function = intern ("format-annotate-function");
4574 staticpro (&Qformat_annotate_function);
4576 Qcar_less_than_car = intern ("car-less-than-car");
4577 staticpro (&Qcar_less_than_car);
4579 Fput (Qfile_error, Qerror_conditions,
4580 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
4581 Fput (Qfile_error, Qerror_message,
4582 build_string ("File error"));
4584 Fput (Qfile_already_exists, Qerror_conditions,
4585 Fcons (Qfile_already_exists,
4586 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
4587 Fput (Qfile_already_exists, Qerror_message,
4588 build_string ("File already exists"));
4590 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
4591 "*Non-nil means when reading a filename start with default dir in minibuffer.");
4592 insert_default_directory = 1;
4594 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
4595 "*Non-nil means write new files with record format `stmlf'.\n\
4596 nil means use format `var'. This variable is meaningful only on VMS.");
4597 vms_stmlf_recfm = 0;
4599 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
4600 "Directory separator character for built-in functions that return file names.\n\
4601 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
4602 This variable affects the built-in functions only on Windows,\n\
4603 on other platforms, it is initialized so that Lisp code can find out\n\
4604 what the normal separator is.");
4605 Vdirectory_sep_char = '/';
4607 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
4608 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
4609 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
4610 HANDLER.\n\
4612 The first argument given to HANDLER is the name of the I/O primitive\n\
4613 to be handled; the remaining arguments are the arguments that were\n\
4614 passed to that primitive. For example, if you do\n\
4615 (file-exists-p FILENAME)\n\
4616 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
4617 (funcall HANDLER 'file-exists-p FILENAME)\n\
4618 The function `find-file-name-handler' checks this list for a handler\n\
4619 for its argument.");
4620 Vfile_name_handler_alist = Qnil;
4622 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
4623 "A list of functions to be called at the end of `insert-file-contents'.\n\
4624 Each is passed one argument, the number of bytes inserted. It should return\n\
4625 the new byte count, and leave point the same. If `insert-file-contents' is\n\
4626 intercepted by a handler from `file-name-handler-alist', that handler is\n\
4627 responsible for calling the after-insert-file-functions if appropriate.");
4628 Vafter_insert_file_functions = Qnil;
4630 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
4631 "A list of functions to be called at the start of `write-region'.\n\
4632 Each is passed two arguments, START and END as for `write-region'.\n\
4633 These are usually two numbers but not always; see the documentation\n\
4634 for `write-region'. The function should return a list of pairs\n\
4635 of the form (POSITION . STRING), consisting of strings to be effectively\n\
4636 inserted at the specified positions of the file being written (1 means to\n\
4637 insert before the first byte written). The POSITIONs must be sorted into\n\
4638 increasing order. If there are several functions in the list, the several\n\
4639 lists are merged destructively.");
4640 Vwrite_region_annotate_functions = Qnil;
4642 DEFVAR_LISP ("write-region-annotations-so-far",
4643 &Vwrite_region_annotations_so_far,
4644 "When an annotation function is called, this holds the previous annotations.\n\
4645 These are the annotations made by other annotation functions\n\
4646 that were already called. See also `write-region-annotate-functions'.");
4647 Vwrite_region_annotations_so_far = Qnil;
4649 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
4650 "A list of file name handlers that temporarily should not be used.\n\
4651 This applies only to the operation `inhibit-file-name-operation'.");
4652 Vinhibit_file_name_handlers = Qnil;
4654 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
4655 "The operation for which `inhibit-file-name-handlers' is applicable.");
4656 Vinhibit_file_name_operation = Qnil;
4658 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
4659 "File name in which we write a list of all auto save file names.\n\
4660 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
4661 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
4662 a non-nil value.");
4663 Vauto_save_list_file_name = Qnil;
4665 defsubr (&Sfind_file_name_handler);
4666 defsubr (&Sfile_name_directory);
4667 defsubr (&Sfile_name_nondirectory);
4668 defsubr (&Sunhandled_file_name_directory);
4669 defsubr (&Sfile_name_as_directory);
4670 defsubr (&Sdirectory_file_name);
4671 defsubr (&Smake_temp_name);
4672 defsubr (&Sexpand_file_name);
4673 defsubr (&Ssubstitute_in_file_name);
4674 defsubr (&Scopy_file);
4675 defsubr (&Smake_directory_internal);
4676 defsubr (&Sdelete_directory);
4677 defsubr (&Sdelete_file);
4678 defsubr (&Srename_file);
4679 defsubr (&Sadd_name_to_file);
4680 #ifdef S_IFLNK
4681 defsubr (&Smake_symbolic_link);
4682 #endif /* S_IFLNK */
4683 #ifdef VMS
4684 defsubr (&Sdefine_logical_name);
4685 #endif /* VMS */
4686 #ifdef HPUX_NET
4687 defsubr (&Ssysnetunam);
4688 #endif /* HPUX_NET */
4689 defsubr (&Sfile_name_absolute_p);
4690 defsubr (&Sfile_exists_p);
4691 defsubr (&Sfile_executable_p);
4692 defsubr (&Sfile_readable_p);
4693 defsubr (&Sfile_writable_p);
4694 defsubr (&Sfile_symlink_p);
4695 defsubr (&Sfile_directory_p);
4696 defsubr (&Sfile_accessible_directory_p);
4697 defsubr (&Sfile_regular_p);
4698 defsubr (&Sfile_modes);
4699 defsubr (&Sset_file_modes);
4700 defsubr (&Sset_default_file_modes);
4701 defsubr (&Sdefault_file_modes);
4702 defsubr (&Sfile_newer_than_file_p);
4703 defsubr (&Sinsert_file_contents);
4704 defsubr (&Swrite_region);
4705 defsubr (&Scar_less_than_car);
4706 defsubr (&Sverify_visited_file_modtime);
4707 defsubr (&Sclear_visited_file_modtime);
4708 defsubr (&Svisited_file_modtime);
4709 defsubr (&Sset_visited_file_modtime);
4710 defsubr (&Sdo_auto_save);
4711 defsubr (&Sset_buffer_auto_saved);
4712 defsubr (&Sclear_buffer_auto_save_failure);
4713 defsubr (&Srecent_auto_save_p);
4715 defsubr (&Sread_file_name_internal);
4716 defsubr (&Sread_file_name);
4718 #ifdef unix
4719 defsubr (&Sunix_sync);
4720 #endif