1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96,1997 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)
28 #include <sys/types.h>
35 #if !defined (S_ISLNK) && defined (S_IFLNK)
36 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
39 #if !defined (S_ISFIFO) && defined (S_IFIFO)
40 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
43 #if !defined (S_ISREG) && defined (S_IFREG)
44 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
55 #include <sys/param.h>
77 extern char *strerror ();
94 #include "intervals.h"
105 #endif /* not WINDOWSNT */
108 #define CORRECT_DIR_SEPS(s) \
109 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
110 else unixtodos_filename (s); \
112 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
113 redirector allows the six letters between 'Z' and 'a' as well. */
115 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
118 #define IS_DRIVE(x) isalpha (x)
120 /* Need to lower-case the drive letter, or else expanded
121 filenames will sometimes compare inequal, because
122 `expand-file-name' doesn't always down-case the drive letter. */
123 #define DRIVE_LETTER(x) (tolower (x))
152 #define min(a, b) ((a) < (b) ? (a) : (b))
153 #define max(a, b) ((a) > (b) ? (a) : (b))
155 /* Nonzero during writing of auto-save files */
158 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
159 a new file with the same mode as the original */
160 int auto_save_mode_bits
;
162 /* Alist of elements (REGEXP . HANDLER) for file names
163 whose I/O is done with a special handler. */
164 Lisp_Object Vfile_name_handler_alist
;
166 /* Format for auto-save files */
167 Lisp_Object Vauto_save_file_format
;
169 /* Lisp functions for translating file formats */
170 Lisp_Object Qformat_decode
, Qformat_annotate_function
;
172 /* Function to be called to decide a coding system of a reading file. */
173 Lisp_Object Vauto_file_coding_system_function
;
175 /* Functions to be called to process text properties in inserted file. */
176 Lisp_Object Vafter_insert_file_functions
;
178 /* Functions to be called to create text property annotations for file. */
179 Lisp_Object Vwrite_region_annotate_functions
;
181 /* During build_annotations, each time an annotation function is called,
182 this holds the annotations made by the previous functions. */
183 Lisp_Object Vwrite_region_annotations_so_far
;
185 /* File name in which we write a list of all our auto save files. */
186 Lisp_Object Vauto_save_list_file_name
;
188 /* Nonzero means, when reading a filename in the minibuffer,
189 start out by inserting the default directory into the minibuffer. */
190 int insert_default_directory
;
192 /* On VMS, nonzero means write new files with record format stmlf.
193 Zero means use var format. */
196 /* On NT, specifies the directory separator character, used (eg.) when
197 expanding file names. This can be bound to / or \. */
198 Lisp_Object Vdirectory_sep_char
;
200 extern Lisp_Object Vuser_login_name
;
202 extern int minibuf_level
;
204 extern int minibuffer_auto_raise
;
206 /* These variables describe handlers that have "already" had a chance
207 to handle the current operation.
209 Vinhibit_file_name_handlers is a list of file name handlers.
210 Vinhibit_file_name_operation is the operation being handled.
211 If we try to handle that operation, we ignore those handlers. */
213 static Lisp_Object Vinhibit_file_name_handlers
;
214 static Lisp_Object Vinhibit_file_name_operation
;
216 Lisp_Object Qfile_error
, Qfile_already_exists
, Qfile_date_error
;
218 Lisp_Object Qfile_name_history
;
220 Lisp_Object Qcar_less_than_car
;
222 report_file_error (string
, data
)
226 Lisp_Object errstring
;
228 errstring
= build_string (strerror (errno
));
230 /* System error messages are capitalized. Downcase the initial
231 unless it is followed by a slash. */
232 if (XSTRING (errstring
)->data
[1] != '/')
233 XSTRING (errstring
)->data
[0] = DOWNCASE (XSTRING (errstring
)->data
[0]);
236 Fsignal (Qfile_error
,
237 Fcons (build_string (string
), Fcons (errstring
, data
)));
240 close_file_unwind (fd
)
243 close (XFASTINT (fd
));
246 /* Restore point, having saved it as a marker. */
248 restore_point_unwind (location
)
249 Lisp_Object location
;
251 SET_PT (marker_position (location
));
252 Fset_marker (location
, Qnil
, Qnil
);
255 Lisp_Object Qexpand_file_name
;
256 Lisp_Object Qsubstitute_in_file_name
;
257 Lisp_Object Qdirectory_file_name
;
258 Lisp_Object Qfile_name_directory
;
259 Lisp_Object Qfile_name_nondirectory
;
260 Lisp_Object Qunhandled_file_name_directory
;
261 Lisp_Object Qfile_name_as_directory
;
262 Lisp_Object Qcopy_file
;
263 Lisp_Object Qmake_directory_internal
;
264 Lisp_Object Qdelete_directory
;
265 Lisp_Object Qdelete_file
;
266 Lisp_Object Qrename_file
;
267 Lisp_Object Qadd_name_to_file
;
268 Lisp_Object Qmake_symbolic_link
;
269 Lisp_Object Qfile_exists_p
;
270 Lisp_Object Qfile_executable_p
;
271 Lisp_Object Qfile_readable_p
;
272 Lisp_Object Qfile_writable_p
;
273 Lisp_Object Qfile_symlink_p
;
274 Lisp_Object Qaccess_file
;
275 Lisp_Object Qfile_directory_p
;
276 Lisp_Object Qfile_regular_p
;
277 Lisp_Object Qfile_accessible_directory_p
;
278 Lisp_Object Qfile_modes
;
279 Lisp_Object Qset_file_modes
;
280 Lisp_Object Qfile_newer_than_file_p
;
281 Lisp_Object Qinsert_file_contents
;
282 Lisp_Object Qwrite_region
;
283 Lisp_Object Qverify_visited_file_modtime
;
284 Lisp_Object Qset_visited_file_modtime
;
286 DEFUN ("find-file-name-handler", Ffind_file_name_handler
, Sfind_file_name_handler
, 2, 2, 0,
287 "Return FILENAME's handler function for OPERATION, if it has one.\n\
288 Otherwise, return nil.\n\
289 A file name is handled if one of the regular expressions in\n\
290 `file-name-handler-alist' matches it.\n\n\
291 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
292 any handlers that are members of `inhibit-file-name-handlers',\n\
293 but we still do run any other handlers. This lets handlers\n\
294 use the standard functions without calling themselves recursively.")
295 (filename
, operation
)
296 Lisp_Object filename
, operation
;
298 /* This function must not munge the match data. */
299 Lisp_Object chain
, inhibited_handlers
;
301 CHECK_STRING (filename
, 0);
303 if (EQ (operation
, Vinhibit_file_name_operation
))
304 inhibited_handlers
= Vinhibit_file_name_handlers
;
306 inhibited_handlers
= Qnil
;
308 for (chain
= Vfile_name_handler_alist
; CONSP (chain
);
309 chain
= XCONS (chain
)->cdr
)
312 elt
= XCONS (chain
)->car
;
316 string
= XCONS (elt
)->car
;
317 if (STRINGP (string
) && fast_string_match (string
, filename
) >= 0)
319 Lisp_Object handler
, tem
;
321 handler
= XCONS (elt
)->cdr
;
322 tem
= Fmemq (handler
, inhibited_handlers
);
333 DEFUN ("file-name-directory", Ffile_name_directory
, Sfile_name_directory
,
335 "Return the directory component in file name FILENAME.\n\
336 Return nil if FILENAME does not include a directory.\n\
337 Otherwise return a directory spec.\n\
338 Given a Unix syntax file name, returns a string ending in slash;\n\
339 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
341 Lisp_Object filename
;
343 register unsigned char *beg
;
344 register unsigned char *p
;
347 CHECK_STRING (filename
, 0);
349 /* If the file name has special constructs in it,
350 call the corresponding file handler. */
351 handler
= Ffind_file_name_handler (filename
, Qfile_name_directory
);
353 return call2 (handler
, Qfile_name_directory
, filename
);
355 #ifdef FILE_SYSTEM_CASE
356 filename
= FILE_SYSTEM_CASE (filename
);
358 beg
= XSTRING (filename
)->data
;
360 beg
= strcpy (alloca (strlen (beg
) + 1), beg
);
362 p
= beg
+ XSTRING (filename
)->size
;
364 while (p
!= beg
&& !IS_DIRECTORY_SEP (p
[-1])
366 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
369 /* only recognise drive specifier at beginning */
370 && !(p
[-1] == ':' && p
== beg
+ 2)
377 /* Expansion of "c:" to drive and default directory. */
378 if (p
== beg
+ 2 && beg
[1] == ':')
380 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
381 unsigned char *res
= alloca (MAXPATHLEN
+ 1);
382 if (getdefdir (toupper (*beg
) - 'A' + 1, res
))
384 if (!IS_DIRECTORY_SEP (res
[strlen (res
) - 1]))
387 p
= beg
+ strlen (beg
);
390 CORRECT_DIR_SEPS (beg
);
392 return make_string (beg
, p
- beg
);
395 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory
, Sfile_name_nondirectory
,
397 "Return file name FILENAME sans its directory.\n\
398 For example, in a Unix-syntax file name,\n\
399 this is everything after the last slash,\n\
400 or the entire name if it contains no slash.")
402 Lisp_Object filename
;
404 register unsigned char *beg
, *p
, *end
;
407 CHECK_STRING (filename
, 0);
409 /* If the file name has special constructs in it,
410 call the corresponding file handler. */
411 handler
= Ffind_file_name_handler (filename
, Qfile_name_nondirectory
);
413 return call2 (handler
, Qfile_name_nondirectory
, filename
);
415 beg
= XSTRING (filename
)->data
;
416 end
= p
= beg
+ XSTRING (filename
)->size
;
418 while (p
!= beg
&& !IS_DIRECTORY_SEP (p
[-1])
420 && p
[-1] != ':' && p
[-1] != ']' && p
[-1] != '>'
423 /* only recognise drive specifier at beginning */
424 && !(p
[-1] == ':' && p
== beg
+ 2)
428 return make_string (p
, end
- p
);
431 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory
, Sunhandled_file_name_directory
, 1, 1, 0,
432 "Return a directly usable directory name somehow associated with FILENAME.\n\
433 A `directly usable' directory name is one that may be used without the\n\
434 intervention of any file handler.\n\
435 If FILENAME is a directly usable file itself, return\n\
436 (file-name-directory FILENAME).\n\
437 The `call-process' and `start-process' functions use this function to\n\
438 get a current directory to run processes in.")
440 Lisp_Object filename
;
444 /* If the file name has special constructs in it,
445 call the corresponding file handler. */
446 handler
= Ffind_file_name_handler (filename
, Qunhandled_file_name_directory
);
448 return call2 (handler
, Qunhandled_file_name_directory
, filename
);
450 return Ffile_name_directory (filename
);
455 file_name_as_directory (out
, in
)
458 int size
= strlen (in
) - 1;
463 /* Is it already a directory string? */
464 if (in
[size
] == ':' || in
[size
] == ']' || in
[size
] == '>')
466 /* Is it a VMS directory file name? If so, hack VMS syntax. */
467 else if (! index (in
, '/')
468 && ((size
> 3 && ! strcmp (&in
[size
- 3], ".DIR"))
469 || (size
> 3 && ! strcmp (&in
[size
- 3], ".dir"))
470 || (size
> 5 && (! strncmp (&in
[size
- 5], ".DIR", 4)
471 || ! strncmp (&in
[size
- 5], ".dir", 4))
472 && (in
[size
- 1] == '.' || in
[size
- 1] == ';')
473 && in
[size
] == '1')))
475 register char *p
, *dot
;
479 dir:x.dir --> dir:[x]
480 dir:[x]y.dir --> dir:[x.y] */
482 while (p
!= in
&& *p
!= ':' && *p
!= '>' && *p
!= ']') p
--;
485 strncpy (out
, in
, p
- in
);
504 dot
= index (p
, '.');
507 /* blindly remove any extension */
508 size
= strlen (out
) + (dot
- p
);
509 strncat (out
, p
, dot
- p
);
520 /* For Unix syntax, Append a slash if necessary */
521 if (!IS_DIRECTORY_SEP (out
[size
]))
523 out
[size
+ 1] = DIRECTORY_SEP
;
524 out
[size
+ 2] = '\0';
527 CORRECT_DIR_SEPS (out
);
533 DEFUN ("file-name-as-directory", Ffile_name_as_directory
,
534 Sfile_name_as_directory
, 1, 1, 0,
535 "Return a string representing file FILENAME interpreted as a directory.\n\
536 This operation exists because a directory is also a file, but its name as\n\
537 a directory is different from its name as a file.\n\
538 The result can be used as the value of `default-directory'\n\
539 or passed as second argument to `expand-file-name'.\n\
540 For a Unix-syntax file name, just appends a slash.\n\
541 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
548 CHECK_STRING (file
, 0);
552 /* If the file name has special constructs in it,
553 call the corresponding file handler. */
554 handler
= Ffind_file_name_handler (file
, Qfile_name_as_directory
);
556 return call2 (handler
, Qfile_name_as_directory
, file
);
558 buf
= (char *) alloca (XSTRING (file
)->size
+ 10);
559 return build_string (file_name_as_directory (buf
, XSTRING (file
)->data
));
563 * Convert from directory name to filename.
565 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
566 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
567 * On UNIX, it's simple: just make sure there isn't a terminating /
569 * Value is nonzero if the string output is different from the input.
572 directory_file_name (src
, dst
)
580 struct FAB fab
= cc$rms_fab
;
581 struct NAM nam
= cc$rms_nam
;
582 char esa
[NAM$C_MAXRSS
];
587 if (! index (src
, '/')
588 && (src
[slen
- 1] == ']'
589 || src
[slen
- 1] == ':'
590 || src
[slen
- 1] == '>'))
592 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
594 fab
.fab$b_fns
= slen
;
595 fab
.fab$l_nam
= &nam
;
596 fab
.fab$l_fop
= FAB$M_NAM
;
599 nam
.nam$b_ess
= sizeof esa
;
600 nam
.nam$b_nop
|= NAM$M_SYNCHK
;
602 /* We call SYS$PARSE to handle such things as [--] for us. */
603 if (SYS$
PARSE (&fab
, 0, 0) == RMS$_NORMAL
)
605 slen
= nam
.nam$b_esl
;
606 if (esa
[slen
- 1] == ';' && esa
[slen
- 2] == '.')
611 if (src
[slen
- 1] != ']' && src
[slen
- 1] != '>')
613 /* what about when we have logical_name:???? */
614 if (src
[slen
- 1] == ':')
615 { /* Xlate logical name and see what we get */
616 ptr
= strcpy (dst
, src
); /* upper case for getenv */
619 if ('a' <= *ptr
&& *ptr
<= 'z')
623 dst
[slen
- 1] = 0; /* remove colon */
624 if (!(src
= egetenv (dst
)))
626 /* should we jump to the beginning of this procedure?
627 Good points: allows us to use logical names that xlate
629 Bad points: can be a problem if we just translated to a device
631 For now, I'll punt and always expect VMS names, and hope for
634 if (src
[slen
- 1] != ']' && src
[slen
- 1] != '>')
635 { /* no recursion here! */
641 { /* not a directory spec */
646 bracket
= src
[slen
- 1];
648 /* If bracket is ']' or '>', bracket - 2 is the corresponding
650 ptr
= index (src
, bracket
- 2);
652 { /* no opening bracket */
656 if (!(rptr
= rindex (src
, '.')))
659 strncpy (dst
, src
, slen
);
663 dst
[slen
++] = bracket
;
668 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
669 then translate the device and recurse. */
670 if (dst
[slen
- 1] == ':'
671 && dst
[slen
- 2] != ':' /* skip decnet nodes */
672 && strcmp (src
+ slen
, "[000000]") == 0)
674 dst
[slen
- 1] = '\0';
675 if ((ptr
= egetenv (dst
))
676 && (rlen
= strlen (ptr
) - 1) > 0
677 && (ptr
[rlen
] == ']' || ptr
[rlen
] == '>')
678 && ptr
[rlen
- 1] == '.')
680 char * buf
= (char *) alloca (strlen (ptr
) + 1);
684 return directory_file_name (buf
, dst
);
689 strcat (dst
, "[000000]");
693 rlen
= strlen (rptr
) - 1;
694 strncat (dst
, rptr
, rlen
);
695 dst
[slen
+ rlen
] = '\0';
696 strcat (dst
, ".DIR.1");
700 /* Process as Unix format: just remove any final slash.
701 But leave "/" unchanged; do not change it to "". */
704 /* Handle // as root for apollo's. */
705 if ((slen
> 2 && dst
[slen
- 1] == '/')
706 || (slen
> 1 && dst
[0] != '/' && dst
[slen
- 1] == '/'))
710 && IS_DIRECTORY_SEP (dst
[slen
- 1])
712 && !IS_ANY_SEP (dst
[slen
- 2])
718 CORRECT_DIR_SEPS (dst
);
723 DEFUN ("directory-file-name", Fdirectory_file_name
, Sdirectory_file_name
,
725 "Returns the file name of the directory named DIRECTORY.\n\
726 This is the name of the file that holds the data for the directory DIRECTORY.\n\
727 This operation exists because a directory is also a file, but its name as\n\
728 a directory is different from its name as a file.\n\
729 In Unix-syntax, this function just removes the final slash.\n\
730 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
731 it returns a file name such as \"[X]Y.DIR.1\".")
733 Lisp_Object directory
;
738 CHECK_STRING (directory
, 0);
740 if (NILP (directory
))
743 /* If the file name has special constructs in it,
744 call the corresponding file handler. */
745 handler
= Ffind_file_name_handler (directory
, Qdirectory_file_name
);
747 return call2 (handler
, Qdirectory_file_name
, directory
);
750 /* 20 extra chars is insufficient for VMS, since we might perform a
751 logical name translation. an equivalence string can be up to 255
752 chars long, so grab that much extra space... - sss */
753 buf
= (char *) alloca (XSTRING (directory
)->size
+ 20 + 255);
755 buf
= (char *) alloca (XSTRING (directory
)->size
+ 20);
757 directory_file_name (XSTRING (directory
)->data
, buf
);
758 return build_string (buf
);
761 DEFUN ("make-temp-name", Fmake_temp_name
, Smake_temp_name
, 1, 1, 0,
762 "Generate temporary file name (string) starting with PREFIX (a string).\n\
763 The Emacs process number forms part of the result,\n\
764 so there is no danger of generating a name being used by another process.")
770 /* Don't use too many characters of the restricted 8+3 DOS
772 val
= concat2 (prefix
, build_string ("a.XXX"));
774 val
= concat2 (prefix
, build_string ("XXXXXX"));
776 mktemp (XSTRING (val
)->data
);
778 CORRECT_DIR_SEPS (XSTRING (val
)->data
);
783 DEFUN ("expand-file-name", Fexpand_file_name
, Sexpand_file_name
, 1, 2, 0,
784 "Convert filename NAME to absolute, and canonicalize it.\n\
785 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
786 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
787 the current buffer's value of default-directory is used.\n\
788 File name components that are `.' are removed, and \n\
789 so are file name components followed by `..', along with the `..' itself;\n\
790 note that these simplifications are done without checking the resulting\n\
791 file names in the file system.\n\
792 An initial `~/' expands to your home directory.\n\
793 An initial `~USER/' expands to USER's home directory.\n\
794 See also the function `substitute-in-file-name'.")
795 (name
, default_directory
)
796 Lisp_Object name
, default_directory
;
800 register unsigned char *newdir
, *p
, *o
;
802 unsigned char *target
;
805 unsigned char * colon
= 0;
806 unsigned char * close
= 0;
807 unsigned char * slash
= 0;
808 unsigned char * brack
= 0;
809 int lbrack
= 0, rbrack
= 0;
814 int collapse_newdir
= 1;
819 CHECK_STRING (name
, 0);
821 /* If the file name has special constructs in it,
822 call the corresponding file handler. */
823 handler
= Ffind_file_name_handler (name
, Qexpand_file_name
);
825 return call3 (handler
, Qexpand_file_name
, name
, default_directory
);
827 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
828 if (NILP (default_directory
))
829 default_directory
= current_buffer
->directory
;
830 CHECK_STRING (default_directory
, 1);
832 if (!NILP (default_directory
))
834 handler
= Ffind_file_name_handler (default_directory
, Qexpand_file_name
);
836 return call3 (handler
, Qexpand_file_name
, name
, default_directory
);
839 o
= XSTRING (default_directory
)->data
;
841 /* Make sure DEFAULT_DIRECTORY is properly expanded.
842 It would be better to do this down below where we actually use
843 default_directory. Unfortunately, calling Fexpand_file_name recursively
844 could invoke GC, and the strings might be relocated. This would
845 be annoying because we have pointers into strings lying around
846 that would need adjusting, and people would add new pointers to
847 the code and forget to adjust them, resulting in intermittent bugs.
848 Putting this call here avoids all that crud.
850 The EQ test avoids infinite recursion. */
851 if (! NILP (default_directory
) && !EQ (default_directory
, name
)
852 /* Save time in some common cases - as long as default_directory
853 is not relative, it can be canonicalized with name below (if it
854 is needed at all) without requiring it to be expanded now. */
856 /* Detect MSDOS file names with drive specifiers. */
857 && ! (IS_DRIVE (o
[0]) && (IS_DEVICE_SEP (o
[1]) && IS_DIRECTORY_SEP (o
[2])))
859 /* Detect Windows file names in UNC format. */
860 && ! (IS_DIRECTORY_SEP (o
[0]) && IS_DIRECTORY_SEP (o
[1]))
862 #else /* not DOS_NT */
863 /* Detect Unix absolute file names (/... alone is not absolute on
865 && ! (IS_DIRECTORY_SEP (o
[0]))
866 #endif /* not DOS_NT */
872 default_directory
= Fexpand_file_name (default_directory
, Qnil
);
877 /* Filenames on VMS are always upper case. */
878 name
= Fupcase (name
);
880 #ifdef FILE_SYSTEM_CASE
881 name
= FILE_SYSTEM_CASE (name
);
884 nm
= XSTRING (name
)->data
;
887 /* We will force directory separators to be either all \ or /, so make
888 a local copy to modify, even if there ends up being no change. */
889 nm
= strcpy (alloca (strlen (nm
) + 1), nm
);
891 /* Find and remove drive specifier if present; this makes nm absolute
892 even if the rest of the name appears to be relative. */
894 unsigned char *colon
= rindex (nm
, ':');
897 /* Only recognize colon as part of drive specifier if there is a
898 single alphabetic character preceeding the colon (and if the
899 character before the drive letter, if present, is a directory
900 separator); this is to support the remote system syntax used by
901 ange-ftp, and the "po:username" syntax for POP mailboxes. */
905 else if (IS_DRIVE (colon
[-1])
906 && (colon
== nm
+ 1 || IS_DIRECTORY_SEP (colon
[-2])))
913 while (--colon
>= nm
)
921 /* Discard any previous drive specifier if nm is now in UNC format. */
922 if (IS_DIRECTORY_SEP (nm
[0]) && IS_DIRECTORY_SEP (nm
[1]))
928 /* If nm is absolute, look for /./ or /../ sequences; if none are
929 found, we can probably return right away. We will avoid allocating
930 a new string if name is already fully expanded. */
932 IS_DIRECTORY_SEP (nm
[0])
937 && (drive
|| IS_DIRECTORY_SEP (nm
[1]))
944 /* If it turns out that the filename we want to return is just a
945 suffix of FILENAME, we don't need to go through and edit
946 things; we just need to construct a new string using data
947 starting at the middle of FILENAME. If we set lose to a
948 non-zero value, that means we've discovered that we can't do
955 /* Since we know the name is absolute, we can assume that each
956 element starts with a "/". */
958 /* "." and ".." are hairy. */
959 if (IS_DIRECTORY_SEP (p
[0])
961 && (IS_DIRECTORY_SEP (p
[2])
963 || (p
[2] == '.' && (IS_DIRECTORY_SEP (p
[3])
970 /* if dev:[dir]/, move nm to / */
971 if (!slash
&& p
> nm
&& (brack
|| colon
)) {
972 nm
= (brack
? brack
+ 1 : colon
+ 1);
981 /* VMS pre V4.4,convert '-'s in filenames. */
982 if (lbrack
== rbrack
)
984 if (dots
< 2) /* this is to allow negative version numbers */
989 if (lbrack
> rbrack
&&
990 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
991 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
997 /* count open brackets, reset close bracket pointer */
998 if (p
[0] == '[' || p
[0] == '<')
1000 /* count close brackets, set close bracket pointer */
1001 if (p
[0] == ']' || p
[0] == '>')
1002 rbrack
++, brack
= p
;
1003 /* detect ][ or >< */
1004 if ((p
[0] == ']' || p
[0] == '>') && (p
[1] == '[' || p
[1] == '<'))
1006 if ((p
[0] == ':' || p
[0] == ']' || p
[0] == '>') && p
[1] == '~')
1007 nm
= p
+ 1, lose
= 1;
1008 if (p
[0] == ':' && (colon
|| slash
))
1009 /* if dev1:[dir]dev2:, move nm to dev2: */
1015 /* if /name/dev:, move nm to dev: */
1018 /* if node::dev:, move colon following dev */
1019 else if (colon
&& colon
[-1] == ':')
1021 /* if dev1:dev2:, move nm to dev2: */
1022 else if (colon
&& colon
[-1] != ':')
1027 if (p
[0] == ':' && !colon
)
1033 if (lbrack
== rbrack
)
1036 else if (p
[0] == '.')
1044 if (index (nm
, '/'))
1045 return build_string (sys_translate_unix (nm
));
1048 /* Make sure directories are all separated with / or \ as
1049 desired, but avoid allocation of a new string when not
1051 CORRECT_DIR_SEPS (nm
);
1053 if (IS_DIRECTORY_SEP (nm
[1]))
1055 if (strcmp (nm
, XSTRING (name
)->data
) != 0)
1056 name
= build_string (nm
);
1060 /* drive must be set, so this is okay */
1061 if (strcmp (nm
- 2, XSTRING (name
)->data
) != 0)
1063 name
= make_string (nm
- 2, p
- nm
+ 2);
1064 XSTRING (name
)->data
[0] = DRIVE_LETTER (drive
);
1065 XSTRING (name
)->data
[1] = ':';
1068 #else /* not DOS_NT */
1069 if (nm
== XSTRING (name
)->data
)
1071 return build_string (nm
);
1072 #endif /* not DOS_NT */
1076 /* At this point, nm might or might not be an absolute file name. We
1077 need to expand ~ or ~user if present, otherwise prefix nm with
1078 default_directory if nm is not absolute, and finally collapse /./
1079 and /foo/../ sequences.
1081 We set newdir to be the appropriate prefix if one is needed:
1082 - the relevant user directory if nm starts with ~ or ~user
1083 - the specified drive's working dir (DOS/NT only) if nm does not
1085 - the value of default_directory.
1087 Note that these prefixes are not guaranteed to be absolute (except
1088 for the working dir of a drive). Therefore, to ensure we always
1089 return an absolute name, if the final prefix is not absolute we
1090 append it to the current working directory. */
1094 if (nm
[0] == '~') /* prefix ~ */
1096 if (IS_DIRECTORY_SEP (nm
[1])
1100 || nm
[1] == 0) /* ~ by itself */
1102 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1103 newdir
= (unsigned char *) "";
1106 collapse_newdir
= 0;
1109 nm
++; /* Don't leave the slash in nm. */
1112 else /* ~user/filename */
1114 for (p
= nm
; *p
&& (!IS_DIRECTORY_SEP (*p
)
1119 o
= (unsigned char *) alloca (p
- nm
+ 1);
1120 bcopy ((char *) nm
, o
, p
- nm
);
1123 pw
= (struct passwd
*) getpwnam (o
+ 1);
1126 newdir
= (unsigned char *) pw
-> pw_dir
;
1128 nm
= p
+ 1; /* skip the terminator */
1132 collapse_newdir
= 0;
1137 /* If we don't find a user of that name, leave the name
1138 unchanged; don't move nm forward to p. */
1143 /* On DOS and Windows, nm is absolute if a drive name was specified;
1144 use the drive's current directory as the prefix if needed. */
1145 if (!newdir
&& drive
)
1147 /* Get default directory if needed to make nm absolute. */
1148 if (!IS_DIRECTORY_SEP (nm
[0]))
1150 newdir
= alloca (MAXPATHLEN
+ 1);
1151 if (!getdefdir (toupper (drive
) - 'A' + 1, newdir
))
1156 /* Either nm starts with /, or drive isn't mounted. */
1157 newdir
= alloca (4);
1158 newdir
[0] = DRIVE_LETTER (drive
);
1166 /* Finally, if no prefix has been specified and nm is not absolute,
1167 then it must be expanded relative to default_directory. */
1171 /* /... alone is not absolute on DOS and Windows. */
1172 && !IS_DIRECTORY_SEP (nm
[0])
1175 && !(IS_DIRECTORY_SEP (nm
[0]) && IS_DIRECTORY_SEP (nm
[1]))
1182 newdir
= XSTRING (default_directory
)->data
;
1188 /* First ensure newdir is an absolute name. */
1190 /* Detect MSDOS file names with drive specifiers. */
1191 ! (IS_DRIVE (newdir
[0])
1192 && IS_DEVICE_SEP (newdir
[1]) && IS_DIRECTORY_SEP (newdir
[2]))
1194 /* Detect Windows file names in UNC format. */
1195 && ! (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
1199 /* Effectively, let newdir be (expand-file-name newdir cwd).
1200 Because of the admonition against calling expand-file-name
1201 when we have pointers into lisp strings, we accomplish this
1202 indirectly by prepending newdir to nm if necessary, and using
1203 cwd (or the wd of newdir's drive) as the new newdir. */
1205 if (IS_DRIVE (newdir
[0]) && newdir
[1] == ':')
1210 if (!IS_DIRECTORY_SEP (nm
[0]))
1212 char * tmp
= alloca (strlen (newdir
) + strlen (nm
) + 2);
1213 file_name_as_directory (tmp
, newdir
);
1217 newdir
= alloca (MAXPATHLEN
+ 1);
1220 if (!getdefdir (toupper (drive
) - 'A' + 1, newdir
))
1227 /* Strip off drive name from prefix, if present. */
1228 if (IS_DRIVE (newdir
[0]) && newdir
[1] == ':')
1234 /* Keep only a prefix from newdir if nm starts with slash
1235 (//server/share for UNC, nothing otherwise). */
1236 if (IS_DIRECTORY_SEP (nm
[0]) && collapse_newdir
)
1239 if (IS_DIRECTORY_SEP (newdir
[0]) && IS_DIRECTORY_SEP (newdir
[1]))
1241 newdir
= strcpy (alloca (strlen (newdir
) + 1), newdir
);
1243 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
1245 while (*p
&& !IS_DIRECTORY_SEP (*p
)) p
++;
1257 /* Get rid of any slash at the end of newdir, unless newdir is
1258 just // (an incomplete UNC name). */
1259 length
= strlen (newdir
);
1260 if (length
> 0 && IS_DIRECTORY_SEP (newdir
[length
- 1])
1262 && !(length
== 2 && IS_DIRECTORY_SEP (newdir
[0]))
1266 unsigned char *temp
= (unsigned char *) alloca (length
);
1267 bcopy (newdir
, temp
, length
- 1);
1268 temp
[length
- 1] = 0;
1276 /* Now concatenate the directory and name to new space in the stack frame */
1277 tlen
+= strlen (nm
) + 1;
1279 /* Add reserved space for drive name. (The Microsoft x86 compiler
1280 produces incorrect code if the following two lines are combined.) */
1281 target
= (unsigned char *) alloca (tlen
+ 2);
1283 #else /* not DOS_NT */
1284 target
= (unsigned char *) alloca (tlen
);
1285 #endif /* not DOS_NT */
1291 if (nm
[0] == 0 || IS_DIRECTORY_SEP (nm
[0]))
1292 strcpy (target
, newdir
);
1295 file_name_as_directory (target
, newdir
);
1298 strcat (target
, nm
);
1300 if (index (target
, '/'))
1301 strcpy (target
, sys_translate_unix (target
));
1304 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1306 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1314 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1320 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1321 /* brackets are offset from each other by 2 */
1324 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1325 /* convert [foo][bar] to [bar] */
1326 while (o
[-1] != '[' && o
[-1] != '<')
1328 else if (*p
== '-' && *o
!= '.')
1331 else if (p
[0] == '-' && o
[-1] == '.' &&
1332 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1333 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1337 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1338 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1340 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1342 /* else [foo.-] ==> [-] */
1348 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1349 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1355 if (!IS_DIRECTORY_SEP (*p
))
1359 else if (IS_DIRECTORY_SEP (p
[0]) && IS_DIRECTORY_SEP (p
[1])
1360 #if defined (APOLLO) || defined (WINDOWSNT)
1361 /* // at start of filename is meaningful in Apollo
1362 and WindowsNT systems */
1364 #endif /* APOLLO || WINDOWSNT */
1370 else if (IS_DIRECTORY_SEP (p
[0])
1372 && (IS_DIRECTORY_SEP (p
[2])
1375 /* If "/." is the entire filename, keep the "/". Otherwise,
1376 just delete the whole "/.". */
1377 if (o
== target
&& p
[2] == '\0')
1381 else if (IS_DIRECTORY_SEP (p
[0]) && p
[1] == '.' && p
[2] == '.'
1382 /* `/../' is the "superroot" on certain file systems. */
1384 && (IS_DIRECTORY_SEP (p
[3]) || p
[3] == 0))
1386 while (o
!= target
&& (--o
) && !IS_DIRECTORY_SEP (*o
))
1388 /* Keep initial / only if this is the whole name. */
1389 if (o
== target
&& IS_ANY_SEP (*o
) && p
[3] == 0)
1397 #endif /* not VMS */
1401 /* At last, set drive name. */
1403 /* Except for network file name. */
1404 if (!(IS_DIRECTORY_SEP (target
[0]) && IS_DIRECTORY_SEP (target
[1])))
1405 #endif /* WINDOWSNT */
1407 if (!drive
) abort ();
1409 target
[0] = DRIVE_LETTER (drive
);
1412 CORRECT_DIR_SEPS (target
);
1415 return make_string (target
, o
- target
);
1419 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1420 DEAFUN ("expand-file-name", Fexpand_file_name
, Sexpand_file_name
, 1, 2, 0,
1421 "Convert FILENAME to absolute, and canonicalize it.\n\
1422 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1423 (does not start with slash); if DEFAULT is nil or missing,\n\
1424 the current buffer's value of default-directory is used.\n\
1425 Filenames containing `.' or `..' as components are simplified;\n\
1426 initial `~/' expands to your home directory.\n\
1427 See also the function `substitute-in-file-name'.")
1429 Lisp_Object name
, defalt
;
1433 register unsigned char *newdir
, *p
, *o
;
1435 unsigned char *target
;
1439 unsigned char * colon
= 0;
1440 unsigned char * close
= 0;
1441 unsigned char * slash
= 0;
1442 unsigned char * brack
= 0;
1443 int lbrack
= 0, rbrack
= 0;
1447 CHECK_STRING (name
, 0);
1450 /* Filenames on VMS are always upper case. */
1451 name
= Fupcase (name
);
1454 nm
= XSTRING (name
)->data
;
1456 /* If nm is absolute, flush ...// and detect /./ and /../.
1457 If no /./ or /../ we can return right away. */
1469 if (p
[0] == '/' && p
[1] == '/'
1471 /* // at start of filename is meaningful on Apollo system */
1476 if (p
[0] == '/' && p
[1] == '~')
1477 nm
= p
+ 1, lose
= 1;
1478 if (p
[0] == '/' && p
[1] == '.'
1479 && (p
[2] == '/' || p
[2] == 0
1480 || (p
[2] == '.' && (p
[3] == '/' || p
[3] == 0))))
1486 /* if dev:[dir]/, move nm to / */
1487 if (!slash
&& p
> nm
&& (brack
|| colon
)) {
1488 nm
= (brack
? brack
+ 1 : colon
+ 1);
1489 lbrack
= rbrack
= 0;
1497 /* VMS pre V4.4,convert '-'s in filenames. */
1498 if (lbrack
== rbrack
)
1500 if (dots
< 2) /* this is to allow negative version numbers */
1505 if (lbrack
> rbrack
&&
1506 ((p
[-1] == '.' || p
[-1] == '[' || p
[-1] == '<') &&
1507 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>')))
1513 /* count open brackets, reset close bracket pointer */
1514 if (p
[0] == '[' || p
[0] == '<')
1515 lbrack
++, brack
= 0;
1516 /* count close brackets, set close bracket pointer */
1517 if (p
[0] == ']' || p
[0] == '>')
1518 rbrack
++, brack
= p
;
1519 /* detect ][ or >< */
1520 if ((p
[0] == ']' || p
[0] == '>') && (p
[1] == '[' || p
[1] == '<'))
1522 if ((p
[0] == ':' || p
[0] == ']' || p
[0] == '>') && p
[1] == '~')
1523 nm
= p
+ 1, lose
= 1;
1524 if (p
[0] == ':' && (colon
|| slash
))
1525 /* if dev1:[dir]dev2:, move nm to dev2: */
1531 /* If /name/dev:, move nm to dev: */
1534 /* If node::dev:, move colon following dev */
1535 else if (colon
&& colon
[-1] == ':')
1537 /* If dev1:dev2:, move nm to dev2: */
1538 else if (colon
&& colon
[-1] != ':')
1543 if (p
[0] == ':' && !colon
)
1549 if (lbrack
== rbrack
)
1552 else if (p
[0] == '.')
1560 if (index (nm
, '/'))
1561 return build_string (sys_translate_unix (nm
));
1563 if (nm
== XSTRING (name
)->data
)
1565 return build_string (nm
);
1569 /* Now determine directory to start with and put it in NEWDIR */
1573 if (nm
[0] == '~') /* prefix ~ */
1578 || nm
[1] == 0)/* ~/filename */
1580 if (!(newdir
= (unsigned char *) egetenv ("HOME")))
1581 newdir
= (unsigned char *) "";
1584 nm
++; /* Don't leave the slash in nm. */
1587 else /* ~user/filename */
1589 /* Get past ~ to user */
1590 unsigned char *user
= nm
+ 1;
1591 /* Find end of name. */
1592 unsigned char *ptr
= (unsigned char *) index (user
, '/');
1593 int len
= ptr
? ptr
- user
: strlen (user
);
1595 unsigned char *ptr1
= index (user
, ':');
1596 if (ptr1
!= 0 && ptr1
- user
< len
)
1599 /* Copy the user name into temp storage. */
1600 o
= (unsigned char *) alloca (len
+ 1);
1601 bcopy ((char *) user
, o
, len
);
1604 /* Look up the user name. */
1605 pw
= (struct passwd
*) getpwnam (o
+ 1);
1607 error ("\"%s\" isn't a registered user", o
+ 1);
1609 newdir
= (unsigned char *) pw
->pw_dir
;
1611 /* Discard the user name from NM. */
1618 #endif /* not VMS */
1622 defalt
= current_buffer
->directory
;
1623 CHECK_STRING (defalt
, 1);
1624 newdir
= XSTRING (defalt
)->data
;
1627 /* Now concatenate the directory and name to new space in the stack frame */
1629 tlen
= (newdir
? strlen (newdir
) + 1 : 0) + strlen (nm
) + 1;
1630 target
= (unsigned char *) alloca (tlen
);
1636 if (nm
[0] == 0 || nm
[0] == '/')
1637 strcpy (target
, newdir
);
1640 file_name_as_directory (target
, newdir
);
1643 strcat (target
, nm
);
1645 if (index (target
, '/'))
1646 strcpy (target
, sys_translate_unix (target
));
1649 /* Now canonicalize by removing /. and /foo/.. if they appear */
1657 if (*p
!= ']' && *p
!= '>' && *p
!= '-')
1663 else if ((p
[0] == ']' || p
[0] == '>') && p
[0] == p
[1] + 2)
1664 /* brackets are offset from each other by 2 */
1667 if (*p
!= '.' && *p
!= '-' && o
[-1] != '.')
1668 /* convert [foo][bar] to [bar] */
1669 while (o
[-1] != '[' && o
[-1] != '<')
1671 else if (*p
== '-' && *o
!= '.')
1674 else if (p
[0] == '-' && o
[-1] == '.' &&
1675 (p
[1] == '.' || p
[1] == ']' || p
[1] == '>'))
1676 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1680 while (o
[-1] != '.' && o
[-1] != '[' && o
[-1] != '<');
1681 if (p
[1] == '.') /* foo.-.bar ==> bar. */
1683 else if (o
[-1] == '.') /* '.foo.-]' ==> ']' */
1685 /* else [foo.-] ==> [-] */
1691 o
[-1] != '[' && o
[-1] != '<' && o
[-1] != '.' &&
1692 p
[1] != ']' && p
[1] != '>' && p
[1] != '.')
1702 else if (!strncmp (p
, "//", 2)
1704 /* // at start of filename is meaningful in Apollo system */
1712 else if (p
[0] == '/' && p
[1] == '.' &&
1713 (p
[2] == '/' || p
[2] == 0))
1715 else if (!strncmp (p
, "/..", 3)
1716 /* `/../' is the "superroot" on certain file systems. */
1718 && (p
[3] == '/' || p
[3] == 0))
1720 while (o
!= target
&& *--o
!= '/')
1723 if (o
== target
+ 1 && o
[-1] == '/' && o
[0] == '/')
1727 if (o
== target
&& *o
== '/')
1735 #endif /* not VMS */
1738 return make_string (target
, o
- target
);
1742 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name
,
1743 Ssubstitute_in_file_name
, 1, 1, 0,
1744 "Substitute environment variables referred to in FILENAME.\n\
1745 `$FOO' where FOO is an environment variable name means to substitute\n\
1746 the value of that variable. The variable name should be terminated\n\
1747 with a character not a letter, digit or underscore; otherwise, enclose\n\
1748 the entire variable name in braces.\n\
1749 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1750 On VMS, `$' substitution is not done; this function does little and only\n\
1751 duplicates what `expand-file-name' does.")
1753 Lisp_Object filename
;
1757 register unsigned char *s
, *p
, *o
, *x
, *endp
;
1758 unsigned char *target
;
1760 int substituted
= 0;
1762 Lisp_Object handler
;
1764 CHECK_STRING (filename
, 0);
1766 /* If the file name has special constructs in it,
1767 call the corresponding file handler. */
1768 handler
= Ffind_file_name_handler (filename
, Qsubstitute_in_file_name
);
1769 if (!NILP (handler
))
1770 return call2 (handler
, Qsubstitute_in_file_name
, filename
);
1772 nm
= XSTRING (filename
)->data
;
1774 nm
= strcpy (alloca (strlen (nm
) + 1), nm
);
1775 CORRECT_DIR_SEPS (nm
);
1776 substituted
= (strcmp (nm
, XSTRING (filename
)->data
) != 0);
1778 endp
= nm
+ XSTRING (filename
)->size
;
1780 /* If /~ or // appears, discard everything through first slash. */
1782 for (p
= nm
; p
!= endp
; p
++)
1785 #if defined (APOLLO) || defined (WINDOWSNT)
1786 /* // at start of file name is meaningful in Apollo and
1787 WindowsNT systems */
1788 || (IS_DIRECTORY_SEP (p
[0]) && p
- 1 != nm
)
1789 #else /* not (APOLLO || WINDOWSNT) */
1790 || IS_DIRECTORY_SEP (p
[0])
1791 #endif /* not (APOLLO || WINDOWSNT) */
1796 || p
[-1] == ':' || p
[-1] == ']' || p
[-1] == '>'
1798 || IS_DIRECTORY_SEP (p
[-1])))
1804 /* see comment in expand-file-name about drive specifiers */
1805 else if (IS_DRIVE (p
[0]) && p
[1] == ':'
1806 && p
> nm
&& IS_DIRECTORY_SEP (p
[-1]))
1815 return build_string (nm
);
1818 /* See if any variables are substituted into the string
1819 and find the total length of their values in `total' */
1821 for (p
= nm
; p
!= endp
;)
1831 /* "$$" means a single "$" */
1840 while (p
!= endp
&& *p
!= '}') p
++;
1841 if (*p
!= '}') goto missingclose
;
1847 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1851 /* Copy out the variable name */
1852 target
= (unsigned char *) alloca (s
- o
+ 1);
1853 strncpy (target
, o
, s
- o
);
1856 strupr (target
); /* $home == $HOME etc. */
1859 /* Get variable value */
1860 o
= (unsigned char *) egetenv (target
);
1861 if (!o
) goto badvar
;
1862 total
+= strlen (o
);
1869 /* If substitution required, recopy the string and do it */
1870 /* Make space in stack frame for the new copy */
1871 xnm
= (unsigned char *) alloca (XSTRING (filename
)->size
+ total
+ 1);
1874 /* Copy the rest of the name through, replacing $ constructs with values */
1891 while (p
!= endp
&& *p
!= '}') p
++;
1892 if (*p
!= '}') goto missingclose
;
1898 while (p
!= endp
&& (isalnum (*p
) || *p
== '_')) p
++;
1902 /* Copy out the variable name */
1903 target
= (unsigned char *) alloca (s
- o
+ 1);
1904 strncpy (target
, o
, s
- o
);
1907 strupr (target
); /* $home == $HOME etc. */
1910 /* Get variable value */
1911 o
= (unsigned char *) egetenv (target
);
1921 /* If /~ or // appears, discard everything through first slash. */
1923 for (p
= xnm
; p
!= x
; p
++)
1925 #if defined (APOLLO) || defined (WINDOWSNT)
1926 || (IS_DIRECTORY_SEP (p
[0]) && p
- 1 != xnm
)
1927 #else /* not (APOLLO || WINDOWSNT) */
1928 || IS_DIRECTORY_SEP (p
[0])
1929 #endif /* not (APOLLO || WINDOWSNT) */
1931 && p
!= xnm
&& IS_DIRECTORY_SEP (p
[-1]))
1934 else if (IS_DRIVE (p
[0]) && p
[1] == ':'
1935 && p
> nm
&& IS_DIRECTORY_SEP (p
[-1]))
1939 return make_string (xnm
, x
- xnm
);
1942 error ("Bad format environment-variable substitution");
1944 error ("Missing \"}\" in environment-variable substitution");
1946 error ("Substituting nonexistent environment variable \"%s\"", target
);
1949 #endif /* not VMS */
1952 /* A slightly faster and more convenient way to get
1953 (directory-file-name (expand-file-name FOO)). */
1956 expand_and_dir_to_file (filename
, defdir
)
1957 Lisp_Object filename
, defdir
;
1959 register Lisp_Object absname
;
1961 absname
= Fexpand_file_name (filename
, defdir
);
1964 register int c
= XSTRING (absname
)->data
[XSTRING (absname
)->size
- 1];
1965 if (c
== ':' || c
== ']' || c
== '>')
1966 absname
= Fdirectory_file_name (absname
);
1969 /* Remove final slash, if any (unless this is the root dir).
1970 stat behaves differently depending! */
1971 if (XSTRING (absname
)->size
> 1
1972 && IS_DIRECTORY_SEP (XSTRING (absname
)->data
[XSTRING (absname
)->size
- 1])
1973 && !IS_DEVICE_SEP (XSTRING (absname
)->data
[XSTRING (absname
)->size
-2]))
1974 /* We cannot take shortcuts; they might be wrong for magic file names. */
1975 absname
= Fdirectory_file_name (absname
);
1980 /* Signal an error if the file ABSNAME already exists.
1981 If INTERACTIVE is nonzero, ask the user whether to proceed,
1982 and bypass the error if the user says to go ahead.
1983 QUERYSTRING is a name for the action that is being considered
1985 *STATPTR is used to store the stat information if the file exists.
1986 If the file does not exist, STATPTR->st_mode is set to 0. */
1989 barf_or_query_if_file_exists (absname
, querystring
, interactive
, statptr
)
1990 Lisp_Object absname
;
1991 unsigned char *querystring
;
1993 struct stat
*statptr
;
1995 register Lisp_Object tem
;
1996 struct stat statbuf
;
1997 struct gcpro gcpro1
;
1999 /* stat is a good way to tell whether the file exists,
2000 regardless of what access permissions it has. */
2001 if (stat (XSTRING (absname
)->data
, &statbuf
) >= 0)
2004 Fsignal (Qfile_already_exists
,
2005 Fcons (build_string ("File already exists"),
2006 Fcons (absname
, Qnil
)));
2008 tem
= do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
2009 XSTRING (absname
)->data
, querystring
));
2012 Fsignal (Qfile_already_exists
,
2013 Fcons (build_string ("File already exists"),
2014 Fcons (absname
, Qnil
)));
2021 statptr
->st_mode
= 0;
2026 DEFUN ("copy-file", Fcopy_file
, Scopy_file
, 2, 4,
2027 "fCopy file: \nFCopy %s to file: \np\nP",
2028 "Copy FILE to NEWNAME. Both args must be strings.\n\
2029 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2030 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2031 A number as third arg means request confirmation if NEWNAME already exists.\n\
2032 This is what happens in interactive use with M-x.\n\
2033 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2034 last-modified time as the old one. (This works on only some systems.)\n\
2035 A prefix arg makes KEEP-TIME non-nil.")
2036 (file
, newname
, ok_if_already_exists
, keep_date
)
2037 Lisp_Object file
, newname
, ok_if_already_exists
, keep_date
;
2040 char buf
[16 * 1024];
2041 struct stat st
, out_st
;
2042 Lisp_Object handler
;
2043 struct gcpro gcpro1
, gcpro2
;
2044 int count
= specpdl_ptr
- specpdl
;
2045 int input_file_statable_p
;
2047 GCPRO2 (file
, newname
);
2048 CHECK_STRING (file
, 0);
2049 CHECK_STRING (newname
, 1);
2050 file
= Fexpand_file_name (file
, Qnil
);
2051 newname
= Fexpand_file_name (newname
, Qnil
);
2053 /* If the input file name has special constructs in it,
2054 call the corresponding file handler. */
2055 handler
= Ffind_file_name_handler (file
, Qcopy_file
);
2056 /* Likewise for output file name. */
2058 handler
= Ffind_file_name_handler (newname
, Qcopy_file
);
2059 if (!NILP (handler
))
2060 RETURN_UNGCPRO (call5 (handler
, Qcopy_file
, file
, newname
,
2061 ok_if_already_exists
, keep_date
));
2063 if (NILP (ok_if_already_exists
)
2064 || INTEGERP (ok_if_already_exists
))
2065 barf_or_query_if_file_exists (newname
, "copy to it",
2066 INTEGERP (ok_if_already_exists
), &out_st
);
2067 else if (stat (XSTRING (newname
)->data
, &out_st
) < 0)
2070 ifd
= open (XSTRING (file
)->data
, O_RDONLY
);
2072 report_file_error ("Opening input file", Fcons (file
, Qnil
));
2074 record_unwind_protect (close_file_unwind
, make_number (ifd
));
2076 /* We can only copy regular files and symbolic links. Other files are not
2078 input_file_statable_p
= (fstat (ifd
, &st
) >= 0);
2080 #if !defined (MSDOS) || __DJGPP__ > 1
2081 if (out_st
.st_mode
!= 0
2082 && st
.st_dev
== out_st
.st_dev
&& st
.st_ino
== out_st
.st_ino
)
2085 report_file_error ("Input and output files are the same",
2086 Fcons (file
, Fcons (newname
, Qnil
)));
2090 #if defined (S_ISREG) && defined (S_ISLNK)
2091 if (input_file_statable_p
)
2093 if (!(S_ISREG (st
.st_mode
)) && !(S_ISLNK (st
.st_mode
)))
2095 #if defined (EISDIR)
2096 /* Get a better looking error message. */
2099 report_file_error ("Non-regular file", Fcons (file
, Qnil
));
2102 #endif /* S_ISREG && S_ISLNK */
2105 /* Create the copy file with the same record format as the input file */
2106 ofd
= sys_creat (XSTRING (newname
)->data
, 0666, ifd
);
2109 /* System's default file type was set to binary by _fmode in emacs.c. */
2110 ofd
= creat (XSTRING (newname
)->data
, S_IREAD
| S_IWRITE
);
2111 #else /* not MSDOS */
2112 ofd
= creat (XSTRING (newname
)->data
, 0666);
2113 #endif /* not MSDOS */
2116 report_file_error ("Opening output file", Fcons (newname
, Qnil
));
2118 record_unwind_protect (close_file_unwind
, make_number (ofd
));
2122 while ((n
= read (ifd
, buf
, sizeof buf
)) > 0)
2123 if (write (ofd
, buf
, n
) != n
)
2124 report_file_error ("I/O error", Fcons (newname
, Qnil
));
2127 /* Closing the output clobbers the file times on some systems. */
2128 if (close (ofd
) < 0)
2129 report_file_error ("I/O error", Fcons (newname
, Qnil
));
2131 if (input_file_statable_p
)
2133 if (!NILP (keep_date
))
2135 EMACS_TIME atime
, mtime
;
2136 EMACS_SET_SECS_USECS (atime
, st
.st_atime
, 0);
2137 EMACS_SET_SECS_USECS (mtime
, st
.st_mtime
, 0);
2138 if (set_file_times (XSTRING (newname
)->data
, atime
, mtime
))
2139 Fsignal (Qfile_date_error
,
2140 Fcons (build_string ("Cannot set file date"),
2141 Fcons (newname
, Qnil
)));
2144 chmod (XSTRING (newname
)->data
, st
.st_mode
& 07777);
2146 #if defined (__DJGPP__) && __DJGPP__ > 1
2147 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2148 and if it can't, it tells so. Otherwise, under MSDOS we usually
2149 get only the READ bit, which will make the copied file read-only,
2150 so it's better not to chmod at all. */
2151 if ((_djstat_flags
& _STFAIL_WRITEBIT
) == 0)
2152 chmod (XSTRING (newname
)->data
, st
.st_mode
& 07777);
2153 #endif /* DJGPP version 2 or newer */
2159 /* Discard the unwind protects. */
2160 specpdl_ptr
= specpdl
+ count
;
2166 DEFUN ("make-directory-internal", Fmake_directory_internal
,
2167 Smake_directory_internal
, 1, 1, 0,
2168 "Create a new directory named DIRECTORY.")
2170 Lisp_Object directory
;
2173 Lisp_Object handler
;
2175 CHECK_STRING (directory
, 0);
2176 directory
= Fexpand_file_name (directory
, Qnil
);
2178 handler
= Ffind_file_name_handler (directory
, Qmake_directory_internal
);
2179 if (!NILP (handler
))
2180 return call2 (handler
, Qmake_directory_internal
, directory
);
2182 dir
= XSTRING (directory
)->data
;
2185 if (mkdir (dir
) != 0)
2187 if (mkdir (dir
, 0777) != 0)
2189 report_file_error ("Creating directory", Flist (1, &directory
));
2194 DEFUN ("delete-directory", Fdelete_directory
, Sdelete_directory
, 1, 1, "FDelete directory: ",
2195 "Delete the directory named DIRECTORY.")
2197 Lisp_Object directory
;
2200 Lisp_Object handler
;
2202 CHECK_STRING (directory
, 0);
2203 directory
= Fdirectory_file_name (Fexpand_file_name (directory
, Qnil
));
2204 dir
= XSTRING (directory
)->data
;
2206 handler
= Ffind_file_name_handler (directory
, Qdelete_directory
);
2207 if (!NILP (handler
))
2208 return call2 (handler
, Qdelete_directory
, directory
);
2210 if (rmdir (dir
) != 0)
2211 report_file_error ("Removing directory", Flist (1, &directory
));
2216 DEFUN ("delete-file", Fdelete_file
, Sdelete_file
, 1, 1, "fDelete file: ",
2217 "Delete file named FILENAME.\n\
2218 If file has multiple names, it continues to exist with the other names.")
2220 Lisp_Object filename
;
2222 Lisp_Object handler
;
2223 CHECK_STRING (filename
, 0);
2224 filename
= Fexpand_file_name (filename
, Qnil
);
2226 handler
= Ffind_file_name_handler (filename
, Qdelete_file
);
2227 if (!NILP (handler
))
2228 return call2 (handler
, Qdelete_file
, filename
);
2230 if (0 > unlink (XSTRING (filename
)->data
))
2231 report_file_error ("Removing old name", Flist (1, &filename
));
2236 internal_delete_file_1 (ignore
)
2242 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2245 internal_delete_file (filename
)
2246 Lisp_Object filename
;
2248 return NILP (internal_condition_case_1 (Fdelete_file
, filename
,
2249 Qt
, internal_delete_file_1
));
2252 DEFUN ("rename-file", Frename_file
, Srename_file
, 2, 3,
2253 "fRename file: \nFRename %s to file: \np",
2254 "Rename FILE as NEWNAME. Both args strings.\n\
2255 If file has names other than FILE, it continues to have those names.\n\
2256 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2257 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2258 A number as third arg means request confirmation if NEWNAME already exists.\n\
2259 This is what happens in interactive use with M-x.")
2260 (file
, newname
, ok_if_already_exists
)
2261 Lisp_Object file
, newname
, ok_if_already_exists
;
2264 Lisp_Object args
[2];
2266 Lisp_Object handler
;
2267 struct gcpro gcpro1
, gcpro2
;
2269 GCPRO2 (file
, newname
);
2270 CHECK_STRING (file
, 0);
2271 CHECK_STRING (newname
, 1);
2272 file
= Fexpand_file_name (file
, Qnil
);
2273 newname
= Fexpand_file_name (newname
, Qnil
);
2275 /* If the file name has special constructs in it,
2276 call the corresponding file handler. */
2277 handler
= Ffind_file_name_handler (file
, Qrename_file
);
2279 handler
= Ffind_file_name_handler (newname
, Qrename_file
);
2280 if (!NILP (handler
))
2281 RETURN_UNGCPRO (call4 (handler
, Qrename_file
,
2282 file
, newname
, ok_if_already_exists
));
2284 if (NILP (ok_if_already_exists
)
2285 || INTEGERP (ok_if_already_exists
))
2286 barf_or_query_if_file_exists (newname
, "rename to it",
2287 INTEGERP (ok_if_already_exists
), 0);
2289 if (0 > rename (XSTRING (file
)->data
, XSTRING (newname
)->data
))
2291 if (0 > link (XSTRING (file
)->data
, XSTRING (newname
)->data
)
2292 || 0 > unlink (XSTRING (file
)->data
))
2297 Fcopy_file (file
, newname
,
2298 /* We have already prompted if it was an integer,
2299 so don't have copy-file prompt again. */
2300 NILP (ok_if_already_exists
) ? Qnil
: Qt
, Qt
);
2301 Fdelete_file (file
);
2308 report_file_error ("Renaming", Flist (2, args
));
2311 report_file_error ("Renaming", Flist (2, &file
));
2318 DEFUN ("add-name-to-file", Fadd_name_to_file
, Sadd_name_to_file
, 2, 3,
2319 "fAdd name to file: \nFName to add to %s: \np",
2320 "Give FILE additional name NEWNAME. Both args strings.\n\
2321 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2322 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2323 A number as third arg means request confirmation if NEWNAME already exists.\n\
2324 This is what happens in interactive use with M-x.")
2325 (file
, newname
, ok_if_already_exists
)
2326 Lisp_Object file
, newname
, ok_if_already_exists
;
2329 Lisp_Object args
[2];
2331 Lisp_Object handler
;
2332 struct gcpro gcpro1
, gcpro2
;
2334 GCPRO2 (file
, newname
);
2335 CHECK_STRING (file
, 0);
2336 CHECK_STRING (newname
, 1);
2337 file
= Fexpand_file_name (file
, Qnil
);
2338 newname
= Fexpand_file_name (newname
, Qnil
);
2340 /* If the file name has special constructs in it,
2341 call the corresponding file handler. */
2342 handler
= Ffind_file_name_handler (file
, Qadd_name_to_file
);
2343 if (!NILP (handler
))
2344 RETURN_UNGCPRO (call4 (handler
, Qadd_name_to_file
, file
,
2345 newname
, ok_if_already_exists
));
2347 /* If the new name has special constructs in it,
2348 call the corresponding file handler. */
2349 handler
= Ffind_file_name_handler (newname
, Qadd_name_to_file
);
2350 if (!NILP (handler
))
2351 RETURN_UNGCPRO (call4 (handler
, Qadd_name_to_file
, file
,
2352 newname
, ok_if_already_exists
));
2354 if (NILP (ok_if_already_exists
)
2355 || INTEGERP (ok_if_already_exists
))
2356 barf_or_query_if_file_exists (newname
, "make it a new name",
2357 INTEGERP (ok_if_already_exists
), 0);
2359 /* Windows does not support this operation. */
2360 report_file_error ("Adding new name", Flist (2, &file
));
2361 #else /* not WINDOWSNT */
2363 unlink (XSTRING (newname
)->data
);
2364 if (0 > link (XSTRING (file
)->data
, XSTRING (newname
)->data
))
2369 report_file_error ("Adding new name", Flist (2, args
));
2371 report_file_error ("Adding new name", Flist (2, &file
));
2374 #endif /* not WINDOWSNT */
2381 DEFUN ("make-symbolic-link", Fmake_symbolic_link
, Smake_symbolic_link
, 2, 3,
2382 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2383 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2384 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2385 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2386 A number as third arg means request confirmation if LINKNAME already exists.\n\
2387 This happens for interactive use with M-x.")
2388 (filename
, linkname
, ok_if_already_exists
)
2389 Lisp_Object filename
, linkname
, ok_if_already_exists
;
2392 Lisp_Object args
[2];
2394 Lisp_Object handler
;
2395 struct gcpro gcpro1
, gcpro2
;
2397 GCPRO2 (filename
, linkname
);
2398 CHECK_STRING (filename
, 0);
2399 CHECK_STRING (linkname
, 1);
2400 /* If the link target has a ~, we must expand it to get
2401 a truly valid file name. Otherwise, do not expand;
2402 we want to permit links to relative file names. */
2403 if (XSTRING (filename
)->data
[0] == '~')
2404 filename
= Fexpand_file_name (filename
, Qnil
);
2405 linkname
= Fexpand_file_name (linkname
, Qnil
);
2407 /* If the file name has special constructs in it,
2408 call the corresponding file handler. */
2409 handler
= Ffind_file_name_handler (filename
, Qmake_symbolic_link
);
2410 if (!NILP (handler
))
2411 RETURN_UNGCPRO (call4 (handler
, Qmake_symbolic_link
, filename
,
2412 linkname
, ok_if_already_exists
));
2414 /* If the new link name has special constructs in it,
2415 call the corresponding file handler. */
2416 handler
= Ffind_file_name_handler (linkname
, Qmake_symbolic_link
);
2417 if (!NILP (handler
))
2418 RETURN_UNGCPRO (call4 (handler
, Qmake_symbolic_link
, filename
,
2419 linkname
, ok_if_already_exists
));
2421 if (NILP (ok_if_already_exists
)
2422 || INTEGERP (ok_if_already_exists
))
2423 barf_or_query_if_file_exists (linkname
, "make it a link",
2424 INTEGERP (ok_if_already_exists
), 0);
2425 if (0 > symlink (XSTRING (filename
)->data
, XSTRING (linkname
)->data
))
2427 /* If we didn't complain already, silently delete existing file. */
2428 if (errno
== EEXIST
)
2430 unlink (XSTRING (linkname
)->data
);
2431 if (0 <= symlink (XSTRING (filename
)->data
, XSTRING (linkname
)->data
))
2441 report_file_error ("Making symbolic link", Flist (2, args
));
2443 report_file_error ("Making symbolic link", Flist (2, &filename
));
2449 #endif /* S_IFLNK */
2453 DEFUN ("define-logical-name", Fdefine_logical_name
, Sdefine_logical_name
,
2454 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2455 "Define the job-wide logical name NAME to have the value STRING.\n\
2456 If STRING is nil or a null string, the logical name NAME is deleted.")
2461 CHECK_STRING (name
, 0);
2463 delete_logical_name (XSTRING (name
)->data
);
2466 CHECK_STRING (string
, 1);
2468 if (XSTRING (string
)->size
== 0)
2469 delete_logical_name (XSTRING (name
)->data
);
2471 define_logical_name (XSTRING (name
)->data
, XSTRING (string
)->data
);
2480 DEFUN ("sysnetunam", Fsysnetunam
, Ssysnetunam
, 2, 2, 0,
2481 "Open a network connection to PATH using LOGIN as the login string.")
2483 Lisp_Object path
, login
;
2487 CHECK_STRING (path
, 0);
2488 CHECK_STRING (login
, 0);
2490 netresult
= netunam (XSTRING (path
)->data
, XSTRING (login
)->data
);
2492 if (netresult
== -1)
2497 #endif /* HPUX_NET */
2499 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p
, Sfile_name_absolute_p
,
2501 "Return t if file FILENAME specifies an absolute file name.\n\
2502 On Unix, this is a name starting with a `/' or a `~'.")
2504 Lisp_Object filename
;
2508 CHECK_STRING (filename
, 0);
2509 ptr
= XSTRING (filename
)->data
;
2510 if (IS_DIRECTORY_SEP (*ptr
) || *ptr
== '~'
2512 /* ??? This criterion is probably wrong for '<'. */
2513 || index (ptr
, ':') || index (ptr
, '<')
2514 || (*ptr
== '[' && (ptr
[1] != '-' || (ptr
[2] != '.' && ptr
[2] != ']'))
2518 || (IS_DRIVE (*ptr
) && ptr
[1] == ':' && IS_DIRECTORY_SEP (ptr
[2]))
2526 /* Return nonzero if file FILENAME exists and can be executed. */
2529 check_executable (filename
)
2533 int len
= strlen (filename
);
2536 if (stat (filename
, &st
) < 0)
2538 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2539 return ((st
.st_mode
& S_IEXEC
) != 0);
2541 return (S_ISREG (st
.st_mode
)
2543 && (stricmp ((suffix
= filename
+ len
-4), ".com") == 0
2544 || stricmp (suffix
, ".exe") == 0
2545 || stricmp (suffix
, ".bat") == 0)
2546 || (st
.st_mode
& S_IFMT
) == S_IFDIR
);
2547 #endif /* not WINDOWSNT */
2548 #else /* not DOS_NT */
2549 #ifdef HAVE_EUIDACCESS
2550 return (euidaccess (filename
, 1) >= 0);
2552 /* Access isn't quite right because it uses the real uid
2553 and we really want to test with the effective uid.
2554 But Unix doesn't give us a right way to do it. */
2555 return (access (filename
, 1) >= 0);
2557 #endif /* not DOS_NT */
2560 /* Return nonzero if file FILENAME exists and can be written. */
2563 check_writable (filename
)
2568 if (stat (filename
, &st
) < 0)
2570 return (st
.st_mode
& S_IWRITE
|| (st
.st_mode
& S_IFMT
) == S_IFDIR
);
2571 #else /* not MSDOS */
2572 #ifdef HAVE_EUIDACCESS
2573 return (euidaccess (filename
, 2) >= 0);
2575 /* Access isn't quite right because it uses the real uid
2576 and we really want to test with the effective uid.
2577 But Unix doesn't give us a right way to do it.
2578 Opening with O_WRONLY could work for an ordinary file,
2579 but would lose for directories. */
2580 return (access (filename
, 2) >= 0);
2582 #endif /* not MSDOS */
2585 DEFUN ("file-exists-p", Ffile_exists_p
, Sfile_exists_p
, 1, 1, 0,
2586 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2587 See also `file-readable-p' and `file-attributes'.")
2589 Lisp_Object filename
;
2591 Lisp_Object absname
;
2592 Lisp_Object handler
;
2593 struct stat statbuf
;
2595 CHECK_STRING (filename
, 0);
2596 absname
= Fexpand_file_name (filename
, Qnil
);
2598 /* If the file name has special constructs in it,
2599 call the corresponding file handler. */
2600 handler
= Ffind_file_name_handler (absname
, Qfile_exists_p
);
2601 if (!NILP (handler
))
2602 return call2 (handler
, Qfile_exists_p
, absname
);
2604 return (stat (XSTRING (absname
)->data
, &statbuf
) >= 0) ? Qt
: Qnil
;
2607 DEFUN ("file-executable-p", Ffile_executable_p
, Sfile_executable_p
, 1, 1, 0,
2608 "Return t if FILENAME can be executed by you.\n\
2609 For a directory, this means you can access files in that directory.")
2611 Lisp_Object filename
;
2614 Lisp_Object absname
;
2615 Lisp_Object handler
;
2617 CHECK_STRING (filename
, 0);
2618 absname
= Fexpand_file_name (filename
, Qnil
);
2620 /* If the file name has special constructs in it,
2621 call the corresponding file handler. */
2622 handler
= Ffind_file_name_handler (absname
, Qfile_executable_p
);
2623 if (!NILP (handler
))
2624 return call2 (handler
, Qfile_executable_p
, absname
);
2626 return (check_executable (XSTRING (absname
)->data
) ? Qt
: Qnil
);
2629 DEFUN ("file-readable-p", Ffile_readable_p
, Sfile_readable_p
, 1, 1, 0,
2630 "Return t if file FILENAME exists and you can read it.\n\
2631 See also `file-exists-p' and `file-attributes'.")
2633 Lisp_Object filename
;
2635 Lisp_Object absname
;
2636 Lisp_Object handler
;
2639 struct stat statbuf
;
2641 CHECK_STRING (filename
, 0);
2642 absname
= Fexpand_file_name (filename
, Qnil
);
2644 /* If the file name has special constructs in it,
2645 call the corresponding file handler. */
2646 handler
= Ffind_file_name_handler (absname
, Qfile_readable_p
);
2647 if (!NILP (handler
))
2648 return call2 (handler
, Qfile_readable_p
, absname
);
2651 /* Under MS-DOS and Windows, open does not work for directories. */
2652 if (access (XSTRING (absname
)->data
, 0) == 0)
2655 #else /* not DOS_NT */
2657 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
2658 /* Opening a fifo without O_NONBLOCK can wait.
2659 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2660 except in the case of a fifo, on a system which handles it. */
2661 desc
= stat (XSTRING (absname
)->data
, &statbuf
);
2664 if (S_ISFIFO (statbuf
.st_mode
))
2665 flags
|= O_NONBLOCK
;
2667 desc
= open (XSTRING (absname
)->data
, flags
);
2672 #endif /* not DOS_NT */
2675 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2677 DEFUN ("file-writable-p", Ffile_writable_p
, Sfile_writable_p
, 1, 1, 0,
2678 "Return t if file FILENAME can be written or created by you.")
2680 Lisp_Object filename
;
2682 Lisp_Object absname
, dir
;
2683 Lisp_Object handler
;
2684 struct stat statbuf
;
2686 CHECK_STRING (filename
, 0);
2687 absname
= Fexpand_file_name (filename
, Qnil
);
2689 /* If the file name has special constructs in it,
2690 call the corresponding file handler. */
2691 handler
= Ffind_file_name_handler (absname
, Qfile_writable_p
);
2692 if (!NILP (handler
))
2693 return call2 (handler
, Qfile_writable_p
, absname
);
2695 if (stat (XSTRING (absname
)->data
, &statbuf
) >= 0)
2696 return (check_writable (XSTRING (absname
)->data
)
2698 dir
= Ffile_name_directory (absname
);
2701 dir
= Fdirectory_file_name (dir
);
2705 dir
= Fdirectory_file_name (dir
);
2707 return (check_writable (!NILP (dir
) ? (char *) XSTRING (dir
)->data
: "")
2711 DEFUN ("access-file", Faccess_file
, Saccess_file
, 2, 2, 0,
2712 "Access file FILENAME, and get an error if that does not work.\n\
2713 The second argument STRING is used in the error message.\n\
2714 If there is no error, we return nil.")
2716 Lisp_Object filename
, string
;
2718 Lisp_Object handler
;
2721 CHECK_STRING (filename
, 0);
2723 /* If the file name has special constructs in it,
2724 call the corresponding file handler. */
2725 handler
= Ffind_file_name_handler (filename
, Qaccess_file
);
2726 if (!NILP (handler
))
2727 return call3 (handler
, Qaccess_file
, filename
, string
);
2729 fd
= open (XSTRING (filename
)->data
, O_RDONLY
);
2731 report_file_error (XSTRING (string
)->data
, Fcons (filename
, Qnil
));
2737 DEFUN ("file-symlink-p", Ffile_symlink_p
, Sfile_symlink_p
, 1, 1, 0,
2738 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2739 The value is the name of the file to which it is linked.\n\
2740 Otherwise returns nil.")
2742 Lisp_Object filename
;
2749 Lisp_Object handler
;
2751 CHECK_STRING (filename
, 0);
2752 filename
= Fexpand_file_name (filename
, Qnil
);
2754 /* If the file name has special constructs in it,
2755 call the corresponding file handler. */
2756 handler
= Ffind_file_name_handler (filename
, Qfile_symlink_p
);
2757 if (!NILP (handler
))
2758 return call2 (handler
, Qfile_symlink_p
, filename
);
2763 buf
= (char *) xmalloc (bufsize
);
2764 bzero (buf
, bufsize
);
2765 valsize
= readlink (XSTRING (filename
)->data
, buf
, bufsize
);
2766 if (valsize
< bufsize
) break;
2767 /* Buffer was not long enough */
2776 val
= make_string (buf
, valsize
);
2779 #else /* not S_IFLNK */
2781 #endif /* not S_IFLNK */
2784 DEFUN ("file-directory-p", Ffile_directory_p
, Sfile_directory_p
, 1, 1, 0,
2785 "Return t if FILENAME names an existing directory.")
2787 Lisp_Object filename
;
2789 register Lisp_Object absname
;
2791 Lisp_Object handler
;
2793 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2795 /* If the file name has special constructs in it,
2796 call the corresponding file handler. */
2797 handler
= Ffind_file_name_handler (absname
, Qfile_directory_p
);
2798 if (!NILP (handler
))
2799 return call2 (handler
, Qfile_directory_p
, absname
);
2801 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2803 return (st
.st_mode
& S_IFMT
) == S_IFDIR
? Qt
: Qnil
;
2806 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p
, Sfile_accessible_directory_p
, 1, 1, 0,
2807 "Return t if file FILENAME is the name of a directory as a file,\n\
2808 and files in that directory can be opened by you. In order to use a\n\
2809 directory as a buffer's current directory, this predicate must return true.\n\
2810 A directory name spec may be given instead; then the value is t\n\
2811 if the directory so specified exists and really is a readable and\n\
2812 searchable directory.")
2814 Lisp_Object filename
;
2816 Lisp_Object handler
;
2818 struct gcpro gcpro1
;
2820 /* If the file name has special constructs in it,
2821 call the corresponding file handler. */
2822 handler
= Ffind_file_name_handler (filename
, Qfile_accessible_directory_p
);
2823 if (!NILP (handler
))
2824 return call2 (handler
, Qfile_accessible_directory_p
, filename
);
2826 /* It's an unlikely combination, but yes we really do need to gcpro:
2827 Suppose that file-accessible-directory-p has no handler, but
2828 file-directory-p does have a handler; this handler causes a GC which
2829 relocates the string in `filename'; and finally file-directory-p
2830 returns non-nil. Then we would end up passing a garbaged string
2831 to file-executable-p. */
2833 tem
= (NILP (Ffile_directory_p (filename
))
2834 || NILP (Ffile_executable_p (filename
)));
2836 return tem
? Qnil
: Qt
;
2839 DEFUN ("file-regular-p", Ffile_regular_p
, Sfile_regular_p
, 1, 1, 0,
2840 "Return t if file FILENAME is the name of a regular file.\n\
2841 This is the sort of file that holds an ordinary stream of data bytes.")
2843 Lisp_Object filename
;
2845 register Lisp_Object absname
;
2847 Lisp_Object handler
;
2849 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2851 /* If the file name has special constructs in it,
2852 call the corresponding file handler. */
2853 handler
= Ffind_file_name_handler (absname
, Qfile_regular_p
);
2854 if (!NILP (handler
))
2855 return call2 (handler
, Qfile_regular_p
, absname
);
2857 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2859 return (st
.st_mode
& S_IFMT
) == S_IFREG
? Qt
: Qnil
;
2862 DEFUN ("file-modes", Ffile_modes
, Sfile_modes
, 1, 1, 0,
2863 "Return mode bits of file named FILENAME, as an integer.")
2865 Lisp_Object filename
;
2867 Lisp_Object absname
;
2869 Lisp_Object handler
;
2871 absname
= expand_and_dir_to_file (filename
, current_buffer
->directory
);
2873 /* If the file name has special constructs in it,
2874 call the corresponding file handler. */
2875 handler
= Ffind_file_name_handler (absname
, Qfile_modes
);
2876 if (!NILP (handler
))
2877 return call2 (handler
, Qfile_modes
, absname
);
2879 if (stat (XSTRING (absname
)->data
, &st
) < 0)
2881 #if defined (MSDOS) && __DJGPP__ < 2
2882 if (check_executable (XSTRING (absname
)->data
))
2883 st
.st_mode
|= S_IEXEC
;
2884 #endif /* MSDOS && __DJGPP__ < 2 */
2886 return make_number (st
.st_mode
& 07777);
2889 DEFUN ("set-file-modes", Fset_file_modes
, Sset_file_modes
, 2, 2, 0,
2890 "Set mode bits of file named FILENAME to MODE (an integer).\n\
2891 Only the 12 low bits of MODE are used.")
2893 Lisp_Object filename
, mode
;
2895 Lisp_Object absname
;
2896 Lisp_Object handler
;
2898 absname
= Fexpand_file_name (filename
, current_buffer
->directory
);
2899 CHECK_NUMBER (mode
, 1);
2901 /* If the file name has special constructs in it,
2902 call the corresponding file handler. */
2903 handler
= Ffind_file_name_handler (absname
, Qset_file_modes
);
2904 if (!NILP (handler
))
2905 return call3 (handler
, Qset_file_modes
, absname
, mode
);
2907 if (chmod (XSTRING (absname
)->data
, XINT (mode
)) < 0)
2908 report_file_error ("Doing chmod", Fcons (absname
, Qnil
));
2913 DEFUN ("set-default-file-modes", Fset_default_file_modes
, Sset_default_file_modes
, 1, 1, 0,
2914 "Set the file permission bits for newly created files.\n\
2915 The argument MODE should be an integer; only the low 9 bits are used.\n\
2916 This setting is inherited by subprocesses.")
2920 CHECK_NUMBER (mode
, 0);
2922 umask ((~ XINT (mode
)) & 0777);
2927 DEFUN ("default-file-modes", Fdefault_file_modes
, Sdefault_file_modes
, 0, 0, 0,
2928 "Return the default file protection for created files.\n\
2929 The value is an integer.")
2935 realmask
= umask (0);
2938 XSETINT (value
, (~ realmask
) & 0777);
2944 DEFUN ("unix-sync", Funix_sync
, Sunix_sync
, 0, 0, "",
2945 "Tell Unix to finish all pending disk updates.")
2954 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p
, Sfile_newer_than_file_p
, 2, 2, 0,
2955 "Return t if file FILE1 is newer than file FILE2.\n\
2956 If FILE1 does not exist, the answer is nil;\n\
2957 otherwise, if FILE2 does not exist, the answer is t.")
2959 Lisp_Object file1
, file2
;
2961 Lisp_Object absname1
, absname2
;
2964 Lisp_Object handler
;
2965 struct gcpro gcpro1
, gcpro2
;
2967 CHECK_STRING (file1
, 0);
2968 CHECK_STRING (file2
, 0);
2971 GCPRO2 (absname1
, file2
);
2972 absname1
= expand_and_dir_to_file (file1
, current_buffer
->directory
);
2973 absname2
= expand_and_dir_to_file (file2
, current_buffer
->directory
);
2976 /* If the file name has special constructs in it,
2977 call the corresponding file handler. */
2978 handler
= Ffind_file_name_handler (absname1
, Qfile_newer_than_file_p
);
2980 handler
= Ffind_file_name_handler (absname2
, Qfile_newer_than_file_p
);
2981 if (!NILP (handler
))
2982 return call3 (handler
, Qfile_newer_than_file_p
, absname1
, absname2
);
2984 if (stat (XSTRING (absname1
)->data
, &st
) < 0)
2987 mtime1
= st
.st_mtime
;
2989 if (stat (XSTRING (absname2
)->data
, &st
) < 0)
2992 return (mtime1
> st
.st_mtime
) ? Qt
: Qnil
;
2996 Lisp_Object Qfind_buffer_file_type
;
2999 #ifndef READ_BUF_SIZE
3000 #define READ_BUF_SIZE (64 << 10)
3003 DEFUN ("insert-file-contents", Finsert_file_contents
, Sinsert_file_contents
,
3005 "Insert contents of file FILENAME after point.\n\
3006 Returns list of absolute file name and length of data inserted.\n\
3007 If second argument VISIT is non-nil, the buffer's visited filename\n\
3008 and last save file modtime are set, and it is marked unmodified.\n\
3009 If visiting and the file does not exist, visiting is completed\n\
3010 before the error is signaled.\n\
3011 The optional third and fourth arguments BEG and END\n\
3012 specify what portion of the file to insert.\n\
3013 If VISIT is non-nil, BEG and END must be nil.\n\
3015 If optional fifth argument REPLACE is non-nil,\n\
3016 it means replace the current buffer contents (in the accessible portion)\n\
3017 with the file contents. This is better than simply deleting and inserting\n\
3018 the whole thing because (1) it preserves some marker positions\n\
3019 and (2) it puts less data in the undo list.\n\
3020 When REPLACE is non-nil, the value is the number of characters actually read,\n\
3021 which is often less than the number of characters to be read.\n\
3022 This does code conversion according to the value of\n\
3023 `coding-system-for-read' or `file-coding-system-alist',\n\
3024 and sets the variable `last-coding-system-used' to the coding system\n\
3026 (filename
, visit
, beg
, end
, replace
)
3027 Lisp_Object filename
, visit
, beg
, end
, replace
;
3031 register int inserted
= 0;
3032 register int how_much
;
3033 register int unprocessed
;
3034 int count
= specpdl_ptr
- specpdl
;
3035 struct gcpro gcpro1
, gcpro2
, gcpro3
;
3036 Lisp_Object handler
, val
, insval
;
3039 int not_regular
= 0;
3040 char read_buf
[READ_BUF_SIZE
];
3041 struct coding_system coding
;
3042 unsigned char buffer
[1 << 14];
3043 int replace_handled
= 0;
3045 if (current_buffer
->base_buffer
&& ! NILP (visit
))
3046 error ("Cannot do file visiting in an indirect buffer");
3048 if (!NILP (current_buffer
->read_only
))
3049 Fbarf_if_buffer_read_only ();
3054 GCPRO3 (filename
, val
, p
);
3056 CHECK_STRING (filename
, 0);
3057 filename
= Fexpand_file_name (filename
, Qnil
);
3059 /* If the file name has special constructs in it,
3060 call the corresponding file handler. */
3061 handler
= Ffind_file_name_handler (filename
, Qinsert_file_contents
);
3062 if (!NILP (handler
))
3064 val
= call6 (handler
, Qinsert_file_contents
, filename
,
3065 visit
, beg
, end
, replace
);
3072 if (stat (XSTRING (filename
)->data
, &st
) < 0)
3074 if ((fd
= open (XSTRING (filename
)->data
, O_RDONLY
)) < 0
3075 || fstat (fd
, &st
) < 0)
3076 #endif /* not APOLLO */
3078 if (fd
>= 0) close (fd
);
3081 report_file_error ("Opening input file", Fcons (filename
, Qnil
));
3088 /* This code will need to be changed in order to work on named
3089 pipes, and it's probably just not worth it. So we should at
3090 least signal an error. */
3091 if (!S_ISREG (st
.st_mode
))
3098 if (! NILP (replace
) || ! NILP (beg
) || ! NILP (end
))
3099 Fsignal (Qfile_error
,
3100 Fcons (build_string ("not a regular file"),
3101 Fcons (filename
, Qnil
)));
3106 if ((fd
= open (XSTRING (filename
)->data
, O_RDONLY
)) < 0)
3109 /* Replacement should preserve point as it preserves markers. */
3110 if (!NILP (replace
))
3111 record_unwind_protect (restore_point_unwind
, Fpoint_marker ());
3113 record_unwind_protect (close_file_unwind
, make_number (fd
));
3115 /* Supposedly happens on VMS. */
3116 if (! not_regular
&& st
.st_size
< 0)
3117 error ("File size is negative");
3119 if (!NILP (beg
) || !NILP (end
))
3121 error ("Attempt to visit less than an entire file");
3124 CHECK_NUMBER (beg
, 0);
3126 XSETFASTINT (beg
, 0);
3129 CHECK_NUMBER (end
, 0);
3134 XSETINT (end
, st
.st_size
);
3135 if (XINT (end
) != st
.st_size
)
3136 error ("Maximum buffer size exceeded");
3140 /* Decide the coding-system of the file. */
3142 Lisp_Object val
= Qnil
;
3144 if (!NILP (Vcoding_system_for_read
))
3145 val
= Vcoding_system_for_read
;
3146 else if (NILP (current_buffer
->enable_multibyte_characters
))
3150 if (SYMBOLP (Vauto_file_coding_system_function
)
3151 && Fboundp (Vauto_file_coding_system_function
))
3153 /* Find a coding system specified in a few lines at the
3154 head of the file. We assume that the fist 1K bytes is
3155 sufficient fot this purpose. */
3156 int nread
= read (fd
, read_buf
, 1024);
3159 error ("IO error reading %s: %s",
3160 XSTRING (filename
)->data
, strerror (errno
));
3163 val
= call1 (Vauto_file_coding_system_function
,
3164 make_string (read_buf
, nread
));
3165 /* Rewind the file for the actual read done later. */
3166 if (lseek (fd
, 0, 0) < 0)
3167 report_file_error ("Setting file position",
3168 Fcons (filename
, Qnil
));
3173 Lisp_Object args
[6], coding_systems
;
3175 args
[0] = Qinsert_file_contents
, args
[1] = filename
,
3176 args
[2] = visit
, args
[3] = beg
, args
[4] = end
, args
[5] = replace
;
3177 coding_systems
= Ffind_operation_coding_system (6, args
);
3178 if (CONSP (coding_systems
)) val
= XCONS (coding_systems
)->car
;
3181 setup_coding_system (Fcheck_coding_system (val
), &coding
);
3184 /* If requested, replace the accessible part of the buffer
3185 with the file contents. Avoid replacing text at the
3186 beginning or end of the buffer that matches the file contents;
3187 that preserves markers pointing to the unchanged parts.
3189 Here we implement this feature in an optimized way
3190 for the case where code conversion is NOT needed.
3191 The following if-statement handles the case of conversion
3192 in a less optimal way.
3194 If the code conversion is "automatic" then we try using this
3195 method and hope for the best.
3196 But if we discover the need for conversion, we give up on this method
3197 and let the following if-statement handle the replace job. */
3199 && CODING_MAY_REQUIRE_NO_CONVERSION (&coding
))
3201 int same_at_start
= BEGV
;
3202 int same_at_end
= ZV
;
3204 /* There is still a possibility we will find the need to do code
3205 conversion. If that happens, we set this variable to 1 to
3206 give up on handling REPLACE in the optimized way. */
3207 int giveup_match_end
= 0;
3209 if (XINT (beg
) != 0)
3211 if (lseek (fd
, XINT (beg
), 0) < 0)
3212 report_file_error ("Setting file position",
3213 Fcons (filename
, Qnil
));
3218 /* Count how many chars at the start of the file
3219 match the text at the beginning of the buffer. */
3224 nread
= read (fd
, buffer
, sizeof buffer
);
3226 error ("IO error reading %s: %s",
3227 XSTRING (filename
)->data
, strerror (errno
));
3228 else if (nread
== 0)
3231 if (coding
.type
== coding_type_undecided
)
3232 detect_coding (&coding
, buffer
, nread
);
3233 if (coding
.type
!= coding_type_undecided
3234 && coding
.type
!= coding_type_no_conversion
3235 && coding
.type
!= coding_type_emacs_mule
)
3236 /* We found that the file should be decoded somehow.
3237 Let's give up here. */
3239 giveup_match_end
= 1;
3243 if (coding
.eol_type
== CODING_EOL_UNDECIDED
)
3244 detect_eol (&coding
, buffer
, nread
);
3245 if (coding
.eol_type
!= CODING_EOL_UNDECIDED
3246 && coding
.eol_type
!= CODING_EOL_LF
)
3247 /* We found that the format of eol should be decoded.
3248 Let's give up here. */
3250 giveup_match_end
= 1;
3255 while (bufpos
< nread
&& same_at_start
< ZV
3256 && FETCH_BYTE (same_at_start
) == buffer
[bufpos
])
3257 same_at_start
++, bufpos
++;
3258 /* If we found a discrepancy, stop the scan.
3259 Otherwise loop around and scan the next bufferful. */
3260 if (bufpos
!= nread
)
3264 /* If the file matches the buffer completely,
3265 there's no need to replace anything. */
3266 if (same_at_start
- BEGV
== XINT (end
))
3270 /* Truncate the buffer to the size of the file. */
3271 del_range_1 (same_at_start
, same_at_end
, 0);
3276 /* Count how many chars at the end of the file
3277 match the text at the end of the buffer. But, if we have
3278 already found that decoding is necessary, don't waste time. */
3279 while (!giveup_match_end
)
3281 int total_read
, nread
, bufpos
, curpos
, trial
;
3283 /* At what file position are we now scanning? */
3284 curpos
= XINT (end
) - (ZV
- same_at_end
);
3285 /* If the entire file matches the buffer tail, stop the scan. */
3288 /* How much can we scan in the next step? */
3289 trial
= min (curpos
, sizeof buffer
);
3290 if (lseek (fd
, curpos
- trial
, 0) < 0)
3291 report_file_error ("Setting file position",
3292 Fcons (filename
, Qnil
));
3295 while (total_read
< trial
)
3297 nread
= read (fd
, buffer
+ total_read
, trial
- total_read
);
3299 error ("IO error reading %s: %s",
3300 XSTRING (filename
)->data
, strerror (errno
));
3301 total_read
+= nread
;
3303 /* Scan this bufferful from the end, comparing with
3304 the Emacs buffer. */
3305 bufpos
= total_read
;
3306 /* Compare with same_at_start to avoid counting some buffer text
3307 as matching both at the file's beginning and at the end. */
3308 while (bufpos
> 0 && same_at_end
> same_at_start
3309 && FETCH_BYTE (same_at_end
- 1) == buffer
[bufpos
- 1])
3310 same_at_end
--, bufpos
--;
3312 /* If we found a discrepancy, stop the scan.
3313 Otherwise loop around and scan the preceding bufferful. */
3316 /* If this discrepancy is because of code conversion,
3317 we cannot use this method; giveup and try the other. */
3318 if (same_at_end
> same_at_start
3319 && FETCH_BYTE (same_at_end
- 1) >= 0200
3320 && ! NILP (current_buffer
->enable_multibyte_characters
)
3321 && ! CODING_REQUIRE_NO_CONVERSION (&coding
))
3322 giveup_match_end
= 1;
3328 if (! giveup_match_end
)
3330 /* We win! We can handle REPLACE the optimized way. */
3332 /* Extends the end of non-matching text area to multibyte
3333 character boundary. */
3334 if (! NILP (current_buffer
->enable_multibyte_characters
))
3335 while (same_at_end
< ZV
&& ! CHAR_HEAD_P (POS_ADDR (same_at_end
)))
3338 /* Don't try to reuse the same piece of text twice. */
3339 overlap
= same_at_start
- BEGV
- (same_at_end
+ st
.st_size
- ZV
);
3341 same_at_end
+= overlap
;
3343 /* Arrange to read only the nonmatching middle part of the file. */
3344 XSETFASTINT (beg
, XINT (beg
) + (same_at_start
- BEGV
));
3345 XSETFASTINT (end
, XINT (end
) - (ZV
- same_at_end
));
3347 del_range_1 (same_at_start
, same_at_end
, 0);
3348 /* Insert from the file at the proper position. */
3349 SET_PT (same_at_start
);
3351 /* If display currently starts at beginning of line,
3352 keep it that way. */
3353 if (XBUFFER (XWINDOW (selected_window
)->buffer
) == current_buffer
)
3354 XWINDOW (selected_window
)->start_at_line_beg
= Fbolp ();
3356 replace_handled
= 1;
3360 /* If requested, replace the accessible part of the buffer
3361 with the file contents. Avoid replacing text at the
3362 beginning or end of the buffer that matches the file contents;
3363 that preserves markers pointing to the unchanged parts.
3365 Here we implement this feature for the case where code conversion
3366 is needed, in a simple way that needs a lot of memory.
3367 The preceding if-statement handles the case of no conversion
3368 in a more optimized way. */
3369 if (!NILP (replace
) && ! replace_handled
)
3371 int same_at_start
= BEGV
;
3372 int same_at_end
= ZV
;
3375 /* Make sure that the gap is large enough. */
3376 int bufsize
= 2 * st
.st_size
;
3377 unsigned char *conversion_buffer
= (unsigned char *) xmalloc (bufsize
);
3379 /* First read the whole file, performing code conversion into
3380 CONVERSION_BUFFER. */
3382 if (lseek (fd
, XINT (beg
), 0) < 0)
3384 free (conversion_buffer
);
3385 report_file_error ("Setting file position",
3386 Fcons (filename
, Qnil
));
3389 total
= st
.st_size
; /* Total bytes in the file. */
3390 how_much
= 0; /* Bytes read from file so far. */
3391 inserted
= 0; /* Bytes put into CONVERSION_BUFFER so far. */
3392 unprocessed
= 0; /* Bytes not processed in previous loop. */
3394 while (how_much
< total
)
3396 /* try is reserved in some compilers (Microsoft C) */
3397 int trytry
= min (total
- how_much
, READ_BUF_SIZE
- unprocessed
);
3398 char *destination
= read_buf
+ unprocessed
;
3401 /* Allow quitting out of the actual I/O. */
3404 this = read (fd
, destination
, trytry
);
3407 if (this < 0 || this + unprocessed
== 0)
3415 if (! CODING_REQUIRE_NO_CONVERSION (&coding
))
3417 int require
, produced
, consumed
;
3419 this += unprocessed
;
3421 /* If we are using more space than estimated,
3422 make CONVERSION_BUFFER bigger. */
3423 require
= decoding_buffer_size (&coding
, this);
3424 if (inserted
+ require
+ 2 * (total
- how_much
) > bufsize
)
3426 bufsize
= inserted
+ require
+ 2 * (total
- how_much
);
3427 conversion_buffer
= (unsigned char *) xrealloc (conversion_buffer
, bufsize
);
3430 /* Convert this batch with results in CONVERSION_BUFFER. */
3431 if (how_much
>= total
) /* This is the last block. */
3432 coding
.last_block
= 1;
3433 produced
= decode_coding (&coding
, read_buf
,
3434 conversion_buffer
+ inserted
,
3435 this, bufsize
- inserted
,
3438 /* Save for next iteration whatever we didn't convert. */
3439 unprocessed
= this - consumed
;
3440 bcopy (read_buf
+ consumed
, read_buf
, unprocessed
);
3447 /* At this point, INSERTED is how many characters
3448 are present in CONVERSION_BUFFER.
3449 HOW_MUCH should equal TOTAL,
3450 or should be <= 0 if we couldn't read the file. */
3454 free (conversion_buffer
);
3457 error ("IO error reading %s: %s",
3458 XSTRING (filename
)->data
, strerror (errno
));
3459 else if (how_much
== -2)
3460 error ("maximum buffer size exceeded");
3463 /* Compare the beginning of the converted file
3464 with the buffer text. */
3467 while (bufpos
< inserted
&& same_at_start
< same_at_end
3468 && FETCH_BYTE (same_at_start
) == conversion_buffer
[bufpos
])
3469 same_at_start
++, bufpos
++;
3471 /* If the file matches the buffer completely,
3472 there's no need to replace anything. */
3474 if (bufpos
== inserted
)
3476 free (conversion_buffer
);
3479 /* Truncate the buffer to the size of the file. */
3480 del_range_1 (same_at_start
, same_at_end
, 0);
3484 /* Scan this bufferful from the end, comparing with
3485 the Emacs buffer. */
3488 /* Compare with same_at_start to avoid counting some buffer text
3489 as matching both at the file's beginning and at the end. */
3490 while (bufpos
> 0 && same_at_end
> same_at_start
3491 && FETCH_BYTE (same_at_end
- 1) == conversion_buffer
[bufpos
- 1])
3492 same_at_end
--, bufpos
--;
3494 /* Don't try to reuse the same piece of text twice. */
3495 overlap
= same_at_start
- BEGV
- (same_at_end
+ inserted
- ZV
);
3497 same_at_end
+= overlap
;
3499 /* If display currently starts at beginning of line,
3500 keep it that way. */
3501 if (XBUFFER (XWINDOW (selected_window
)->buffer
) == current_buffer
)
3502 XWINDOW (selected_window
)->start_at_line_beg
= Fbolp ();
3504 /* Replace the chars that we need to replace,
3505 and update INSERTED to equal the number of bytes
3506 we are taking from the file. */
3507 inserted
-= (Z
- same_at_end
) + (same_at_start
- BEG
);
3508 move_gap (same_at_start
);
3509 del_range_1 (same_at_start
, same_at_end
, 0);
3510 SET_PT (same_at_start
);
3511 insert_1 (conversion_buffer
+ same_at_start
- BEG
, inserted
, 0, 0);
3513 free (conversion_buffer
);
3522 register Lisp_Object temp
;
3524 total
= XINT (end
) - XINT (beg
);
3526 /* Make sure point-max won't overflow after this insertion. */
3527 XSETINT (temp
, total
);
3528 if (total
!= XINT (temp
))
3529 error ("Maximum buffer size exceeded");
3532 /* For a special file, all we can do is guess. */
3533 total
= READ_BUF_SIZE
;
3535 if (NILP (visit
) && total
> 0)
3536 prepare_to_modify_buffer (PT
, PT
, NULL
);
3539 if (GAP_SIZE
< total
)
3540 make_gap (total
- GAP_SIZE
);
3542 if (XINT (beg
) != 0 || !NILP (replace
))
3544 if (lseek (fd
, XINT (beg
), 0) < 0)
3545 report_file_error ("Setting file position", Fcons (filename
, Qnil
));
3548 /* In the following loop, HOW_MUCH contains the total bytes read so
3549 far. Before exiting the loop, it is set to -1 if I/O error
3550 occurs, set to -2 if the maximum buffer size is exceeded. */
3552 /* Total bytes inserted. */
3554 /* Bytes not processed in the previous loop because short gap size. */
3556 while (how_much
< total
)
3558 /* try is reserved in some compilers (Microsoft C) */
3559 int trytry
= min (total
- how_much
, READ_BUF_SIZE
- unprocessed
);
3560 char *destination
= (CODING_REQUIRE_NO_CONVERSION (&coding
)
3561 ? (char *) (POS_ADDR (PT
+ inserted
- 1) + 1)
3562 : read_buf
+ unprocessed
);
3565 /* Allow quitting out of the actual I/O. */
3568 this = read (fd
, destination
, trytry
);
3571 if (this < 0 || this + unprocessed
== 0)
3577 /* For a regular file, where TOTAL is the real size,
3578 count HOW_MUCH to compare with it.
3579 For a special file, where TOTAL is just a buffer size,
3580 so don't bother counting in HOW_MUCH.
3581 (INSERTED is where we count the number of characters inserted.) */
3585 if (! CODING_REQUIRE_NO_CONVERSION (&coding
))
3587 int require
, produced
, consumed
;
3589 this += unprocessed
;
3590 /* Make sure that the gap is large enough. */
3591 require
= decoding_buffer_size (&coding
, this);
3592 if (GAP_SIZE
< require
)
3593 make_gap (require
- GAP_SIZE
);
3597 if (how_much
>= total
) /* This is the last block. */
3598 coding
.last_block
= 1;
3602 /* If we encounter EOF, say it is the last block. (The
3603 data this will apply to is the UNPROCESSED characters
3604 carried over from the last batch.) */
3606 coding
.last_block
= 1;
3609 produced
= decode_coding (&coding
, read_buf
,
3610 POS_ADDR (PT
+ inserted
- 1) + 1,
3611 this, GAP_SIZE
, &consumed
);
3616 XSET (temp
, Lisp_Int
, Z
+ produced
);
3617 if (Z
+ produced
!= XINT (temp
))
3623 unprocessed
= this - consumed
;
3624 bcopy (read_buf
+ consumed
, read_buf
, unprocessed
);
3633 /* Put an anchor to ensure multi-byte form ends at gap. */
3640 /* Use the conversion type to determine buffer-file-type
3641 (find-buffer-file-type is now used to help determine the
3643 if (coding
.eol_type
!= CODING_EOL_UNDECIDED
3644 && coding
.eol_type
!= CODING_EOL_LF
)
3645 current_buffer
->buffer_file_type
= Qnil
;
3647 current_buffer
->buffer_file_type
= Qt
;
3650 /* We don't have to consider file type of MSDOS because all files
3651 are read as binary and end-of-line format has already been
3652 decoded appropriately. */
3655 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3656 /* Determine file type from name and remove LFs from CR-LFs if the file
3657 is deemed to be a text file. */
3659 current_buffer
->buffer_file_type
3660 = call1 (Qfind_buffer_file_type
, filename
);
3661 if (NILP (current_buffer
->buffer_file_type
))
3664 = inserted
- crlf_to_lf (inserted
, POS_ADDR (PT
- 1) + 1);
3667 GPT
-= reduced_size
;
3668 GAP_SIZE
+= reduced_size
;
3669 inserted
-= reduced_size
;
3677 record_insert (PT
, inserted
);
3679 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
3680 offset_intervals (current_buffer
, PT
, inserted
);
3686 /* Discard the unwind protect for closing the file. */
3690 error ("IO error reading %s: %s",
3691 XSTRING (filename
)->data
, strerror (errno
));
3692 else if (how_much
== -2)
3693 error ("maximum buffer size exceeded");
3700 if (!EQ (current_buffer
->undo_list
, Qt
))
3701 current_buffer
->undo_list
= Qnil
;
3703 stat (XSTRING (filename
)->data
, &st
);
3708 current_buffer
->modtime
= st
.st_mtime
;
3709 current_buffer
->filename
= filename
;
3712 SAVE_MODIFF
= MODIFF
;
3713 current_buffer
->auto_save_modified
= MODIFF
;
3714 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3715 #ifdef CLASH_DETECTION
3718 if (!NILP (current_buffer
->file_truename
))
3719 unlock_file (current_buffer
->file_truename
);
3720 unlock_file (filename
);
3722 #endif /* CLASH_DETECTION */
3724 Fsignal (Qfile_error
,
3725 Fcons (build_string ("not a regular file"),
3726 Fcons (filename
, Qnil
)));
3728 /* If visiting nonexistent file, return nil. */
3729 if (current_buffer
->modtime
== -1)
3730 report_file_error ("Opening input file", Fcons (filename
, Qnil
));
3733 /* Decode file format */
3736 insval
= call3 (Qformat_decode
,
3737 Qnil
, make_number (inserted
), visit
);
3738 CHECK_NUMBER (insval
, 0);
3739 inserted
= XFASTINT (insval
);
3742 /* Call after-change hooks for the inserted text, aside from the case
3743 of normal visiting (not with REPLACE), which is done in a new buffer
3744 "before" the buffer is changed. */
3745 if (inserted
> 0 && total
> 0
3746 && (NILP (visit
) || !NILP (replace
)))
3747 signal_after_change (PT
, 0, inserted
);
3751 p
= Vafter_insert_file_functions
;
3752 if (!NILP (coding
.post_read_conversion
))
3753 p
= Fcons (coding
.post_read_conversion
, p
);
3757 insval
= call1 (Fcar (p
), make_number (inserted
));
3760 CHECK_NUMBER (insval
, 0);
3761 inserted
= XFASTINT (insval
);
3769 val
= Fcons (filename
,
3770 Fcons (make_number (inserted
),
3773 RETURN_UNGCPRO (unbind_to (count
, val
));
3776 static Lisp_Object
build_annotations ();
3777 extern Lisp_Object
Ffile_locked_p ();
3779 /* If build_annotations switched buffers, switch back to BUF.
3780 Kill the temporary buffer that was selected in the meantime.
3782 Since this kill only the last temporary buffer, some buffers remain
3783 not killed if build_annotations switched buffers more than once.
3787 build_annotations_unwind (buf
)
3792 if (XBUFFER (buf
) == current_buffer
)
3794 tembuf
= Fcurrent_buffer ();
3796 Fkill_buffer (tembuf
);
3800 DEFUN ("write-region", Fwrite_region
, Swrite_region
, 3, 6,
3801 "r\nFWrite region to file: ",
3802 "Write current region into specified file.\n\
3803 When called from a program, takes three arguments:\n\
3804 START, END and FILENAME. START and END are buffer positions.\n\
3805 Optional fourth argument APPEND if non-nil means\n\
3806 append to existing file contents (if any).\n\
3807 Optional fifth argument VISIT if t means\n\
3808 set the last-save-file-modtime of buffer to this file's modtime\n\
3809 and mark buffer not modified.\n\
3810 If VISIT is a string, it is a second file name;\n\
3811 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3812 VISIT is also the file name to lock and unlock for clash detection.\n\
3813 If VISIT is neither t nor nil nor a string,\n\
3814 that means do not print the \"Wrote file\" message.\n\
3815 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3816 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3817 Kludgy feature: if START is a string, then that string is written\n\
3818 to the file, instead of any buffer contents, and END is ignored.")
3819 (start
, end
, filename
, append
, visit
, lockname
)
3820 Lisp_Object start
, end
, filename
, append
, visit
, lockname
;
3828 int count
= specpdl_ptr
- specpdl
;
3831 unsigned char *fname
= 0; /* If non-0, original filename (must rename) */
3833 Lisp_Object handler
;
3834 Lisp_Object visit_file
;
3835 Lisp_Object annotations
;
3836 int visiting
, quietly
;
3837 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
3838 struct buffer
*given_buffer
;
3840 int buffer_file_type
= O_BINARY
;
3842 struct coding_system coding
;
3844 if (current_buffer
->base_buffer
&& ! NILP (visit
))
3845 error ("Cannot do file visiting in an indirect buffer");
3847 if (!NILP (start
) && !STRINGP (start
))
3848 validate_region (&start
, &end
);
3850 GCPRO4 (start
, filename
, visit
, lockname
);
3852 /* Decide the coding-system to be encoded to. */
3858 else if (!NILP (Vcoding_system_for_write
))
3859 val
= Vcoding_system_for_write
;
3860 else if (NILP (current_buffer
->enable_multibyte_characters
))
3861 val
= (NILP (Flocal_variable_p (Qbuffer_file_coding_system
, Qnil
))
3863 : Fsymbol_value (Qbuffer_file_coding_system
));
3866 Lisp_Object args
[7], coding_systems
;
3868 args
[0] = Qwrite_region
, args
[1] = start
, args
[2] = end
,
3869 args
[3] = filename
, args
[4] = append
, args
[5] = visit
,
3871 coding_systems
= Ffind_operation_coding_system (7, args
);
3872 val
= (CONSP (coding_systems
) && !NILP (XCONS (coding_systems
)->cdr
)
3873 ? XCONS (coding_systems
)->cdr
3874 : current_buffer
->buffer_file_coding_system
);
3876 setup_coding_system (Fcheck_coding_system (val
), &coding
);
3877 if (!STRINGP (start
) && !NILP (current_buffer
->selective_display
))
3878 coding
.selective
= 1;
3881 filename
= Fexpand_file_name (filename
, Qnil
);
3882 if (STRINGP (visit
))
3883 visit_file
= Fexpand_file_name (visit
, Qnil
);
3885 visit_file
= filename
;
3888 visiting
= (EQ (visit
, Qt
) || STRINGP (visit
));
3889 quietly
= !NILP (visit
);
3893 if (NILP (lockname
))
3894 lockname
= visit_file
;
3896 GCPRO5 (start
, filename
, annotations
, visit_file
, lockname
);
3898 /* If the file name has special constructs in it,
3899 call the corresponding file handler. */
3900 handler
= Ffind_file_name_handler (filename
, Qwrite_region
);
3901 /* If FILENAME has no handler, see if VISIT has one. */
3902 if (NILP (handler
) && STRINGP (visit
))
3903 handler
= Ffind_file_name_handler (visit
, Qwrite_region
);
3905 if (!NILP (handler
))
3908 val
= call6 (handler
, Qwrite_region
, start
, end
,
3909 filename
, append
, visit
);
3913 SAVE_MODIFF
= MODIFF
;
3914 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
3915 current_buffer
->filename
= visit_file
;
3921 /* Special kludge to simplify auto-saving. */
3924 XSETFASTINT (start
, BEG
);
3925 XSETFASTINT (end
, Z
);
3928 record_unwind_protect (build_annotations_unwind
, Fcurrent_buffer ());
3929 count1
= specpdl_ptr
- specpdl
;
3931 given_buffer
= current_buffer
;
3932 annotations
= build_annotations (start
, end
, coding
.pre_write_conversion
);
3933 if (current_buffer
!= given_buffer
)
3935 XSETFASTINT (start
, BEGV
);
3936 XSETFASTINT (end
, ZV
);
3939 #ifdef CLASH_DETECTION
3942 #if 0 /* This causes trouble for GNUS. */
3943 /* If we've locked this file for some other buffer,
3944 query before proceeding. */
3945 if (!visiting
&& EQ (Ffile_locked_p (lockname
), Qt
))
3946 call2 (intern ("ask-user-about-lock"), filename
, Vuser_login_name
);
3949 lock_file (lockname
);
3951 #endif /* CLASH_DETECTION */
3953 fn
= XSTRING (filename
)->data
;
3957 desc
= open (fn
, O_WRONLY
| buffer_file_type
);
3958 #else /* not DOS_NT */
3959 desc
= open (fn
, O_WRONLY
);
3960 #endif /* not DOS_NT */
3962 if (desc
< 0 && (NILP (append
) || errno
== ENOENT
) )
3964 if (auto_saving
) /* Overwrite any previous version of autosave file */
3966 vms_truncate (fn
); /* if fn exists, truncate to zero length */
3967 desc
= open (fn
, O_RDWR
);
3969 desc
= creat_copy_attrs (STRINGP (current_buffer
->filename
)
3970 ? XSTRING (current_buffer
->filename
)->data
: 0,
3973 else /* Write to temporary name and rename if no errors */
3975 Lisp_Object temp_name
;
3976 temp_name
= Ffile_name_directory (filename
);
3978 if (!NILP (temp_name
))
3980 temp_name
= Fmake_temp_name (concat2 (temp_name
,
3981 build_string ("$$SAVE$$")));
3982 fname
= XSTRING (filename
)->data
;
3983 fn
= XSTRING (temp_name
)->data
;
3984 desc
= creat_copy_attrs (fname
, fn
);
3987 /* If we can't open the temporary file, try creating a new
3988 version of the original file. VMS "creat" creates a
3989 new version rather than truncating an existing file. */
3992 desc
= creat (fn
, 0666);
3993 #if 0 /* This can clobber an existing file and fail to replace it,
3994 if the user runs out of space. */
3997 /* We can't make a new version;
3998 try to truncate and rewrite existing version if any. */
4000 desc
= open (fn
, O_RDWR
);
4006 desc
= creat (fn
, 0666);
4011 O_WRONLY
| O_TRUNC
| O_CREAT
| buffer_file_type
,
4012 S_IREAD
| S_IWRITE
);
4013 #else /* not DOS_NT */
4014 desc
= creat (fn
, auto_saving
? auto_save_mode_bits
: 0666);
4015 #endif /* not DOS_NT */
4016 #endif /* not VMS */
4022 #ifdef CLASH_DETECTION
4024 if (!auto_saving
) unlock_file (lockname
);
4026 #endif /* CLASH_DETECTION */
4027 report_file_error ("Opening output file", Fcons (filename
, Qnil
));
4030 record_unwind_protect (close_file_unwind
, make_number (desc
));
4033 if (lseek (desc
, 0, 2) < 0)
4035 #ifdef CLASH_DETECTION
4036 if (!auto_saving
) unlock_file (lockname
);
4037 #endif /* CLASH_DETECTION */
4038 report_file_error ("Lseek error", Fcons (filename
, Qnil
));
4043 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4044 * if we do writes that don't end with a carriage return. Furthermore
4045 * it cannot handle writes of more then 16K. The modified
4046 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4047 * this EXCEPT for the last record (iff it doesn't end with a carriage
4048 * return). This implies that if your buffer doesn't end with a carriage
4049 * return, you get one free... tough. However it also means that if
4050 * we make two calls to sys_write (a la the following code) you can
4051 * get one at the gap as well. The easiest way to fix this (honest)
4052 * is to move the gap to the next newline (or the end of the buffer).
4057 if (GPT
> BEG
&& GPT_ADDR
[-1] != '\n')
4058 move_gap (find_next_newline (GPT
, 1));
4060 /* Whether VMS or not, we must move the gap to the next of newline
4061 when we must put designation sequences at beginning of line. */
4062 if (INTEGERP (start
)
4063 && coding
.type
== coding_type_iso2022
4064 && coding
.flags
& CODING_FLAG_ISO_DESIGNATE_AT_BOL
4065 && GPT
> BEG
&& GPT_ADDR
[-1] != '\n')
4066 move_gap (find_next_newline (GPT
, 1));
4072 if (STRINGP (start
))
4074 failure
= 0 > a_write (desc
, XSTRING (start
)->data
,
4075 XSTRING (start
)->size
, 0, &annotations
, &coding
);
4078 else if (XINT (start
) != XINT (end
))
4081 if (XINT (start
) < GPT
)
4083 register int end1
= XINT (end
);
4085 failure
= 0 > a_write (desc
, POS_ADDR (tem
),
4086 min (GPT
, end1
) - tem
, tem
, &annotations
,
4088 nwritten
+= min (GPT
, end1
) - tem
;
4092 if (XINT (end
) > GPT
&& !failure
)
4095 tem
= max (tem
, GPT
);
4096 failure
= 0 > a_write (desc
, POS_ADDR (tem
), XINT (end
) - tem
,
4097 tem
, &annotations
, &coding
);
4098 nwritten
+= XINT (end
) - tem
;
4104 /* If file was empty, still need to write the annotations */
4105 coding
.last_block
= 1;
4106 failure
= 0 > a_write (desc
, "", 0, XINT (start
), &annotations
, &coding
);
4110 if (coding
.require_flushing
&& !coding
.last_block
)
4112 /* We have to flush out a data. */
4113 coding
.last_block
= 1;
4114 failure
= 0 > e_write (desc
, "", 0, &coding
);
4121 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4122 Disk full in NFS may be reported here. */
4123 /* mib says that closing the file will try to write as fast as NFS can do
4124 it, and that means the fsync here is not crucial for autosave files. */
4125 if (!auto_saving
&& fsync (desc
) < 0)
4127 /* If fsync fails with EINTR, don't treat that as serious. */
4129 failure
= 1, save_errno
= errno
;
4133 /* Spurious "file has changed on disk" warnings have been
4134 observed on Suns as well.
4135 It seems that `close' can change the modtime, under nfs.
4137 (This has supposedly been fixed in Sunos 4,
4138 but who knows about all the other machines with NFS?) */
4141 /* On VMS and APOLLO, must do the stat after the close
4142 since closing changes the modtime. */
4145 /* Recall that #if defined does not work on VMS. */
4152 /* NFS can report a write failure now. */
4153 if (close (desc
) < 0)
4154 failure
= 1, save_errno
= errno
;
4157 /* If we wrote to a temporary name and had no errors, rename to real name. */
4161 failure
= (rename (fn
, fname
) != 0), save_errno
= errno
;
4169 /* Discard the unwind protect for close_file_unwind. */
4170 specpdl_ptr
= specpdl
+ count1
;
4171 /* Restore the original current buffer. */
4172 visit_file
= unbind_to (count
, visit_file
);
4174 #ifdef CLASH_DETECTION
4176 unlock_file (lockname
);
4177 #endif /* CLASH_DETECTION */
4179 /* Do this before reporting IO error
4180 to avoid a "file has changed on disk" warning on
4181 next attempt to save. */
4183 current_buffer
->modtime
= st
.st_mtime
;
4186 error ("IO error writing %s: %s", fn
, strerror (save_errno
));
4190 SAVE_MODIFF
= MODIFF
;
4191 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4192 current_buffer
->filename
= visit_file
;
4193 update_mode_lines
++;
4199 message ("Wrote %s", XSTRING (visit_file
)->data
);
4204 Lisp_Object
merge ();
4206 DEFUN ("car-less-than-car", Fcar_less_than_car
, Scar_less_than_car
, 2, 2, 0,
4207 "Return t if (car A) is numerically less than (car B).")
4211 return Flss (Fcar (a
), Fcar (b
));
4214 /* Build the complete list of annotations appropriate for writing out
4215 the text between START and END, by calling all the functions in
4216 write-region-annotate-functions and merging the lists they return.
4217 If one of these functions switches to a different buffer, we assume
4218 that buffer contains altered text. Therefore, the caller must
4219 make sure to restore the current buffer in all cases,
4220 as save-excursion would do. */
4223 build_annotations (start
, end
, pre_write_conversion
)
4224 Lisp_Object start
, end
, pre_write_conversion
;
4226 Lisp_Object annotations
;
4228 struct gcpro gcpro1
, gcpro2
;
4229 Lisp_Object original_buffer
;
4231 XSETBUFFER (original_buffer
, current_buffer
);
4234 p
= Vwrite_region_annotate_functions
;
4235 GCPRO2 (annotations
, p
);
4238 struct buffer
*given_buffer
= current_buffer
;
4239 Vwrite_region_annotations_so_far
= annotations
;
4240 res
= call2 (Fcar (p
), start
, end
);
4241 /* If the function makes a different buffer current,
4242 assume that means this buffer contains altered text to be output.
4243 Reset START and END from the buffer bounds
4244 and discard all previous annotations because they should have
4245 been dealt with by this function. */
4246 if (current_buffer
!= given_buffer
)
4248 XSETFASTINT (start
, BEGV
);
4249 XSETFASTINT (end
, ZV
);
4252 Flength (res
); /* Check basic validity of return value */
4253 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
4257 /* Now do the same for annotation functions implied by the file-format */
4258 if (auto_saving
&& (!EQ (Vauto_save_file_format
, Qt
)))
4259 p
= Vauto_save_file_format
;
4261 p
= current_buffer
->file_format
;
4264 struct buffer
*given_buffer
= current_buffer
;
4265 Vwrite_region_annotations_so_far
= annotations
;
4266 res
= call4 (Qformat_annotate_function
, Fcar (p
), start
, end
,
4268 if (current_buffer
!= given_buffer
)
4270 XSETFASTINT (start
, BEGV
);
4271 XSETFASTINT (end
, ZV
);
4275 annotations
= merge (annotations
, res
, Qcar_less_than_car
);
4279 /* At last, do the same for the function PRE_WRITE_CONVERSION
4280 implied by the current coding-system. */
4281 if (!NILP (pre_write_conversion
))
4283 struct buffer
*given_buffer
= current_buffer
;
4284 Vwrite_region_annotations_so_far
= annotations
;
4285 res
= call2 (pre_write_conversion
, start
, end
);
4287 annotations
= (current_buffer
!= given_buffer
4289 : merge (annotations
, res
, Qcar_less_than_car
));
4296 /* Write to descriptor DESC the LEN characters starting at ADDR,
4297 assuming they start at position POS in the buffer.
4298 Intersperse with them the annotations from *ANNOT
4299 (those which fall within the range of positions POS to POS + LEN),
4300 each at its appropriate position.
4302 Modify *ANNOT by discarding elements as we output them.
4303 The return value is negative in case of system call failure. */
4306 a_write (desc
, addr
, len
, pos
, annot
, coding
)
4308 register char *addr
;
4312 struct coding_system
*coding
;
4316 int lastpos
= pos
+ len
;
4318 while (NILP (*annot
) || CONSP (*annot
))
4320 tem
= Fcar_safe (Fcar (*annot
));
4321 if (INTEGERP (tem
) && XINT (tem
) >= pos
&& XFASTINT (tem
) <= lastpos
)
4322 nextpos
= XFASTINT (tem
);
4324 return e_write (desc
, addr
, lastpos
- pos
, coding
);
4327 if (0 > e_write (desc
, addr
, nextpos
- pos
, coding
))
4329 addr
+= nextpos
- pos
;
4332 tem
= Fcdr (Fcar (*annot
));
4335 if (0 > e_write (desc
, XSTRING (tem
)->data
, XSTRING (tem
)->size
,
4339 *annot
= Fcdr (*annot
);
4343 #ifndef WRITE_BUF_SIZE
4344 #define WRITE_BUF_SIZE (16 * 1024)
4348 e_write (desc
, addr
, len
, coding
)
4350 register char *addr
;
4352 struct coding_system
*coding
;
4354 char buf
[WRITE_BUF_SIZE
];
4355 int produced
, consumed
;
4357 /* We used to have a code for handling selective display here. But,
4358 now it is handled within encode_coding. */
4361 produced
= encode_coding (coding
, addr
, buf
, len
, WRITE_BUF_SIZE
,
4363 len
-= consumed
, addr
+= consumed
;
4366 produced
-= write (desc
, buf
, produced
);
4367 if (produced
) return -1;
4375 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime
,
4376 Sverify_visited_file_modtime
, 1, 1, 0,
4377 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4378 This means that the file has not been changed since it was visited or saved.")
4384 Lisp_Object handler
;
4386 CHECK_BUFFER (buf
, 0);
4389 if (!STRINGP (b
->filename
)) return Qt
;
4390 if (b
->modtime
== 0) return Qt
;
4392 /* If the file name has special constructs in it,
4393 call the corresponding file handler. */
4394 handler
= Ffind_file_name_handler (b
->filename
,
4395 Qverify_visited_file_modtime
);
4396 if (!NILP (handler
))
4397 return call2 (handler
, Qverify_visited_file_modtime
, buf
);
4399 if (stat (XSTRING (b
->filename
)->data
, &st
) < 0)
4401 /* If the file doesn't exist now and didn't exist before,
4402 we say that it isn't modified, provided the error is a tame one. */
4403 if (errno
== ENOENT
|| errno
== EACCES
|| errno
== ENOTDIR
)
4408 if (st
.st_mtime
== b
->modtime
4409 /* If both are positive, accept them if they are off by one second. */
4410 || (st
.st_mtime
> 0 && b
->modtime
> 0
4411 && (st
.st_mtime
== b
->modtime
+ 1
4412 || st
.st_mtime
== b
->modtime
- 1)))
4417 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime
,
4418 Sclear_visited_file_modtime
, 0, 0, 0,
4419 "Clear out records of last mod time of visited file.\n\
4420 Next attempt to save will certainly not complain of a discrepancy.")
4423 current_buffer
->modtime
= 0;
4427 DEFUN ("visited-file-modtime", Fvisited_file_modtime
,
4428 Svisited_file_modtime
, 0, 0, 0,
4429 "Return the current buffer's recorded visited file modification time.\n\
4430 The value is a list of the form (HIGH . LOW), like the time values\n\
4431 that `file-attributes' returns.")
4434 return long_to_cons ((unsigned long) current_buffer
->modtime
);
4437 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime
,
4438 Sset_visited_file_modtime
, 0, 1, 0,
4439 "Update buffer's recorded modification time from the visited file's time.\n\
4440 Useful if the buffer was not read from the file normally\n\
4441 or if the file itself has been changed for some known benign reason.\n\
4442 An argument specifies the modification time value to use\n\
4443 \(instead of that of the visited file), in the form of a list\n\
4444 \(HIGH . LOW) or (HIGH LOW).")
4446 Lisp_Object time_list
;
4448 if (!NILP (time_list
))
4449 current_buffer
->modtime
= cons_to_long (time_list
);
4452 register Lisp_Object filename
;
4454 Lisp_Object handler
;
4456 filename
= Fexpand_file_name (current_buffer
->filename
, Qnil
);
4458 /* If the file name has special constructs in it,
4459 call the corresponding file handler. */
4460 handler
= Ffind_file_name_handler (filename
, Qset_visited_file_modtime
);
4461 if (!NILP (handler
))
4462 /* The handler can find the file name the same way we did. */
4463 return call2 (handler
, Qset_visited_file_modtime
, Qnil
);
4464 else if (stat (XSTRING (filename
)->data
, &st
) >= 0)
4465 current_buffer
->modtime
= st
.st_mtime
;
4475 message ("Autosaving...error for %s", XSTRING (current_buffer
->name
)->data
);
4476 Fsleep_for (make_number (1), Qnil
);
4477 message ("Autosaving...error!for %s", XSTRING (current_buffer
->name
)->data
);
4478 Fsleep_for (make_number (1), Qnil
);
4479 message ("Autosaving...error for %s", XSTRING (current_buffer
->name
)->data
);
4480 Fsleep_for (make_number (1), Qnil
);
4490 /* Get visited file's mode to become the auto save file's mode. */
4491 if (stat (XSTRING (current_buffer
->filename
)->data
, &st
) >= 0)
4492 /* But make sure we can overwrite it later! */
4493 auto_save_mode_bits
= st
.st_mode
| 0600;
4495 auto_save_mode_bits
= 0666;
4498 Fwrite_region (Qnil
, Qnil
,
4499 current_buffer
->auto_save_file_name
,
4500 Qnil
, Qlambda
, Qnil
);
4504 do_auto_save_unwind (stream
) /* used as unwind-protect function */
4509 fclose ((FILE *) (XFASTINT (XCONS (stream
)->car
) << 16
4510 | XFASTINT (XCONS (stream
)->cdr
)));
4515 do_auto_save_unwind_1 (value
) /* used as unwind-protect function */
4518 minibuffer_auto_raise
= XINT (value
);
4522 DEFUN ("do-auto-save", Fdo_auto_save
, Sdo_auto_save
, 0, 2, "",
4523 "Auto-save all buffers that need it.\n\
4524 This is all buffers that have auto-saving enabled\n\
4525 and are changed since last auto-saved.\n\
4526 Auto-saving writes the buffer into a file\n\
4527 so that your editing is not lost if the system crashes.\n\
4528 This file is not the file you visited; that changes only when you save.\n\
4529 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4530 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4531 A non-nil CURRENT-ONLY argument means save only current buffer.")
4532 (no_message
, current_only
)
4533 Lisp_Object no_message
, current_only
;
4535 struct buffer
*old
= current_buffer
, *b
;
4536 Lisp_Object tail
, buf
;
4538 char *omessage
= echo_area_glyphs
;
4539 int omessage_length
= echo_area_glyphs_length
;
4540 int do_handled_files
;
4543 Lisp_Object lispstream
;
4544 int count
= specpdl_ptr
- specpdl
;
4546 int orig_minibuffer_auto_raise
= minibuffer_auto_raise
;
4548 /* Ordinarily don't quit within this function,
4549 but don't make it impossible to quit (in case we get hung in I/O). */
4553 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4554 point to non-strings reached from Vbuffer_alist. */
4559 if (!NILP (Vrun_hooks
))
4560 call1 (Vrun_hooks
, intern ("auto-save-hook"));
4562 if (STRINGP (Vauto_save_list_file_name
))
4564 Lisp_Object listfile
;
4565 listfile
= Fexpand_file_name (Vauto_save_list_file_name
, Qnil
);
4566 stream
= fopen (XSTRING (listfile
)->data
, "w");
4569 /* Arrange to close that file whether or not we get an error.
4570 Also reset auto_saving to 0. */
4571 lispstream
= Fcons (Qnil
, Qnil
);
4572 XSETFASTINT (XCONS (lispstream
)->car
, (EMACS_UINT
)stream
>> 16);
4573 XSETFASTINT (XCONS (lispstream
)->cdr
, (EMACS_UINT
)stream
& 0xffff);
4584 record_unwind_protect (do_auto_save_unwind
, lispstream
);
4585 record_unwind_protect (do_auto_save_unwind_1
,
4586 make_number (minibuffer_auto_raise
));
4587 minibuffer_auto_raise
= 0;
4590 /* First, save all files which don't have handlers. If Emacs is
4591 crashing, the handlers may tweak what is causing Emacs to crash
4592 in the first place, and it would be a shame if Emacs failed to
4593 autosave perfectly ordinary files because it couldn't handle some
4595 for (do_handled_files
= 0; do_handled_files
< 2; do_handled_files
++)
4596 for (tail
= Vbuffer_alist
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4598 buf
= XCONS (XCONS (tail
)->car
)->cdr
;
4601 /* Record all the buffers that have auto save mode
4602 in the special file that lists them. For each of these buffers,
4603 Record visited name (if any) and auto save name. */
4604 if (STRINGP (b
->auto_save_file_name
)
4605 && stream
!= NULL
&& do_handled_files
== 0)
4607 if (!NILP (b
->filename
))
4609 fwrite (XSTRING (b
->filename
)->data
, 1,
4610 XSTRING (b
->filename
)->size
, stream
);
4612 putc ('\n', stream
);
4613 fwrite (XSTRING (b
->auto_save_file_name
)->data
, 1,
4614 XSTRING (b
->auto_save_file_name
)->size
, stream
);
4615 putc ('\n', stream
);
4618 if (!NILP (current_only
)
4619 && b
!= current_buffer
)
4622 /* Don't auto-save indirect buffers.
4623 The base buffer takes care of it. */
4627 /* Check for auto save enabled
4628 and file changed since last auto save
4629 and file changed since last real save. */
4630 if (STRINGP (b
->auto_save_file_name
)
4631 && BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)
4632 && b
->auto_save_modified
< BUF_MODIFF (b
)
4633 /* -1 means we've turned off autosaving for a while--see below. */
4634 && XINT (b
->save_length
) >= 0
4635 && (do_handled_files
4636 || NILP (Ffind_file_name_handler (b
->auto_save_file_name
,
4639 EMACS_TIME before_time
, after_time
;
4641 EMACS_GET_TIME (before_time
);
4643 /* If we had a failure, don't try again for 20 minutes. */
4644 if (b
->auto_save_failure_time
>= 0
4645 && EMACS_SECS (before_time
) - b
->auto_save_failure_time
< 1200)
4648 if ((XFASTINT (b
->save_length
) * 10
4649 > (BUF_Z (b
) - BUF_BEG (b
)) * 13)
4650 /* A short file is likely to change a large fraction;
4651 spare the user annoying messages. */
4652 && XFASTINT (b
->save_length
) > 5000
4653 /* These messages are frequent and annoying for `*mail*'. */
4654 && !EQ (b
->filename
, Qnil
)
4655 && NILP (no_message
))
4657 /* It has shrunk too much; turn off auto-saving here. */
4658 minibuffer_auto_raise
= orig_minibuffer_auto_raise
;
4659 message ("Buffer %s has shrunk a lot; auto save turned off there",
4660 XSTRING (b
->name
)->data
);
4661 minibuffer_auto_raise
= 0;
4662 /* Turn off auto-saving until there's a real save,
4663 and prevent any more warnings. */
4664 XSETINT (b
->save_length
, -1);
4665 Fsleep_for (make_number (1), Qnil
);
4668 set_buffer_internal (b
);
4669 if (!auto_saved
&& NILP (no_message
))
4670 message1 ("Auto-saving...");
4671 internal_condition_case (auto_save_1
, Qt
, auto_save_error
);
4673 b
->auto_save_modified
= BUF_MODIFF (b
);
4674 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4675 set_buffer_internal (old
);
4677 EMACS_GET_TIME (after_time
);
4679 /* If auto-save took more than 60 seconds,
4680 assume it was an NFS failure that got a timeout. */
4681 if (EMACS_SECS (after_time
) - EMACS_SECS (before_time
) > 60)
4682 b
->auto_save_failure_time
= EMACS_SECS (after_time
);
4686 /* Prevent another auto save till enough input events come in. */
4687 record_auto_save ();
4689 if (auto_saved
&& NILP (no_message
))
4693 sit_for (1, 0, 0, 0, 0);
4694 message2 (omessage
, omessage_length
);
4697 message1 ("Auto-saving...done");
4702 unbind_to (count
, Qnil
);
4706 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved
,
4707 Sset_buffer_auto_saved
, 0, 0, 0,
4708 "Mark current buffer as auto-saved with its current text.\n\
4709 No auto-save file will be written until the buffer changes again.")
4712 current_buffer
->auto_save_modified
= MODIFF
;
4713 XSETFASTINT (current_buffer
->save_length
, Z
- BEG
);
4714 current_buffer
->auto_save_failure_time
= -1;
4718 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure
,
4719 Sclear_buffer_auto_save_failure
, 0, 0, 0,
4720 "Clear any record of a recent auto-save failure in the current buffer.")
4723 current_buffer
->auto_save_failure_time
= -1;
4727 DEFUN ("recent-auto-save-p", Frecent_auto_save_p
, Srecent_auto_save_p
,
4729 "Return t if buffer has been auto-saved since last read in or saved.")
4732 return (SAVE_MODIFF
< current_buffer
->auto_save_modified
) ? Qt
: Qnil
;
4735 /* Reading and completing file names */
4736 extern Lisp_Object
Ffile_name_completion (), Ffile_name_all_completions ();
4738 /* In the string VAL, change each $ to $$ and return the result. */
4741 double_dollars (val
)
4744 register unsigned char *old
, *new;
4748 osize
= XSTRING (val
)->size
;
4749 /* Quote "$" as "$$" to get it past substitute-in-file-name */
4750 for (n
= osize
, count
= 0, old
= XSTRING (val
)->data
; n
> 0; n
--)
4751 if (*old
++ == '$') count
++;
4754 old
= XSTRING (val
)->data
;
4755 val
= Fmake_string (make_number (osize
+ count
), make_number (0));
4756 new = XSTRING (val
)->data
;
4757 for (n
= osize
; n
> 0; n
--)
4770 DEFUN ("read-file-name-internal", Fread_file_name_internal
, Sread_file_name_internal
,
4772 "Internal subroutine for read-file-name. Do not call this.")
4773 (string
, dir
, action
)
4774 Lisp_Object string
, dir
, action
;
4775 /* action is nil for complete, t for return list of completions,
4776 lambda for verify final value */
4778 Lisp_Object name
, specdir
, realdir
, val
, orig_string
;
4780 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
4782 CHECK_STRING (string
, 0);
4789 /* No need to protect ACTION--we only compare it with t and nil. */
4790 GCPRO5 (string
, realdir
, name
, specdir
, orig_string
);
4792 if (XSTRING (string
)->size
== 0)
4794 if (EQ (action
, Qlambda
))
4802 orig_string
= string
;
4803 string
= Fsubstitute_in_file_name (string
);
4804 changed
= NILP (Fstring_equal (string
, orig_string
));
4805 name
= Ffile_name_nondirectory (string
);
4806 val
= Ffile_name_directory (string
);
4808 realdir
= Fexpand_file_name (val
, realdir
);
4813 specdir
= Ffile_name_directory (string
);
4814 val
= Ffile_name_completion (name
, realdir
);
4819 return double_dollars (string
);
4823 if (!NILP (specdir
))
4824 val
= concat2 (specdir
, val
);
4826 return double_dollars (val
);
4829 #endif /* not VMS */
4833 if (EQ (action
, Qt
))
4834 return Ffile_name_all_completions (name
, realdir
);
4835 /* Only other case actually used is ACTION = lambda */
4837 /* Supposedly this helps commands such as `cd' that read directory names,
4838 but can someone explain how it helps them? -- RMS */
4839 if (XSTRING (name
)->size
== 0)
4842 return Ffile_exists_p (string
);
4845 DEFUN ("read-file-name", Fread_file_name
, Sread_file_name
, 1, 5, 0,
4846 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
4847 Value is not expanded---you must call `expand-file-name' yourself.\n\
4848 Default name to DEFAULT-FILENAME if user enters a null string.\n\
4849 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
4850 except that if INITIAL is specified, that combined with DIR is used.)\n\
4851 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
4852 Non-nil and non-t means also require confirmation after completion.\n\
4853 Fifth arg INITIAL specifies text to start with.\n\
4854 DIR defaults to current buffer's directory default.")
4855 (prompt
, dir
, default_filename
, mustmatch
, initial
)
4856 Lisp_Object prompt
, dir
, default_filename
, mustmatch
, initial
;
4858 Lisp_Object val
, insdef
, insdef1
, tem
;
4859 struct gcpro gcpro1
, gcpro2
;
4860 register char *homedir
;
4864 dir
= current_buffer
->directory
;
4865 if (NILP (default_filename
))
4867 if (! NILP (initial
))
4868 default_filename
= Fexpand_file_name (initial
, dir
);
4870 default_filename
= current_buffer
->filename
;
4873 /* If dir starts with user's homedir, change that to ~. */
4874 homedir
= (char *) egetenv ("HOME");
4876 homedir
= strcpy (alloca (strlen (homedir
) + 1), homedir
);
4877 CORRECT_DIR_SEPS (homedir
);
4881 && !strncmp (homedir
, XSTRING (dir
)->data
, strlen (homedir
))
4882 && IS_DIRECTORY_SEP (XSTRING (dir
)->data
[strlen (homedir
)]))
4884 dir
= make_string (XSTRING (dir
)->data
+ strlen (homedir
) - 1,
4885 XSTRING (dir
)->size
- strlen (homedir
) + 1);
4886 XSTRING (dir
)->data
[0] = '~';
4889 if (insert_default_directory
&& STRINGP (dir
))
4892 if (!NILP (initial
))
4894 Lisp_Object args
[2], pos
;
4898 insdef
= Fconcat (2, args
);
4899 pos
= make_number (XSTRING (double_dollars (dir
))->size
);
4900 insdef1
= Fcons (double_dollars (insdef
), pos
);
4903 insdef1
= double_dollars (insdef
);
4905 else if (STRINGP (initial
))
4908 insdef1
= Fcons (double_dollars (insdef
), make_number (0));
4911 insdef
= Qnil
, insdef1
= Qnil
;
4914 count
= specpdl_ptr
- specpdl
;
4915 specbind (intern ("completion-ignore-case"), Qt
);
4918 GCPRO2 (insdef
, default_filename
);
4919 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4920 dir
, mustmatch
, insdef1
,
4921 Qfile_name_history
, default_filename
);
4922 /* If Fcompleting_read returned the default string itself
4923 (rather than a new string with the same contents),
4924 it has to mean that the user typed RET with the minibuffer empty.
4925 In that case, we really want to return ""
4926 so that commands such as set-visited-file-name can distinguish. */
4927 if (EQ (val
, default_filename
))
4928 val
= build_string ("");
4931 unbind_to (count
, Qnil
);
4936 error ("No file name specified");
4937 tem
= Fstring_equal (val
, insdef
);
4938 if (!NILP (tem
) && !NILP (default_filename
))
4939 return default_filename
;
4940 if (XSTRING (val
)->size
== 0 && NILP (insdef
))
4942 if (!NILP (default_filename
))
4943 return default_filename
;
4945 error ("No default file name");
4947 return Fsubstitute_in_file_name (val
);
4950 #if 0 /* Old version */
4951 DEFUN ("read-file-name", Fread_file_name
, Sread_file_name
, 1, 5, 0,
4952 /* Don't confuse make-docfile by having two doc strings for this function.
4953 make-docfile does not pay attention to #if, for good reason! */
4955 (prompt
, dir
, defalt
, mustmatch
, initial
)
4956 Lisp_Object prompt
, dir
, defalt
, mustmatch
, initial
;
4958 Lisp_Object val
, insdef
, tem
;
4959 struct gcpro gcpro1
, gcpro2
;
4960 register char *homedir
;
4964 dir
= current_buffer
->directory
;
4966 defalt
= current_buffer
->filename
;
4968 /* If dir starts with user's homedir, change that to ~. */
4969 homedir
= (char *) egetenv ("HOME");
4972 && !strncmp (homedir
, XSTRING (dir
)->data
, strlen (homedir
))
4973 && XSTRING (dir
)->data
[strlen (homedir
)] == '/')
4975 dir
= make_string (XSTRING (dir
)->data
+ strlen (homedir
) - 1,
4976 XSTRING (dir
)->size
- strlen (homedir
) + 1);
4977 XSTRING (dir
)->data
[0] = '~';
4980 if (!NILP (initial
))
4982 else if (insert_default_directory
)
4985 insdef
= build_string ("");
4988 count
= specpdl_ptr
- specpdl
;
4989 specbind (intern ("completion-ignore-case"), Qt
);
4992 GCPRO2 (insdef
, defalt
);
4993 val
= Fcompleting_read (prompt
, intern ("read-file-name-internal"),
4995 insert_default_directory
? insdef
: Qnil
,
4996 Qfile_name_history
, Qnil
);
4999 unbind_to (count
, Qnil
);
5004 error ("No file name specified");
5005 tem
= Fstring_equal (val
, insdef
);
5006 if (!NILP (tem
) && !NILP (defalt
))
5008 return Fsubstitute_in_file_name (val
);
5010 #endif /* Old version */
5014 Qexpand_file_name
= intern ("expand-file-name");
5015 Qsubstitute_in_file_name
= intern ("substitute-in-file-name");
5016 Qdirectory_file_name
= intern ("directory-file-name");
5017 Qfile_name_directory
= intern ("file-name-directory");
5018 Qfile_name_nondirectory
= intern ("file-name-nondirectory");
5019 Qunhandled_file_name_directory
= intern ("unhandled-file-name-directory");
5020 Qfile_name_as_directory
= intern ("file-name-as-directory");
5021 Qcopy_file
= intern ("copy-file");
5022 Qmake_directory_internal
= intern ("make-directory-internal");
5023 Qdelete_directory
= intern ("delete-directory");
5024 Qdelete_file
= intern ("delete-file");
5025 Qrename_file
= intern ("rename-file");
5026 Qadd_name_to_file
= intern ("add-name-to-file");
5027 Qmake_symbolic_link
= intern ("make-symbolic-link");
5028 Qfile_exists_p
= intern ("file-exists-p");
5029 Qfile_executable_p
= intern ("file-executable-p");
5030 Qfile_readable_p
= intern ("file-readable-p");
5031 Qfile_writable_p
= intern ("file-writable-p");
5032 Qfile_symlink_p
= intern ("file-symlink-p");
5033 Qaccess_file
= intern ("access-file");
5034 Qfile_directory_p
= intern ("file-directory-p");
5035 Qfile_regular_p
= intern ("file-regular-p");
5036 Qfile_accessible_directory_p
= intern ("file-accessible-directory-p");
5037 Qfile_modes
= intern ("file-modes");
5038 Qset_file_modes
= intern ("set-file-modes");
5039 Qfile_newer_than_file_p
= intern ("file-newer-than-file-p");
5040 Qinsert_file_contents
= intern ("insert-file-contents");
5041 Qwrite_region
= intern ("write-region");
5042 Qverify_visited_file_modtime
= intern ("verify-visited-file-modtime");
5043 Qset_visited_file_modtime
= intern ("set-visited-file-modtime");
5045 staticpro (&Qexpand_file_name
);
5046 staticpro (&Qsubstitute_in_file_name
);
5047 staticpro (&Qdirectory_file_name
);
5048 staticpro (&Qfile_name_directory
);
5049 staticpro (&Qfile_name_nondirectory
);
5050 staticpro (&Qunhandled_file_name_directory
);
5051 staticpro (&Qfile_name_as_directory
);
5052 staticpro (&Qcopy_file
);
5053 staticpro (&Qmake_directory_internal
);
5054 staticpro (&Qdelete_directory
);
5055 staticpro (&Qdelete_file
);
5056 staticpro (&Qrename_file
);
5057 staticpro (&Qadd_name_to_file
);
5058 staticpro (&Qmake_symbolic_link
);
5059 staticpro (&Qfile_exists_p
);
5060 staticpro (&Qfile_executable_p
);
5061 staticpro (&Qfile_readable_p
);
5062 staticpro (&Qfile_writable_p
);
5063 staticpro (&Qaccess_file
);
5064 staticpro (&Qfile_symlink_p
);
5065 staticpro (&Qfile_directory_p
);
5066 staticpro (&Qfile_regular_p
);
5067 staticpro (&Qfile_accessible_directory_p
);
5068 staticpro (&Qfile_modes
);
5069 staticpro (&Qset_file_modes
);
5070 staticpro (&Qfile_newer_than_file_p
);
5071 staticpro (&Qinsert_file_contents
);
5072 staticpro (&Qwrite_region
);
5073 staticpro (&Qverify_visited_file_modtime
);
5074 staticpro (&Qset_visited_file_modtime
);
5076 Qfile_name_history
= intern ("file-name-history");
5077 Fset (Qfile_name_history
, Qnil
);
5078 staticpro (&Qfile_name_history
);
5080 Qfile_error
= intern ("file-error");
5081 staticpro (&Qfile_error
);
5082 Qfile_already_exists
= intern ("file-already-exists");
5083 staticpro (&Qfile_already_exists
);
5084 Qfile_date_error
= intern ("file-date-error");
5085 staticpro (&Qfile_date_error
);
5088 Qfind_buffer_file_type
= intern ("find-buffer-file-type");
5089 staticpro (&Qfind_buffer_file_type
);
5092 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format
,
5093 "*Format in which to write auto-save files.\n\
5094 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5095 If it is t, which is the default, auto-save files are written in the\n\
5096 same format as a regular save would use.");
5097 Vauto_save_file_format
= Qt
;
5099 Qformat_decode
= intern ("format-decode");
5100 staticpro (&Qformat_decode
);
5101 Qformat_annotate_function
= intern ("format-annotate-function");
5102 staticpro (&Qformat_annotate_function
);
5104 Qcar_less_than_car
= intern ("car-less-than-car");
5105 staticpro (&Qcar_less_than_car
);
5107 Fput (Qfile_error
, Qerror_conditions
,
5108 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
)));
5109 Fput (Qfile_error
, Qerror_message
,
5110 build_string ("File error"));
5112 Fput (Qfile_already_exists
, Qerror_conditions
,
5113 Fcons (Qfile_already_exists
,
5114 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
))));
5115 Fput (Qfile_already_exists
, Qerror_message
,
5116 build_string ("File already exists"));
5118 Fput (Qfile_date_error
, Qerror_conditions
,
5119 Fcons (Qfile_date_error
,
5120 Fcons (Qfile_error
, Fcons (Qerror
, Qnil
))));
5121 Fput (Qfile_date_error
, Qerror_message
,
5122 build_string ("Cannot set file date"));
5124 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory
,
5125 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5126 insert_default_directory
= 1;
5128 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm
,
5129 "*Non-nil means write new files with record format `stmlf'.\n\
5130 nil means use format `var'. This variable is meaningful only on VMS.");
5131 vms_stmlf_recfm
= 0;
5133 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char
,
5134 "Directory separator character for built-in functions that return file names.\n\
5135 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5136 This variable affects the built-in functions only on Windows,\n\
5137 on other platforms, it is initialized so that Lisp code can find out\n\
5138 what the normal separator is.");
5139 XSETFASTINT (Vdirectory_sep_char
, '/');
5141 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist
,
5142 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5143 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5146 The first argument given to HANDLER is the name of the I/O primitive\n\
5147 to be handled; the remaining arguments are the arguments that were\n\
5148 passed to that primitive. For example, if you do\n\
5149 (file-exists-p FILENAME)\n\
5150 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5151 (funcall HANDLER 'file-exists-p FILENAME)\n\
5152 The function `find-file-name-handler' checks this list for a handler\n\
5153 for its argument.");
5154 Vfile_name_handler_alist
= Qnil
;
5156 DEFVAR_LISP ("auto-file-coding-system-function",
5157 &Vauto_file_coding_system_function
,
5158 "If non-nil, a function to call to decide a coding system of file.
5159 One argument is passed to this function: the string of the first
5160 few lines of a file to be read.
5161 This function should return a coding system to decode the file contents
5162 specified in the heading lines with the format:
5163 -*- ... coding: CODING-SYSTEM; ... -*-");
5164 Vauto_file_coding_system_function
= Qnil
;
5166 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions
,
5167 "A list of functions to be called at the end of `insert-file-contents'.\n\
5168 Each is passed one argument, the number of bytes inserted. It should return\n\
5169 the new byte count, and leave point the same. If `insert-file-contents' is\n\
5170 intercepted by a handler from `file-name-handler-alist', that handler is\n\
5171 responsible for calling the after-insert-file-functions if appropriate.");
5172 Vafter_insert_file_functions
= Qnil
;
5174 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions
,
5175 "A list of functions to be called at the start of `write-region'.\n\
5176 Each is passed two arguments, START and END as for `write-region'.\n\
5177 These are usually two numbers but not always; see the documentation\n\
5178 for `write-region'. The function should return a list of pairs\n\
5179 of the form (POSITION . STRING), consisting of strings to be effectively\n\
5180 inserted at the specified positions of the file being written (1 means to\n\
5181 insert before the first byte written). The POSITIONs must be sorted into\n\
5182 increasing order. If there are several functions in the list, the several\n\
5183 lists are merged destructively.");
5184 Vwrite_region_annotate_functions
= Qnil
;
5186 DEFVAR_LISP ("write-region-annotations-so-far",
5187 &Vwrite_region_annotations_so_far
,
5188 "When an annotation function is called, this holds the previous annotations.\n\
5189 These are the annotations made by other annotation functions\n\
5190 that were already called. See also `write-region-annotate-functions'.");
5191 Vwrite_region_annotations_so_far
= Qnil
;
5193 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers
,
5194 "A list of file name handlers that temporarily should not be used.\n\
5195 This applies only to the operation `inhibit-file-name-operation'.");
5196 Vinhibit_file_name_handlers
= Qnil
;
5198 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation
,
5199 "The operation for which `inhibit-file-name-handlers' is applicable.");
5200 Vinhibit_file_name_operation
= Qnil
;
5202 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name
,
5203 "File name in which we write a list of all auto save file names.\n\
5204 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5205 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5207 Vauto_save_list_file_name
= Qnil
;
5209 defsubr (&Sfind_file_name_handler
);
5210 defsubr (&Sfile_name_directory
);
5211 defsubr (&Sfile_name_nondirectory
);
5212 defsubr (&Sunhandled_file_name_directory
);
5213 defsubr (&Sfile_name_as_directory
);
5214 defsubr (&Sdirectory_file_name
);
5215 defsubr (&Smake_temp_name
);
5216 defsubr (&Sexpand_file_name
);
5217 defsubr (&Ssubstitute_in_file_name
);
5218 defsubr (&Scopy_file
);
5219 defsubr (&Smake_directory_internal
);
5220 defsubr (&Sdelete_directory
);
5221 defsubr (&Sdelete_file
);
5222 defsubr (&Srename_file
);
5223 defsubr (&Sadd_name_to_file
);
5225 defsubr (&Smake_symbolic_link
);
5226 #endif /* S_IFLNK */
5228 defsubr (&Sdefine_logical_name
);
5231 defsubr (&Ssysnetunam
);
5232 #endif /* HPUX_NET */
5233 defsubr (&Sfile_name_absolute_p
);
5234 defsubr (&Sfile_exists_p
);
5235 defsubr (&Sfile_executable_p
);
5236 defsubr (&Sfile_readable_p
);
5237 defsubr (&Sfile_writable_p
);
5238 defsubr (&Saccess_file
);
5239 defsubr (&Sfile_symlink_p
);
5240 defsubr (&Sfile_directory_p
);
5241 defsubr (&Sfile_accessible_directory_p
);
5242 defsubr (&Sfile_regular_p
);
5243 defsubr (&Sfile_modes
);
5244 defsubr (&Sset_file_modes
);
5245 defsubr (&Sset_default_file_modes
);
5246 defsubr (&Sdefault_file_modes
);
5247 defsubr (&Sfile_newer_than_file_p
);
5248 defsubr (&Sinsert_file_contents
);
5249 defsubr (&Swrite_region
);
5250 defsubr (&Scar_less_than_car
);
5251 defsubr (&Sverify_visited_file_modtime
);
5252 defsubr (&Sclear_visited_file_modtime
);
5253 defsubr (&Svisited_file_modtime
);
5254 defsubr (&Sset_visited_file_modtime
);
5255 defsubr (&Sdo_auto_save
);
5256 defsubr (&Sset_buffer_auto_saved
);
5257 defsubr (&Sclear_buffer_auto_save_failure
);
5258 defsubr (&Srecent_auto_save_p
);
5260 defsubr (&Sread_file_name_internal
);
5261 defsubr (&Sread_file_name
);
5264 defsubr (&Sunix_sync
);