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)
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. */
23 #include <sys/types.h>
30 #if !defined (S_ISLNK) && defined (S_IFLNK)
31 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
34 #if !defined (S_ISREG) && defined (S_IFREG)
35 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
46 #include <sys/param.h>
68 extern char *strerror ();
85 #include "intervals.h"
94 #endif /* not WINDOWSNT */
97 #define CORRECT_DIR_SEPS(s) \
98 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
99 else unixtodos_filename (s); \
101 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
102 redirector allows the six letters between 'Z' and 'a' as well. */
104 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
107 #define IS_DRIVE(x) isalpha (x)
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))
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 */
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. */
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
)
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]);
216 Fsignal (Qfile_error
,
217 Fcons (build_string (string
), Fcons (errstring
, data
)));
220 close_file_unwind (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
;
285 inhibited_handlers
= Qnil
;
287 for (chain
= Vfile_name_handler_alist
; CONSP (chain
);
288 chain
= XCONS (chain
)->cdr
)
291 elt
= XCONS (chain
)->car
;
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
);
312 DEFUN ("file-name-directory", Ffile_name_directory
, Sfile_name_directory
,
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 `>'.")
320 Lisp_Object filename
;
322 register unsigned char *beg
;
323 register unsigned char *p
;
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
);
332 return call2 (handler
, Qfile_name_directory
, filename
);
334 #ifdef FILE_SYSTEM_CASE
335 filename
= FILE_SYSTEM_CASE (filename
);
337 beg
= XSTRING (filename
)->data
;
339 beg
= strcpy (alloca (strlen (beg
) + 1), beg
);
341 p
= beg
+ XSTRING (filename
)->size
;
343 while (p
!= beg
&& !IS_DIRECTORY_SEP (p
[-1])
345 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
348 /* only recognise drive specifier at beginning */
349 && !(p
[-1] == ':' && p
== beg
+ 2)
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]))
366 p
= beg
+ strlen (beg
);
369 CORRECT_DIR_SEPS (beg
);
371 return make_string (beg
, p
- beg
);
374 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory
, Sfile_name_nondirectory
,
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.")
381 Lisp_Object filename
;
383 register unsigned char *beg
, *p
, *end
;
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
);
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])
399 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
402 /* only recognise drive specifier at beginning */
403 && !(p
[-1] == ':' && p
== beg
+ 2)
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.")
419 Lisp_Object filename
;
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
);
427 return call2 (handler
, Qunhandled_file_name_directory
, filename
);
429 return Ffile_name_directory (filename
);
434 file_name_as_directory (out
, in
)
437 int size
= strlen (in
) - 1;
442 /* Is it already a directory string? */
443 if (in
[size
] == ':' || in
[size
] == ']' || in
[size
] == '>')
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
;
458 dir:x.dir --> dir:[x]
459 dir:[x]y.dir --> dir:[x.y] */
461 while (p
!= in
&& *p
!= ':' && *p
!= '>' && *p
!= ']') p
--;
464 strncpy (out
, in
, p
- in
);
483 dot
= index (p
, '.');
486 /* blindly remove any extension */
487 size
= strlen (out
) + (dot
- p
);
488 strncat (out
, p
, dot
- p
);
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';
506 CORRECT_DIR_SEPS (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.")
527 CHECK_STRING (file
, 0);
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
);
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.
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
)
559 struct FAB fab
= cc$rms_fab
;
560 struct NAM nam
= cc$rms_nam
;
561 char esa
[NAM$C_MAXRSS
];
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 */
573 fab
.fab$b_fns
= slen
;
574 fab
.fab$l_nam
= &nam
;
575 fab
.fab$l_fop
= FAB$M_NAM
;
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] == '.')
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 */
598 if ('a' <= *ptr
&& *ptr
<= 'z')
602 dst
[slen
- 1] = 0; /* remove colon */
603 if (!(src
= egetenv (dst
)))
605 /* should we jump to the beginning of this procedure?
606 Good points: allows us to use logical names that xlate
608 Bad points: can be a problem if we just translated to a device
610 For now, I'll punt and always expect VMS names, and hope for
613 if (src
[slen
- 1] != ']' && src
[slen
- 1] != '>')
614 { /* no recursion here! */
620 { /* not a directory spec */
625 bracket
= src
[slen
- 1];
627 /* If bracket is ']' or '>', bracket - 2 is the corresponding
629 ptr
= index (src
, bracket
- 2);
631 { /* no opening bracket */
635 if (!(rptr
= rindex (src
, '.')))
638 strncpy (dst
, src
, slen
);
642 dst
[slen
++] = bracket
;
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);
663 return directory_file_name (buf
, dst
);
668 strcat (dst
, "[000000]");
672 rlen
= strlen (rptr
) - 1;
673 strncat (dst
, rptr
, rlen
);
674 dst
[slen
+ rlen
] = '\0';
675 strcat (dst
, ".DIR.1");
679 /* Process as Unix format: just remove any final slash.
680 But leave "/" unchanged; do not change it to "". */
683 /* Handle // as root for apollo's. */
684 if ((slen
> 2 && dst
[slen
- 1] == '/')
685 || (slen
> 1 && dst
[0] != '/' && dst
[slen
- 1] == '/'))
689 && IS_DIRECTORY_SEP (dst
[slen
- 1])
691 && !IS_ANY_SEP (dst
[slen
- 2])
697 CORRECT_DIR_SEPS (dst
);
702 DEFUN ("directory-file-name", Fdirectory_file_name
, Sdirectory_file_name
,
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\".")
712 Lisp_Object directory
;
717 CHECK_STRING (directory
, 0);
719 if (NILP (directory
))
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
);
726 return call2 (handler
, Qdirectory_file_name
, directory
);
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);
734 buf
= (char *) alloca (XSTRING (directory
)->size
+ 20);
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.")
749 /* Don't use too many characters of the restricted 8+3 DOS
751 val
= concat2 (prefix
, build_string ("a.XXX"));
753 val
= concat2 (prefix
, build_string ("XXXXXX"));
755 mktemp (XSTRING (val
)->data
);
757 CORRECT_DIR_SEPS (XSTRING (val
)->data
);
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
;
779 register unsigned char *newdir
, *p
, *o
;
781 unsigned char *target
;
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;
793 int collapse_newdir
= 1;
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
);
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
);
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. */
835 /* Detect MSDOS file names with drive specifiers. */
836 && ! (IS_DRIVE (o
[0]) && (IS_DEVICE_SEP (o
[1]) && IS_DIRECTORY_SEP (o
[2])))
838 /* Detect Windows file names in UNC format. */
839 && ! (IS_DIRECTORY_SEP (o
[0]) && IS_DIRECTORY_SEP (o
[1]))
841 #else /* not DOS_NT */
842 /* Detect Unix absolute file names (/... alone is not absolute on
844 && ! (IS_DIRECTORY_SEP (o
[0]))
845 #endif /* not DOS_NT */
851 default_directory
= Fexpand_file_name (default_directory
, Qnil
);
856 /* Filenames on VMS are always upper case. */
857 name
= Fupcase (name
);
859 #ifdef FILE_SYSTEM_CASE
860 name
= FILE_SYSTEM_CASE (name
);
863 nm
= XSTRING (name
)->data
;
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
, ':');
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. */
884 else if (IS_DRIVE (colon
[-1])
885 && (colon
== nm
+ 1 || IS_DIRECTORY_SEP (colon
[-2])))
892 while (--colon
>= nm
)
899 /* Handle // and /~ in middle of file name
900 by discarding everything through the first / of that sequence. */
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 */
912 #endif /* APOLLO || WINDOWSNT */
916 if (IS_DIRECTORY_SEP (p
[0]) && p
[1] == '~')
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]))
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. */
934 IS_DIRECTORY_SEP (nm
[0])
939 && (drive
|| IS_DIRECTORY_SEP (nm
[1]))
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
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])
963 && (IS_DIRECTORY_SEP (p
[2])
965 || (p
[2] == '.' && (IS_DIRECTORY_SEP (p
[3])
972 /* if dev:[dir]/, move nm to / */
973 if (!slash
&& p
> nm
&& (brack
|| colon
)) {
974 nm
= (brack
? brack
+ 1 : colon
+ 1);
983 /* VMS pre V4.4,convert '-'s in filenames. */
984 if (lbrack
== rbrack
)
986 if (dots
< 2) /* this is to allow negative version numbers */
991 if (lbrack
> rbrack
&&
992 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
993 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
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] == '<'))
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: */
1017 /* if /name/dev:, move nm to dev: */
1020 /* if node::dev:, move colon following dev */
1021 else if (colon
&& colon
[-1] == ':')
1023 /* if dev1:dev2:, move nm to dev2: */
1024 else if (colon
&& colon
[-1] != ':')
1029 if (p
[0] == ':' && !colon
)
1035 if (lbrack
== rbrack
)
1038 else if (p
[0] == '.')
1046 if (index (nm
, '/'))
1047 return build_string (sys_translate_unix (nm
));
1050 /* Make sure directories are all separated with / or \ as
1051 desired, but avoid allocation of a new string when not
1053 CORRECT_DIR_SEPS (nm
);
1055 if (IS_DIRECTORY_SEP (nm
[1]))
1057 if (strcmp (nm
, XSTRING (name
)->data
) != 0)
1058 name
= build_string (nm
);
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] = ':';
1070 #else /* not DOS_NT */
1071 if (nm
== XSTRING (name
)->data
)
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
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. */
1096 if (nm
[0] == '~') /* prefix ~ */
1098 if (IS_DIRECTORY_SEP (nm
[1])
1102 || nm
[1] == 0) /* ~ by itself */
1104 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1105 newdir
= (unsigned char *) "";
1108 collapse_newdir
= 0;
1111 nm
++; /* Don't leave the slash in nm. */
1114 else /* ~user/filename */
1116 for (p
= nm
; *p
&& (!IS_DIRECTORY_SEP (*p
)
1121 o
= (unsigned char *) alloca (p
- nm
+ 1);
1122 bcopy ((char *) nm
, o
, p
- nm
);
1125 pw
= (struct passwd
*) getpwnam (o
+ 1);
1128 newdir
= (unsigned char *) pw
-> pw_dir
;
1130 nm
= p
+ 1; /* skip the terminator */
1134 collapse_newdir
= 0;
1139 /* If we don't find a user of that name, leave the name
1140 unchanged; don't move nm forward to p. */
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
))
1158 /* Either nm starts with /, or drive isn't mounted. */
1159 newdir
= alloca (4);
1160 newdir
[0] = DRIVE_LETTER (drive
);
1168 /* Finally, if no prefix has been specified and nm is not absolute,
1169 then it must be expanded relative to default_directory. */
1173 /* /... alone is not absolute on DOS and Windows. */
1174 && !IS_DIRECTORY_SEP (nm
[0])
1177 && !(IS_DIRECTORY_SEP (nm
[0]) && IS_DIRECTORY_SEP (nm
[1]))
1184 newdir
= XSTRING (default_directory
)->data
;
1190 /* First ensure newdir is an absolute name. */
1192 /* Detect MSDOS file names with drive specifiers. */
1193 ! (IS_DRIVE (newdir
[0])
1194 && IS_DEVICE_SEP (newdir
[1]) && IS_DIRECTORY_SEP (newdir
[2]))
1196 /* Detect Windows file names in UNC format. */
1197 && ! (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
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] == ':')
1212 if (!IS_DIRECTORY_SEP (nm
[0]))
1214 char * tmp
= alloca (strlen (newdir
) + strlen (nm
) + 2);
1215 file_name_as_directory (tmp
, newdir
);
1219 newdir
= alloca (MAXPATHLEN
+ 1);
1222 if (!getdefdir (toupper (drive
) - 'A' + 1, newdir
))
1229 /* Strip off drive name from prefix, if present. */
1230 if (IS_DRIVE (newdir
[0]) && newdir
[1] == ':')
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
)
1241 if (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
1243 newdir
= strcpy (alloca (strlen (newdir
) + 1), newdir
);
1245 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
1247 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
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])
1264 && !(length
== 2 && IS_DIRECTORY_SEP (newdir
[0]))
1268 unsigned char *temp
= (unsigned char *) alloca (length
);
1269 bcopy (newdir
, temp
, length
- 1);
1270 temp
[length
- 1] = 0;
1278 /* Now concatenate the directory and name to new space in the stack frame */
1279 tlen
+= strlen (nm
) + 1;
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);
1285 #else /* not DOS_NT */
1286 target
= (unsigned char *) alloca (tlen
);
1287 #endif /* not DOS_NT */
1293 if (nm
[0] == 0 || IS_DIRECTORY_SEP (nm
[0]))
1294 strcpy (target
, newdir
);
1297 file_name_as_directory (target
, newdir
);
1300 strcat (target
, nm
);
1302 if (index (target
, '/'))
1303 strcpy (target
, sys_translate_unix (target
));
1306 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1308 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1316 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1322 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1323 /* brackets are offset from each other by 2 */
1326 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1327 /* convert [foo][bar] to [bar] */
1328 while (o
[-1] != '[' && o
[-1] != '<')
1330 else if (*p
== '-' && *o
!= '.')
1333 else if (p
[0] == '-' && o
[-1] == '.' &&
1334 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1335 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1339 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1340 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1342 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1344 /* else [foo.-] ==> [-] */
1350 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1351 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1357 if (!IS_DIRECTORY_SEP (*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 */
1366 #endif /* APOLLO || WINDOWSNT */
1372 else if (IS_DIRECTORY_SEP (p
[0])
1374 && (IS_DIRECTORY_SEP (p
[2])
1377 /* If "/." is the entire filename, keep the "/". Otherwise,
1378 just delete the whole "/.". */
1379 if (o
== target
&& p
[2] == '\0')
1383 else if (IS_DIRECTORY_SEP (p
[0]) && p
[1] == '.' && p
[2] == '.'
1384 /* `/../' is the "superroot" on certain file systems. */
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
))
1398 #endif /* not VMS */
1402 /* At last, set drive name. */
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 ();
1410 target
[0] = DRIVE_LETTER (drive
);
1413 CORRECT_DIR_SEPS (target
);
1416 return make_string (target
, o
- target
);
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'.")
1430 Lisp_Object name
, defalt
;
1434 register unsigned char *newdir
, *p
, *o
;
1436 unsigned char *target
;
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;
1448 CHECK_STRING (name
, 0);
1451 /* Filenames on VMS are always upper case. */
1452 name
= Fupcase (name
);
1455 nm
= XSTRING (name
)->data
;
1457 /* If nm is absolute, flush ...// and detect /./ and /../.
1458 If no /./ or /../ we can return right away. */
1470 if (p
[0] == '/' && p
[1] == '/'
1472 /* // at start of filename is meaningful on Apollo system */
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))))
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;
1498 /* VMS pre V4.4,convert '-'s in filenames. */
1499 if (lbrack
== rbrack
)
1501 if (dots
< 2) /* this is to allow negative version numbers */
1506 if (lbrack
> rbrack
&&
1507 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
1508 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
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] == '<'))
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: */
1532 /* If /name/dev:, move nm to dev: */
1535 /* If node::dev:, move colon following dev */
1536 else if (colon
&& colon
[-1] == ':')
1538 /* If dev1:dev2:, move nm to dev2: */
1539 else if (colon
&& colon
[-1] != ':')
1544 if (p
[0] == ':' && !colon
)
1550 if (lbrack
== rbrack
)
1553 else if (p
[0] == '.')
1561 if (index (nm
, '/'))
1562 return build_string (sys_translate_unix (nm
));
1564 if (nm
== XSTRING (name
)->data
)
1566 return build_string (nm
);
1570 /* Now determine directory to start with and put it in NEWDIR */
1574 if (nm
[0] == '~') /* prefix ~ */
1579 || nm
[1] == 0)/* ~/filename */
1581 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1582 newdir
= (unsigned char *) "";
1585 nm
++; /* Don't leave the slash in nm. */
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
);
1596 unsigned char *ptr1
= index (user
, ':');
1597 if (ptr1
!= 0 && ptr1
- user
< len
)
1600 /* Copy the user name into temp storage. */
1601 o
= (unsigned char *) alloca (len
+ 1);
1602 bcopy ((char *) user
, o
, len
);
1605 /* Look up the user name. */
1606 pw
= (struct passwd
*) getpwnam (o
+ 1);
1608 error ("\"%s\" isn't a registered user", o
+ 1);
1610 newdir
= (unsigned char *) pw
->pw_dir
;
1612 /* Discard the user name from NM. */
1619 #endif /* not VMS */
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
);
1637 if (nm
[0] == 0 || nm
[0] == '/')
1638 strcpy (target
, newdir
);
1641 file_name_as_directory (target
, newdir
);
1644 strcat (target
, nm
);
1646 if (index (target
, '/'))
1647 strcpy (target
, sys_translate_unix (target
));
1650 /* Now canonicalize by removing /. and /foo/.. if they appear */
1658 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1664 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1665 /* brackets are offset from each other by 2 */
1668 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1669 /* convert [foo][bar] to [bar] */
1670 while (o
[-1] != '[' && o
[-1] != '<')
1672 else if (*p
== '-' && *o
!= '.')
1675 else if (p
[0] == '-' && o
[-1] == '.' &&
1676 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1677 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1681 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1682 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1684 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1686 /* else [foo.-] ==> [-] */
1692 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1693 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1703 else if (!strncmp (p
, "//", 2)
1705 /* // at start of filename is meaningful in Apollo system */
1713 else if (p
[0] == '/' && p
[1] == '.' &&
1714 (p
[2] == '/' || p
[2] == 0))
1716 else if (!strncmp (p
, "/..", 3)
1717 /* `/../' is the "superroot" on certain file systems. */
1719 && (p
[3] == '/' || p
[3] == 0))
1721 while (o
!= target
&& *--o
!= '/')
1724 if (o
== target
+ 1 && o
[-1] == '/' && o
[0] == '/')
1728 if (o
== target
&& *o
== '/')
1736 #endif /* not VMS */
1739 return make_string (target
, o
- target
);
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.")
1754 Lisp_Object filename
;
1758 register unsigned char *s
, *p
, *o
, *x
, *endp
;
1759 unsigned char *target
;
1761 int substituted
= 0;
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
;
1775 nm
= strcpy (alloca (strlen (nm
) + 1), nm
);
1776 CORRECT_DIR_SEPS (nm
);
1777 substituted
= (strcmp (nm
, XSTRING (filename
)->data
) != 0);
1779 endp
= nm
+ XSTRING (filename
)->size
;
1781 /* If /~ or // appears, discard everything through first slash. */
1783 for (p
= nm
; p
!= endp
; p
++)
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) */
1797 || p
[-1] == ':' || p
[-1] == ']' || p
[-1] == '>'
1799 || IS_DIRECTORY_SEP (p
[-1])))
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]))
1816 return build_string (nm
);
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
;)
1832 /* "$$" means a single "$" */
1841 while (p
!= endp
&& *p
!= '}') p
++;
1842 if (*p
!= '}') goto missingclose
;
1848 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1852 /* Copy out the variable name */
1853 target
= (unsigned char *) alloca (s
- o
+ 1);
1854 strncpy (target
, o
, s
- o
);
1857 strupr (target
); /* $home == $HOME etc. */
1860 /* Get variable value */
1861 o
= (unsigned char *) egetenv (target
);
1862 if (!o
) goto badvar
;
1863 total
+= strlen (o
);
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);
1875 /* Copy the rest of the name through, replacing $ constructs with values */
1892 while (p
!= endp
&& *p
!= '}') p
++;
1893 if (*p
!= '}') goto missingclose
;
1899 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1903 /* Copy out the variable name */
1904 target
= (unsigned char *) alloca (s
- o
+ 1);
1905 strncpy (target
, o
, s
- o
);
1908 strupr (target
); /* $home == $HOME etc. */
1911 /* Get variable value */
1912 o
= (unsigned char *) egetenv (target
);
1922 /* If /~ or // appears, discard everything through first slash. */
1924 for (p
= xnm
; p
!= x
; p
++)
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]))
1935 else if (IS_DRIVE (p
[0]) && p
[1] == ':'
1936 && p
> nm
&& IS_DIRECTORY_SEP (p
[-1]))
1940 return make_string (xnm
, x
- xnm
);
1943 error ("Bad format environment-variable substitution");
1945 error ("Missing \"}\" in environment-variable substitution");
1947 error ("Substituting nonexistent environment variable \"%s\"", target
);
1950 #endif /* not VMS */
1953 /* A slightly faster and more convenient way to get
1954 (directory-file-name (expand-file-name FOO)). */
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
);
1965 register int c
= XSTRING (absname
)->data
[XSTRING (absname
)->size
- 1];
1966 if (c
== ':' || c
== ']' || c
== '>')
1967 absname
= Fdirectory_file_name (absname
);
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
);
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
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. */
1990 barf_or_query_if_file_exists (absname
, querystring
, interactive
, statptr
)
1991 Lisp_Object absname
;
1992 unsigned char *querystring
;
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)
2005 Fsignal (Qfile_already_exists
,
2006 Fcons (build_string ("File already exists"),
2007 Fcons (absname
, Qnil
)));
2009 tem
= do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
2010 XSTRING (absname
)->data
, querystring
));
2013 Fsignal (Qfile_already_exists
,
2014 Fcons (build_string ("File already exists"),
2015 Fcons (absname
, Qnil
)));
2022 statptr
->st_mode
= 0;
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
;
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. */
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)
2071 ifd
= open (XSTRING (file
)->data
, O_RDONLY
);
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
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
)
2086 report_file_error ("Input and output files are the same",
2087 Fcons (file
, Fcons (newname
, Qnil
)));
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. */
2100 report_file_error ("Non-regular file", Fcons (file
, Qnil
));
2103 #endif /* S_ISREG && S_ISLNK */
2106 /* Create the copy file with the same record format as the input file */
2107 ofd
= sys_creat (XSTRING (newname
)->data
, 0666, ifd
);
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 */
2117 report_file_error ("Opening output file", Fcons (newname
, Qnil
));
2119 record_unwind_protect (close_file_unwind
, make_number (ofd
));
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
));
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
));
2143 chmod (XSTRING (newname
)->data
, st
.st_mode
& 07777);
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 */
2158 /* Discard the unwind protects. */
2159 specpdl_ptr
= specpdl
+ count
;
2165 DEFUN ("make-directory-internal", Fmake_directory_internal
,
2166 Smake_directory_internal
, 1, 1, 0,
2167 "Create a new directory named DIRECTORY.")
2169 Lisp_Object directory
;
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
;
2184 if (mkdir (dir
) != 0)
2186 if (mkdir (dir
, 0777) != 0)
2188 report_file_error ("Creating directory", Flist (1, &directory
));
2193 DEFUN ("delete-directory", Fdelete_directory
, Sdelete_directory
, 1, 1, "FDelete directory: ",
2194 "Delete the directory named DIRECTORY.")
2196 Lisp_Object directory
;
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
));
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.")
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
));
2235 internal_delete_file_1 (ignore
)
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
;
2263 Lisp_Object args
[2];
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
);
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);
2288 if (0 > rename (XSTRING (file
)->data
, XSTRING (newname
)->data
))
2290 if (0 > link (XSTRING (file
)->data
, XSTRING (newname
)->data
)
2291 || 0 > unlink (XSTRING (file
)->data
))
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
);
2307 report_file_error ("Renaming", Flist (2, args
));
2310 report_file_error ("Renaming", Flist (2, &file
));
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
;
2328 Lisp_Object args
[2];
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);
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
))
2368 report_file_error ("Adding new name", Flist (2, args
));
2370 report_file_error ("Adding new name", Flist (2, &file
));
2373 #endif /* not WINDOWSNT */
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
;
2391 Lisp_Object args
[2];
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
))
2440 report_file_error ("Making symbolic link", Flist (2, args
));
2442 report_file_error ("Making symbolic link", Flist (2, &filename
));
2448 #endif /* S_IFLNK */
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.")
2460 CHECK_STRING (name
, 0);
2462 delete_logical_name (XSTRING (name
)->data
);
2465 CHECK_STRING (string
, 1);
2467 if (XSTRING (string
)->size
== 0)
2468 delete_logical_name (XSTRING (name
)->data
);
2470 define_logical_name (XSTRING (name
)->data
, XSTRING (string
)->data
);
2479 DEFUN ("sysnetunam", Fsysnetunam
, Ssysnetunam
, 2, 2, 0,
2480 "Open a network connection to PATH using LOGIN as the login string.")
2482 Lisp_Object path
, login
;
2486 CHECK_STRING (path
, 0);
2487 CHECK_STRING (login
, 0);
2489 netresult
= netunam (XSTRING (path
)->data
, XSTRING (login
)->data
);
2491 if (netresult
== -1)
2496 #endif /* HPUX_NET */
2498 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p
, Sfile_name_absolute_p
,
2500 "Return t if file FILENAME specifies an absolute file name.\n\
2501 On Unix, this is a name starting with a `/' or a `~'.")
2503 Lisp_Object filename
;
2507 CHECK_STRING (filename
, 0);
2508 ptr
= XSTRING (filename
)->data
;
2509 if (IS_DIRECTORY_SEP (*ptr
) || *ptr
== '~'
2511 /* ??? This criterion is probably wrong for '<'. */
2512 || index (ptr
, ':') || index (ptr
, '<')
2513 || (*ptr
== '[' && (ptr
[1] != '-' || (ptr
[2] != '.' && ptr
[2] != ']'))
2517 || (IS_DRIVE (*ptr
) && ptr
[1] == ':' && IS_DIRECTORY_SEP (ptr
[2]))
2525 /* Return nonzero if file FILENAME exists and can be executed. */
2528 check_executable (filename
)
2532 int len
= strlen (filename
);
2535 if (stat (filename
, &st
) < 0)
2537 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2538 return ((st
.st_mode
& S_IEXEC
) != 0);
2540 return (S_ISREG (st
.st_mode
)
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);
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);
2556 #endif /* not DOS_NT */
2559 /* Return nonzero if file FILENAME exists and can be written. */
2562 check_writable (filename
)
2567 if (stat (filename
, &st
) < 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);
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);
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'.")
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.")
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'.")
2632 Lisp_Object filename
;
2634 Lisp_Object absname
;
2635 Lisp_Object handler
;
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
);
2648 /* Under MS-DOS and Windows, open does not work for directories. */
2649 if (access (XSTRING (absname
)->data
, 0) == 0)
2652 #else /* not DOS_NT */
2653 desc
= open (XSTRING (absname
)->data
, O_RDONLY
);
2658 #endif /* not DOS_NT */
2661 /* Having this before file-symlink-p mysteriously caused it to be forgotten
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.")
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
)
2684 dir
= Ffile_name_directory (absname
);
2687 dir
= Fdirectory_file_name (dir
);
2691 dir
= Fdirectory_file_name (dir
);
2693 return (check_writable (!NILP (dir
) ? (char *) XSTRING (dir
)->data
: "")
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.")
2702 Lisp_Object filename
;
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
);
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 */
2736 val
= make_string (buf
, valsize
);
2739 #else /* not S_IFLNK */
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.")
2749 Lisp_Object filename
;
2751 register Lisp_Object absname
;
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)
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.")
2776 Lisp_Object filename
;
2778 Lisp_Object handler
;
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. */
2795 tem
= (NILP (Ffile_directory_p (filename
))
2796 || NILP (Ffile_executable_p (filename
)));
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.")
2805 Lisp_Object filename
;
2807 register Lisp_Object absname
;
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)
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.")
2827 Lisp_Object filename
;
2829 Lisp_Object absname
;
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)
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.")
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
));
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.")
2882 CHECK_NUMBER (mode
, 0);
2884 umask ((~ XINT (mode
)) & 0777);
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.")
2897 realmask
= umask (0);
2900 XSETINT (value
, (~ realmask
) & 0777);
2906 DEFUN ("unix-sync", Funix_sync
, Sunix_sync
, 0, 0, "",
2907 "Tell Unix to finish all pending disk updates.")
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.")
2921 Lisp_Object file1
, file2
;
2923 Lisp_Object absname1
, absname2
;
2926 Lisp_Object handler
;
2927 struct gcpro gcpro1
, gcpro2
;
2929 CHECK_STRING (file1
, 0);
2930 CHECK_STRING (file2
, 0);
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
);
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
);
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)
2949 mtime1
= st
.st_mtime
;
2951 if (stat (XSTRING (absname2
)->data
, &st
) < 0)
2954 return (mtime1
> st
.st_mtime
) ? Qt
: Qnil
;
2958 Lisp_Object Qfind_buffer_file_type
;
2961 DEFUN ("insert-file-contents", Finsert_file_contents
, Sinsert_file_contents
,
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
;
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
;
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 ();
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
);
3018 if (stat (XSTRING (filename
)->data
, &st
) < 0)
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
);
3027 report_file_error ("Opening input file", Fcons (filename
, Qnil
));
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
))
3040 Fsignal (Qfile_error
,
3041 Fcons (build_string ("not a regular file"),
3042 Fcons (filename
, Qnil
)));
3050 if ((fd
= open (XSTRING (filename
)->data
, O_RDONLY
)) < 0)
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. */
3061 error ("File size is negative");
3063 if (!NILP (beg
) || !NILP (end
))
3065 error ("Attempt to visit less than an entire file");
3068 CHECK_NUMBER (beg
, 0);
3070 XSETFASTINT (beg
, 0);
3073 CHECK_NUMBER (end
, 0);
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. */
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
))
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
;
3105 /* Count how many chars at the start of the file
3106 match the text at the beginning of the buffer. */
3111 nread
= read (fd
, buffer
, sizeof buffer
);
3113 error ("IO error reading %s: %s",
3114 XSTRING (filename
)->data
, strerror (errno
));
3115 else if (nread
== 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
)
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
)
3133 /* Truncate the buffer to the size of the file. */
3134 del_range_1 (same_at_start
, same_at_end
, 0);
3139 /* Count how many chars at the end of the file
3140 match the text at the end of the buffer. */
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. */
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
));
3157 while (total_read
< trial
)
3159 nread
= read (fd
, buffer
+ total_read
, trial
- total_read
);
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. */
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 ();
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
);
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
);
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
));
3224 while (inserted
< total
)
3226 /* try is reserved in some compilers (Microsoft C) */
3227 int trytry
= min (total
- inserted
, 64 << 10);
3230 /* Allow quitting out of the actual I/O. */
3233 this = read (fd
, &FETCH_CHAR (point
+ inserted
- 1) + 1, trytry
);
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
))
3259 = inserted
- crlf_to_lf (inserted
, &FETCH_CHAR (point
- 1) + 1);
3262 GPT
-= reduced_size
;
3263 GAP_SIZE
+= reduced_size
;
3264 inserted
-= reduced_size
;
3271 record_insert (point
, inserted
);
3273 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
3274 offset_intervals (current_buffer
, point
, inserted
);
3280 /* Discard the unwind protect for closing the file. */
3284 error ("IO error reading %s: %s",
3285 XSTRING (filename
)->data
, strerror (errno
));
3292 if (!EQ (current_buffer
->undo_list
, Qt
))
3293 current_buffer
->undo_list
= Qnil
;
3295 stat (XSTRING (filename
)->data
, &st
);
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
3310 if (!NILP (current_buffer
->file_truename
))
3311 unlock_file (current_buffer
->file_truename
);
3312 unlock_file (filename
);
3314 #endif /* CLASH_DETECTION */
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 */
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
);
3339 p
= Vafter_insert_file_functions
;
3342 insval
= call1 (Fcar (p
), make_number (inserted
));
3345 CHECK_NUMBER (insval
, 0);
3346 inserted
= XFASTINT (insval
);
3354 val
= Fcons (filename
,
3355 Fcons (make_number (inserted
),
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. */
3367 build_annotations_unwind (buf
)
3372 if (XBUFFER (buf
) == current_buffer
)
3374 tembuf
= Fcurrent_buffer ();
3376 Fkill_buffer (tembuf
);
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
;
3408 int count
= specpdl_ptr
- specpdl
;
3411 unsigned char *fname
= 0; /* If non-0, original filename (must rename) */
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
;
3420 int buffer_file_type
3421 = NILP (current_buffer
->buffer_file_type
) ? O_TEXT
: O_BINARY
;
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
);
3435 visit_file
= filename
;
3438 visiting
= (EQ (visit
, Qt
) || STRINGP (visit
));
3439 quietly
= !NILP (visit
);
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
))
3458 val
= call6 (handler
, Qwrite_region
, start
, end
,
3459 filename
, append
, visit
);
3463 SAVE_MODIFF
= MODIFF
;
3464 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3465 current_buffer
->filename
= visit_file
;
3471 /* Special kludge to simplify auto-saving. */
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
)
3489 #ifdef CLASH_DETECTION
3491 lock_file (lockname
);
3492 #endif /* CLASH_DETECTION */
3494 fn
= XSTRING (filename
)->data
;
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 */
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
);
3510 desc
= creat_copy_attrs (STRINGP (current_buffer
->filename
)
3511 ? XSTRING (current_buffer
->filename
)->data
: 0,
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
);
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. */
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. */
3538 /* We can't make a new version;
3539 try to truncate and rewrite existing version if any. */
3541 desc
= open (fn
, O_RDWR
);
3547 desc
= creat (fn
, 0666);
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 */
3563 #ifdef CLASH_DETECTION
3565 if (!auto_saving
) unlock_file (lockname
);
3567 #endif /* CLASH_DETECTION */
3568 report_file_error ("Opening output file", Fcons (filename
, Qnil
));
3571 record_unwind_protect (close_file_unwind
, make_number (desc
));
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
));
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).
3598 if (GPT
> BEG
&& GPT_ADDR
[-1] != '\n')
3599 move_gap (find_next_newline (GPT
, 1));
3605 if (STRINGP (start
))
3607 failure
= 0 > a_write (desc
, XSTRING (start
)->data
,
3608 XSTRING (start
)->size
, 0, &annotations
);
3611 else if (XINT (start
) != XINT (end
))
3614 if (XINT (start
) < GPT
)
3616 register int end1
= XINT (end
);
3618 failure
= 0 > a_write (desc
, &FETCH_CHAR (tem
),
3619 min (GPT
, end1
) - tem
, tem
, &annotations
);
3620 nwritten
+= min (GPT
, end1
) - tem
;
3624 if (XINT (end
) > GPT
&& !failure
)
3627 tem
= max (tem
, GPT
);
3628 failure
= 0 > a_write (desc
, &FETCH_CHAR (tem
), XINT (end
) - tem
,
3630 nwritten
+= XINT (end
) - tem
;
3636 /* If file was empty, still need to write the annotations */
3637 failure
= 0 > a_write (desc
, "", 0, XINT (start
), &annotations
);
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. */
3652 failure
= 1, save_errno
= errno
;
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?) */
3664 /* On VMS and APOLLO, must do the stat after the close
3665 since closing changes the modtime. */
3668 /* Recall that #if defined does not work on VMS. */
3675 /* NFS can report a write failure now. */
3676 if (close (desc
) < 0)
3677 failure
= 1, save_errno
= errno
;
3680 /* If we wrote to a temporary name and had no errors, rename to real name. */
3684 failure
= (rename (fn
, fname
) != 0), save_errno
= errno
;
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
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. */
3706 current_buffer
->modtime
= st
.st_mtime
;
3709 error ("IO error writing %s: %s", fn
, strerror (save_errno
));
3713 SAVE_MODIFF
= MODIFF
;
3714 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3715 current_buffer
->filename
= visit_file
;
3716 update_mode_lines
++;
3722 message ("Wrote %s", XSTRING (visit_file
)->data
);
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).")
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. */
3746 build_annotations (start
, end
)
3747 Lisp_Object start
, end
;
3749 Lisp_Object annotations
;
3751 struct gcpro gcpro1
, gcpro2
;
3754 p
= Vwrite_region_annotate_functions
;
3755 GCPRO2 (annotations
, 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
)
3772 Flength (res
); /* Check basic validity of return value */
3773 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
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
;
3781 p
= current_buffer
->file_format
;
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
)
3794 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
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
)
3813 register char *addr
;
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
);
3828 return e_write (desc
, addr
, lastpos
- pos
);
3831 if (0 > e_write (desc
, addr
, nextpos
- pos
))
3833 addr
+= nextpos
- pos
;
3836 tem
= Fcdr (Fcar (*annot
));
3839 if (0 > e_write (desc
, XSTRING (tem
)->data
, XSTRING (tem
)->size
))
3842 *annot
= Fcdr (*annot
);
3847 e_write (desc
, addr
, len
)
3849 register char *addr
;
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
;
3860 end
= p
+ sizeof buf
;
3865 if (write (desc
, buf
, sizeof buf
) != sizeof buf
)
3874 if (write (desc
, buf
, p
- buf
) != p
- buf
)
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.")
3889 Lisp_Object handler
;
3891 CHECK_BUFFER (buf
, 0);
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
)
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)))
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;
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).")
3951 Lisp_Object time_list
;
3953 if (!NILP (time_list
))
3954 current_buffer
->modtime
= cons_to_long (time_list
);
3957 register Lisp_Object filename
;
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
;
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
);
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;
4000 auto_save_mode_bits
= 0666;
4003 Fwrite_region (Qnil
, Qnil
,
4004 current_buffer
->auto_save_file_name
,
4005 Qnil
, Qlambda
, Qnil
);
4009 do_auto_save_unwind (desc
) /* used as unwind-protect function */
4013 if (XINT (desc
) >= 0)
4014 close (XINT (desc
));
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
;
4034 char *omessage
= echo_area_glyphs
;
4035 int omessage_length
= echo_area_glyphs_length
;
4036 extern int minibuf_level
;
4037 int do_handled_files
;
4040 int count
= specpdl_ptr
- specpdl
;
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). */
4048 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4049 point to non-strings reached from Vbuffer_alist. */
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
);
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 */
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
));
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
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
;
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
)
4110 /* Don't auto-save indirect buffers.
4111 The base buffer takes care of it. */
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
,
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)
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
);
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
);
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
))
4179 sit_for (1, 0, 0, 0);
4180 message2 (omessage
, omessage_length
);
4183 message1 ("Auto-saving...done");
4188 unbind_to (count
, 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;
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;
4213 DEFUN ("recent-auto-save-p", Frecent_auto_save_p
, Srecent_auto_save_p
,
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. */
4227 double_dollars (val
)
4230 register unsigned char *old
, *new;
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
++;
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
--)
4256 DEFUN ("read-file-name-internal", Fread_file_name_internal
, Sread_file_name_internal
,
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
;
4266 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
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
))
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
);
4292 realdir
= Fexpand_file_name (val
, realdir
);
4297 specdir
= Ffile_name_directory (string
);
4298 val
= Ffile_name_completion (name
, realdir
);
4303 return double_dollars (string
);
4307 if (!NILP (specdir
))
4308 val
= concat2 (specdir
, val
);
4310 return double_dollars (val
);
4313 #endif /* not VMS */
4317 if (EQ (action
, Qt
))
4318 return Ffile_name_all_completions (name
, realdir
);
4319 /* Only other case actually used is ACTION = lambda */
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)
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
;
4348 dir
= current_buffer
->directory
;
4349 if (NILP (default_filename
))
4351 if (! NILP (initial
))
4352 default_filename
= Fexpand_file_name (initial
, dir
);
4354 default_filename
= current_buffer
->filename
;
4357 /* If dir starts with user's homedir, change that to ~. */
4358 homedir
= (char *) egetenv ("HOME");
4360 homedir
= strcpy (alloca (strlen (homedir
) + 1), homedir
);
4361 CORRECT_DIR_SEPS (homedir
);
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
)
4376 if (!NILP (initial
))
4378 Lisp_Object args
[2], pos
;
4382 insdef
= Fconcat (2, args
);
4383 pos
= make_number (XSTRING (double_dollars (dir
))->size
);
4384 insdef1
= Fcons (double_dollars (insdef
), pos
);
4387 insdef1
= double_dollars (insdef
);
4389 else if (!NILP (initial
))
4392 insdef1
= Fcons (double_dollars (insdef
), 0);
4395 insdef
= Qnil
, insdef1
= Qnil
;
4398 count
= specpdl_ptr
- specpdl
;
4399 specbind (intern ("completion-ignore-case"), Qt
);
4402 GCPRO2 (insdef
, default_filename
);
4403 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4404 dir
, mustmatch
, insdef1
,
4405 Qfile_name_history
);
4408 unbind_to (count
, Qnil
);
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
;
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
;
4441 dir
= current_buffer
->directory
;
4443 defalt
= current_buffer
->filename
;
4445 /* If dir starts with user's homedir, change that to ~. */
4446 homedir
= (char *) egetenv ("HOME");
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
))
4459 else if (insert_default_directory
)
4462 insdef
= build_string ("");
4465 count
= specpdl_ptr
- specpdl
;
4466 specbind (intern ("completion-ignore-case"), Qt
);
4469 GCPRO2 (insdef
, defalt
);
4470 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4472 insert_default_directory
? insdef
: Qnil
,
4473 Qfile_name_history
);
4476 unbind_to (count
, Qnil
);
4481 error ("No file name specified");
4482 tem
= Fstring_equal (val
, insdef
);
4483 if (!NILP (tem
) && !NILP (defalt
))
4485 return Fsubstitute_in_file_name (val
);
4487 #endif /* Old version */
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
);
4560 Qfind_buffer_file_type
= intern ("find-buffer-file-type");
4561 staticpro (&Qfind_buffer_file_type
);
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\
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\
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
);
4681 defsubr (&Smake_symbolic_link
);
4682 #endif /* S_IFLNK */
4684 defsubr (&Sdefine_logical_name
);
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
);
4719 defsubr (&Sunix_sync
);