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 #if defined (USG5) || defined (BSD_SYSTEM) || defined (LINUX)
27 #include <sys/types.h>
34 #if !defined (S_ISLNK) && defined (S_IFLNK)
35 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
38 #if !defined (S_ISFIFO) && defined (S_IFIFO)
39 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
42 #if !defined (S_ISREG) && defined (S_IFREG)
43 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
54 #include <sys/param.h>
76 extern char *strerror ();
93 #include "intervals.h"
104 #endif /* not WINDOWSNT */
107 #define CORRECT_DIR_SEPS(s) \
108 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
109 else unixtodos_filename (s); \
111 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
112 redirector allows the six letters between 'Z' and 'a' as well. */
114 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
117 #define IS_DRIVE(x) isalpha (x)
119 /* Need to lower-case the drive letter, or else expanded
120 filenames will sometimes compare inequal, because
121 `expand-file-name' doesn't always down-case the drive letter. */
122 #define DRIVE_LETTER(x) (tolower (x))
151 #define min(a, b) ((a) < (b) ? (a) : (b))
152 #define max(a, b) ((a) > (b) ? (a) : (b))
154 /* Nonzero during writing of auto-save files */
157 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
158 a new file with the same mode as the original */
159 int auto_save_mode_bits
;
161 /* Alist of elements (REGEXP . HANDLER) for file names
162 whose I/O is done with a special handler. */
163 Lisp_Object Vfile_name_handler_alist
;
165 /* Format for auto-save files */
166 Lisp_Object Vauto_save_file_format
;
168 /* Lisp functions for translating file formats */
169 Lisp_Object Qformat_decode
, Qformat_annotate_function
;
171 /* Functions to be called to process text properties in inserted file. */
172 Lisp_Object Vafter_insert_file_functions
;
174 /* Functions to be called to create text property annotations for file. */
175 Lisp_Object Vwrite_region_annotate_functions
;
177 /* During build_annotations, each time an annotation function is called,
178 this holds the annotations made by the previous functions. */
179 Lisp_Object Vwrite_region_annotations_so_far
;
181 /* File name in which we write a list of all our auto save files. */
182 Lisp_Object Vauto_save_list_file_name
;
184 /* Nonzero means, when reading a filename in the minibuffer,
185 start out by inserting the default directory into the minibuffer. */
186 int insert_default_directory
;
188 /* On VMS, nonzero means write new files with record format stmlf.
189 Zero means use var format. */
192 /* On NT, specifies the directory separator character, used (eg.) when
193 expanding file names. This can be bound to / or \. */
194 Lisp_Object Vdirectory_sep_char
;
196 extern Lisp_Object Vuser_login_name
;
198 extern int minibuf_level
;
200 /* These variables describe handlers that have "already" had a chance
201 to handle the current operation.
203 Vinhibit_file_name_handlers is a list of file name handlers.
204 Vinhibit_file_name_operation is the operation being handled.
205 If we try to handle that operation, we ignore those handlers. */
207 static Lisp_Object Vinhibit_file_name_handlers
;
208 static Lisp_Object Vinhibit_file_name_operation
;
210 Lisp_Object Qfile_error
, Qfile_already_exists
, Qfile_date_error
;
212 Lisp_Object Qfile_name_history
;
214 Lisp_Object Qcar_less_than_car
;
216 report_file_error (string
, data
)
220 Lisp_Object errstring
;
222 errstring
= build_string (strerror (errno
));
224 /* System error messages are capitalized. Downcase the initial
225 unless it is followed by a slash. */
226 if (XSTRING (errstring
)->data
[1] != '/')
227 XSTRING (errstring
)->data
[0] = DOWNCASE (XSTRING (errstring
)->data
[0]);
230 Fsignal (Qfile_error
,
231 Fcons (build_string (string
), Fcons (errstring
, data
)));
234 close_file_unwind (fd
)
237 close (XFASTINT (fd
));
240 /* Restore point, having saved it as a marker. */
242 restore_point_unwind (location
)
243 Lisp_Object location
;
245 SET_PT (marker_position (location
));
246 Fset_marker (location
, Qnil
, Qnil
);
249 Lisp_Object Qexpand_file_name
;
250 Lisp_Object Qsubstitute_in_file_name
;
251 Lisp_Object Qdirectory_file_name
;
252 Lisp_Object Qfile_name_directory
;
253 Lisp_Object Qfile_name_nondirectory
;
254 Lisp_Object Qunhandled_file_name_directory
;
255 Lisp_Object Qfile_name_as_directory
;
256 Lisp_Object Qcopy_file
;
257 Lisp_Object Qmake_directory_internal
;
258 Lisp_Object Qdelete_directory
;
259 Lisp_Object Qdelete_file
;
260 Lisp_Object Qrename_file
;
261 Lisp_Object Qadd_name_to_file
;
262 Lisp_Object Qmake_symbolic_link
;
263 Lisp_Object Qfile_exists_p
;
264 Lisp_Object Qfile_executable_p
;
265 Lisp_Object Qfile_readable_p
;
266 Lisp_Object Qfile_writable_p
;
267 Lisp_Object Qfile_symlink_p
;
268 Lisp_Object Qaccess_file
;
269 Lisp_Object Qfile_directory_p
;
270 Lisp_Object Qfile_regular_p
;
271 Lisp_Object Qfile_accessible_directory_p
;
272 Lisp_Object Qfile_modes
;
273 Lisp_Object Qset_file_modes
;
274 Lisp_Object Qfile_newer_than_file_p
;
275 Lisp_Object Qinsert_file_contents
;
276 Lisp_Object Qwrite_region
;
277 Lisp_Object Qverify_visited_file_modtime
;
278 Lisp_Object Qset_visited_file_modtime
;
280 DEFUN ("find-file-name-handler", Ffind_file_name_handler
, Sfind_file_name_handler
, 2, 2, 0,
281 "Return FILENAME's handler function for OPERATION, if it has one.\n\
282 Otherwise, return nil.\n\
283 A file name is handled if one of the regular expressions in\n\
284 `file-name-handler-alist' matches it.\n\n\
285 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
286 any handlers that are members of `inhibit-file-name-handlers',\n\
287 but we still do run any other handlers. This lets handlers\n\
288 use the standard functions without calling themselves recursively.")
289 (filename
, operation
)
290 Lisp_Object filename
, operation
;
292 /* This function must not munge the match data. */
293 Lisp_Object chain
, inhibited_handlers
;
295 CHECK_STRING (filename
, 0);
297 if (EQ (operation
, Vinhibit_file_name_operation
))
298 inhibited_handlers
= Vinhibit_file_name_handlers
;
300 inhibited_handlers
= Qnil
;
302 for (chain
= Vfile_name_handler_alist
; CONSP (chain
);
303 chain
= XCONS (chain
)->cdr
)
306 elt
= XCONS (chain
)->car
;
310 string
= XCONS (elt
)->car
;
311 if (STRINGP (string
) && fast_string_match (string
, filename
) >= 0)
313 Lisp_Object handler
, tem
;
315 handler
= XCONS (elt
)->cdr
;
316 tem
= Fmemq (handler
, inhibited_handlers
);
327 DEFUN ("file-name-directory", Ffile_name_directory
, Sfile_name_directory
,
329 "Return the directory component in file name FILENAME.\n\
330 Return nil if FILENAME does not include a directory.\n\
331 Otherwise return a directory spec.\n\
332 Given a Unix syntax file name, returns a string ending in slash;\n\
333 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
335 Lisp_Object filename
;
337 register unsigned char *beg
;
338 register unsigned char *p
;
341 CHECK_STRING (filename
, 0);
343 /* If the file name has special constructs in it,
344 call the corresponding file handler. */
345 handler
= Ffind_file_name_handler (filename
, Qfile_name_directory
);
347 return call2 (handler
, Qfile_name_directory
, filename
);
349 #ifdef FILE_SYSTEM_CASE
350 filename
= FILE_SYSTEM_CASE (filename
);
352 beg
= XSTRING (filename
)->data
;
354 beg
= strcpy (alloca (strlen (beg
) + 1), beg
);
356 p
= beg
+ XSTRING (filename
)->size
;
358 while (p
!= beg
&& !IS_DIRECTORY_SEP (p
[-1])
360 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
363 /* only recognise drive specifier at beginning */
364 && !(p
[-1] == ':' && p
== beg
+ 2)
371 /* Expansion of "c:" to drive and default directory. */
372 if (p
== beg
+ 2 && beg
[1] == ':')
374 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
375 unsigned char *res
= alloca (MAXPATHLEN
+ 1);
376 if (getdefdir (toupper (*beg
) - 'A' + 1, res
))
378 if (!IS_DIRECTORY_SEP (res
[strlen (res
) - 1]))
381 p
= beg
+ strlen (beg
);
384 CORRECT_DIR_SEPS (beg
);
386 return make_string (beg
, p
- beg
);
389 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory
, Sfile_name_nondirectory
,
391 "Return file name FILENAME sans its directory.\n\
392 For example, in a Unix-syntax file name,\n\
393 this is everything after the last slash,\n\
394 or the entire name if it contains no slash.")
396 Lisp_Object filename
;
398 register unsigned char *beg
, *p
, *end
;
401 CHECK_STRING (filename
, 0);
403 /* If the file name has special constructs in it,
404 call the corresponding file handler. */
405 handler
= Ffind_file_name_handler (filename
, Qfile_name_nondirectory
);
407 return call2 (handler
, Qfile_name_nondirectory
, filename
);
409 beg
= XSTRING (filename
)->data
;
410 end
= p
= beg
+ XSTRING (filename
)->size
;
412 while (p
!= beg
&& !IS_DIRECTORY_SEP (p
[-1])
414 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
417 /* only recognise drive specifier at beginning */
418 && !(p
[-1] == ':' && p
== beg
+ 2)
422 return make_string (p
, end
- p
);
425 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory
, Sunhandled_file_name_directory
, 1, 1, 0,
426 "Return a directly usable directory name somehow associated with FILENAME.\n\
427 A `directly usable' directory name is one that may be used without the\n\
428 intervention of any file handler.\n\
429 If FILENAME is a directly usable file itself, return\n\
430 (file-name-directory FILENAME).\n\
431 The `call-process' and `start-process' functions use this function to\n\
432 get a current directory to run processes in.")
434 Lisp_Object filename
;
438 /* If the file name has special constructs in it,
439 call the corresponding file handler. */
440 handler
= Ffind_file_name_handler (filename
, Qunhandled_file_name_directory
);
442 return call2 (handler
, Qunhandled_file_name_directory
, filename
);
444 return Ffile_name_directory (filename
);
449 file_name_as_directory (out
, in
)
452 int size
= strlen (in
) - 1;
457 /* Is it already a directory string? */
458 if (in
[size
] == ':' || in
[size
] == ']' || in
[size
] == '>')
460 /* Is it a VMS directory file name? If so, hack VMS syntax. */
461 else if (! index (in
, '/')
462 && ((size
> 3 && ! strcmp (&in
[size
- 3], ".DIR"))
463 || (size
> 3 && ! strcmp (&in
[size
- 3], ".dir"))
464 || (size
> 5 && (! strncmp (&in
[size
- 5], ".DIR", 4)
465 || ! strncmp (&in
[size
- 5], ".dir", 4))
466 && (in
[size
- 1] == '.' || in
[size
- 1] == ';')
467 && in
[size
] == '1')))
469 register char *p
, *dot
;
473 dir:x.dir --> dir:[x]
474 dir:[x]y.dir --> dir:[x.y] */
476 while (p
!= in
&& *p
!= ':' && *p
!= '>' && *p
!= ']') p
--;
479 strncpy (out
, in
, p
- in
);
498 dot
= index (p
, '.');
501 /* blindly remove any extension */
502 size
= strlen (out
) + (dot
- p
);
503 strncat (out
, p
, dot
- p
);
514 /* For Unix syntax, Append a slash if necessary */
515 if (!IS_DIRECTORY_SEP (out
[size
]))
517 out
[size
+ 1] = DIRECTORY_SEP
;
518 out
[size
+ 2] = '\0';
521 CORRECT_DIR_SEPS (out
);
527 DEFUN ("file-name-as-directory", Ffile_name_as_directory
,
528 Sfile_name_as_directory
, 1, 1, 0,
529 "Return a string representing file FILENAME interpreted as a directory.\n\
530 This operation exists because a directory is also a file, but its name as\n\
531 a directory is different from its name as a file.\n\
532 The result can be used as the value of `default-directory'\n\
533 or passed as second argument to `expand-file-name'.\n\
534 For a Unix-syntax file name, just appends a slash.\n\
535 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
542 CHECK_STRING (file
, 0);
546 /* If the file name has special constructs in it,
547 call the corresponding file handler. */
548 handler
= Ffind_file_name_handler (file
, Qfile_name_as_directory
);
550 return call2 (handler
, Qfile_name_as_directory
, file
);
552 buf
= (char *) alloca (XSTRING (file
)->size
+ 10);
553 return build_string (file_name_as_directory (buf
, XSTRING (file
)->data
));
557 * Convert from directory name to filename.
559 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
560 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
561 * On UNIX, it's simple: just make sure there isn't a terminating /
563 * Value is nonzero if the string output is different from the input.
566 directory_file_name (src
, dst
)
574 struct FAB fab
= cc$rms_fab
;
575 struct NAM nam
= cc$rms_nam
;
576 char esa
[NAM$C_MAXRSS
];
581 if (! index (src
, '/')
582 && (src
[slen
- 1] == ']'
583 || src
[slen
- 1] == ':'
584 || src
[slen
- 1] == '>'))
586 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
588 fab
.fab$b_fns
= slen
;
589 fab
.fab$l_nam
= &nam
;
590 fab
.fab$l_fop
= FAB$M_NAM
;
593 nam
.nam$b_ess
= sizeof esa
;
594 nam
.nam$b_nop
|= NAM$M_SYNCHK
;
596 /* We call SYS$PARSE to handle such things as [--] for us. */
597 if (SYS$
PARSE (&fab
, 0, 0) == RMS$_NORMAL
)
599 slen
= nam
.nam$b_esl
;
600 if (esa
[slen
- 1] == ';' && esa
[slen
- 2] == '.')
605 if (src
[slen
- 1] != ']' && src
[slen
- 1] != '>')
607 /* what about when we have logical_name:???? */
608 if (src
[slen
- 1] == ':')
609 { /* Xlate logical name and see what we get */
610 ptr
= strcpy (dst
, src
); /* upper case for getenv */
613 if ('a' <= *ptr
&& *ptr
<= 'z')
617 dst
[slen
- 1] = 0; /* remove colon */
618 if (!(src
= egetenv (dst
)))
620 /* should we jump to the beginning of this procedure?
621 Good points: allows us to use logical names that xlate
623 Bad points: can be a problem if we just translated to a device
625 For now, I'll punt and always expect VMS names, and hope for
628 if (src
[slen
- 1] != ']' && src
[slen
- 1] != '>')
629 { /* no recursion here! */
635 { /* not a directory spec */
640 bracket
= src
[slen
- 1];
642 /* If bracket is ']' or '>', bracket - 2 is the corresponding
644 ptr
= index (src
, bracket
- 2);
646 { /* no opening bracket */
650 if (!(rptr
= rindex (src
, '.')))
653 strncpy (dst
, src
, slen
);
657 dst
[slen
++] = bracket
;
662 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
663 then translate the device and recurse. */
664 if (dst
[slen
- 1] == ':'
665 && dst
[slen
- 2] != ':' /* skip decnet nodes */
666 && strcmp (src
+ slen
, "[000000]") == 0)
668 dst
[slen
- 1] = '\0';
669 if ((ptr
= egetenv (dst
))
670 && (rlen
= strlen (ptr
) - 1) > 0
671 && (ptr
[rlen
] == ']' || ptr
[rlen
] == '>')
672 && ptr
[rlen
- 1] == '.')
674 char * buf
= (char *) alloca (strlen (ptr
) + 1);
678 return directory_file_name (buf
, dst
);
683 strcat (dst
, "[000000]");
687 rlen
= strlen (rptr
) - 1;
688 strncat (dst
, rptr
, rlen
);
689 dst
[slen
+ rlen
] = '\0';
690 strcat (dst
, ".DIR.1");
694 /* Process as Unix format: just remove any final slash.
695 But leave "/" unchanged; do not change it to "". */
698 /* Handle // as root for apollo's. */
699 if ((slen
> 2 && dst
[slen
- 1] == '/')
700 || (slen
> 1 && dst
[0] != '/' && dst
[slen
- 1] == '/'))
704 && IS_DIRECTORY_SEP (dst
[slen
- 1])
706 && !IS_ANY_SEP (dst
[slen
- 2])
712 CORRECT_DIR_SEPS (dst
);
717 DEFUN ("directory-file-name", Fdirectory_file_name
, Sdirectory_file_name
,
719 "Returns the file name of the directory named DIRECTORY.\n\
720 This is the name of the file that holds the data for the directory DIRECTORY.\n\
721 This operation exists because a directory is also a file, but its name as\n\
722 a directory is different from its name as a file.\n\
723 In Unix-syntax, this function just removes the final slash.\n\
724 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
725 it returns a file name such as \"[X]Y.DIR.1\".")
727 Lisp_Object directory
;
732 CHECK_STRING (directory
, 0);
734 if (NILP (directory
))
737 /* If the file name has special constructs in it,
738 call the corresponding file handler. */
739 handler
= Ffind_file_name_handler (directory
, Qdirectory_file_name
);
741 return call2 (handler
, Qdirectory_file_name
, directory
);
744 /* 20 extra chars is insufficient for VMS, since we might perform a
745 logical name translation. an equivalence string can be up to 255
746 chars long, so grab that much extra space... - sss */
747 buf
= (char *) alloca (XSTRING (directory
)->size
+ 20 + 255);
749 buf
= (char *) alloca (XSTRING (directory
)->size
+ 20);
751 directory_file_name (XSTRING (directory
)->data
, buf
);
752 return build_string (buf
);
755 DEFUN ("make-temp-name", Fmake_temp_name
, Smake_temp_name
, 1, 1, 0,
756 "Generate temporary file name (string) starting with PREFIX (a string).\n\
757 The Emacs process number forms part of the result,\n\
758 so there is no danger of generating a name being used by another process.")
764 /* Don't use too many characters of the restricted 8+3 DOS
766 val
= concat2 (prefix
, build_string ("a.XXX"));
768 val
= concat2 (prefix
, build_string ("XXXXXX"));
770 mktemp (XSTRING (val
)->data
);
772 CORRECT_DIR_SEPS (XSTRING (val
)->data
);
777 DEFUN ("expand-file-name", Fexpand_file_name
, Sexpand_file_name
, 1, 2, 0,
778 "Convert filename NAME to absolute, and canonicalize it.\n\
779 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
780 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
781 the current buffer's value of default-directory is used.\n\
782 File name components that are `.' are removed, and \n\
783 so are file name components followed by `..', along with the `..' itself;\n\
784 note that these simplifications are done without checking the resulting\n\
785 file names in the file system.\n\
786 An initial `~/' expands to your home directory.\n\
787 An initial `~USER/' expands to USER's home directory.\n\
788 See also the function `substitute-in-file-name'.")
789 (name
, default_directory
)
790 Lisp_Object name
, default_directory
;
794 register unsigned char *newdir
, *p
, *o
;
796 unsigned char *target
;
799 unsigned char * colon
= 0;
800 unsigned char * close
= 0;
801 unsigned char * slash
= 0;
802 unsigned char * brack
= 0;
803 int lbrack
= 0, rbrack
= 0;
808 int collapse_newdir
= 1;
813 CHECK_STRING (name
, 0);
815 /* If the file name has special constructs in it,
816 call the corresponding file handler. */
817 handler
= Ffind_file_name_handler (name
, Qexpand_file_name
);
819 return call3 (handler
, Qexpand_file_name
, name
, default_directory
);
821 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
822 if (NILP (default_directory
))
823 default_directory
= current_buffer
->directory
;
824 CHECK_STRING (default_directory
, 1);
826 if (!NILP (default_directory
))
828 handler
= Ffind_file_name_handler (default_directory
, Qexpand_file_name
);
830 return call3 (handler
, Qexpand_file_name
, name
, default_directory
);
833 o
= XSTRING (default_directory
)->data
;
835 /* Make sure DEFAULT_DIRECTORY is properly expanded.
836 It would be better to do this down below where we actually use
837 default_directory. Unfortunately, calling Fexpand_file_name recursively
838 could invoke GC, and the strings might be relocated. This would
839 be annoying because we have pointers into strings lying around
840 that would need adjusting, and people would add new pointers to
841 the code and forget to adjust them, resulting in intermittent bugs.
842 Putting this call here avoids all that crud.
844 The EQ test avoids infinite recursion. */
845 if (! NILP (default_directory
) && !EQ (default_directory
, name
)
846 /* Save time in some common cases - as long as default_directory
847 is not relative, it can be canonicalized with name below (if it
848 is needed at all) without requiring it to be expanded now. */
850 /* Detect MSDOS file names with drive specifiers. */
851 && ! (IS_DRIVE (o
[0]) && (IS_DEVICE_SEP (o
[1]) && IS_DIRECTORY_SEP (o
[2])))
853 /* Detect Windows file names in UNC format. */
854 && ! (IS_DIRECTORY_SEP (o
[0]) && IS_DIRECTORY_SEP (o
[1]))
856 #else /* not DOS_NT */
857 /* Detect Unix absolute file names (/... alone is not absolute on
859 && ! (IS_DIRECTORY_SEP (o
[0]))
860 #endif /* not DOS_NT */
866 default_directory
= Fexpand_file_name (default_directory
, Qnil
);
871 /* Filenames on VMS are always upper case. */
872 name
= Fupcase (name
);
874 #ifdef FILE_SYSTEM_CASE
875 name
= FILE_SYSTEM_CASE (name
);
878 nm
= XSTRING (name
)->data
;
881 /* We will force directory separators to be either all \ or /, so make
882 a local copy to modify, even if there ends up being no change. */
883 nm
= strcpy (alloca (strlen (nm
) + 1), nm
);
885 /* Find and remove drive specifier if present; this makes nm absolute
886 even if the rest of the name appears to be relative. */
888 unsigned char *colon
= rindex (nm
, ':');
891 /* Only recognize colon as part of drive specifier if there is a
892 single alphabetic character preceeding the colon (and if the
893 character before the drive letter, if present, is a directory
894 separator); this is to support the remote system syntax used by
895 ange-ftp, and the "po:username" syntax for POP mailboxes. */
899 else if (IS_DRIVE (colon
[-1])
900 && (colon
== nm
+ 1 || IS_DIRECTORY_SEP (colon
[-2])))
907 while (--colon
>= nm
)
915 /* Discard any previous drive specifier if nm is now in UNC format. */
916 if (IS_DIRECTORY_SEP (nm
[0]) && IS_DIRECTORY_SEP (nm
[1]))
922 /* If nm is absolute, look for /./ or /../ sequences; if none are
923 found, we can probably return right away. We will avoid allocating
924 a new string if name is already fully expanded. */
926 IS_DIRECTORY_SEP (nm
[0])
931 && (drive
|| IS_DIRECTORY_SEP (nm
[1]))
938 /* If it turns out that the filename we want to return is just a
939 suffix of FILENAME, we don't need to go through and edit
940 things; we just need to construct a new string using data
941 starting at the middle of FILENAME. If we set lose to a
942 non-zero value, that means we've discovered that we can't do
949 /* Since we know the name is absolute, we can assume that each
950 element starts with a "/". */
952 /* "." and ".." are hairy. */
953 if (IS_DIRECTORY_SEP (p
[0])
955 && (IS_DIRECTORY_SEP (p
[2])
957 || (p
[2] == '.' && (IS_DIRECTORY_SEP (p
[3])
964 /* if dev:[dir]/, move nm to / */
965 if (!slash
&& p
> nm
&& (brack
|| colon
)) {
966 nm
= (brack
? brack
+ 1 : colon
+ 1);
975 /* VMS pre V4.4,convert '-'s in filenames. */
976 if (lbrack
== rbrack
)
978 if (dots
< 2) /* this is to allow negative version numbers */
983 if (lbrack
> rbrack
&&
984 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
985 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
991 /* count open brackets, reset close bracket pointer */
992 if (p
[0] == '[' || p
[0] == '<')
994 /* count close brackets, set close bracket pointer */
995 if (p
[0] == ']' || p
[0] == '>')
997 /* detect ][ or >< */
998 if ((p
[0] == ']' || p
[0] == '>') && (p
[1] == '[' || p
[1] == '<'))
1000 if ((p
[0] == ':' || p
[0] == ']' || p
[0] == '>') && p
[1] == '~')
1001 nm
= p
+ 1, lose
= 1;
1002 if (p
[0] == ':' && (colon
|| slash
))
1003 /* if dev1:[dir]dev2:, move nm to dev2: */
1009 /* if /name/dev:, move nm to dev: */
1012 /* if node::dev:, move colon following dev */
1013 else if (colon
&& colon
[-1] == ':')
1015 /* if dev1:dev2:, move nm to dev2: */
1016 else if (colon
&& colon
[-1] != ':')
1021 if (p
[0] == ':' && !colon
)
1027 if (lbrack
== rbrack
)
1030 else if (p
[0] == '.')
1038 if (index (nm
, '/'))
1039 return build_string (sys_translate_unix (nm
));
1042 /* Make sure directories are all separated with / or \ as
1043 desired, but avoid allocation of a new string when not
1045 CORRECT_DIR_SEPS (nm
);
1047 if (IS_DIRECTORY_SEP (nm
[1]))
1049 if (strcmp (nm
, XSTRING (name
)->data
) != 0)
1050 name
= build_string (nm
);
1054 /* drive must be set, so this is okay */
1055 if (strcmp (nm
- 2, XSTRING (name
)->data
) != 0)
1057 name
= make_string (nm
- 2, p
- nm
+ 2);
1058 XSTRING (name
)->data
[0] = DRIVE_LETTER (drive
);
1059 XSTRING (name
)->data
[1] = ':';
1062 #else /* not DOS_NT */
1063 if (nm
== XSTRING (name
)->data
)
1065 return build_string (nm
);
1066 #endif /* not DOS_NT */
1070 /* At this point, nm might or might not be an absolute file name. We
1071 need to expand ~ or ~user if present, otherwise prefix nm with
1072 default_directory if nm is not absolute, and finally collapse /./
1073 and /foo/../ sequences.
1075 We set newdir to be the appropriate prefix if one is needed:
1076 - the relevant user directory if nm starts with ~ or ~user
1077 - the specified drive's working dir (DOS/NT only) if nm does not
1079 - the value of default_directory.
1081 Note that these prefixes are not guaranteed to be absolute (except
1082 for the working dir of a drive). Therefore, to ensure we always
1083 return an absolute name, if the final prefix is not absolute we
1084 append it to the current working directory. */
1088 if (nm
[0] == '~') /* prefix ~ */
1090 if (IS_DIRECTORY_SEP (nm
[1])
1094 || nm
[1] == 0) /* ~ by itself */
1096 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1097 newdir
= (unsigned char *) "";
1100 collapse_newdir
= 0;
1103 nm
++; /* Don't leave the slash in nm. */
1106 else /* ~user/filename */
1108 for (p
= nm
; *p
&& (!IS_DIRECTORY_SEP (*p
)
1113 o
= (unsigned char *) alloca (p
- nm
+ 1);
1114 bcopy ((char *) nm
, o
, p
- nm
);
1117 pw
= (struct passwd
*) getpwnam (o
+ 1);
1120 newdir
= (unsigned char *) pw
-> pw_dir
;
1122 nm
= p
+ 1; /* skip the terminator */
1126 collapse_newdir
= 0;
1131 /* If we don't find a user of that name, leave the name
1132 unchanged; don't move nm forward to p. */
1137 /* On DOS and Windows, nm is absolute if a drive name was specified;
1138 use the drive's current directory as the prefix if needed. */
1139 if (!newdir
&& drive
)
1141 /* Get default directory if needed to make nm absolute. */
1142 if (!IS_DIRECTORY_SEP (nm
[0]))
1144 newdir
= alloca (MAXPATHLEN
+ 1);
1145 if (!getdefdir (toupper (drive
) - 'A' + 1, newdir
))
1150 /* Either nm starts with /, or drive isn't mounted. */
1151 newdir
= alloca (4);
1152 newdir
[0] = DRIVE_LETTER (drive
);
1160 /* Finally, if no prefix has been specified and nm is not absolute,
1161 then it must be expanded relative to default_directory. */
1165 /* /... alone is not absolute on DOS and Windows. */
1166 && !IS_DIRECTORY_SEP (nm
[0])
1169 && !(IS_DIRECTORY_SEP (nm
[0]) && IS_DIRECTORY_SEP (nm
[1]))
1176 newdir
= XSTRING (default_directory
)->data
;
1182 /* First ensure newdir is an absolute name. */
1184 /* Detect MSDOS file names with drive specifiers. */
1185 ! (IS_DRIVE (newdir
[0])
1186 && IS_DEVICE_SEP (newdir
[1]) && IS_DIRECTORY_SEP (newdir
[2]))
1188 /* Detect Windows file names in UNC format. */
1189 && ! (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
1193 /* Effectively, let newdir be (expand-file-name newdir cwd).
1194 Because of the admonition against calling expand-file-name
1195 when we have pointers into lisp strings, we accomplish this
1196 indirectly by prepending newdir to nm if necessary, and using
1197 cwd (or the wd of newdir's drive) as the new newdir. */
1199 if (IS_DRIVE (newdir
[0]) && newdir
[1] == ':')
1204 if (!IS_DIRECTORY_SEP (nm
[0]))
1206 char * tmp
= alloca (strlen (newdir
) + strlen (nm
) + 2);
1207 file_name_as_directory (tmp
, newdir
);
1211 newdir
= alloca (MAXPATHLEN
+ 1);
1214 if (!getdefdir (toupper (drive
) - 'A' + 1, newdir
))
1221 /* Strip off drive name from prefix, if present. */
1222 if (IS_DRIVE (newdir
[0]) && newdir
[1] == ':')
1228 /* Keep only a prefix from newdir if nm starts with slash
1229 (//server/share for UNC, nothing otherwise). */
1230 if (IS_DIRECTORY_SEP (nm
[0]) && collapse_newdir
)
1233 if (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
1235 newdir
= strcpy (alloca (strlen (newdir
) + 1), newdir
);
1237 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
1239 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
1251 /* Get rid of any slash at the end of newdir, unless newdir is
1252 just // (an incomplete UNC name). */
1253 length
= strlen (newdir
);
1254 if (length
> 0 && IS_DIRECTORY_SEP (newdir
[length
- 1])
1256 && !(length
== 2 && IS_DIRECTORY_SEP (newdir
[0]))
1260 unsigned char *temp
= (unsigned char *) alloca (length
);
1261 bcopy (newdir
, temp
, length
- 1);
1262 temp
[length
- 1] = 0;
1270 /* Now concatenate the directory and name to new space in the stack frame */
1271 tlen
+= strlen (nm
) + 1;
1273 /* Add reserved space for drive name. (The Microsoft x86 compiler
1274 produces incorrect code if the following two lines are combined.) */
1275 target
= (unsigned char *) alloca (tlen
+ 2);
1277 #else /* not DOS_NT */
1278 target
= (unsigned char *) alloca (tlen
);
1279 #endif /* not DOS_NT */
1285 if (nm
[0] == 0 || IS_DIRECTORY_SEP (nm
[0]))
1286 strcpy (target
, newdir
);
1289 file_name_as_directory (target
, newdir
);
1292 strcat (target
, nm
);
1294 if (index (target
, '/'))
1295 strcpy (target
, sys_translate_unix (target
));
1298 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1300 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1308 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1314 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1315 /* brackets are offset from each other by 2 */
1318 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1319 /* convert [foo][bar] to [bar] */
1320 while (o
[-1] != '[' && o
[-1] != '<')
1322 else if (*p
== '-' && *o
!= '.')
1325 else if (p
[0] == '-' && o
[-1] == '.' &&
1326 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1327 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1331 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1332 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1334 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1336 /* else [foo.-] ==> [-] */
1342 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1343 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1349 if (!IS_DIRECTORY_SEP (*p
))
1353 else if (IS_DIRECTORY_SEP (p
[0]) && IS_DIRECTORY_SEP (p
[1])
1354 #if defined (APOLLO) || defined (WINDOWSNT)
1355 /* // at start of filename is meaningful in Apollo
1356 and WindowsNT systems */
1358 #endif /* APOLLO || WINDOWSNT */
1364 else if (IS_DIRECTORY_SEP (p
[0])
1366 && (IS_DIRECTORY_SEP (p
[2])
1369 /* If "/." is the entire filename, keep the "/". Otherwise,
1370 just delete the whole "/.". */
1371 if (o
== target
&& p
[2] == '\0')
1375 else if (IS_DIRECTORY_SEP (p
[0]) && p
[1] == '.' && p
[2] == '.'
1376 /* `/../' is the "superroot" on certain file systems. */
1378 && (IS_DIRECTORY_SEP (p
[3]) || p
[3] == 0))
1380 while (o
!= target
&& (--o
) && !IS_DIRECTORY_SEP (*o
))
1382 /* Keep initial / only if this is the whole name. */
1383 if (o
== target
&& IS_ANY_SEP (*o
) && p
[3] == 0)
1391 #endif /* not VMS */
1395 /* At last, set drive name. */
1397 /* Except for network file name. */
1398 if (!(IS_DIRECTORY_SEP (target
[0]) && IS_DIRECTORY_SEP (target
[1])))
1399 #endif /* WINDOWSNT */
1401 if (!drive
) abort ();
1403 target
[0] = DRIVE_LETTER (drive
);
1406 CORRECT_DIR_SEPS (target
);
1409 return make_string (target
, o
- target
);
1413 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1414 DEAFUN ("expand-file-name", Fexpand_file_name
, Sexpand_file_name
, 1, 2, 0,
1415 "Convert FILENAME to absolute, and canonicalize it.\n\
1416 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1417 (does not start with slash); if DEFAULT is nil or missing,\n\
1418 the current buffer's value of default-directory is used.\n\
1419 Filenames containing `.' or `..' as components are simplified;\n\
1420 initial `~/' expands to your home directory.\n\
1421 See also the function `substitute-in-file-name'.")
1423 Lisp_Object name
, defalt
;
1427 register unsigned char *newdir
, *p
, *o
;
1429 unsigned char *target
;
1433 unsigned char * colon
= 0;
1434 unsigned char * close
= 0;
1435 unsigned char * slash
= 0;
1436 unsigned char * brack
= 0;
1437 int lbrack
= 0, rbrack
= 0;
1441 CHECK_STRING (name
, 0);
1444 /* Filenames on VMS are always upper case. */
1445 name
= Fupcase (name
);
1448 nm
= XSTRING (name
)->data
;
1450 /* If nm is absolute, flush ...// and detect /./ and /../.
1451 If no /./ or /../ we can return right away. */
1463 if (p
[0] == '/' && p
[1] == '/'
1465 /* // at start of filename is meaningful on Apollo system */
1470 if (p
[0] == '/' && p
[1] == '~')
1471 nm
= p
+ 1, lose
= 1;
1472 if (p
[0] == '/' && p
[1] == '.'
1473 && (p
[2] == '/' || p
[2] == 0
1474 || (p
[2] == '.' && (p
[3] == '/' || p
[3] == 0))))
1480 /* if dev:[dir]/, move nm to / */
1481 if (!slash
&& p
> nm
&& (brack
|| colon
)) {
1482 nm
= (brack
? brack
+ 1 : colon
+ 1);
1483 lbrack
= rbrack
= 0;
1491 /* VMS pre V4.4,convert '-'s in filenames. */
1492 if (lbrack
== rbrack
)
1494 if (dots
< 2) /* this is to allow negative version numbers */
1499 if (lbrack
> rbrack
&&
1500 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
1501 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
1507 /* count open brackets, reset close bracket pointer */
1508 if (p
[0] == '[' || p
[0] == '<')
1509 lbrack
++, brack
= 0;
1510 /* count close brackets, set close bracket pointer */
1511 if (p
[0] == ']' || p
[0] == '>')
1512 rbrack
++, brack
= p
;
1513 /* detect ][ or >< */
1514 if ((p
[0] == ']' || p
[0] == '>') && (p
[1] == '[' || p
[1] == '<'))
1516 if ((p
[0] == ':' || p
[0] == ']' || p
[0] == '>') && p
[1] == '~')
1517 nm
= p
+ 1, lose
= 1;
1518 if (p
[0] == ':' && (colon
|| slash
))
1519 /* if dev1:[dir]dev2:, move nm to dev2: */
1525 /* If /name/dev:, move nm to dev: */
1528 /* If node::dev:, move colon following dev */
1529 else if (colon
&& colon
[-1] == ':')
1531 /* If dev1:dev2:, move nm to dev2: */
1532 else if (colon
&& colon
[-1] != ':')
1537 if (p
[0] == ':' && !colon
)
1543 if (lbrack
== rbrack
)
1546 else if (p
[0] == '.')
1554 if (index (nm
, '/'))
1555 return build_string (sys_translate_unix (nm
));
1557 if (nm
== XSTRING (name
)->data
)
1559 return build_string (nm
);
1563 /* Now determine directory to start with and put it in NEWDIR */
1567 if (nm
[0] == '~') /* prefix ~ */
1572 || nm
[1] == 0)/* ~/filename */
1574 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1575 newdir
= (unsigned char *) "";
1578 nm
++; /* Don't leave the slash in nm. */
1581 else /* ~user/filename */
1583 /* Get past ~ to user */
1584 unsigned char *user
= nm
+ 1;
1585 /* Find end of name. */
1586 unsigned char *ptr
= (unsigned char *) index (user
, '/');
1587 int len
= ptr
? ptr
- user
: strlen (user
);
1589 unsigned char *ptr1
= index (user
, ':');
1590 if (ptr1
!= 0 && ptr1
- user
< len
)
1593 /* Copy the user name into temp storage. */
1594 o
= (unsigned char *) alloca (len
+ 1);
1595 bcopy ((char *) user
, o
, len
);
1598 /* Look up the user name. */
1599 pw
= (struct passwd
*) getpwnam (o
+ 1);
1601 error ("\"%s\" isn't a registered user", o
+ 1);
1603 newdir
= (unsigned char *) pw
->pw_dir
;
1605 /* Discard the user name from NM. */
1612 #endif /* not VMS */
1616 defalt
= current_buffer
->directory
;
1617 CHECK_STRING (defalt
, 1);
1618 newdir
= XSTRING (defalt
)->data
;
1621 /* Now concatenate the directory and name to new space in the stack frame */
1623 tlen
= (newdir
? strlen (newdir
) + 1 : 0) + strlen (nm
) + 1;
1624 target
= (unsigned char *) alloca (tlen
);
1630 if (nm
[0] == 0 || nm
[0] == '/')
1631 strcpy (target
, newdir
);
1634 file_name_as_directory (target
, newdir
);
1637 strcat (target
, nm
);
1639 if (index (target
, '/'))
1640 strcpy (target
, sys_translate_unix (target
));
1643 /* Now canonicalize by removing /. and /foo/.. if they appear */
1651 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1657 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1658 /* brackets are offset from each other by 2 */
1661 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1662 /* convert [foo][bar] to [bar] */
1663 while (o
[-1] != '[' && o
[-1] != '<')
1665 else if (*p
== '-' && *o
!= '.')
1668 else if (p
[0] == '-' && o
[-1] == '.' &&
1669 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1670 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1674 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1675 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1677 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1679 /* else [foo.-] ==> [-] */
1685 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1686 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1696 else if (!strncmp (p
, "//", 2)
1698 /* // at start of filename is meaningful in Apollo system */
1706 else if (p
[0] == '/' && p
[1] == '.' &&
1707 (p
[2] == '/' || p
[2] == 0))
1709 else if (!strncmp (p
, "/..", 3)
1710 /* `/../' is the "superroot" on certain file systems. */
1712 && (p
[3] == '/' || p
[3] == 0))
1714 while (o
!= target
&& *--o
!= '/')
1717 if (o
== target
+ 1 && o
[-1] == '/' && o
[0] == '/')
1721 if (o
== target
&& *o
== '/')
1729 #endif /* not VMS */
1732 return make_string (target
, o
- target
);
1736 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name
,
1737 Ssubstitute_in_file_name
, 1, 1, 0,
1738 "Substitute environment variables referred to in FILENAME.\n\
1739 `$FOO' where FOO is an environment variable name means to substitute\n\
1740 the value of that variable. The variable name should be terminated\n\
1741 with a character not a letter, digit or underscore; otherwise, enclose\n\
1742 the entire variable name in braces.\n\
1743 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1744 On VMS, `$' substitution is not done; this function does little and only\n\
1745 duplicates what `expand-file-name' does.")
1747 Lisp_Object filename
;
1751 register unsigned char *s
, *p
, *o
, *x
, *endp
;
1752 unsigned char *target
;
1754 int substituted
= 0;
1756 Lisp_Object handler
;
1758 CHECK_STRING (filename
, 0);
1760 /* If the file name has special constructs in it,
1761 call the corresponding file handler. */
1762 handler
= Ffind_file_name_handler (filename
, Qsubstitute_in_file_name
);
1763 if (!NILP (handler
))
1764 return call2 (handler
, Qsubstitute_in_file_name
, filename
);
1766 nm
= XSTRING (filename
)->data
;
1768 nm
= strcpy (alloca (strlen (nm
) + 1), nm
);
1769 CORRECT_DIR_SEPS (nm
);
1770 substituted
= (strcmp (nm
, XSTRING (filename
)->data
) != 0);
1772 endp
= nm
+ XSTRING (filename
)->size
;
1774 /* If /~ or // appears, discard everything through first slash. */
1776 for (p
= nm
; p
!= endp
; p
++)
1779 #if defined (APOLLO) || defined (WINDOWSNT)
1780 /* // at start of file name is meaningful in Apollo and
1781 WindowsNT systems */
1782 || (IS_DIRECTORY_SEP (p
[0]) && p
- 1 != nm
)
1783 #else /* not (APOLLO || WINDOWSNT) */
1784 || IS_DIRECTORY_SEP (p
[0])
1785 #endif /* not (APOLLO || WINDOWSNT) */
1790 || p
[-1] == ':' || p
[-1] == ']' || p
[-1] == '>'
1792 || IS_DIRECTORY_SEP (p
[-1])))
1798 /* see comment in expand-file-name about drive specifiers */
1799 else if (IS_DRIVE (p
[0]) && p
[1] == ':'
1800 && p
> nm
&& IS_DIRECTORY_SEP (p
[-1]))
1809 return build_string (nm
);
1812 /* See if any variables are substituted into the string
1813 and find the total length of their values in `total' */
1815 for (p
= nm
; p
!= endp
;)
1825 /* "$$" means a single "$" */
1834 while (p
!= endp
&& *p
!= '}') p
++;
1835 if (*p
!= '}') goto missingclose
;
1841 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1845 /* Copy out the variable name */
1846 target
= (unsigned char *) alloca (s
- o
+ 1);
1847 strncpy (target
, o
, s
- o
);
1850 strupr (target
); /* $home == $HOME etc. */
1853 /* Get variable value */
1854 o
= (unsigned char *) egetenv (target
);
1855 if (!o
) goto badvar
;
1856 total
+= strlen (o
);
1863 /* If substitution required, recopy the string and do it */
1864 /* Make space in stack frame for the new copy */
1865 xnm
= (unsigned char *) alloca (XSTRING (filename
)->size
+ total
+ 1);
1868 /* Copy the rest of the name through, replacing $ constructs with values */
1885 while (p
!= endp
&& *p
!= '}') p
++;
1886 if (*p
!= '}') goto missingclose
;
1892 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1896 /* Copy out the variable name */
1897 target
= (unsigned char *) alloca (s
- o
+ 1);
1898 strncpy (target
, o
, s
- o
);
1901 strupr (target
); /* $home == $HOME etc. */
1904 /* Get variable value */
1905 o
= (unsigned char *) egetenv (target
);
1915 /* If /~ or // appears, discard everything through first slash. */
1917 for (p
= xnm
; p
!= x
; p
++)
1919 #if defined (APOLLO) || defined (WINDOWSNT)
1920 || (IS_DIRECTORY_SEP (p
[0]) && p
- 1 != xnm
)
1921 #else /* not (APOLLO || WINDOWSNT) */
1922 || IS_DIRECTORY_SEP (p
[0])
1923 #endif /* not (APOLLO || WINDOWSNT) */
1925 && p
!= xnm
&& IS_DIRECTORY_SEP (p
[-1]))
1928 else if (IS_DRIVE (p
[0]) && p
[1] == ':'
1929 && p
> nm
&& IS_DIRECTORY_SEP (p
[-1]))
1933 return make_string (xnm
, x
- xnm
);
1936 error ("Bad format environment-variable substitution");
1938 error ("Missing \"}\" in environment-variable substitution");
1940 error ("Substituting nonexistent environment variable \"%s\"", target
);
1943 #endif /* not VMS */
1946 /* A slightly faster and more convenient way to get
1947 (directory-file-name (expand-file-name FOO)). */
1950 expand_and_dir_to_file (filename
, defdir
)
1951 Lisp_Object filename
, defdir
;
1953 register Lisp_Object absname
;
1955 absname
= Fexpand_file_name (filename
, defdir
);
1958 register int c
= XSTRING (absname
)->data
[XSTRING (absname
)->size
- 1];
1959 if (c
== ':' || c
== ']' || c
== '>')
1960 absname
= Fdirectory_file_name (absname
);
1963 /* Remove final slash, if any (unless this is the root dir).
1964 stat behaves differently depending! */
1965 if (XSTRING (absname
)->size
> 1
1966 && IS_DIRECTORY_SEP (XSTRING (absname
)->data
[XSTRING (absname
)->size
- 1])
1967 && !IS_DEVICE_SEP (XSTRING (absname
)->data
[XSTRING (absname
)->size
-2]))
1968 /* We cannot take shortcuts; they might be wrong for magic file names. */
1969 absname
= Fdirectory_file_name (absname
);
1974 /* Signal an error if the file ABSNAME already exists.
1975 If INTERACTIVE is nonzero, ask the user whether to proceed,
1976 and bypass the error if the user says to go ahead.
1977 QUERYSTRING is a name for the action that is being considered
1979 *STATPTR is used to store the stat information if the file exists.
1980 If the file does not exist, STATPTR->st_mode is set to 0. */
1983 barf_or_query_if_file_exists (absname
, querystring
, interactive
, statptr
)
1984 Lisp_Object absname
;
1985 unsigned char *querystring
;
1987 struct stat
*statptr
;
1989 register Lisp_Object tem
;
1990 struct stat statbuf
;
1991 struct gcpro gcpro1
;
1993 /* stat is a good way to tell whether the file exists,
1994 regardless of what access permissions it has. */
1995 if (stat (XSTRING (absname
)->data
, &statbuf
) >= 0)
1998 Fsignal (Qfile_already_exists
,
1999 Fcons (build_string ("File already exists"),
2000 Fcons (absname
, Qnil
)));
2002 tem
= do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
2003 XSTRING (absname
)->data
, querystring
));
2006 Fsignal (Qfile_already_exists
,
2007 Fcons (build_string ("File already exists"),
2008 Fcons (absname
, Qnil
)));
2015 statptr
->st_mode
= 0;
2020 DEFUN ("copy-file", Fcopy_file
, Scopy_file
, 2, 4,
2021 "fCopy file: \nFCopy %s to file: \np\nP",
2022 "Copy FILE to NEWNAME. Both args must be strings.\n\
2023 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2024 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2025 A number as third arg means request confirmation if NEWNAME already exists.\n\
2026 This is what happens in interactive use with M-x.\n\
2027 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2028 last-modified time as the old one. (This works on only some systems.)\n\
2029 A prefix arg makes KEEP-TIME non-nil.")
2030 (file
, newname
, ok_if_already_exists
, keep_date
)
2031 Lisp_Object file
, newname
, ok_if_already_exists
, keep_date
;
2034 char buf
[16 * 1024];
2035 struct stat st
, out_st
;
2036 Lisp_Object handler
;
2037 struct gcpro gcpro1
, gcpro2
;
2038 int count
= specpdl_ptr
- specpdl
;
2039 int input_file_statable_p
;
2041 GCPRO2 (file
, newname
);
2042 CHECK_STRING (file
, 0);
2043 CHECK_STRING (newname
, 1);
2044 file
= Fexpand_file_name (file
, Qnil
);
2045 newname
= Fexpand_file_name (newname
, Qnil
);
2047 /* If the input file name has special constructs in it,
2048 call the corresponding file handler. */
2049 handler
= Ffind_file_name_handler (file
, Qcopy_file
);
2050 /* Likewise for output file name. */
2052 handler
= Ffind_file_name_handler (newname
, Qcopy_file
);
2053 if (!NILP (handler
))
2054 RETURN_UNGCPRO (call5 (handler
, Qcopy_file
, file
, newname
,
2055 ok_if_already_exists
, keep_date
));
2057 if (NILP (ok_if_already_exists
)
2058 || INTEGERP (ok_if_already_exists
))
2059 barf_or_query_if_file_exists (newname
, "copy to it",
2060 INTEGERP (ok_if_already_exists
), &out_st
);
2061 else if (stat (XSTRING (newname
)->data
, &out_st
) < 0)
2064 ifd
= open (XSTRING (file
)->data
, O_RDONLY
);
2066 report_file_error ("Opening input file", Fcons (file
, Qnil
));
2068 record_unwind_protect (close_file_unwind
, make_number (ifd
));
2070 /* We can only copy regular files and symbolic links. Other files are not
2072 input_file_statable_p
= (fstat (ifd
, &st
) >= 0);
2074 #if !defined (MSDOS) || __DJGPP__ > 1
2075 if (out_st
.st_mode
!= 0
2076 && st
.st_dev
== out_st
.st_dev
&& st
.st_ino
== out_st
.st_ino
)
2079 report_file_error ("Input and output files are the same",
2080 Fcons (file
, Fcons (newname
, Qnil
)));
2084 #if defined (S_ISREG) && defined (S_ISLNK)
2085 if (input_file_statable_p
)
2087 if (!(S_ISREG (st
.st_mode
)) && !(S_ISLNK (st
.st_mode
)))
2089 #if defined (EISDIR)
2090 /* Get a better looking error message. */
2093 report_file_error ("Non-regular file", Fcons (file
, Qnil
));
2096 #endif /* S_ISREG && S_ISLNK */
2099 /* Create the copy file with the same record format as the input file */
2100 ofd
= sys_creat (XSTRING (newname
)->data
, 0666, ifd
);
2103 /* System's default file type was set to binary by _fmode in emacs.c. */
2104 ofd
= creat (XSTRING (newname
)->data
, S_IREAD
| S_IWRITE
);
2105 #else /* not MSDOS */
2106 ofd
= creat (XSTRING (newname
)->data
, 0666);
2107 #endif /* not MSDOS */
2110 report_file_error ("Opening output file", Fcons (newname
, Qnil
));
2112 record_unwind_protect (close_file_unwind
, make_number (ofd
));
2116 while ((n
= read (ifd
, buf
, sizeof buf
)) > 0)
2117 if (write (ofd
, buf
, n
) != n
)
2118 report_file_error ("I/O error", Fcons (newname
, Qnil
));
2121 /* Closing the output clobbers the file times on some systems. */
2122 if (close (ofd
) < 0)
2123 report_file_error ("I/O error", Fcons (newname
, Qnil
));
2125 if (input_file_statable_p
)
2127 if (!NILP (keep_date
))
2129 EMACS_TIME atime
, mtime
;
2130 EMACS_SET_SECS_USECS (atime
, st
.st_atime
, 0);
2131 EMACS_SET_SECS_USECS (mtime
, st
.st_mtime
, 0);
2132 if (set_file_times (XSTRING (newname
)->data
, atime
, mtime
))
2133 Fsignal (Qfile_date_error
,
2134 Fcons (build_string ("Cannot set file date"),
2135 Fcons (newname
, Qnil
)));
2138 chmod (XSTRING (newname
)->data
, st
.st_mode
& 07777);
2140 #if defined (__DJGPP__) && __DJGPP__ > 1
2141 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2142 and if it can't, it tells so. Otherwise, under MSDOS we usually
2143 get only the READ bit, which will make the copied file read-only,
2144 so it's better not to chmod at all. */
2145 if ((_djstat_flags
& _STFAIL_WRITEBIT
) == 0)
2146 chmod (XSTRING (newname
)->data
, st
.st_mode
& 07777);
2147 #endif /* DJGPP version 2 or newer */
2153 /* Discard the unwind protects. */
2154 specpdl_ptr
= specpdl
+ count
;
2160 DEFUN ("make-directory-internal", Fmake_directory_internal
,
2161 Smake_directory_internal
, 1, 1, 0,
2162 "Create a new directory named DIRECTORY.")
2164 Lisp_Object directory
;
2167 Lisp_Object handler
;
2169 CHECK_STRING (directory
, 0);
2170 directory
= Fexpand_file_name (directory
, Qnil
);
2172 handler
= Ffind_file_name_handler (directory
, Qmake_directory_internal
);
2173 if (!NILP (handler
))
2174 return call2 (handler
, Qmake_directory_internal
, directory
);
2176 dir
= XSTRING (directory
)->data
;
2179 if (mkdir (dir
) != 0)
2181 if (mkdir (dir
, 0777) != 0)
2183 report_file_error ("Creating directory", Flist (1, &directory
));
2188 DEFUN ("delete-directory", Fdelete_directory
, Sdelete_directory
, 1, 1, "FDelete directory: ",
2189 "Delete the directory named DIRECTORY.")
2191 Lisp_Object directory
;
2194 Lisp_Object handler
;
2196 CHECK_STRING (directory
, 0);
2197 directory
= Fdirectory_file_name (Fexpand_file_name (directory
, Qnil
));
2198 dir
= XSTRING (directory
)->data
;
2200 handler
= Ffind_file_name_handler (directory
, Qdelete_directory
);
2201 if (!NILP (handler
))
2202 return call2 (handler
, Qdelete_directory
, directory
);
2204 if (rmdir (dir
) != 0)
2205 report_file_error ("Removing directory", Flist (1, &directory
));
2210 DEFUN ("delete-file", Fdelete_file
, Sdelete_file
, 1, 1, "fDelete file: ",
2211 "Delete file named FILENAME.\n\
2212 If file has multiple names, it continues to exist with the other names.")
2214 Lisp_Object filename
;
2216 Lisp_Object handler
;
2217 CHECK_STRING (filename
, 0);
2218 filename
= Fexpand_file_name (filename
, Qnil
);
2220 handler
= Ffind_file_name_handler (filename
, Qdelete_file
);
2221 if (!NILP (handler
))
2222 return call2 (handler
, Qdelete_file
, filename
);
2224 if (0 > unlink (XSTRING (filename
)->data
))
2225 report_file_error ("Removing old name", Flist (1, &filename
));
2230 internal_delete_file_1 (ignore
)
2236 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2239 internal_delete_file (filename
)
2240 Lisp_Object filename
;
2242 return NILP (internal_condition_case_1 (Fdelete_file
, filename
,
2243 Qt
, internal_delete_file_1
));
2246 DEFUN ("rename-file", Frename_file
, Srename_file
, 2, 3,
2247 "fRename file: \nFRename %s to file: \np",
2248 "Rename FILE as NEWNAME. Both args strings.\n\
2249 If file has names other than FILE, it continues to have those names.\n\
2250 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2251 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2252 A number as third arg means request confirmation if NEWNAME already exists.\n\
2253 This is what happens in interactive use with M-x.")
2254 (file
, newname
, ok_if_already_exists
)
2255 Lisp_Object file
, newname
, ok_if_already_exists
;
2258 Lisp_Object args
[2];
2260 Lisp_Object handler
;
2261 struct gcpro gcpro1
, gcpro2
;
2263 GCPRO2 (file
, newname
);
2264 CHECK_STRING (file
, 0);
2265 CHECK_STRING (newname
, 1);
2266 file
= Fexpand_file_name (file
, Qnil
);
2267 newname
= Fexpand_file_name (newname
, Qnil
);
2269 /* If the file name has special constructs in it,
2270 call the corresponding file handler. */
2271 handler
= Ffind_file_name_handler (file
, Qrename_file
);
2273 handler
= Ffind_file_name_handler (newname
, Qrename_file
);
2274 if (!NILP (handler
))
2275 RETURN_UNGCPRO (call4 (handler
, Qrename_file
,
2276 file
, newname
, ok_if_already_exists
));
2278 if (NILP (ok_if_already_exists
)
2279 || INTEGERP (ok_if_already_exists
))
2280 barf_or_query_if_file_exists (newname
, "rename to it",
2281 INTEGERP (ok_if_already_exists
), 0);
2283 if (0 > rename (XSTRING (file
)->data
, XSTRING (newname
)->data
))
2285 if (0 > link (XSTRING (file
)->data
, XSTRING (newname
)->data
)
2286 || 0 > unlink (XSTRING (file
)->data
))
2291 Fcopy_file (file
, newname
,
2292 /* We have already prompted if it was an integer,
2293 so don't have copy-file prompt again. */
2294 NILP (ok_if_already_exists
) ? Qnil
: Qt
, Qt
);
2295 Fdelete_file (file
);
2302 report_file_error ("Renaming", Flist (2, args
));
2305 report_file_error ("Renaming", Flist (2, &file
));
2312 DEFUN ("add-name-to-file", Fadd_name_to_file
, Sadd_name_to_file
, 2, 3,
2313 "fAdd name to file: \nFName to add to %s: \np",
2314 "Give FILE additional name NEWNAME. Both args strings.\n\
2315 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2316 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2317 A number as third arg means request confirmation if NEWNAME already exists.\n\
2318 This is what happens in interactive use with M-x.")
2319 (file
, newname
, ok_if_already_exists
)
2320 Lisp_Object file
, newname
, ok_if_already_exists
;
2323 Lisp_Object args
[2];
2325 Lisp_Object handler
;
2326 struct gcpro gcpro1
, gcpro2
;
2328 GCPRO2 (file
, newname
);
2329 CHECK_STRING (file
, 0);
2330 CHECK_STRING (newname
, 1);
2331 file
= Fexpand_file_name (file
, Qnil
);
2332 newname
= Fexpand_file_name (newname
, Qnil
);
2334 /* If the file name has special constructs in it,
2335 call the corresponding file handler. */
2336 handler
= Ffind_file_name_handler (file
, Qadd_name_to_file
);
2337 if (!NILP (handler
))
2338 RETURN_UNGCPRO (call4 (handler
, Qadd_name_to_file
, file
,
2339 newname
, ok_if_already_exists
));
2341 /* If the new name has special constructs in it,
2342 call the corresponding file handler. */
2343 handler
= Ffind_file_name_handler (newname
, Qadd_name_to_file
);
2344 if (!NILP (handler
))
2345 RETURN_UNGCPRO (call4 (handler
, Qadd_name_to_file
, file
,
2346 newname
, ok_if_already_exists
));
2348 if (NILP (ok_if_already_exists
)
2349 || INTEGERP (ok_if_already_exists
))
2350 barf_or_query_if_file_exists (newname
, "make it a new name",
2351 INTEGERP (ok_if_already_exists
), 0);
2353 /* Windows does not support this operation. */
2354 report_file_error ("Adding new name", Flist (2, &file
));
2355 #else /* not WINDOWSNT */
2357 unlink (XSTRING (newname
)->data
);
2358 if (0 > link (XSTRING (file
)->data
, XSTRING (newname
)->data
))
2363 report_file_error ("Adding new name", Flist (2, args
));
2365 report_file_error ("Adding new name", Flist (2, &file
));
2368 #endif /* not WINDOWSNT */
2375 DEFUN ("make-symbolic-link", Fmake_symbolic_link
, Smake_symbolic_link
, 2, 3,
2376 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2377 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2378 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2379 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2380 A number as third arg means request confirmation if LINKNAME already exists.\n\
2381 This happens for interactive use with M-x.")
2382 (filename
, linkname
, ok_if_already_exists
)
2383 Lisp_Object filename
, linkname
, ok_if_already_exists
;
2386 Lisp_Object args
[2];
2388 Lisp_Object handler
;
2389 struct gcpro gcpro1
, gcpro2
;
2391 GCPRO2 (filename
, linkname
);
2392 CHECK_STRING (filename
, 0);
2393 CHECK_STRING (linkname
, 1);
2394 /* If the link target has a ~, we must expand it to get
2395 a truly valid file name. Otherwise, do not expand;
2396 we want to permit links to relative file names. */
2397 if (XSTRING (filename
)->data
[0] == '~')
2398 filename
= Fexpand_file_name (filename
, Qnil
);
2399 linkname
= Fexpand_file_name (linkname
, Qnil
);
2401 /* If the file name has special constructs in it,
2402 call the corresponding file handler. */
2403 handler
= Ffind_file_name_handler (filename
, Qmake_symbolic_link
);
2404 if (!NILP (handler
))
2405 RETURN_UNGCPRO (call4 (handler
, Qmake_symbolic_link
, filename
,
2406 linkname
, ok_if_already_exists
));
2408 /* If the new link name has special constructs in it,
2409 call the corresponding file handler. */
2410 handler
= Ffind_file_name_handler (linkname
, Qmake_symbolic_link
);
2411 if (!NILP (handler
))
2412 RETURN_UNGCPRO (call4 (handler
, Qmake_symbolic_link
, filename
,
2413 linkname
, ok_if_already_exists
));
2415 if (NILP (ok_if_already_exists
)
2416 || INTEGERP (ok_if_already_exists
))
2417 barf_or_query_if_file_exists (linkname
, "make it a link",
2418 INTEGERP (ok_if_already_exists
), 0);
2419 if (0 > symlink (XSTRING (filename
)->data
, XSTRING (linkname
)->data
))
2421 /* If we didn't complain already, silently delete existing file. */
2422 if (errno
== EEXIST
)
2424 unlink (XSTRING (linkname
)->data
);
2425 if (0 <= symlink (XSTRING (filename
)->data
, XSTRING (linkname
)->data
))
2435 report_file_error ("Making symbolic link", Flist (2, args
));
2437 report_file_error ("Making symbolic link", Flist (2, &filename
));
2443 #endif /* S_IFLNK */
2447 DEFUN ("define-logical-name", Fdefine_logical_name
, Sdefine_logical_name
,
2448 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2449 "Define the job-wide logical name NAME to have the value STRING.\n\
2450 If STRING is nil or a null string, the logical name NAME is deleted.")
2455 CHECK_STRING (name
, 0);
2457 delete_logical_name (XSTRING (name
)->data
);
2460 CHECK_STRING (string
, 1);
2462 if (XSTRING (string
)->size
== 0)
2463 delete_logical_name (XSTRING (name
)->data
);
2465 define_logical_name (XSTRING (name
)->data
, XSTRING (string
)->data
);
2474 DEFUN ("sysnetunam", Fsysnetunam
, Ssysnetunam
, 2, 2, 0,
2475 "Open a network connection to PATH using LOGIN as the login string.")
2477 Lisp_Object path
, login
;
2481 CHECK_STRING (path
, 0);
2482 CHECK_STRING (login
, 0);
2484 netresult
= netunam (XSTRING (path
)->data
, XSTRING (login
)->data
);
2486 if (netresult
== -1)
2491 #endif /* HPUX_NET */
2493 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p
, Sfile_name_absolute_p
,
2495 "Return t if file FILENAME specifies an absolute file name.\n\
2496 On Unix, this is a name starting with a `/' or a `~'.")
2498 Lisp_Object filename
;
2502 CHECK_STRING (filename
, 0);
2503 ptr
= XSTRING (filename
)->data
;
2504 if (IS_DIRECTORY_SEP (*ptr
) || *ptr
== '~'
2506 /* ??? This criterion is probably wrong for '<'. */
2507 || index (ptr
, ':') || index (ptr
, '<')
2508 || (*ptr
== '[' && (ptr
[1] != '-' || (ptr
[2] != '.' && ptr
[2] != ']'))
2512 || (IS_DRIVE (*ptr
) && ptr
[1] == ':' && IS_DIRECTORY_SEP (ptr
[2]))
2520 /* Return nonzero if file FILENAME exists and can be executed. */
2523 check_executable (filename
)
2527 int len
= strlen (filename
);
2530 if (stat (filename
, &st
) < 0)
2532 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2533 return ((st
.st_mode
& S_IEXEC
) != 0);
2535 return (S_ISREG (st
.st_mode
)
2537 && (stricmp ((suffix
= filename
+ len
-4), ".com") == 0
2538 || stricmp (suffix
, ".exe") == 0
2539 || stricmp (suffix
, ".bat") == 0)
2540 || (st
.st_mode
& S_IFMT
) == S_IFDIR
);
2541 #endif /* not WINDOWSNT */
2542 #else /* not DOS_NT */
2543 #ifdef HAVE_EUIDACCESS
2544 return (euidaccess (filename
, 1) >= 0);
2546 /* Access isn't quite right because it uses the real uid
2547 and we really want to test with the effective uid.
2548 But Unix doesn't give us a right way to do it. */
2549 return (access (filename
, 1) >= 0);
2551 #endif /* not DOS_NT */
2554 /* Return nonzero if file FILENAME exists and can be written. */
2557 check_writable (filename
)
2562 if (stat (filename
, &st
) < 0)
2564 return (st
.st_mode
& S_IWRITE
|| (st
.st_mode
& S_IFMT
) == S_IFDIR
);
2565 #else /* not MSDOS */
2566 #ifdef HAVE_EUIDACCESS
2567 return (euidaccess (filename
, 2) >= 0);
2569 /* Access isn't quite right because it uses the real uid
2570 and we really want to test with the effective uid.
2571 But Unix doesn't give us a right way to do it.
2572 Opening with O_WRONLY could work for an ordinary file,
2573 but would lose for directories. */
2574 return (access (filename
, 2) >= 0);
2576 #endif /* not MSDOS */
2579 DEFUN ("file-exists-p", Ffile_exists_p
, Sfile_exists_p
, 1, 1, 0,
2580 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2581 See also `file-readable-p' and `file-attributes'.")
2583 Lisp_Object filename
;
2585 Lisp_Object absname
;
2586 Lisp_Object handler
;
2587 struct stat statbuf
;
2589 CHECK_STRING (filename
, 0);
2590 absname
= Fexpand_file_name (filename
, Qnil
);
2592 /* If the file name has special constructs in it,
2593 call the corresponding file handler. */
2594 handler
= Ffind_file_name_handler (absname
, Qfile_exists_p
);
2595 if (!NILP (handler
))
2596 return call2 (handler
, Qfile_exists_p
, absname
);
2598 return (stat (XSTRING (absname
)->data
, &statbuf
) >= 0) ? Qt
: Qnil
;
2601 DEFUN ("file-executable-p", Ffile_executable_p
, Sfile_executable_p
, 1, 1, 0,
2602 "Return t if FILENAME can be executed by you.\n\
2603 For a directory, this means you can access files in that directory.")
2605 Lisp_Object filename
;
2608 Lisp_Object absname
;
2609 Lisp_Object handler
;
2611 CHECK_STRING (filename
, 0);
2612 absname
= Fexpand_file_name (filename
, Qnil
);
2614 /* If the file name has special constructs in it,
2615 call the corresponding file handler. */
2616 handler
= Ffind_file_name_handler (absname
, Qfile_executable_p
);
2617 if (!NILP (handler
))
2618 return call2 (handler
, Qfile_executable_p
, absname
);
2620 return (check_executable (XSTRING (absname
)->data
) ? Qt
: Qnil
);
2623 DEFUN ("file-readable-p", Ffile_readable_p
, Sfile_readable_p
, 1, 1, 0,
2624 "Return t if file FILENAME exists and you can read it.\n\
2625 See also `file-exists-p' and `file-attributes'.")
2627 Lisp_Object filename
;
2629 Lisp_Object absname
;
2630 Lisp_Object handler
;
2633 struct stat statbuf
;
2635 CHECK_STRING (filename
, 0);
2636 absname
= Fexpand_file_name (filename
, Qnil
);
2638 /* If the file name has special constructs in it,
2639 call the corresponding file handler. */
2640 handler
= Ffind_file_name_handler (absname
, Qfile_readable_p
);
2641 if (!NILP (handler
))
2642 return call2 (handler
, Qfile_readable_p
, absname
);
2645 /* Under MS-DOS and Windows, open does not work for directories. */
2646 if (access (XSTRING (absname
)->data
, 0) == 0)
2649 #else /* not DOS_NT */
2651 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
2652 /* Opening a fifo without O_NONBLOCK can wait.
2653 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2654 except in the case of a fifo, on a system which handles it. */
2655 desc
= stat (XSTRING (absname
)->data
, &statbuf
);
2658 if (S_ISFIFO (statbuf
.st_mode
))
2659 flags
|= O_NONBLOCK
;
2661 desc
= open (XSTRING (absname
)->data
, flags
);
2666 #endif /* not DOS_NT */
2669 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2671 DEFUN ("file-writable-p", Ffile_writable_p
, Sfile_writable_p
, 1, 1, 0,
2672 "Return t if file FILENAME can be written or created by you.")
2674 Lisp_Object filename
;
2676 Lisp_Object absname
, dir
;
2677 Lisp_Object handler
;
2678 struct stat statbuf
;
2680 CHECK_STRING (filename
, 0);
2681 absname
= Fexpand_file_name (filename
, Qnil
);
2683 /* If the file name has special constructs in it,
2684 call the corresponding file handler. */
2685 handler
= Ffind_file_name_handler (absname
, Qfile_writable_p
);
2686 if (!NILP (handler
))
2687 return call2 (handler
, Qfile_writable_p
, absname
);
2689 if (stat (XSTRING (absname
)->data
, &statbuf
) >= 0)
2690 return (check_writable (XSTRING (absname
)->data
)
2692 dir
= Ffile_name_directory (absname
);
2695 dir
= Fdirectory_file_name (dir
);
2699 dir
= Fdirectory_file_name (dir
);
2701 return (check_writable (!NILP (dir
) ? (char *) XSTRING (dir
)->data
: "")
2705 DEFUN ("access-file", Faccess_file
, Saccess_file
, 2, 2, 0,
2706 "Access file FILENAME, and get an error if that does not work.\n\
2707 The second argument STRING is used in the error message.\n\
2708 If there is no error, we return nil.")
2710 Lisp_Object filename
, string
;
2712 Lisp_Object handler
;
2715 CHECK_STRING (filename
, 0);
2717 /* If the file name has special constructs in it,
2718 call the corresponding file handler. */
2719 handler
= Ffind_file_name_handler (filename
, Qaccess_file
);
2720 if (!NILP (handler
))
2721 return call3 (handler
, Qaccess_file
, filename
, string
);
2723 fd
= open (XSTRING (filename
)->data
, O_RDONLY
);
2725 report_file_error (XSTRING (string
)->data
, Fcons (filename
, Qnil
));
2731 DEFUN ("file-symlink-p", Ffile_symlink_p
, Sfile_symlink_p
, 1, 1, 0,
2732 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2733 The value is the name of the file to which it is linked.\n\
2734 Otherwise returns nil.")
2736 Lisp_Object filename
;
2743 Lisp_Object handler
;
2745 CHECK_STRING (filename
, 0);
2746 filename
= Fexpand_file_name (filename
, Qnil
);
2748 /* If the file name has special constructs in it,
2749 call the corresponding file handler. */
2750 handler
= Ffind_file_name_handler (filename
, Qfile_symlink_p
);
2751 if (!NILP (handler
))
2752 return call2 (handler
, Qfile_symlink_p
, filename
);
2757 buf
= (char *) xmalloc (bufsize
);
2758 bzero (buf
, bufsize
);
2759 valsize
= readlink (XSTRING (filename
)->data
, buf
, bufsize
);
2760 if (valsize
< bufsize
) break;
2761 /* Buffer was not long enough */
2770 val
= make_string (buf
, valsize
);
2773 #else /* not S_IFLNK */
2775 #endif /* not S_IFLNK */
2778 DEFUN ("file-directory-p", Ffile_directory_p
, Sfile_directory_p
, 1, 1, 0,
2779 "Return t if file FILENAME is the name of a directory as a file.\n\
2780 A directory name spec may be given instead; then the value is t\n\
2781 if the directory so specified exists and really is a directory.")
2783 Lisp_Object filename
;
2785 register Lisp_Object absname
;
2787 Lisp_Object handler
;
2789 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2791 /* If the file name has special constructs in it,
2792 call the corresponding file handler. */
2793 handler
= Ffind_file_name_handler (absname
, Qfile_directory_p
);
2794 if (!NILP (handler
))
2795 return call2 (handler
, Qfile_directory_p
, absname
);
2797 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2799 return (st
.st_mode
& S_IFMT
) == S_IFDIR
? Qt
: Qnil
;
2802 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p
, Sfile_accessible_directory_p
, 1, 1, 0,
2803 "Return t if file FILENAME is the name of a directory as a file,\n\
2804 and files in that directory can be opened by you. In order to use a\n\
2805 directory as a buffer's current directory, this predicate must return true.\n\
2806 A directory name spec may be given instead; then the value is t\n\
2807 if the directory so specified exists and really is a readable and\n\
2808 searchable directory.")
2810 Lisp_Object filename
;
2812 Lisp_Object handler
;
2814 struct gcpro gcpro1
;
2816 /* If the file name has special constructs in it,
2817 call the corresponding file handler. */
2818 handler
= Ffind_file_name_handler (filename
, Qfile_accessible_directory_p
);
2819 if (!NILP (handler
))
2820 return call2 (handler
, Qfile_accessible_directory_p
, filename
);
2822 /* It's an unlikely combination, but yes we really do need to gcpro:
2823 Suppose that file-accessible-directory-p has no handler, but
2824 file-directory-p does have a handler; this handler causes a GC which
2825 relocates the string in `filename'; and finally file-directory-p
2826 returns non-nil. Then we would end up passing a garbaged string
2827 to file-executable-p. */
2829 tem
= (NILP (Ffile_directory_p (filename
))
2830 || NILP (Ffile_executable_p (filename
)));
2832 return tem
? Qnil
: Qt
;
2835 DEFUN ("file-regular-p", Ffile_regular_p
, Sfile_regular_p
, 1, 1, 0,
2836 "Return t if file FILENAME is the name of a regular file.\n\
2837 This is the sort of file that holds an ordinary stream of data bytes.")
2839 Lisp_Object filename
;
2841 register Lisp_Object absname
;
2843 Lisp_Object handler
;
2845 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2847 /* If the file name has special constructs in it,
2848 call the corresponding file handler. */
2849 handler
= Ffind_file_name_handler (absname
, Qfile_regular_p
);
2850 if (!NILP (handler
))
2851 return call2 (handler
, Qfile_regular_p
, absname
);
2853 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2855 return (st
.st_mode
& S_IFMT
) == S_IFREG
? Qt
: Qnil
;
2858 DEFUN ("file-modes", Ffile_modes
, Sfile_modes
, 1, 1, 0,
2859 "Return mode bits of file named FILENAME, as an integer.")
2861 Lisp_Object filename
;
2863 Lisp_Object absname
;
2865 Lisp_Object handler
;
2867 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2869 /* If the file name has special constructs in it,
2870 call the corresponding file handler. */
2871 handler
= Ffind_file_name_handler (absname
, Qfile_modes
);
2872 if (!NILP (handler
))
2873 return call2 (handler
, Qfile_modes
, absname
);
2875 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2877 #if defined (MSDOS) && __DJGPP__ < 2
2878 if (check_executable (XSTRING (absname
)->data
))
2879 st
.st_mode
|= S_IEXEC
;
2880 #endif /* MSDOS && __DJGPP__ < 2 */
2882 return make_number (st
.st_mode
& 07777);
2885 DEFUN ("set-file-modes", Fset_file_modes
, Sset_file_modes
, 2, 2, 0,
2886 "Set mode bits of file named FILENAME to MODE (an integer).\n\
2887 Only the 12 low bits of MODE are used.")
2889 Lisp_Object filename
, mode
;
2891 Lisp_Object absname
;
2892 Lisp_Object handler
;
2894 absname
= Fexpand_file_name (filename
, current_buffer
->directory
);
2895 CHECK_NUMBER (mode
, 1);
2897 /* If the file name has special constructs in it,
2898 call the corresponding file handler. */
2899 handler
= Ffind_file_name_handler (absname
, Qset_file_modes
);
2900 if (!NILP (handler
))
2901 return call3 (handler
, Qset_file_modes
, absname
, mode
);
2903 if (chmod (XSTRING (absname
)->data
, XINT (mode
)) < 0)
2904 report_file_error ("Doing chmod", Fcons (absname
, Qnil
));
2909 DEFUN ("set-default-file-modes", Fset_default_file_modes
, Sset_default_file_modes
, 1, 1, 0,
2910 "Set the file permission bits for newly created files.\n\
2911 The argument MODE should be an integer; only the low 9 bits are used.\n\
2912 This setting is inherited by subprocesses.")
2916 CHECK_NUMBER (mode
, 0);
2918 umask ((~ XINT (mode
)) & 0777);
2923 DEFUN ("default-file-modes", Fdefault_file_modes
, Sdefault_file_modes
, 0, 0, 0,
2924 "Return the default file protection for created files.\n\
2925 The value is an integer.")
2931 realmask
= umask (0);
2934 XSETINT (value
, (~ realmask
) & 0777);
2940 DEFUN ("unix-sync", Funix_sync
, Sunix_sync
, 0, 0, "",
2941 "Tell Unix to finish all pending disk updates.")
2950 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p
, Sfile_newer_than_file_p
, 2, 2, 0,
2951 "Return t if file FILE1 is newer than file FILE2.\n\
2952 If FILE1 does not exist, the answer is nil;\n\
2953 otherwise, if FILE2 does not exist, the answer is t.")
2955 Lisp_Object file1
, file2
;
2957 Lisp_Object absname1
, absname2
;
2960 Lisp_Object handler
;
2961 struct gcpro gcpro1
, gcpro2
;
2963 CHECK_STRING (file1
, 0);
2964 CHECK_STRING (file2
, 0);
2967 GCPRO2 (absname1
, file2
);
2968 absname1
= expand_and_dir_to_file (file1
, current_buffer
->directory
);
2969 absname2
= expand_and_dir_to_file (file2
, current_buffer
->directory
);
2972 /* If the file name has special constructs in it,
2973 call the corresponding file handler. */
2974 handler
= Ffind_file_name_handler (absname1
, Qfile_newer_than_file_p
);
2976 handler
= Ffind_file_name_handler (absname2
, Qfile_newer_than_file_p
);
2977 if (!NILP (handler
))
2978 return call3 (handler
, Qfile_newer_than_file_p
, absname1
, absname2
);
2980 if (stat (XSTRING (absname1
)->data
, &st
) < 0)
2983 mtime1
= st
.st_mtime
;
2985 if (stat (XSTRING (absname2
)->data
, &st
) < 0)
2988 return (mtime1
> st
.st_mtime
) ? Qt
: Qnil
;
2992 Lisp_Object Qfind_buffer_file_type
;
2995 #ifndef READ_BUF_SIZE
2996 #define READ_BUF_SIZE (64 << 10)
2999 DEFUN ("insert-file-contents", Finsert_file_contents
, Sinsert_file_contents
,
3001 "Insert contents of file FILENAME after point.\n\
3002 Returns list of absolute file name and length of data inserted.\n\
3003 If second argument VISIT is non-nil, the buffer's visited filename\n\
3004 and last save file modtime are set, and it is marked unmodified.\n\
3005 If visiting and the file does not exist, visiting is completed\n\
3006 before the error is signaled.\n\
3007 The optional third and fourth arguments BEG and END\n\
3008 specify what portion of the file to insert.\n\
3009 If VISIT is non-nil, BEG and END must be nil.\n\
3011 If optional fifth argument REPLACE is non-nil,\n\
3012 it means replace the current buffer contents (in the accessible portion)\n\
3013 with the file contents. This is better than simply deleting and inserting\n\
3014 the whole thing because (1) it preserves some marker positions\n\
3015 and (2) it puts less data in the undo list.\n\
3016 When REPLACE is non-nil, the value is the number of characters actually read,\n\
3017 which is often less than the number of characters to be read.\n\
3018 This does code conversion according to the value of\n\
3019 `coding-system-for-read' or `coding-system-alist', and sets the variable\n\
3020 `last-coding-system-used' to the coding system actually used.")
3021 (filename
, visit
, beg
, end
, replace
)
3022 Lisp_Object filename
, visit
, beg
, end
, replace
;
3026 register int inserted
= 0;
3027 register int how_much
;
3028 register int unprocessed
;
3029 int count
= specpdl_ptr
- specpdl
;
3030 struct gcpro gcpro1
, gcpro2
, gcpro3
;
3031 Lisp_Object handler
, val
, insval
;
3034 int not_regular
= 0;
3035 char read_buf
[READ_BUF_SIZE
];
3036 struct coding_system coding
;
3037 unsigned char buffer
[1 << 14];
3038 int replace_handled
= 0;
3040 if (current_buffer
->base_buffer
&& ! NILP (visit
))
3041 error ("Cannot do file visiting in an indirect buffer");
3043 if (!NILP (current_buffer
->read_only
))
3044 Fbarf_if_buffer_read_only ();
3049 GCPRO3 (filename
, val
, p
);
3051 CHECK_STRING (filename
, 0);
3052 filename
= Fexpand_file_name (filename
, Qnil
);
3054 /* If the file name has special constructs in it,
3055 call the corresponding file handler. */
3056 handler
= Ffind_file_name_handler (filename
, Qinsert_file_contents
);
3057 if (!NILP (handler
))
3059 val
= call6 (handler
, Qinsert_file_contents
, filename
,
3060 visit
, beg
, end
, replace
);
3064 /* Decide the coding-system of the file. */
3066 Lisp_Object val
= Vcoding_system_for_read
;
3067 if (NILP (current_buffer
->enable_multibyte_characters
))
3069 else if (NILP (val
))
3071 Lisp_Object args
[6], coding_systems
;
3073 args
[0] = Qinsert_file_contents
, args
[1] = filename
, args
[2] = visit
,
3074 args
[3] = beg
, args
[4] = end
, args
[5] = replace
;
3075 coding_systems
= Ffind_coding_system (6, args
);
3076 val
= CONSP (coding_systems
) ? XCONS (coding_systems
)->car
: Qnil
;
3078 setup_coding_system (Fcheck_coding_system (val
), &coding
);
3084 if (stat (XSTRING (filename
)->data
, &st
) < 0)
3086 if ((fd
= open (XSTRING (filename
)->data
, O_RDONLY
)) < 0
3087 || fstat (fd
, &st
) < 0)
3088 #endif /* not APOLLO */
3090 if (fd
>= 0) close (fd
);
3093 report_file_error ("Opening input file", Fcons (filename
, Qnil
));
3100 /* This code will need to be changed in order to work on named
3101 pipes, and it's probably just not worth it. So we should at
3102 least signal an error. */
3103 if (!S_ISREG (st
.st_mode
))
3110 if (! NILP (replace
) || ! NILP (beg
) || ! NILP (end
))
3111 Fsignal (Qfile_error
,
3112 Fcons (build_string ("not a regular file"),
3113 Fcons (filename
, Qnil
)));
3118 if ((fd
= open (XSTRING (filename
)->data
, O_RDONLY
)) < 0)
3121 /* Replacement should preserve point as it preserves markers. */
3122 if (!NILP (replace
))
3123 record_unwind_protect (restore_point_unwind
, Fpoint_marker ());
3125 record_unwind_protect (close_file_unwind
, make_number (fd
));
3127 /* Supposedly happens on VMS. */
3128 if (! not_regular
&& st
.st_size
< 0)
3129 error ("File size is negative");
3131 if (!NILP (beg
) || !NILP (end
))
3133 error ("Attempt to visit less than an entire file");
3136 CHECK_NUMBER (beg
, 0);
3138 XSETFASTINT (beg
, 0);
3141 CHECK_NUMBER (end
, 0);
3146 XSETINT (end
, st
.st_size
);
3147 if (XINT (end
) != st
.st_size
)
3148 error ("Maximum buffer size exceeded");
3152 /* If requested, replace the accessible part of the buffer
3153 with the file contents. Avoid replacing text at the
3154 beginning or end of the buffer that matches the file contents;
3155 that preserves markers pointing to the unchanged parts.
3157 Here we implement this feature in an optimized way
3158 for the case where code conversion is NOT needed.
3159 The following if-statement handles the case of conversion
3160 in a less optimal way.
3162 If the code conversion is "automatic" then we try using this
3163 method and hope for the best.
3164 But if we discover the need for conversion, we give up on this method
3165 and let the following if-statement handle the replace job. */
3167 && (! CODING_REQUIRE_CONVERSION (&coding
)
3168 || (coding
.type
== coding_type_automatic
3169 && ! CODING_REQUIRE_TEXT_CONVERSION (&coding
))
3170 || (coding
.eol_type
== CODING_EOL_AUTOMATIC
3171 && ! CODING_REQUIRE_EOL_CONVERSION (&coding
))))
3173 int same_at_start
= BEGV
;
3174 int same_at_end
= ZV
;
3176 /* There is still a possibility we will find the need to do code
3177 conversion. If that happens, we set this variable to 1 to
3178 give up on handling REPLACE in the optimized way. */
3179 int giveup_match_end
= 0;
3181 if (XINT (beg
) != 0)
3183 if (lseek (fd
, XINT (beg
), 0) < 0)
3184 report_file_error ("Setting file position",
3185 Fcons (filename
, Qnil
));
3190 /* Count how many chars at the start of the file
3191 match the text at the beginning of the buffer. */
3196 nread
= read (fd
, buffer
, sizeof buffer
);
3198 error ("IO error reading %s: %s",
3199 XSTRING (filename
)->data
, strerror (errno
));
3200 else if (nread
== 0)
3203 if (coding
.type
== coding_type_automatic
)
3204 detect_coding (&coding
, buffer
, nread
);
3205 if (CODING_REQUIRE_TEXT_CONVERSION (&coding
))
3206 /* We found that the file should be decoded somehow.
3207 Let's give up here. */
3209 giveup_match_end
= 1;
3213 if (coding
.eol_type
== CODING_EOL_AUTOMATIC
)
3214 detect_eol (&coding
, buffer
, nread
);
3215 if (CODING_REQUIRE_EOL_CONVERSION (&coding
))
3216 /* We found that the format of eol should be decoded.
3217 Let's give up here. */
3219 giveup_match_end
= 1;
3224 while (bufpos
< nread
&& same_at_start
< ZV
3225 && FETCH_BYTE (same_at_start
) == buffer
[bufpos
])
3226 same_at_start
++, bufpos
++;
3227 /* If we found a discrepancy, stop the scan.
3228 Otherwise loop around and scan the next bufferful. */
3229 if (bufpos
!= nread
)
3233 /* If the file matches the buffer completely,
3234 there's no need to replace anything. */
3235 if (same_at_start
- BEGV
== XINT (end
))
3239 /* Truncate the buffer to the size of the file. */
3240 del_range_1 (same_at_start
, same_at_end
, 0);
3245 /* Count how many chars at the end of the file
3246 match the text at the end of the buffer. But, if we have
3247 already found that decoding is necessary, don't waste time. */
3248 while (!giveup_match_end
)
3250 int total_read
, nread
, bufpos
, curpos
, trial
;
3252 /* At what file position are we now scanning? */
3253 curpos
= XINT (end
) - (ZV
- same_at_end
);
3254 /* If the entire file matches the buffer tail, stop the scan. */
3257 /* How much can we scan in the next step? */
3258 trial
= min (curpos
, sizeof buffer
);
3259 if (lseek (fd
, curpos
- trial
, 0) < 0)
3260 report_file_error ("Setting file position",
3261 Fcons (filename
, Qnil
));
3264 while (total_read
< trial
)
3266 nread
= read (fd
, buffer
+ total_read
, trial
- total_read
);
3268 error ("IO error reading %s: %s",
3269 XSTRING (filename
)->data
, strerror (errno
));
3270 total_read
+= nread
;
3272 /* Scan this bufferful from the end, comparing with
3273 the Emacs buffer. */
3274 bufpos
= total_read
;
3275 /* Compare with same_at_start to avoid counting some buffer text
3276 as matching both at the file's beginning and at the end. */
3277 while (bufpos
> 0 && same_at_end
> same_at_start
3278 && FETCH_BYTE (same_at_end
- 1) == buffer
[bufpos
- 1])
3279 same_at_end
--, bufpos
--;
3281 /* If we found a discrepancy, stop the scan.
3282 Otherwise loop around and scan the preceding bufferful. */
3285 /* If this discrepancy is because of code conversion,
3286 we cannot use this method; giveup and try the other. */
3287 if (same_at_end
> same_at_start
3288 && FETCH_BYTE (same_at_end
- 1) >= 0200
3289 && ! NILP (current_buffer
->enable_multibyte_characters
))
3290 giveup_match_end
= 1;
3296 if (! giveup_match_end
)
3298 /* We win! We can handle REPLACE the optimized way. */
3300 /* Don't try to reuse the same piece of text twice. */
3301 overlap
= same_at_start
- BEGV
- (same_at_end
+ st
.st_size
- ZV
);
3303 same_at_end
+= overlap
;
3305 /* Arrange to read only the nonmatching middle part of the file. */
3306 XSETFASTINT (beg
, XINT (beg
) + (same_at_start
- BEGV
));
3307 XSETFASTINT (end
, XINT (end
) - (ZV
- same_at_end
));
3309 del_range_1 (same_at_start
, same_at_end
, 0);
3310 /* Insert from the file at the proper position. */
3311 SET_PT (same_at_start
);
3313 /* If display currently starts at beginning of line,
3314 keep it that way. */
3315 if (XBUFFER (XWINDOW (selected_window
)->buffer
) == current_buffer
)
3316 XWINDOW (selected_window
)->start_at_line_beg
= Fbolp ();
3318 replace_handled
= 1;
3322 /* If requested, replace the accessible part of the buffer
3323 with the file contents. Avoid replacing text at the
3324 beginning or end of the buffer that matches the file contents;
3325 that preserves markers pointing to the unchanged parts.
3327 Here we implement this feature for the case where code conversion
3328 is needed, in a simple way that needs a lot of memory.
3329 The preceding if-statement handles the case of no conversion
3330 in a more optimized way. */
3331 if (!NILP (replace
) && ! replace_handled
)
3333 int same_at_start
= BEGV
;
3334 int same_at_end
= ZV
;
3337 /* Make sure that the gap is large enough. */
3338 int bufsize
= 2 * st
.st_size
;
3339 unsigned char *conversion_buffer
= (unsigned char *) malloc (bufsize
);
3341 /* First read the whole file, performing code conversion into
3342 CONVERSION_BUFFER. */
3344 if (lseek (fd
, XINT (beg
), 0) < 0)
3346 free (conversion_buffer
);
3347 report_file_error ("Setting file position",
3348 Fcons (filename
, Qnil
));
3351 total
= st
.st_size
; /* Total bytes in the file. */
3352 how_much
= 0; /* Bytes read from file so far. */
3353 inserted
= 0; /* Bytes put into CONVERSION_BUFFER so far. */
3354 unprocessed
= 0; /* Bytes not processed in previous loop. */
3356 while (how_much
< total
)
3358 /* try is reserved in some compilers (Microsoft C) */
3359 int trytry
= min (total
- how_much
, READ_BUF_SIZE
- unprocessed
);
3360 char *destination
= read_buf
+ unprocessed
;
3363 /* Allow quitting out of the actual I/O. */
3366 this = read (fd
, destination
, trytry
);
3369 if (this < 0 || this + unprocessed
== 0)
3377 if (CODING_REQUIRE_CONVERSION (&coding
))
3379 int require
, produced
, consumed
;
3381 this += unprocessed
;
3383 /* If we are using more space than estimated,
3384 make CONVERSION_BUFFER bigger. */
3385 require
= decoding_buffer_size (&coding
, this);
3386 if (inserted
+ require
+ 2 * (total
- how_much
) > bufsize
)
3388 bufsize
= inserted
+ require
+ 2 * (total
- how_much
);
3389 conversion_buffer
= (unsigned char *) realloc (conversion_buffer
, bufsize
);
3392 /* Convert this batch with results in CONVERSION_BUFFER. */
3393 if (how_much
>= total
) /* This is the last block. */
3394 coding
.last_block
= 1;
3395 produced
= decode_coding (&coding
, read_buf
,
3396 conversion_buffer
+ inserted
,
3397 this, bufsize
- inserted
,
3400 /* Save for next iteration whatever we didn't convert. */
3401 unprocessed
= this - consumed
;
3402 bcopy (read_buf
+ consumed
, read_buf
, unprocessed
);
3409 /* At this point, INSERTED is how many characters
3410 are present in CONVERSION_BUFFER.
3411 HOW_MUCH should equal TOTAL,
3412 or should be <= 0 if we couldn't read the file. */
3416 free (conversion_buffer
);
3419 error ("IO error reading %s: %s",
3420 XSTRING (filename
)->data
, strerror (errno
));
3421 else if (how_much
== -2)
3422 error ("maximum buffer size exceeded");
3425 /* Compare the beginning of the converted file
3426 with the buffer text. */
3429 while (bufpos
< inserted
&& same_at_start
< same_at_end
3430 && FETCH_BYTE (same_at_start
) == conversion_buffer
[bufpos
])
3431 same_at_start
++, bufpos
++;
3433 /* If the file matches the buffer completely,
3434 there's no need to replace anything. */
3436 if (bufpos
== inserted
)
3438 free (conversion_buffer
);
3441 /* Truncate the buffer to the size of the file. */
3442 del_range_1 (same_at_start
, same_at_end
, 0);
3446 /* Scan this bufferful from the end, comparing with
3447 the Emacs buffer. */
3450 /* Compare with same_at_start to avoid counting some buffer text
3451 as matching both at the file's beginning and at the end. */
3452 while (bufpos
> 0 && same_at_end
> same_at_start
3453 && FETCH_BYTE (same_at_end
- 1) == conversion_buffer
[bufpos
- 1])
3454 same_at_end
--, bufpos
--;
3456 /* Don't try to reuse the same piece of text twice. */
3457 overlap
= same_at_start
- BEGV
- (same_at_end
+ inserted
- ZV
);
3459 same_at_end
+= overlap
;
3461 /* If display currently starts at beginning of line,
3462 keep it that way. */
3463 if (XBUFFER (XWINDOW (selected_window
)->buffer
) == current_buffer
)
3464 XWINDOW (selected_window
)->start_at_line_beg
= Fbolp ();
3466 /* Replace the chars that we need to replace,
3467 and update INSERTED to equal the number of bytes
3468 we are taking from the file. */
3469 inserted
-= (Z
- same_at_end
) + (same_at_start
- BEG
);
3470 move_gap (same_at_start
);
3471 del_range_1 (same_at_start
, same_at_end
, 0);
3472 SET_PT (same_at_start
);
3473 insert_1 (conversion_buffer
+ same_at_start
- BEG
, inserted
, 0, 0);
3475 free (conversion_buffer
);
3484 register Lisp_Object temp
;
3486 total
= XINT (end
) - XINT (beg
);
3488 /* Make sure point-max won't overflow after this insertion. */
3489 XSETINT (temp
, total
);
3490 if (total
!= XINT (temp
))
3491 error ("Maximum buffer size exceeded");
3494 /* For a special file, all we can do is guess. */
3495 total
= READ_BUF_SIZE
;
3497 if (NILP (visit
) && total
> 0)
3498 prepare_to_modify_buffer (PT
, PT
);
3501 if (GAP_SIZE
< total
)
3502 make_gap (total
- GAP_SIZE
);
3504 if (XINT (beg
) != 0 || !NILP (replace
))
3506 if (lseek (fd
, XINT (beg
), 0) < 0)
3507 report_file_error ("Setting file position", Fcons (filename
, Qnil
));
3510 /* In the following loop, HOW_MUCH contains the total bytes read so
3511 far. Before exiting the loop, it is set to -1 if I/O error
3512 occurs, set to -2 if the maximum buffer size is exceeded. */
3514 /* Total bytes inserted. */
3516 /* Bytes not processed in the previous loop because short gap size. */
3518 while (how_much
< total
)
3520 /* try is reserved in some compilers (Microsoft C) */
3521 int trytry
= min (total
- how_much
, READ_BUF_SIZE
- unprocessed
);
3522 char *destination
= (CODING_REQUIRE_CONVERSION (&coding
)
3523 ? read_buf
+ unprocessed
3524 : (char *) (POS_ADDR (PT
+ inserted
- 1) + 1));
3527 /* Allow quitting out of the actual I/O. */
3530 this = read (fd
, destination
, trytry
);
3533 if (this < 0 || this + unprocessed
== 0)
3539 /* For a regular file, where TOTAL is the real size,
3540 count HOW_MUCH to compare with it.
3541 For a special file, where TOTAL is just a buffer size,
3542 so don't bother counting in HOW_MUCH.
3543 (INSERTED is where we count the number of characters inserted.) */
3547 if (CODING_REQUIRE_CONVERSION (&coding
))
3549 int require
, produced
, consumed
;
3551 this += unprocessed
;
3552 /* Make sure that the gap is large enough. */
3553 require
= decoding_buffer_size (&coding
, this);
3554 if (GAP_SIZE
< require
)
3555 make_gap (require
- GAP_SIZE
);
3559 if (how_much
>= total
) /* This is the last block. */
3560 coding
.last_block
= 1;
3564 /* If we encounter EOF, say it is the last block. (The
3565 data this will apply to is the UNPROCESSED characters
3566 carried over from the last batch.) */
3568 coding
.last_block
= 1;
3571 produced
= decode_coding (&coding
, read_buf
,
3572 POS_ADDR (PT
+ inserted
- 1) + 1,
3573 this, GAP_SIZE
, &consumed
);
3578 XSET (temp
, Lisp_Int
, Z
+ produced
);
3579 if (Z
+ produced
!= XINT (temp
))
3585 unprocessed
= this - consumed
;
3586 bcopy (read_buf
+ consumed
, read_buf
, unprocessed
);
3595 /* Put an anchor to ensure multi-byte form ends at gap. */
3600 /* We don't have to consider file type of MSDOS because all files
3601 are read as binary and end-of-line format has already been
3602 decoded appropriately. */
3605 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3606 /* Determine file type from name and remove LFs from CR-LFs if the file
3607 is deemed to be a text file. */
3609 current_buffer
->buffer_file_type
3610 = call1 (Qfind_buffer_file_type
, filename
);
3611 if (NILP (current_buffer
->buffer_file_type
))
3614 = inserted
- crlf_to_lf (inserted
, POS_ADDR (PT
- 1) + 1);
3617 GPT
-= reduced_size
;
3618 GAP_SIZE
+= reduced_size
;
3619 inserted
-= reduced_size
;
3627 record_insert (PT
, inserted
);
3629 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
3630 offset_intervals (current_buffer
, PT
, inserted
);
3636 /* Discard the unwind protect for closing the file. */
3640 error ("IO error reading %s: %s",
3641 XSTRING (filename
)->data
, strerror (errno
));
3642 else if (how_much
== -2)
3643 error ("maximum buffer size exceeded");
3650 if (!EQ (current_buffer
->undo_list
, Qt
))
3651 current_buffer
->undo_list
= Qnil
;
3653 stat (XSTRING (filename
)->data
, &st
);
3658 current_buffer
->modtime
= st
.st_mtime
;
3659 current_buffer
->filename
= filename
;
3662 SAVE_MODIFF
= MODIFF
;
3663 current_buffer
->auto_save_modified
= MODIFF
;
3664 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3665 #ifdef CLASH_DETECTION
3668 if (!NILP (current_buffer
->file_truename
))
3669 unlock_file (current_buffer
->file_truename
);
3670 unlock_file (filename
);
3672 #endif /* CLASH_DETECTION */
3674 Fsignal (Qfile_error
,
3675 Fcons (build_string ("not a regular file"),
3676 Fcons (filename
, Qnil
)));
3678 /* If visiting nonexistent file, return nil. */
3679 if (current_buffer
->modtime
== -1)
3680 report_file_error ("Opening input file", Fcons (filename
, Qnil
));
3683 /* Decode file format */
3686 insval
= call3 (Qformat_decode
,
3687 Qnil
, make_number (inserted
), visit
);
3688 CHECK_NUMBER (insval
, 0);
3689 inserted
= XFASTINT (insval
);
3692 /* Call after-change hooks for the inserted text, aside from the case
3693 of normal visiting (not with REPLACE), which is done in a new buffer
3694 "before" the buffer is changed. */
3695 if (inserted
> 0 && total
> 0
3696 && (NILP (visit
) || !NILP (replace
)))
3697 signal_after_change (PT
, 0, inserted
);
3701 p
= Vafter_insert_file_functions
;
3702 if (!NILP (coding
.post_read_conversion
))
3703 p
= Fcons (coding
.post_read_conversion
, p
);
3707 insval
= call1 (Fcar (p
), make_number (inserted
));
3710 CHECK_NUMBER (insval
, 0);
3711 inserted
= XFASTINT (insval
);
3719 val
= Fcons (filename
,
3720 Fcons (make_number (inserted
),
3723 RETURN_UNGCPRO (unbind_to (count
, val
));
3726 static Lisp_Object
build_annotations ();
3728 /* If build_annotations switched buffers, switch back to BUF.
3729 Kill the temporary buffer that was selected in the meantime.
3731 Since this kill only the last temporary buffer, some buffers remain
3732 not killed if build_annotations switched buffers more than once.
3736 build_annotations_unwind (buf
)
3741 if (XBUFFER (buf
) == current_buffer
)
3743 tembuf
= Fcurrent_buffer ();
3745 Fkill_buffer (tembuf
);
3749 DEFUN ("write-region", Fwrite_region
, Swrite_region
, 3, 6,
3750 "r\nFWrite region to file: ",
3751 "Write current region into specified file.\n\
3752 When called from a program, takes three arguments:\n\
3753 START, END and FILENAME. START and END are buffer positions.\n\
3754 Optional fourth argument APPEND if non-nil means\n\
3755 append to existing file contents (if any).\n\
3756 Optional fifth argument VISIT if t means\n\
3757 set the last-save-file-modtime of buffer to this file's modtime\n\
3758 and mark buffer not modified.\n\
3759 If VISIT is a string, it is a second file name;\n\
3760 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3761 VISIT is also the file name to lock and unlock for clash detection.\n\
3762 If VISIT is neither t nor nil nor a string,\n\
3763 that means do not print the \"Wrote file\" message.\n\
3764 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3765 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3766 Kludgy feature: if START is a string, then that string is written\n\
3767 to the file, instead of any buffer contents, and END is ignored.\n\
3768 This does code conversion according to the value of\n\
3769 `coding-system-for-write' or `coding-system-alist', and sets the variable\n\
3770 `last-coding-system-used' to the coding system actually used.")
3771 (start
, end
, filename
, append
, visit
, lockname
)
3772 Lisp_Object start
, end
, filename
, append
, visit
, lockname
;
3780 int count
= specpdl_ptr
- specpdl
;
3783 unsigned char *fname
= 0; /* If non-0, original filename (must rename) */
3785 Lisp_Object handler
;
3786 Lisp_Object visit_file
;
3787 Lisp_Object annotations
;
3788 int visiting
, quietly
;
3789 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
3790 struct buffer
*given_buffer
;
3792 int buffer_file_type
3793 = NILP (current_buffer
->buffer_file_type
) ? O_TEXT
: O_BINARY
;
3795 struct coding_system coding
;
3797 if (current_buffer
->base_buffer
&& ! NILP (visit
))
3798 error ("Cannot do file visiting in an indirect buffer");
3800 if (!NILP (start
) && !STRINGP (start
))
3801 validate_region (&start
, &end
);
3803 GCPRO4 (start
, filename
, visit
, lockname
);
3804 filename
= Fexpand_file_name (filename
, Qnil
);
3805 if (STRINGP (visit
))
3806 visit_file
= Fexpand_file_name (visit
, Qnil
);
3808 visit_file
= filename
;
3811 visiting
= (EQ (visit
, Qt
) || STRINGP (visit
));
3812 quietly
= !NILP (visit
);
3816 if (NILP (lockname
))
3817 lockname
= visit_file
;
3819 GCPRO5 (start
, filename
, annotations
, visit_file
, lockname
);
3821 /* If the file name has special constructs in it,
3822 call the corresponding file handler. */
3823 handler
= Ffind_file_name_handler (filename
, Qwrite_region
);
3824 /* If FILENAME has no handler, see if VISIT has one. */
3825 if (NILP (handler
) && STRINGP (visit
))
3826 handler
= Ffind_file_name_handler (visit
, Qwrite_region
);
3828 if (!NILP (handler
))
3831 val
= call6 (handler
, Qwrite_region
, start
, end
,
3832 filename
, append
, visit
);
3836 SAVE_MODIFF
= MODIFF
;
3837 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3838 current_buffer
->filename
= visit_file
;
3844 /* Decide the coding-system to be encoded to. */
3848 if (auto_saving
|| NILP (current_buffer
->enable_multibyte_characters
))
3850 else if (!NILP (Vcoding_system_for_write
))
3851 val
= Vcoding_system_for_write
;
3852 else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system
,
3854 val
= Fsymbol_value (Qbuffer_file_coding_system
);
3857 Lisp_Object args
[7], coding_systems
;
3859 args
[0] = Qwrite_region
, args
[1] = start
, args
[2] = end
,
3860 args
[3] = filename
, args
[4] = append
, args
[5] = visit
,
3862 coding_systems
= Ffind_coding_system (7, args
);
3863 val
= (CONSP (coding_systems
)
3864 ? XCONS (coding_systems
)->cdr
3865 : Fsymbol_value (Qbuffer_file_coding_system
));
3867 setup_coding_system (Fcheck_coding_system (val
), &coding
);
3868 if (!STRINGP (start
) && !NILP (current_buffer
->selective_display
))
3869 coding
.selective
= 1;
3871 if (!NILP (current_buffer
->buffer_file_type
))
3872 coding
.eol_type
= CODING_EOL_LF
;
3876 /* Special kludge to simplify auto-saving. */
3879 XSETFASTINT (start
, BEG
);
3880 XSETFASTINT (end
, Z
);
3883 record_unwind_protect (build_annotations_unwind
, Fcurrent_buffer ());
3884 count1
= specpdl_ptr
- specpdl
;
3886 given_buffer
= current_buffer
;
3887 annotations
= build_annotations (start
, end
, coding
.pre_write_conversion
);
3888 if (current_buffer
!= given_buffer
)
3894 #ifdef CLASH_DETECTION
3897 /* If we've locked this file for some other buffer,
3898 query before proceeding. */
3899 if (!visiting
&& EQ (Ffile_locked_p (lockname
), Qt
))
3900 call2 (intern ("ask-user-about-lock"), fn
, Vuser_login_name
);
3902 lock_file (lockname
);
3904 #endif /* CLASH_DETECTION */
3906 fn
= XSTRING (filename
)->data
;
3910 desc
= open (fn
, O_WRONLY
| buffer_file_type
);
3911 #else /* not DOS_NT */
3912 desc
= open (fn
, O_WRONLY
);
3913 #endif /* not DOS_NT */
3915 if (desc
< 0 && (NILP (append
) || errno
== ENOENT
) )
3917 if (auto_saving
) /* Overwrite any previous version of autosave file */
3919 vms_truncate (fn
); /* if fn exists, truncate to zero length */
3920 desc
= open (fn
, O_RDWR
);
3922 desc
= creat_copy_attrs (STRINGP (current_buffer
->filename
)
3923 ? XSTRING (current_buffer
->filename
)->data
: 0,
3926 else /* Write to temporary name and rename if no errors */
3928 Lisp_Object temp_name
;
3929 temp_name
= Ffile_name_directory (filename
);
3931 if (!NILP (temp_name
))
3933 temp_name
= Fmake_temp_name (concat2 (temp_name
,
3934 build_string ("$$SAVE$$")));
3935 fname
= XSTRING (filename
)->data
;
3936 fn
= XSTRING (temp_name
)->data
;
3937 desc
= creat_copy_attrs (fname
, fn
);
3940 /* If we can't open the temporary file, try creating a new
3941 version of the original file. VMS "creat" creates a
3942 new version rather than truncating an existing file. */
3945 desc
= creat (fn
, 0666);
3946 #if 0 /* This can clobber an existing file and fail to replace it,
3947 if the user runs out of space. */
3950 /* We can't make a new version;
3951 try to truncate and rewrite existing version if any. */
3953 desc
= open (fn
, O_RDWR
);
3959 desc
= creat (fn
, 0666);
3964 O_WRONLY
| O_TRUNC
| O_CREAT
| buffer_file_type
,
3965 S_IREAD
| S_IWRITE
);
3966 #else /* not DOS_NT */
3967 desc
= creat (fn
, auto_saving
? auto_save_mode_bits
: 0666);
3968 #endif /* not DOS_NT */
3969 #endif /* not VMS */
3975 #ifdef CLASH_DETECTION
3977 if (!auto_saving
) unlock_file (lockname
);
3979 #endif /* CLASH_DETECTION */
3980 report_file_error ("Opening output file", Fcons (filename
, Qnil
));
3983 record_unwind_protect (close_file_unwind
, make_number (desc
));
3986 if (lseek (desc
, 0, 2) < 0)
3988 #ifdef CLASH_DETECTION
3989 if (!auto_saving
) unlock_file (lockname
);
3990 #endif /* CLASH_DETECTION */
3991 report_file_error ("Lseek error", Fcons (filename
, Qnil
));
3996 * Kludge Warning: The VMS C RTL likes to insert carriage returns
3997 * if we do writes that don't end with a carriage return. Furthermore
3998 * it cannot handle writes of more then 16K. The modified
3999 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4000 * this EXCEPT for the last record (iff it doesn't end with a carriage
4001 * return). This implies that if your buffer doesn't end with a carriage
4002 * return, you get one free... tough. However it also means that if
4003 * we make two calls to sys_write (a la the following code) you can
4004 * get one at the gap as well. The easiest way to fix this (honest)
4005 * is to move the gap to the next newline (or the end of the buffer).
4010 if (GPT
> BEG
&& GPT_ADDR
[-1] != '\n')
4011 move_gap (find_next_newline (GPT
, 1));
4017 if (STRINGP (start
))
4019 failure
= 0 > a_write (desc
, XSTRING (start
)->data
,
4020 XSTRING (start
)->size
, 0, &annotations
, &coding
);
4023 else if (XINT (start
) != XINT (end
))
4026 if (XINT (start
) < GPT
)
4028 register int end1
= XINT (end
);
4030 failure
= 0 > a_write (desc
, POS_ADDR (tem
),
4031 min (GPT
, end1
) - tem
, tem
, &annotations
,
4033 nwritten
+= min (GPT
, end1
) - tem
;
4037 if (XINT (end
) > GPT
&& !failure
)
4040 tem
= max (tem
, GPT
);
4041 failure
= 0 > a_write (desc
, POS_ADDR (tem
), XINT (end
) - tem
,
4042 tem
, &annotations
, &coding
);
4043 nwritten
+= XINT (end
) - tem
;
4049 /* If file was empty, still need to write the annotations */
4050 failure
= 0 > a_write (desc
, "", 0, XINT (start
), &annotations
, &coding
);
4054 if (coding
.require_flushing
)
4056 /* We have to flush out a data. */
4057 coding
.last_block
= 1;
4058 failure
= 0 > e_write (desc
, "", 0, &coding
);
4065 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4066 Disk full in NFS may be reported here. */
4067 /* mib says that closing the file will try to write as fast as NFS can do
4068 it, and that means the fsync here is not crucial for autosave files. */
4069 if (!auto_saving
&& fsync (desc
) < 0)
4071 /* If fsync fails with EINTR, don't treat that as serious. */
4073 failure
= 1, save_errno
= errno
;
4077 /* Spurious "file has changed on disk" warnings have been
4078 observed on Suns as well.
4079 It seems that `close' can change the modtime, under nfs.
4081 (This has supposedly been fixed in Sunos 4,
4082 but who knows about all the other machines with NFS?) */
4085 /* On VMS and APOLLO, must do the stat after the close
4086 since closing changes the modtime. */
4089 /* Recall that #if defined does not work on VMS. */
4096 /* NFS can report a write failure now. */
4097 if (close (desc
) < 0)
4098 failure
= 1, save_errno
= errno
;
4101 /* If we wrote to a temporary name and had no errors, rename to real name. */
4105 failure
= (rename (fn
, fname
) != 0), save_errno
= errno
;
4113 /* Discard the unwind protect for close_file_unwind. */
4114 specpdl_ptr
= specpdl
+ count1
;
4115 /* Restore the original current buffer. */
4116 visit_file
= unbind_to (count
, visit_file
);
4118 #ifdef CLASH_DETECTION
4120 unlock_file (lockname
);
4121 #endif /* CLASH_DETECTION */
4123 /* Do this before reporting IO error
4124 to avoid a "file has changed on disk" warning on
4125 next attempt to save. */
4127 current_buffer
->modtime
= st
.st_mtime
;
4130 error ("IO error writing %s: %s", fn
, strerror (save_errno
));
4134 SAVE_MODIFF
= MODIFF
;
4135 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4136 current_buffer
->filename
= visit_file
;
4137 update_mode_lines
++;
4143 message ("Wrote %s", XSTRING (visit_file
)->data
);
4148 Lisp_Object
merge ();
4150 DEFUN ("car-less-than-car", Fcar_less_than_car
, Scar_less_than_car
, 2, 2, 0,
4151 "Return t if (car A) is numerically less than (car B).")
4155 return Flss (Fcar (a
), Fcar (b
));
4158 /* Build the complete list of annotations appropriate for writing out
4159 the text between START and END, by calling all the functions in
4160 write-region-annotate-functions and merging the lists they return.
4161 If one of these functions switches to a different buffer, we assume
4162 that buffer contains altered text. Therefore, the caller must
4163 make sure to restore the current buffer in all cases,
4164 as save-excursion would do. */
4167 build_annotations (start
, end
, pre_write_conversion
)
4168 Lisp_Object start
, end
, pre_write_conversion
;
4170 Lisp_Object annotations
;
4172 struct gcpro gcpro1
, gcpro2
;
4173 Lisp_Object original_buffer
;
4175 XSETBUFFER (original_buffer
, current_buffer
);
4178 p
= Vwrite_region_annotate_functions
;
4179 GCPRO2 (annotations
, p
);
4182 struct buffer
*given_buffer
= current_buffer
;
4183 Vwrite_region_annotations_so_far
= annotations
;
4184 res
= call2 (Fcar (p
), start
, end
);
4185 /* If the function makes a different buffer current,
4186 assume that means this buffer contains altered text to be output.
4187 Reset START and END from the buffer bounds
4188 and discard all previous annotations because they should have
4189 been dealt with by this function. */
4190 if (current_buffer
!= given_buffer
)
4196 Flength (res
); /* Check basic validity of return value */
4197 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
4201 /* Now do the same for annotation functions implied by the file-format */
4202 if (auto_saving
&& (!EQ (Vauto_save_file_format
, Qt
)))
4203 p
= Vauto_save_file_format
;
4205 p
= current_buffer
->file_format
;
4208 struct buffer
*given_buffer
= current_buffer
;
4209 Vwrite_region_annotations_so_far
= annotations
;
4210 res
= call4 (Qformat_annotate_function
, Fcar (p
), start
, end
,
4212 if (current_buffer
!= given_buffer
)
4219 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
4223 /* At last, do the same for the function PRE_WRITE_CONVERSION
4224 implied by the current coding-system. */
4225 if (!NILP (pre_write_conversion
))
4227 struct buffer
*given_buffer
= current_buffer
;
4228 Vwrite_region_annotations_so_far
= annotations
;
4229 res
= call2 (pre_write_conversion
, start
, end
);
4230 if (current_buffer
!= given_buffer
)
4237 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
4244 /* Write to descriptor DESC the LEN characters starting at ADDR,
4245 assuming they start at position POS in the buffer.
4246 Intersperse with them the annotations from *ANNOT
4247 (those which fall within the range of positions POS to POS + LEN),
4248 each at its appropriate position.
4250 Modify *ANNOT by discarding elements as we output them.
4251 The return value is negative in case of system call failure. */
4254 a_write (desc
, addr
, len
, pos
, annot
, coding
)
4256 register char *addr
;
4260 struct coding_system
*coding
;
4264 int lastpos
= pos
+ len
;
4266 while (NILP (*annot
) || CONSP (*annot
))
4268 tem
= Fcar_safe (Fcar (*annot
));
4269 if (INTEGERP (tem
) && XINT (tem
) >= pos
&& XFASTINT (tem
) <= lastpos
)
4270 nextpos
= XFASTINT (tem
);
4272 return e_write (desc
, addr
, lastpos
- pos
, coding
);
4275 if (0 > e_write (desc
, addr
, nextpos
- pos
, coding
))
4277 addr
+= nextpos
- pos
;
4280 tem
= Fcdr (Fcar (*annot
));
4283 if (0 > e_write (desc
, XSTRING (tem
)->data
, XSTRING (tem
)->size
,
4287 *annot
= Fcdr (*annot
);
4291 #ifndef WRITE_BUF_SIZE
4292 #define WRITE_BUF_SIZE (16 * 1024)
4296 e_write (desc
, addr
, len
, coding
)
4298 register char *addr
;
4300 struct coding_system
*coding
;
4302 char buf
[WRITE_BUF_SIZE
];
4303 int produced
, consumed
;
4305 /* We used to have a code for handling selective display here. But,
4306 now it is handled within encode_coding. */
4309 produced
= encode_coding (coding
, addr
, buf
, len
, WRITE_BUF_SIZE
,
4311 len
-= consumed
, addr
+= consumed
;
4312 if (produced
== 0 && len
> 0)
4314 /* There was a carry over because of invalid codes in the source.
4315 We just write out them as is. */
4316 bcopy (addr
, buf
, len
);
4322 produced
-= write (desc
, buf
, produced
);
4323 if (produced
) return -1;
4331 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime
,
4332 Sverify_visited_file_modtime
, 1, 1, 0,
4333 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4334 This means that the file has not been changed since it was visited or saved.")
4340 Lisp_Object handler
;
4342 CHECK_BUFFER (buf
, 0);
4345 if (!STRINGP (b
->filename
)) return Qt
;
4346 if (b
->modtime
== 0) return Qt
;
4348 /* If the file name has special constructs in it,
4349 call the corresponding file handler. */
4350 handler
= Ffind_file_name_handler (b
->filename
,
4351 Qverify_visited_file_modtime
);
4352 if (!NILP (handler
))
4353 return call2 (handler
, Qverify_visited_file_modtime
, buf
);
4355 if (stat (XSTRING (b
->filename
)->data
, &st
) < 0)
4357 /* If the file doesn't exist now and didn't exist before,
4358 we say that it isn't modified, provided the error is a tame one. */
4359 if (errno
== ENOENT
|| errno
== EACCES
|| errno
== ENOTDIR
)
4364 if (st
.st_mtime
== b
->modtime
4365 /* If both are positive, accept them if they are off by one second. */
4366 || (st
.st_mtime
> 0 && b
->modtime
> 0
4367 && (st
.st_mtime
== b
->modtime
+ 1
4368 || st
.st_mtime
== b
->modtime
- 1)))
4373 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime
,
4374 Sclear_visited_file_modtime
, 0, 0, 0,
4375 "Clear out records of last mod time of visited file.\n\
4376 Next attempt to save will certainly not complain of a discrepancy.")
4379 current_buffer
->modtime
= 0;
4383 DEFUN ("visited-file-modtime", Fvisited_file_modtime
,
4384 Svisited_file_modtime
, 0, 0, 0,
4385 "Return the current buffer's recorded visited file modification time.\n\
4386 The value is a list of the form (HIGH . LOW), like the time values\n\
4387 that `file-attributes' returns.")
4390 return long_to_cons ((unsigned long) current_buffer
->modtime
);
4393 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime
,
4394 Sset_visited_file_modtime
, 0, 1, 0,
4395 "Update buffer's recorded modification time from the visited file's time.\n\
4396 Useful if the buffer was not read from the file normally\n\
4397 or if the file itself has been changed for some known benign reason.\n\
4398 An argument specifies the modification time value to use\n\
4399 \(instead of that of the visited file), in the form of a list\n\
4400 \(HIGH . LOW) or (HIGH LOW).")
4402 Lisp_Object time_list
;
4404 if (!NILP (time_list
))
4405 current_buffer
->modtime
= cons_to_long (time_list
);
4408 register Lisp_Object filename
;
4410 Lisp_Object handler
;
4412 filename
= Fexpand_file_name (current_buffer
->filename
, Qnil
);
4414 /* If the file name has special constructs in it,
4415 call the corresponding file handler. */
4416 handler
= Ffind_file_name_handler (filename
, Qset_visited_file_modtime
);
4417 if (!NILP (handler
))
4418 /* The handler can find the file name the same way we did. */
4419 return call2 (handler
, Qset_visited_file_modtime
, Qnil
);
4420 else if (stat (XSTRING (filename
)->data
, &st
) >= 0)
4421 current_buffer
->modtime
= st
.st_mtime
;
4431 message ("Autosaving...error for %s", XSTRING (current_buffer
->name
)->data
);
4432 Fsleep_for (make_number (1), Qnil
);
4433 message ("Autosaving...error!for %s", XSTRING (current_buffer
->name
)->data
);
4434 Fsleep_for (make_number (1), Qnil
);
4435 message ("Autosaving...error for %s", XSTRING (current_buffer
->name
)->data
);
4436 Fsleep_for (make_number (1), Qnil
);
4446 /* Get visited file's mode to become the auto save file's mode. */
4447 if (stat (XSTRING (current_buffer
->filename
)->data
, &st
) >= 0)
4448 /* But make sure we can overwrite it later! */
4449 auto_save_mode_bits
= st
.st_mode
| 0600;
4451 auto_save_mode_bits
= 0666;
4454 Fwrite_region (Qnil
, Qnil
,
4455 current_buffer
->auto_save_file_name
,
4456 Qnil
, Qlambda
, Qnil
);
4460 do_auto_save_unwind (desc
) /* used as unwind-protect function */
4464 if (XINT (desc
) >= 0)
4465 close (XINT (desc
));
4469 DEFUN ("do-auto-save", Fdo_auto_save
, Sdo_auto_save
, 0, 2, "",
4470 "Auto-save all buffers that need it.\n\
4471 This is all buffers that have auto-saving enabled\n\
4472 and are changed since last auto-saved.\n\
4473 Auto-saving writes the buffer into a file\n\
4474 so that your editing is not lost if the system crashes.\n\
4475 This file is not the file you visited; that changes only when you save.\n\
4476 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4477 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4478 A non-nil CURRENT-ONLY argument means save only current buffer.")
4479 (no_message
, current_only
)
4480 Lisp_Object no_message
, current_only
;
4482 struct buffer
*old
= current_buffer
, *b
;
4483 Lisp_Object tail
, buf
;
4485 char *omessage
= echo_area_glyphs
;
4486 int omessage_length
= echo_area_glyphs_length
;
4487 int do_handled_files
;
4490 int count
= specpdl_ptr
- specpdl
;
4493 /* Ordinarily don't quit within this function,
4494 but don't make it impossible to quit (in case we get hung in I/O). */
4498 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4499 point to non-strings reached from Vbuffer_alist. */
4504 if (!NILP (Vrun_hooks
))
4505 call1 (Vrun_hooks
, intern ("auto-save-hook"));
4507 if (STRINGP (Vauto_save_list_file_name
))
4509 Lisp_Object listfile
;
4510 listfile
= Fexpand_file_name (Vauto_save_list_file_name
, Qnil
);
4512 listdesc
= open (XSTRING (listfile
)->data
,
4513 O_WRONLY
| O_TRUNC
| O_CREAT
| O_TEXT
,
4514 S_IREAD
| S_IWRITE
);
4515 #else /* not DOS_NT */
4516 listdesc
= creat (XSTRING (listfile
)->data
, 0666);
4517 #endif /* not DOS_NT */
4522 /* Arrange to close that file whether or not we get an error.
4523 Also reset auto_saving to 0. */
4524 record_unwind_protect (do_auto_save_unwind
, make_number (listdesc
));
4528 /* First, save all files which don't have handlers. If Emacs is
4529 crashing, the handlers may tweak what is causing Emacs to crash
4530 in the first place, and it would be a shame if Emacs failed to
4531 autosave perfectly ordinary files because it couldn't handle some
4533 for (do_handled_files
= 0; do_handled_files
< 2; do_handled_files
++)
4534 for (tail
= Vbuffer_alist
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4536 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
4539 /* Record all the buffers that have auto save mode
4540 in the special file that lists them. For each of these buffers,
4541 Record visited name (if any) and auto save name. */
4542 if (STRINGP (b
->auto_save_file_name
)
4543 && listdesc
>= 0 && do_handled_files
== 0)
4545 if (!NILP (b
->filename
))
4547 write (listdesc
, XSTRING (b
->filename
)->data
,
4548 XSTRING (b
->filename
)->size
);
4550 write (listdesc
, "\n", 1);
4551 write (listdesc
, XSTRING (b
->auto_save_file_name
)->data
,
4552 XSTRING (b
->auto_save_file_name
)->size
);
4553 write (listdesc
, "\n", 1);
4556 if (!NILP (current_only
)
4557 && b
!= current_buffer
)
4560 /* Don't auto-save indirect buffers.
4561 The base buffer takes care of it. */
4565 /* Check for auto save enabled
4566 and file changed since last auto save
4567 and file changed since last real save. */
4568 if (STRINGP (b
->auto_save_file_name
)
4569 && BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)
4570 && b
->auto_save_modified
< BUF_MODIFF (b
)
4571 /* -1 means we've turned off autosaving for a while--see below. */
4572 && XINT (b
->save_length
) >= 0
4573 && (do_handled_files
4574 || NILP (Ffind_file_name_handler (b
->auto_save_file_name
,
4577 EMACS_TIME before_time
, after_time
;
4579 EMACS_GET_TIME (before_time
);
4581 /* If we had a failure, don't try again for 20 minutes. */
4582 if (b
->auto_save_failure_time
>= 0
4583 && EMACS_SECS (before_time
) - b
->auto_save_failure_time
< 1200)
4586 if ((XFASTINT (b
->save_length
) * 10
4587 > (BUF_Z (b
) - BUF_BEG (b
)) * 13)
4588 /* A short file is likely to change a large fraction;
4589 spare the user annoying messages. */
4590 && XFASTINT (b
->save_length
) > 5000
4591 /* These messages are frequent and annoying for `*mail*'. */
4592 && !EQ (b
->filename
, Qnil
)
4593 && NILP (no_message
))
4595 /* It has shrunk too much; turn off auto-saving here. */
4596 message ("Buffer %s has shrunk a lot; auto save turned off there",
4597 XSTRING (b
->name
)->data
);
4598 /* Turn off auto-saving until there's a real save,
4599 and prevent any more warnings. */
4600 XSETINT (b
->save_length
, -1);
4601 Fsleep_for (make_number (1), Qnil
);
4604 set_buffer_internal (b
);
4605 if (!auto_saved
&& NILP (no_message
))
4606 message1 ("Auto-saving...");
4607 internal_condition_case (auto_save_1
, Qt
, auto_save_error
);
4609 b
->auto_save_modified
= BUF_MODIFF (b
);
4610 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4611 set_buffer_internal (old
);
4613 EMACS_GET_TIME (after_time
);
4615 /* If auto-save took more than 60 seconds,
4616 assume it was an NFS failure that got a timeout. */
4617 if (EMACS_SECS (after_time
) - EMACS_SECS (before_time
) > 60)
4618 b
->auto_save_failure_time
= EMACS_SECS (after_time
);
4622 /* Prevent another auto save till enough input events come in. */
4623 record_auto_save ();
4625 if (auto_saved
&& NILP (no_message
))
4629 sit_for (1, 0, 0, 0);
4630 message2 (omessage
, omessage_length
);
4633 message1 ("Auto-saving...done");
4638 unbind_to (count
, Qnil
);
4642 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved
,
4643 Sset_buffer_auto_saved
, 0, 0, 0,
4644 "Mark current buffer as auto-saved with its current text.\n\
4645 No auto-save file will be written until the buffer changes again.")
4648 current_buffer
->auto_save_modified
= MODIFF
;
4649 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4650 current_buffer
->auto_save_failure_time
= -1;
4654 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure
,
4655 Sclear_buffer_auto_save_failure
, 0, 0, 0,
4656 "Clear any record of a recent auto-save failure in the current buffer.")
4659 current_buffer
->auto_save_failure_time
= -1;
4663 DEFUN ("recent-auto-save-p", Frecent_auto_save_p
, Srecent_auto_save_p
,
4665 "Return t if buffer has been auto-saved since last read in or saved.")
4668 return (SAVE_MODIFF
< current_buffer
->auto_save_modified
) ? Qt
: Qnil
;
4671 /* Reading and completing file names */
4672 extern Lisp_Object
Ffile_name_completion (), Ffile_name_all_completions ();
4674 /* In the string VAL, change each $ to $$ and return the result. */
4677 double_dollars (val
)
4680 register unsigned char *old
, *new;
4684 osize
= XSTRING (val
)->size
;
4685 /* Quote "$" as "$$" to get it past substitute-in-file-name */
4686 for (n
= osize
, count
= 0, old
= XSTRING (val
)->data
; n
> 0; n
--)
4687 if (*old
++ == '$') count
++;
4690 old
= XSTRING (val
)->data
;
4691 val
= Fmake_string (make_number (osize
+ count
), make_number (0));
4692 new = XSTRING (val
)->data
;
4693 for (n
= osize
; n
> 0; n
--)
4706 DEFUN ("read-file-name-internal", Fread_file_name_internal
, Sread_file_name_internal
,
4708 "Internal subroutine for read-file-name. Do not call this.")
4709 (string
, dir
, action
)
4710 Lisp_Object string
, dir
, action
;
4711 /* action is nil for complete, t for return list of completions,
4712 lambda for verify final value */
4714 Lisp_Object name
, specdir
, realdir
, val
, orig_string
;
4716 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
4718 CHECK_STRING (string
, 0);
4725 /* No need to protect ACTION--we only compare it with t and nil. */
4726 GCPRO5 (string
, realdir
, name
, specdir
, orig_string
);
4728 if (XSTRING (string
)->size
== 0)
4730 if (EQ (action
, Qlambda
))
4738 orig_string
= string
;
4739 string
= Fsubstitute_in_file_name (string
);
4740 changed
= NILP (Fstring_equal (string
, orig_string
));
4741 name
= Ffile_name_nondirectory (string
);
4742 val
= Ffile_name_directory (string
);
4744 realdir
= Fexpand_file_name (val
, realdir
);
4749 specdir
= Ffile_name_directory (string
);
4750 val
= Ffile_name_completion (name
, realdir
);
4755 return double_dollars (string
);
4759 if (!NILP (specdir
))
4760 val
= concat2 (specdir
, val
);
4762 return double_dollars (val
);
4765 #endif /* not VMS */
4769 if (EQ (action
, Qt
))
4770 return Ffile_name_all_completions (name
, realdir
);
4771 /* Only other case actually used is ACTION = lambda */
4773 /* Supposedly this helps commands such as `cd' that read directory names,
4774 but can someone explain how it helps them? -- RMS */
4775 if (XSTRING (name
)->size
== 0)
4778 return Ffile_exists_p (string
);
4781 DEFUN ("read-file-name", Fread_file_name
, Sread_file_name
, 1, 5, 0,
4782 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
4783 Value is not expanded---you must call `expand-file-name' yourself.\n\
4784 Default name to DEFAULT-FILENAME if user enters a null string.\n\
4785 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
4786 except that if INITIAL is specified, that combined with DIR is used.)\n\
4787 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
4788 Non-nil and non-t means also require confirmation after completion.\n\
4789 Fifth arg INITIAL specifies text to start with.\n\
4790 DIR defaults to current buffer's directory default.")
4791 (prompt
, dir
, default_filename
, mustmatch
, initial
)
4792 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, initial
;
4794 Lisp_Object val
, insdef
, insdef1
, tem
;
4795 struct gcpro gcpro1
, gcpro2
;
4796 register char *homedir
;
4800 dir
= current_buffer
->directory
;
4801 if (NILP (default_filename
))
4803 if (! NILP (initial
))
4804 default_filename
= Fexpand_file_name (initial
, dir
);
4806 default_filename
= current_buffer
->filename
;
4809 /* If dir starts with user's homedir, change that to ~. */
4810 homedir
= (char *) egetenv ("HOME");
4812 homedir
= strcpy (alloca (strlen (homedir
) + 1), homedir
);
4813 CORRECT_DIR_SEPS (homedir
);
4817 && !strncmp (homedir
, XSTRING (dir
)->data
, strlen (homedir
))
4818 && IS_DIRECTORY_SEP (XSTRING (dir
)->data
[strlen (homedir
)]))
4820 dir
= make_string (XSTRING (dir
)->data
+ strlen (homedir
) - 1,
4821 XSTRING (dir
)->size
- strlen (homedir
) + 1);
4822 XSTRING (dir
)->data
[0] = '~';
4825 if (insert_default_directory
&& STRINGP (dir
))
4828 if (!NILP (initial
))
4830 Lisp_Object args
[2], pos
;
4834 insdef
= Fconcat (2, args
);
4835 pos
= make_number (XSTRING (double_dollars (dir
))->size
);
4836 insdef1
= Fcons (double_dollars (insdef
), pos
);
4839 insdef1
= double_dollars (insdef
);
4841 else if (STRINGP (initial
))
4844 insdef1
= Fcons (double_dollars (insdef
), 0);
4847 insdef
= Qnil
, insdef1
= Qnil
;
4850 count
= specpdl_ptr
- specpdl
;
4851 specbind (intern ("completion-ignore-case"), Qt
);
4854 GCPRO2 (insdef
, default_filename
);
4855 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4856 dir
, mustmatch
, insdef1
,
4857 Qfile_name_history
, default_filename
);
4860 unbind_to (count
, Qnil
);
4865 error ("No file name specified");
4866 tem
= Fstring_equal (val
, insdef
);
4867 if (!NILP (tem
) && !NILP (default_filename
))
4868 return default_filename
;
4869 if (XSTRING (val
)->size
== 0 && NILP (insdef
))
4871 if (!NILP (default_filename
))
4872 return default_filename
;
4874 error ("No default file name");
4876 return Fsubstitute_in_file_name (val
);
4879 #if 0 /* Old version */
4880 DEFUN ("read-file-name", Fread_file_name
, Sread_file_name
, 1, 5, 0,
4881 /* Don't confuse make-docfile by having two doc strings for this function.
4882 make-docfile does not pay attention to #if, for good reason! */
4884 (prompt
, dir
, defalt
, mustmatch
, initial
)
4885 Lisp_Object prompt
, dir
, defalt
, mustmatch
, initial
;
4887 Lisp_Object val
, insdef
, tem
;
4888 struct gcpro gcpro1
, gcpro2
;
4889 register char *homedir
;
4893 dir
= current_buffer
->directory
;
4895 defalt
= current_buffer
->filename
;
4897 /* If dir starts with user's homedir, change that to ~. */
4898 homedir
= (char *) egetenv ("HOME");
4901 && !strncmp (homedir
, XSTRING (dir
)->data
, strlen (homedir
))
4902 && XSTRING (dir
)->data
[strlen (homedir
)] == '/')
4904 dir
= make_string (XSTRING (dir
)->data
+ strlen (homedir
) - 1,
4905 XSTRING (dir
)->size
- strlen (homedir
) + 1);
4906 XSTRING (dir
)->data
[0] = '~';
4909 if (!NILP (initial
))
4911 else if (insert_default_directory
)
4914 insdef
= build_string ("");
4917 count
= specpdl_ptr
- specpdl
;
4918 specbind (intern ("completion-ignore-case"), Qt
);
4921 GCPRO2 (insdef
, defalt
);
4922 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4924 insert_default_directory
? insdef
: Qnil
,
4925 Qfile_name_history
);
4928 unbind_to (count
, Qnil
);
4933 error ("No file name specified");
4934 tem
= Fstring_equal (val
, insdef
);
4935 if (!NILP (tem
) && !NILP (defalt
))
4937 return Fsubstitute_in_file_name (val
);
4939 #endif /* Old version */
4943 Qexpand_file_name
= intern ("expand-file-name");
4944 Qsubstitute_in_file_name
= intern ("substitute-in-file-name");
4945 Qdirectory_file_name
= intern ("directory-file-name");
4946 Qfile_name_directory
= intern ("file-name-directory");
4947 Qfile_name_nondirectory
= intern ("file-name-nondirectory");
4948 Qunhandled_file_name_directory
= intern ("unhandled-file-name-directory");
4949 Qfile_name_as_directory
= intern ("file-name-as-directory");
4950 Qcopy_file
= intern ("copy-file");
4951 Qmake_directory_internal
= intern ("make-directory-internal");
4952 Qdelete_directory
= intern ("delete-directory");
4953 Qdelete_file
= intern ("delete-file");
4954 Qrename_file
= intern ("rename-file");
4955 Qadd_name_to_file
= intern ("add-name-to-file");
4956 Qmake_symbolic_link
= intern ("make-symbolic-link");
4957 Qfile_exists_p
= intern ("file-exists-p");
4958 Qfile_executable_p
= intern ("file-executable-p");
4959 Qfile_readable_p
= intern ("file-readable-p");
4960 Qfile_writable_p
= intern ("file-writable-p");
4961 Qfile_symlink_p
= intern ("file-symlink-p");
4962 Qaccess_file
= intern ("access-file");
4963 Qfile_directory_p
= intern ("file-directory-p");
4964 Qfile_regular_p
= intern ("file-regular-p");
4965 Qfile_accessible_directory_p
= intern ("file-accessible-directory-p");
4966 Qfile_modes
= intern ("file-modes");
4967 Qset_file_modes
= intern ("set-file-modes");
4968 Qfile_newer_than_file_p
= intern ("file-newer-than-file-p");
4969 Qinsert_file_contents
= intern ("insert-file-contents");
4970 Qwrite_region
= intern ("write-region");
4971 Qverify_visited_file_modtime
= intern ("verify-visited-file-modtime");
4972 Qset_visited_file_modtime
= intern ("set-visited-file-modtime");
4974 staticpro (&Qexpand_file_name
);
4975 staticpro (&Qsubstitute_in_file_name
);
4976 staticpro (&Qdirectory_file_name
);
4977 staticpro (&Qfile_name_directory
);
4978 staticpro (&Qfile_name_nondirectory
);
4979 staticpro (&Qunhandled_file_name_directory
);
4980 staticpro (&Qfile_name_as_directory
);
4981 staticpro (&Qcopy_file
);
4982 staticpro (&Qmake_directory_internal
);
4983 staticpro (&Qdelete_directory
);
4984 staticpro (&Qdelete_file
);
4985 staticpro (&Qrename_file
);
4986 staticpro (&Qadd_name_to_file
);
4987 staticpro (&Qmake_symbolic_link
);
4988 staticpro (&Qfile_exists_p
);
4989 staticpro (&Qfile_executable_p
);
4990 staticpro (&Qfile_readable_p
);
4991 staticpro (&Qfile_writable_p
);
4992 staticpro (&Qaccess_file
);
4993 staticpro (&Qfile_symlink_p
);
4994 staticpro (&Qfile_directory_p
);
4995 staticpro (&Qfile_regular_p
);
4996 staticpro (&Qfile_accessible_directory_p
);
4997 staticpro (&Qfile_modes
);
4998 staticpro (&Qset_file_modes
);
4999 staticpro (&Qfile_newer_than_file_p
);
5000 staticpro (&Qinsert_file_contents
);
5001 staticpro (&Qwrite_region
);
5002 staticpro (&Qverify_visited_file_modtime
);
5003 staticpro (&Qset_visited_file_modtime
);
5005 Qfile_name_history
= intern ("file-name-history");
5006 Fset (Qfile_name_history
, Qnil
);
5007 staticpro (&Qfile_name_history
);
5009 Qfile_error
= intern ("file-error");
5010 staticpro (&Qfile_error
);
5011 Qfile_already_exists
= intern ("file-already-exists");
5012 staticpro (&Qfile_already_exists
);
5013 Qfile_date_error
= intern ("file-date-error");
5014 staticpro (&Qfile_date_error
);
5017 Qfind_buffer_file_type
= intern ("find-buffer-file-type");
5018 staticpro (&Qfind_buffer_file_type
);
5021 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format
,
5022 "*Format in which to write auto-save files.\n\
5023 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5024 If it is t, which is the default, auto-save files are written in the\n\
5025 same format as a regular save would use.");
5026 Vauto_save_file_format
= Qt
;
5028 Qformat_decode
= intern ("format-decode");
5029 staticpro (&Qformat_decode
);
5030 Qformat_annotate_function
= intern ("format-annotate-function");
5031 staticpro (&Qformat_annotate_function
);
5033 Qcar_less_than_car
= intern ("car-less-than-car");
5034 staticpro (&Qcar_less_than_car
);
5036 Fput (Qfile_error
, Qerror_conditions
,
5037 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
)));
5038 Fput (Qfile_error
, Qerror_message
,
5039 build_string ("File error"));
5041 Fput (Qfile_already_exists
, Qerror_conditions
,
5042 Fcons (Qfile_already_exists
,
5043 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
))));
5044 Fput (Qfile_already_exists
, Qerror_message
,
5045 build_string ("File already exists"));
5047 Fput (Qfile_date_error
, Qerror_conditions
,
5048 Fcons (Qfile_date_error
,
5049 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
))));
5050 Fput (Qfile_date_error
, Qerror_message
,
5051 build_string ("Cannot set file date"));
5053 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory
,
5054 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5055 insert_default_directory
= 1;
5057 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm
,
5058 "*Non-nil means write new files with record format `stmlf'.\n\
5059 nil means use format `var'. This variable is meaningful only on VMS.");
5060 vms_stmlf_recfm
= 0;
5062 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char
,
5063 "Directory separator character for built-in functions that return file names.\n\
5064 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5065 This variable affects the built-in functions only on Windows,\n\
5066 on other platforms, it is initialized so that Lisp code can find out\n\
5067 what the normal separator is.");
5068 Vdirectory_sep_char
= '/';
5070 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist
,
5071 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5072 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5075 The first argument given to HANDLER is the name of the I/O primitive\n\
5076 to be handled; the remaining arguments are the arguments that were\n\
5077 passed to that primitive. For example, if you do\n\
5078 (file-exists-p FILENAME)\n\
5079 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5080 (funcall HANDLER 'file-exists-p FILENAME)\n\
5081 The function `find-file-name-handler' checks this list for a handler\n\
5082 for its argument.");
5083 Vfile_name_handler_alist
= Qnil
;
5085 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions
,
5086 "A list of functions to be called at the end of `insert-file-contents'.\n\
5087 Each is passed one argument, the number of bytes inserted. It should return\n\
5088 the new byte count, and leave point the same. If `insert-file-contents' is\n\
5089 intercepted by a handler from `file-name-handler-alist', that handler is\n\
5090 responsible for calling the after-insert-file-functions if appropriate.");
5091 Vafter_insert_file_functions
= Qnil
;
5093 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions
,
5094 "A list of functions to be called at the start of `write-region'.\n\
5095 Each is passed two arguments, START and END as for `write-region'.\n\
5096 These are usually two numbers but not always; see the documentation\n\
5097 for `write-region'. The function should return a list of pairs\n\
5098 of the form (POSITION . STRING), consisting of strings to be effectively\n\
5099 inserted at the specified positions of the file being written (1 means to\n\
5100 insert before the first byte written). The POSITIONs must be sorted into\n\
5101 increasing order. If there are several functions in the list, the several\n\
5102 lists are merged destructively.");
5103 Vwrite_region_annotate_functions
= Qnil
;
5105 DEFVAR_LISP ("write-region-annotations-so-far",
5106 &Vwrite_region_annotations_so_far
,
5107 "When an annotation function is called, this holds the previous annotations.\n\
5108 These are the annotations made by other annotation functions\n\
5109 that were already called. See also `write-region-annotate-functions'.");
5110 Vwrite_region_annotations_so_far
= Qnil
;
5112 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers
,
5113 "A list of file name handlers that temporarily should not be used.\n\
5114 This applies only to the operation `inhibit-file-name-operation'.");
5115 Vinhibit_file_name_handlers
= Qnil
;
5117 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation
,
5118 "The operation for which `inhibit-file-name-handlers' is applicable.");
5119 Vinhibit_file_name_operation
= Qnil
;
5121 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name
,
5122 "File name in which we write a list of all auto save file names.\n\
5123 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5124 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5126 Vauto_save_list_file_name
= Qnil
;
5128 defsubr (&Sfind_file_name_handler
);
5129 defsubr (&Sfile_name_directory
);
5130 defsubr (&Sfile_name_nondirectory
);
5131 defsubr (&Sunhandled_file_name_directory
);
5132 defsubr (&Sfile_name_as_directory
);
5133 defsubr (&Sdirectory_file_name
);
5134 defsubr (&Smake_temp_name
);
5135 defsubr (&Sexpand_file_name
);
5136 defsubr (&Ssubstitute_in_file_name
);
5137 defsubr (&Scopy_file
);
5138 defsubr (&Smake_directory_internal
);
5139 defsubr (&Sdelete_directory
);
5140 defsubr (&Sdelete_file
);
5141 defsubr (&Srename_file
);
5142 defsubr (&Sadd_name_to_file
);
5144 defsubr (&Smake_symbolic_link
);
5145 #endif /* S_IFLNK */
5147 defsubr (&Sdefine_logical_name
);
5150 defsubr (&Ssysnetunam
);
5151 #endif /* HPUX_NET */
5152 defsubr (&Sfile_name_absolute_p
);
5153 defsubr (&Sfile_exists_p
);
5154 defsubr (&Sfile_executable_p
);
5155 defsubr (&Sfile_readable_p
);
5156 defsubr (&Sfile_writable_p
);
5157 defsubr (&Saccess_file
);
5158 defsubr (&Sfile_symlink_p
);
5159 defsubr (&Sfile_directory_p
);
5160 defsubr (&Sfile_accessible_directory_p
);
5161 defsubr (&Sfile_regular_p
);
5162 defsubr (&Sfile_modes
);
5163 defsubr (&Sset_file_modes
);
5164 defsubr (&Sset_default_file_modes
);
5165 defsubr (&Sdefault_file_modes
);
5166 defsubr (&Sfile_newer_than_file_p
);
5167 defsubr (&Sinsert_file_contents
);
5168 defsubr (&Swrite_region
);
5169 defsubr (&Scar_less_than_car
);
5170 defsubr (&Sverify_visited_file_modtime
);
5171 defsubr (&Sclear_visited_file_modtime
);
5172 defsubr (&Svisited_file_modtime
);
5173 defsubr (&Sset_visited_file_modtime
);
5174 defsubr (&Sdo_auto_save
);
5175 defsubr (&Sset_buffer_auto_saved
);
5176 defsubr (&Sclear_buffer_auto_save_failure
);
5177 defsubr (&Srecent_auto_save_p
);
5179 defsubr (&Sread_file_name_internal
);
5180 defsubr (&Sread_file_name
);
5183 defsubr (&Sunix_sync
);