(Fmake_temp_name): Doc fix.
[emacs.git] / src / fileio.c
blobd328a2d3636f19164ac2e90703dcceee760934af
1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96,97,98,99,2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #define _GNU_SOURCE /* for euidaccess */
24 #include <config.h>
26 #if defined (USG5) || defined (BSD_SYSTEM) || defined (GNU_LINUX)
27 #include <fcntl.h>
28 #endif
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
38 #if !defined (S_ISLNK) && defined (S_IFLNK)
39 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
40 #endif
42 #if !defined (S_ISFIFO) && defined (S_IFIFO)
43 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
44 #endif
46 #if !defined (S_ISREG) && defined (S_IFREG)
47 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
48 #endif
50 #ifdef VMS
51 #include "vms-pwd.h"
52 #else
53 #include <pwd.h>
54 #endif
56 #include <ctype.h>
58 #ifdef VMS
59 #include "vmsdir.h"
60 #include <perror.h>
61 #include <stddef.h>
62 #include <string.h>
63 #endif
65 #include <errno.h>
67 #ifndef vax11c
68 #ifndef USE_CRT_DLL
69 extern int errno;
70 #endif
71 #endif
73 #ifdef APOLLO
74 #include <sys/time.h>
75 #endif
77 #ifndef USG
78 #ifndef VMS
79 #ifndef BSD4_1
80 #ifndef WINDOWSNT
81 #define HAVE_FSYNC
82 #endif
83 #endif
84 #endif
85 #endif
87 #include "lisp.h"
88 #include "intervals.h"
89 #include "buffer.h"
90 #include "charset.h"
91 #include "coding.h"
92 #include "window.h"
94 #ifdef WINDOWSNT
95 #define NOMINMAX 1
96 #include <windows.h>
97 #include <stdlib.h>
98 #include <fcntl.h>
99 #endif /* not WINDOWSNT */
101 #ifdef MSDOS
102 #include "msdos.h"
103 #include <sys/param.h>
104 #if __DJGPP__ >= 2
105 #include <fcntl.h>
106 #include <string.h>
107 #endif
108 #endif
110 #ifdef DOS_NT
111 #define CORRECT_DIR_SEPS(s) \
112 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
113 else unixtodos_filename (s); \
114 } while (0)
115 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
116 redirector allows the six letters between 'Z' and 'a' as well. */
117 #ifdef MSDOS
118 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
119 #endif
120 #ifdef WINDOWSNT
121 #define IS_DRIVE(x) isalpha (x)
122 #endif
123 /* Need to lower-case the drive letter, or else expanded
124 filenames will sometimes compare inequal, because
125 `expand-file-name' doesn't always down-case the drive letter. */
126 #define DRIVE_LETTER(x) (tolower (x))
127 #endif
129 #ifdef VMS
130 #include <file.h>
131 #include <rmsdef.h>
132 #include <fab.h>
133 #include <nam.h>
134 #endif
136 #include "systime.h"
138 #ifdef HPUX
139 #include <netio.h>
140 #ifndef HPUX8
141 #ifndef HPUX9
142 #include <errnet.h>
143 #endif
144 #endif
145 #endif
147 #include "commands.h"
148 extern int use_dialog_box;
150 #ifndef O_WRONLY
151 #define O_WRONLY 1
152 #endif
154 #ifndef O_RDONLY
155 #define O_RDONLY 0
156 #endif
158 #ifndef S_ISLNK
159 # define lstat stat
160 #endif
162 /* Nonzero during writing of auto-save files */
163 int auto_saving;
165 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
166 a new file with the same mode as the original */
167 int auto_save_mode_bits;
169 /* Coding system for file names, or nil if none. */
170 Lisp_Object Vfile_name_coding_system;
172 /* Coding system for file names used only when
173 Vfile_name_coding_system is nil. */
174 Lisp_Object Vdefault_file_name_coding_system;
176 /* Alist of elements (REGEXP . HANDLER) for file names
177 whose I/O is done with a special handler. */
178 Lisp_Object Vfile_name_handler_alist;
180 /* Format for auto-save files */
181 Lisp_Object Vauto_save_file_format;
183 /* Lisp functions for translating file formats */
184 Lisp_Object Qformat_decode, Qformat_annotate_function;
186 /* Function to be called to decide a coding system of a reading file. */
187 Lisp_Object Vset_auto_coding_function;
189 /* Functions to be called to process text properties in inserted file. */
190 Lisp_Object Vafter_insert_file_functions;
192 /* Functions to be called to create text property annotations for file. */
193 Lisp_Object Vwrite_region_annotate_functions;
195 /* During build_annotations, each time an annotation function is called,
196 this holds the annotations made by the previous functions. */
197 Lisp_Object Vwrite_region_annotations_so_far;
199 /* File name in which we write a list of all our auto save files. */
200 Lisp_Object Vauto_save_list_file_name;
202 /* Nonzero means, when reading a filename in the minibuffer,
203 start out by inserting the default directory into the minibuffer. */
204 int insert_default_directory;
206 /* On VMS, nonzero means write new files with record format stmlf.
207 Zero means use var format. */
208 int vms_stmlf_recfm;
210 /* On NT, specifies the directory separator character, used (eg.) when
211 expanding file names. This can be bound to / or \. */
212 Lisp_Object Vdirectory_sep_char;
214 extern Lisp_Object Vuser_login_name;
216 #ifdef WINDOWSNT
217 extern Lisp_Object Vw32_get_true_file_attributes;
218 #endif
220 extern int minibuf_level;
222 extern int minibuffer_auto_raise;
224 /* These variables describe handlers that have "already" had a chance
225 to handle the current operation.
227 Vinhibit_file_name_handlers is a list of file name handlers.
228 Vinhibit_file_name_operation is the operation being handled.
229 If we try to handle that operation, we ignore those handlers. */
231 static Lisp_Object Vinhibit_file_name_handlers;
232 static Lisp_Object Vinhibit_file_name_operation;
234 Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
235 Lisp_Object Qexcl;
236 Lisp_Object Qfile_name_history;
238 Lisp_Object Qcar_less_than_car;
240 static int a_write P_ ((int, Lisp_Object, int, int,
241 Lisp_Object *, struct coding_system *));
242 static int e_write P_ ((int, Lisp_Object, int, int, struct coding_system *));
245 void
246 report_file_error (string, data)
247 char *string;
248 Lisp_Object data;
250 Lisp_Object errstring;
251 int errorno = errno;
253 synchronize_system_messages_locale ();
254 errstring = code_convert_string_norecord (build_string (strerror (errorno)),
255 Vlocale_coding_system, 0);
257 while (1)
258 switch (errorno)
260 case EEXIST:
261 Fsignal (Qfile_already_exists, Fcons (errstring, data));
262 break;
263 default:
264 /* System error messages are capitalized. Downcase the initial
265 unless it is followed by a slash. */
266 if (XSTRING (errstring)->data[1] != '/')
267 XSTRING (errstring)->data[0] = DOWNCASE (XSTRING (errstring)->data[0]);
269 Fsignal (Qfile_error,
270 Fcons (build_string (string), Fcons (errstring, data)));
274 Lisp_Object
275 close_file_unwind (fd)
276 Lisp_Object fd;
278 emacs_close (XFASTINT (fd));
279 return Qnil;
282 /* Restore point, having saved it as a marker. */
284 static Lisp_Object
285 restore_point_unwind (location)
286 Lisp_Object location;
288 Fgoto_char (location);
289 Fset_marker (location, Qnil, Qnil);
290 return Qnil;
293 Lisp_Object Qexpand_file_name;
294 Lisp_Object Qsubstitute_in_file_name;
295 Lisp_Object Qdirectory_file_name;
296 Lisp_Object Qfile_name_directory;
297 Lisp_Object Qfile_name_nondirectory;
298 Lisp_Object Qunhandled_file_name_directory;
299 Lisp_Object Qfile_name_as_directory;
300 Lisp_Object Qcopy_file;
301 Lisp_Object Qmake_directory_internal;
302 Lisp_Object Qmake_directory;
303 Lisp_Object Qdelete_directory;
304 Lisp_Object Qdelete_file;
305 Lisp_Object Qrename_file;
306 Lisp_Object Qadd_name_to_file;
307 Lisp_Object Qmake_symbolic_link;
308 Lisp_Object Qfile_exists_p;
309 Lisp_Object Qfile_executable_p;
310 Lisp_Object Qfile_readable_p;
311 Lisp_Object Qfile_writable_p;
312 Lisp_Object Qfile_symlink_p;
313 Lisp_Object Qaccess_file;
314 Lisp_Object Qfile_directory_p;
315 Lisp_Object Qfile_regular_p;
316 Lisp_Object Qfile_accessible_directory_p;
317 Lisp_Object Qfile_modes;
318 Lisp_Object Qset_file_modes;
319 Lisp_Object Qfile_newer_than_file_p;
320 Lisp_Object Qinsert_file_contents;
321 Lisp_Object Qwrite_region;
322 Lisp_Object Qverify_visited_file_modtime;
323 Lisp_Object Qset_visited_file_modtime;
325 DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
326 doc: /* Return FILENAME's handler function for OPERATION, if it has one.
327 Otherwise, return nil.
328 A file name is handled if one of the regular expressions in
329 `file-name-handler-alist' matches it.
331 If OPERATION equals `inhibit-file-name-operation', then we ignore
332 any handlers that are members of `inhibit-file-name-handlers',
333 but we still do run any other handlers. This lets handlers
334 use the standard functions without calling themselves recursively. */)
335 (filename, operation)
336 Lisp_Object filename, operation;
338 /* This function must not munge the match data. */
339 Lisp_Object chain, inhibited_handlers, result;
340 int pos = -1;
342 result = Qnil;
343 CHECK_STRING (filename);
345 if (EQ (operation, Vinhibit_file_name_operation))
346 inhibited_handlers = Vinhibit_file_name_handlers;
347 else
348 inhibited_handlers = Qnil;
350 for (chain = Vfile_name_handler_alist; CONSP (chain);
351 chain = XCDR (chain))
353 Lisp_Object elt;
354 elt = XCAR (chain);
355 if (CONSP (elt))
357 Lisp_Object string;
358 int match_pos;
359 string = XCAR (elt);
360 if (STRINGP (string)
361 && (match_pos = fast_string_match (string, filename)) > pos)
363 Lisp_Object handler, tem;
365 handler = XCDR (elt);
366 tem = Fmemq (handler, inhibited_handlers);
367 if (NILP (tem))
369 result = handler;
370 pos = match_pos;
375 QUIT;
377 return result;
380 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
381 1, 1, 0,
382 doc: /* Return the directory component in file name FILENAME.
383 Return nil if FILENAME does not include a directory.
384 Otherwise return a directory spec.
385 Given a Unix syntax file name, returns a string ending in slash;
386 on VMS, perhaps instead a string ending in `:', `]' or `>'. */)
387 (filename)
388 Lisp_Object filename;
390 register unsigned char *beg;
391 register unsigned char *p;
392 Lisp_Object handler;
394 CHECK_STRING (filename);
396 /* If the file name has special constructs in it,
397 call the corresponding file handler. */
398 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
399 if (!NILP (handler))
400 return call2 (handler, Qfile_name_directory, filename);
402 #ifdef FILE_SYSTEM_CASE
403 filename = FILE_SYSTEM_CASE (filename);
404 #endif
405 beg = XSTRING (filename)->data;
406 #ifdef DOS_NT
407 beg = strcpy (alloca (strlen (beg) + 1), beg);
408 #endif
409 p = beg + STRING_BYTES (XSTRING (filename));
411 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
412 #ifdef VMS
413 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
414 #endif /* VMS */
415 #ifdef DOS_NT
416 /* only recognise drive specifier at the beginning */
417 && !(p[-1] == ':'
418 /* handle the "/:d:foo" and "/:foo" cases correctly */
419 && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
420 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
421 #endif
422 ) p--;
424 if (p == beg)
425 return Qnil;
426 #ifdef DOS_NT
427 /* Expansion of "c:" to drive and default directory. */
428 if (p[-1] == ':')
430 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
431 unsigned char *res = alloca (MAXPATHLEN + 1);
432 unsigned char *r = res;
434 if (p == beg + 4 && IS_DIRECTORY_SEP (*beg) && beg[1] == ':')
436 strncpy (res, beg, 2);
437 beg += 2;
438 r += 2;
441 if (getdefdir (toupper (*beg) - 'A' + 1, r))
443 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
444 strcat (res, "/");
445 beg = res;
446 p = beg + strlen (beg);
449 CORRECT_DIR_SEPS (beg);
450 #endif /* DOS_NT */
452 if (STRING_MULTIBYTE (filename))
453 return make_string (beg, p - beg);
454 return make_unibyte_string (beg, p - beg);
457 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
458 Sfile_name_nondirectory, 1, 1, 0,
459 doc: /* Return file name FILENAME sans its directory.
460 For example, in a Unix-syntax file name,
461 this is everything after the last slash,
462 or the entire name if it contains no slash. */)
463 (filename)
464 Lisp_Object filename;
466 register unsigned char *beg, *p, *end;
467 Lisp_Object handler;
469 CHECK_STRING (filename);
471 /* If the file name has special constructs in it,
472 call the corresponding file handler. */
473 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
474 if (!NILP (handler))
475 return call2 (handler, Qfile_name_nondirectory, filename);
477 beg = XSTRING (filename)->data;
478 end = p = beg + STRING_BYTES (XSTRING (filename));
480 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
481 #ifdef VMS
482 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
483 #endif /* VMS */
484 #ifdef DOS_NT
485 /* only recognise drive specifier at beginning */
486 && !(p[-1] == ':'
487 /* handle the "/:d:foo" case correctly */
488 && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
489 #endif
491 p--;
493 if (STRING_MULTIBYTE (filename))
494 return make_string (p, end - p);
495 return make_unibyte_string (p, end - p);
498 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory,
499 Sunhandled_file_name_directory, 1, 1, 0,
500 doc: /* Return a directly usable directory name somehow associated with FILENAME.
501 A `directly usable' directory name is one that may be used without the
502 intervention of any file handler.
503 If FILENAME is a directly usable file itself, return
504 \(file-name-directory FILENAME).
505 The `call-process' and `start-process' functions use this function to
506 get a current directory to run processes in. */)
507 (filename)
508 Lisp_Object filename;
510 Lisp_Object handler;
512 /* If the file name has special constructs in it,
513 call the corresponding file handler. */
514 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
515 if (!NILP (handler))
516 return call2 (handler, Qunhandled_file_name_directory, filename);
518 return Ffile_name_directory (filename);
522 char *
523 file_name_as_directory (out, in)
524 char *out, *in;
526 int size = strlen (in) - 1;
528 strcpy (out, in);
530 if (size < 0)
532 out[0] = '.';
533 out[1] = '/';
534 out[2] = 0;
535 return out;
538 #ifdef VMS
539 /* Is it already a directory string? */
540 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
541 return out;
542 /* Is it a VMS directory file name? If so, hack VMS syntax. */
543 else if (! index (in, '/')
544 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
545 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
546 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
547 || ! strncmp (&in[size - 5], ".dir", 4))
548 && (in[size - 1] == '.' || in[size - 1] == ';')
549 && in[size] == '1')))
551 register char *p, *dot;
552 char brack;
554 /* x.dir -> [.x]
555 dir:x.dir --> dir:[x]
556 dir:[x]y.dir --> dir:[x.y] */
557 p = in + size;
558 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
559 if (p != in)
561 strncpy (out, in, p - in);
562 out[p - in] = '\0';
563 if (*p == ':')
565 brack = ']';
566 strcat (out, ":[");
568 else
570 brack = *p;
571 strcat (out, ".");
573 p++;
575 else
577 brack = ']';
578 strcpy (out, "[.");
580 dot = index (p, '.');
581 if (dot)
583 /* blindly remove any extension */
584 size = strlen (out) + (dot - p);
585 strncat (out, p, dot - p);
587 else
589 strcat (out, p);
590 size = strlen (out);
592 out[size++] = brack;
593 out[size] = '\0';
595 #else /* not VMS */
596 /* For Unix syntax, Append a slash if necessary */
597 if (!IS_DIRECTORY_SEP (out[size]))
599 out[size + 1] = DIRECTORY_SEP;
600 out[size + 2] = '\0';
602 #ifdef DOS_NT
603 CORRECT_DIR_SEPS (out);
604 #endif
605 #endif /* not VMS */
606 return out;
609 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
610 Sfile_name_as_directory, 1, 1, 0,
611 doc: /* Return a string representing file FILENAME interpreted as a directory.
612 This operation exists because a directory is also a file, but its name as
613 a directory is different from its name as a file.
614 The result can be used as the value of `default-directory'
615 or passed as second argument to `expand-file-name'.
616 For a Unix-syntax file name, just appends a slash.
617 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc. */)
618 (file)
619 Lisp_Object file;
621 char *buf;
622 Lisp_Object handler;
624 CHECK_STRING (file);
625 if (NILP (file))
626 return Qnil;
628 /* If the file name has special constructs in it,
629 call the corresponding file handler. */
630 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
631 if (!NILP (handler))
632 return call2 (handler, Qfile_name_as_directory, file);
634 buf = (char *) alloca (STRING_BYTES (XSTRING (file)) + 10);
635 return build_string (file_name_as_directory (buf, XSTRING (file)->data));
639 * Convert from directory name to filename.
640 * On VMS:
641 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
642 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
643 * On UNIX, it's simple: just make sure there isn't a terminating /
645 * Value is nonzero if the string output is different from the input.
649 directory_file_name (src, dst)
650 char *src, *dst;
652 long slen;
653 #ifdef VMS
654 long rlen;
655 char * ptr, * rptr;
656 char bracket;
657 struct FAB fab = cc$rms_fab;
658 struct NAM nam = cc$rms_nam;
659 char esa[NAM$C_MAXRSS];
660 #endif /* VMS */
662 slen = strlen (src);
663 #ifdef VMS
664 if (! index (src, '/')
665 && (src[slen - 1] == ']'
666 || src[slen - 1] == ':'
667 || src[slen - 1] == '>'))
669 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
670 fab.fab$l_fna = src;
671 fab.fab$b_fns = slen;
672 fab.fab$l_nam = &nam;
673 fab.fab$l_fop = FAB$M_NAM;
675 nam.nam$l_esa = esa;
676 nam.nam$b_ess = sizeof esa;
677 nam.nam$b_nop |= NAM$M_SYNCHK;
679 /* We call SYS$PARSE to handle such things as [--] for us. */
680 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
682 slen = nam.nam$b_esl;
683 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
684 slen -= 2;
685 esa[slen] = '\0';
686 src = esa;
688 if (src[slen - 1] != ']' && src[slen - 1] != '>')
690 /* what about when we have logical_name:???? */
691 if (src[slen - 1] == ':')
692 { /* Xlate logical name and see what we get */
693 ptr = strcpy (dst, src); /* upper case for getenv */
694 while (*ptr)
696 if ('a' <= *ptr && *ptr <= 'z')
697 *ptr -= 040;
698 ptr++;
700 dst[slen - 1] = 0; /* remove colon */
701 if (!(src = egetenv (dst)))
702 return 0;
703 /* should we jump to the beginning of this procedure?
704 Good points: allows us to use logical names that xlate
705 to Unix names,
706 Bad points: can be a problem if we just translated to a device
707 name...
708 For now, I'll punt and always expect VMS names, and hope for
709 the best! */
710 slen = strlen (src);
711 if (src[slen - 1] != ']' && src[slen - 1] != '>')
712 { /* no recursion here! */
713 strcpy (dst, src);
714 return 0;
717 else
718 { /* not a directory spec */
719 strcpy (dst, src);
720 return 0;
723 bracket = src[slen - 1];
725 /* If bracket is ']' or '>', bracket - 2 is the corresponding
726 opening bracket. */
727 ptr = index (src, bracket - 2);
728 if (ptr == 0)
729 { /* no opening bracket */
730 strcpy (dst, src);
731 return 0;
733 if (!(rptr = rindex (src, '.')))
734 rptr = ptr;
735 slen = rptr - src;
736 strncpy (dst, src, slen);
737 dst[slen] = '\0';
738 if (*rptr == '.')
740 dst[slen++] = bracket;
741 dst[slen] = '\0';
743 else
745 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
746 then translate the device and recurse. */
747 if (dst[slen - 1] == ':'
748 && dst[slen - 2] != ':' /* skip decnet nodes */
749 && strcmp (src + slen, "[000000]") == 0)
751 dst[slen - 1] = '\0';
752 if ((ptr = egetenv (dst))
753 && (rlen = strlen (ptr) - 1) > 0
754 && (ptr[rlen] == ']' || ptr[rlen] == '>')
755 && ptr[rlen - 1] == '.')
757 char * buf = (char *) alloca (strlen (ptr) + 1);
758 strcpy (buf, ptr);
759 buf[rlen - 1] = ']';
760 buf[rlen] = '\0';
761 return directory_file_name (buf, dst);
763 else
764 dst[slen - 1] = ':';
766 strcat (dst, "[000000]");
767 slen += 8;
769 rptr++;
770 rlen = strlen (rptr) - 1;
771 strncat (dst, rptr, rlen);
772 dst[slen + rlen] = '\0';
773 strcat (dst, ".DIR.1");
774 return 1;
776 #endif /* VMS */
777 /* Process as Unix format: just remove any final slash.
778 But leave "/" unchanged; do not change it to "". */
779 strcpy (dst, src);
780 #ifdef APOLLO
781 /* Handle // as root for apollo's. */
782 if ((slen > 2 && dst[slen - 1] == '/')
783 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
784 dst[slen - 1] = 0;
785 #else
786 if (slen > 1
787 && IS_DIRECTORY_SEP (dst[slen - 1])
788 #ifdef DOS_NT
789 && !IS_ANY_SEP (dst[slen - 2])
790 #endif
792 dst[slen - 1] = 0;
793 #endif
794 #ifdef DOS_NT
795 CORRECT_DIR_SEPS (dst);
796 #endif
797 return 1;
800 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
801 1, 1, 0,
802 doc: /* Returns the file name of the directory named DIRECTORY.
803 This is the name of the file that holds the data for the directory DIRECTORY.
804 This operation exists because a directory is also a file, but its name as
805 a directory is different from its name as a file.
806 In Unix-syntax, this function just removes the final slash.
807 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",
808 it returns a file name such as \"[X]Y.DIR.1\". */)
809 (directory)
810 Lisp_Object directory;
812 char *buf;
813 Lisp_Object handler;
815 CHECK_STRING (directory);
817 if (NILP (directory))
818 return Qnil;
820 /* If the file name has special constructs in it,
821 call the corresponding file handler. */
822 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
823 if (!NILP (handler))
824 return call2 (handler, Qdirectory_file_name, directory);
826 #ifdef VMS
827 /* 20 extra chars is insufficient for VMS, since we might perform a
828 logical name translation. an equivalence string can be up to 255
829 chars long, so grab that much extra space... - sss */
830 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20 + 255);
831 #else
832 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20);
833 #endif
834 directory_file_name (XSTRING (directory)->data, buf);
835 return build_string (buf);
838 static char make_temp_name_tbl[64] =
840 'A','B','C','D','E','F','G','H',
841 'I','J','K','L','M','N','O','P',
842 'Q','R','S','T','U','V','W','X',
843 'Y','Z','a','b','c','d','e','f',
844 'g','h','i','j','k','l','m','n',
845 'o','p','q','r','s','t','u','v',
846 'w','x','y','z','0','1','2','3',
847 '4','5','6','7','8','9','-','_'
850 static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
852 /* Value is a temporary file name starting with PREFIX, a string.
854 The Emacs process number forms part of the result, so there is
855 no danger of generating a name being used by another process.
856 In addition, this function makes an attempt to choose a name
857 which has no existing file. To make this work, PREFIX should be
858 an absolute file name.
860 BASE64_P non-zero means add the pid as 3 characters in base64
861 encoding. In this case, 6 characters will be added to PREFIX to
862 form the file name. Otherwise, if Emacs is running on a system
863 with long file names, add the pid as a decimal number.
865 This function signals an error if no unique file name could be
866 generated. */
868 Lisp_Object
869 make_temp_name (prefix, base64_p)
870 Lisp_Object prefix;
871 int base64_p;
873 Lisp_Object val;
874 int len;
875 int pid;
876 unsigned char *p, *data;
877 char pidbuf[20];
878 int pidlen;
880 CHECK_STRING (prefix);
882 /* VAL is created by adding 6 characters to PREFIX. The first
883 three are the PID of this process, in base 64, and the second
884 three are incremented if the file already exists. This ensures
885 262144 unique file names per PID per PREFIX. */
887 pid = (int) getpid ();
889 if (base64_p)
891 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
892 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
893 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
894 pidlen = 3;
896 else
898 #ifdef HAVE_LONG_FILE_NAMES
899 sprintf (pidbuf, "%d", pid);
900 pidlen = strlen (pidbuf);
901 #else
902 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
903 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
904 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
905 pidlen = 3;
906 #endif
909 len = XSTRING (prefix)->size;
910 val = make_uninit_string (len + 3 + pidlen);
911 data = XSTRING (val)->data;
912 bcopy(XSTRING (prefix)->data, data, len);
913 p = data + len;
915 bcopy (pidbuf, p, pidlen);
916 p += pidlen;
918 /* Here we try to minimize useless stat'ing when this function is
919 invoked many times successively with the same PREFIX. We achieve
920 this by initializing count to a random value, and incrementing it
921 afterwards.
923 We don't want make-temp-name to be called while dumping,
924 because then make_temp_name_count_initialized_p would get set
925 and then make_temp_name_count would not be set when Emacs starts. */
927 if (!make_temp_name_count_initialized_p)
929 make_temp_name_count = (unsigned) time (NULL);
930 make_temp_name_count_initialized_p = 1;
933 while (1)
935 struct stat ignored;
936 unsigned num = make_temp_name_count;
938 p[0] = make_temp_name_tbl[num & 63], num >>= 6;
939 p[1] = make_temp_name_tbl[num & 63], num >>= 6;
940 p[2] = make_temp_name_tbl[num & 63], num >>= 6;
942 /* Poor man's congruential RN generator. Replace with
943 ++make_temp_name_count for debugging. */
944 make_temp_name_count += 25229;
945 make_temp_name_count %= 225307;
947 if (stat (data, &ignored) < 0)
949 /* We want to return only if errno is ENOENT. */
950 if (errno == ENOENT)
951 return val;
952 else
953 /* The error here is dubious, but there is little else we
954 can do. The alternatives are to return nil, which is
955 as bad as (and in many cases worse than) throwing the
956 error, or to ignore the error, which will likely result
957 in looping through 225307 stat's, which is not only
958 dog-slow, but also useless since it will fallback to
959 the errow below, anyway. */
960 report_file_error ("Cannot create temporary name for prefix",
961 Fcons (prefix, Qnil));
962 /* not reached */
966 error ("Cannot create temporary name for prefix `%s'",
967 XSTRING (prefix)->data);
968 return Qnil;
972 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
973 doc: /* Generate temporary file name (string) starting with PREFIX (a string).
974 The Emacs process number forms part of the result,
975 so there is no danger of generating a name being used by another process.
977 In addition, this function makes an attempt to choose a name
978 which has no existing file. To make this work,
979 PREFIX should be an absolute file name.
981 There is a race condition between calling `make-temp-name' and creating the
982 file which opens all kinds of security holes. For that reason, you should
983 probably use `make-temp-file' instead, except in three circumstances:
985 * If you are creating the file in the user's home directory.
986 * If you are creating a directory rather than an ordinary file.
987 * If you are taking special precautions as `make-temp-file' does. */)
988 (prefix)
989 Lisp_Object prefix;
991 return make_temp_name (prefix, 0);
996 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
997 doc: /* Convert filename NAME to absolute, and canonicalize it.
998 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
999 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,
1000 the current buffer's value of default-directory is used.
1001 File name components that are `.' are removed, and
1002 so are file name components followed by `..', along with the `..' itself;
1003 note that these simplifications are done without checking the resulting
1004 file names in the file system.
1005 An initial `~/' expands to your home directory.
1006 An initial `~USER/' expands to USER's home directory.
1007 See also the function `substitute-in-file-name'. */)
1008 (name, default_directory)
1009 Lisp_Object name, default_directory;
1011 unsigned char *nm;
1013 register unsigned char *newdir, *p, *o;
1014 int tlen;
1015 unsigned char *target;
1016 struct passwd *pw;
1017 #ifdef VMS
1018 unsigned char * colon = 0;
1019 unsigned char * close = 0;
1020 unsigned char * slash = 0;
1021 unsigned char * brack = 0;
1022 int lbrack = 0, rbrack = 0;
1023 int dots = 0;
1024 #endif /* VMS */
1025 #ifdef DOS_NT
1026 int drive = 0;
1027 int collapse_newdir = 1;
1028 int is_escaped = 0;
1029 #endif /* DOS_NT */
1030 int length;
1031 Lisp_Object handler;
1033 CHECK_STRING (name);
1035 /* If the file name has special constructs in it,
1036 call the corresponding file handler. */
1037 handler = Ffind_file_name_handler (name, Qexpand_file_name);
1038 if (!NILP (handler))
1039 return call3 (handler, Qexpand_file_name, name, default_directory);
1041 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
1042 if (NILP (default_directory))
1043 default_directory = current_buffer->directory;
1044 if (! STRINGP (default_directory))
1046 #ifdef DOS_NT
1047 /* "/" is not considered a root directory on DOS_NT, so using "/"
1048 here causes an infinite recursion in, e.g., the following:
1050 (let (default-directory)
1051 (expand-file-name "a"))
1053 To avoid this, we set default_directory to the root of the
1054 current drive. */
1055 extern char *emacs_root_dir (void);
1057 default_directory = build_string (emacs_root_dir ());
1058 #else
1059 default_directory = build_string ("/");
1060 #endif
1063 if (!NILP (default_directory))
1065 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
1066 if (!NILP (handler))
1067 return call3 (handler, Qexpand_file_name, name, default_directory);
1070 o = XSTRING (default_directory)->data;
1072 /* Make sure DEFAULT_DIRECTORY is properly expanded.
1073 It would be better to do this down below where we actually use
1074 default_directory. Unfortunately, calling Fexpand_file_name recursively
1075 could invoke GC, and the strings might be relocated. This would
1076 be annoying because we have pointers into strings lying around
1077 that would need adjusting, and people would add new pointers to
1078 the code and forget to adjust them, resulting in intermittent bugs.
1079 Putting this call here avoids all that crud.
1081 The EQ test avoids infinite recursion. */
1082 if (! NILP (default_directory) && !EQ (default_directory, name)
1083 /* Save time in some common cases - as long as default_directory
1084 is not relative, it can be canonicalized with name below (if it
1085 is needed at all) without requiring it to be expanded now. */
1086 #ifdef DOS_NT
1087 /* Detect MSDOS file names with drive specifiers. */
1088 && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))
1089 #ifdef WINDOWSNT
1090 /* Detect Windows file names in UNC format. */
1091 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
1092 #endif
1093 #else /* not DOS_NT */
1094 /* Detect Unix absolute file names (/... alone is not absolute on
1095 DOS or Windows). */
1096 && ! (IS_DIRECTORY_SEP (o[0]))
1097 #endif /* not DOS_NT */
1100 struct gcpro gcpro1;
1102 GCPRO1 (name);
1103 default_directory = Fexpand_file_name (default_directory, Qnil);
1104 UNGCPRO;
1107 #ifdef VMS
1108 /* Filenames on VMS are always upper case. */
1109 name = Fupcase (name);
1110 #endif
1111 #ifdef FILE_SYSTEM_CASE
1112 name = FILE_SYSTEM_CASE (name);
1113 #endif
1115 nm = XSTRING (name)->data;
1117 #ifdef DOS_NT
1118 /* We will force directory separators to be either all \ or /, so make
1119 a local copy to modify, even if there ends up being no change. */
1120 nm = strcpy (alloca (strlen (nm) + 1), nm);
1122 /* Note if special escape prefix is present, but remove for now. */
1123 if (nm[0] == '/' && nm[1] == ':')
1125 is_escaped = 1;
1126 nm += 2;
1129 /* Find and remove drive specifier if present; this makes nm absolute
1130 even if the rest of the name appears to be relative. Only look for
1131 drive specifier at the beginning. */
1132 if (IS_DRIVE (nm[0]) && IS_DEVICE_SEP (nm[1]))
1134 drive = nm[0];
1135 nm += 2;
1138 #ifdef WINDOWSNT
1139 /* If we see "c://somedir", we want to strip the first slash after the
1140 colon when stripping the drive letter. Otherwise, this expands to
1141 "//somedir". */
1142 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1143 nm++;
1144 #endif /* WINDOWSNT */
1145 #endif /* DOS_NT */
1147 #ifdef WINDOWSNT
1148 /* Discard any previous drive specifier if nm is now in UNC format. */
1149 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1151 drive = 0;
1153 #endif
1155 /* If nm is absolute, look for `/./' or `/../' or `//''sequences; if
1156 none are found, we can probably return right away. We will avoid
1157 allocating a new string if name is already fully expanded. */
1158 if (
1159 IS_DIRECTORY_SEP (nm[0])
1160 #ifdef MSDOS
1161 && drive && !is_escaped
1162 #endif
1163 #ifdef WINDOWSNT
1164 && (drive || IS_DIRECTORY_SEP (nm[1])) && !is_escaped
1165 #endif
1166 #ifdef VMS
1167 || index (nm, ':')
1168 #endif /* VMS */
1171 /* If it turns out that the filename we want to return is just a
1172 suffix of FILENAME, we don't need to go through and edit
1173 things; we just need to construct a new string using data
1174 starting at the middle of FILENAME. If we set lose to a
1175 non-zero value, that means we've discovered that we can't do
1176 that cool trick. */
1177 int lose = 0;
1179 p = nm;
1180 while (*p)
1182 /* Since we know the name is absolute, we can assume that each
1183 element starts with a "/". */
1185 /* "." and ".." are hairy. */
1186 if (IS_DIRECTORY_SEP (p[0])
1187 && p[1] == '.'
1188 && (IS_DIRECTORY_SEP (p[2])
1189 || p[2] == 0
1190 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
1191 || p[3] == 0))))
1192 lose = 1;
1193 /* We want to replace multiple `/' in a row with a single
1194 slash. */
1195 else if (p > nm
1196 && IS_DIRECTORY_SEP (p[0])
1197 && IS_DIRECTORY_SEP (p[1]))
1198 lose = 1;
1200 #ifdef VMS
1201 if (p[0] == '\\')
1202 lose = 1;
1203 if (p[0] == '/') {
1204 /* if dev:[dir]/, move nm to / */
1205 if (!slash && p > nm && (brack || colon)) {
1206 nm = (brack ? brack + 1 : colon + 1);
1207 lbrack = rbrack = 0;
1208 brack = 0;
1209 colon = 0;
1211 slash = p;
1213 if (p[0] == '-')
1214 #ifndef VMS4_4
1215 /* VMS pre V4.4,convert '-'s in filenames. */
1216 if (lbrack == rbrack)
1218 if (dots < 2) /* this is to allow negative version numbers */
1219 p[0] = '_';
1221 else
1222 #endif /* VMS4_4 */
1223 if (lbrack > rbrack &&
1224 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1225 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1226 lose = 1;
1227 #ifndef VMS4_4
1228 else
1229 p[0] = '_';
1230 #endif /* VMS4_4 */
1231 /* count open brackets, reset close bracket pointer */
1232 if (p[0] == '[' || p[0] == '<')
1233 lbrack++, brack = 0;
1234 /* count close brackets, set close bracket pointer */
1235 if (p[0] == ']' || p[0] == '>')
1236 rbrack++, brack = p;
1237 /* detect ][ or >< */
1238 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1239 lose = 1;
1240 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1241 nm = p + 1, lose = 1;
1242 if (p[0] == ':' && (colon || slash))
1243 /* if dev1:[dir]dev2:, move nm to dev2: */
1244 if (brack)
1246 nm = brack + 1;
1247 brack = 0;
1249 /* if /name/dev:, move nm to dev: */
1250 else if (slash)
1251 nm = slash + 1;
1252 /* if node::dev:, move colon following dev */
1253 else if (colon && colon[-1] == ':')
1254 colon = p;
1255 /* if dev1:dev2:, move nm to dev2: */
1256 else if (colon && colon[-1] != ':')
1258 nm = colon + 1;
1259 colon = 0;
1261 if (p[0] == ':' && !colon)
1263 if (p[1] == ':')
1264 p++;
1265 colon = p;
1267 if (lbrack == rbrack)
1268 if (p[0] == ';')
1269 dots = 2;
1270 else if (p[0] == '.')
1271 dots++;
1272 #endif /* VMS */
1273 p++;
1275 if (!lose)
1277 #ifdef VMS
1278 if (index (nm, '/'))
1279 return build_string (sys_translate_unix (nm));
1280 #endif /* VMS */
1281 #ifdef DOS_NT
1282 /* Make sure directories are all separated with / or \ as
1283 desired, but avoid allocation of a new string when not
1284 required. */
1285 CORRECT_DIR_SEPS (nm);
1286 #ifdef WINDOWSNT
1287 if (IS_DIRECTORY_SEP (nm[1]))
1289 if (strcmp (nm, XSTRING (name)->data) != 0)
1290 name = build_string (nm);
1292 else
1293 #endif
1294 /* drive must be set, so this is okay */
1295 if (strcmp (nm - 2, XSTRING (name)->data) != 0)
1297 name = make_string (nm - 2, p - nm + 2);
1298 XSTRING (name)->data[0] = DRIVE_LETTER (drive);
1299 XSTRING (name)->data[1] = ':';
1301 return name;
1302 #else /* not DOS_NT */
1303 if (nm == XSTRING (name)->data)
1304 return name;
1305 return build_string (nm);
1306 #endif /* not DOS_NT */
1310 /* At this point, nm might or might not be an absolute file name. We
1311 need to expand ~ or ~user if present, otherwise prefix nm with
1312 default_directory if nm is not absolute, and finally collapse /./
1313 and /foo/../ sequences.
1315 We set newdir to be the appropriate prefix if one is needed:
1316 - the relevant user directory if nm starts with ~ or ~user
1317 - the specified drive's working dir (DOS/NT only) if nm does not
1318 start with /
1319 - the value of default_directory.
1321 Note that these prefixes are not guaranteed to be absolute (except
1322 for the working dir of a drive). Therefore, to ensure we always
1323 return an absolute name, if the final prefix is not absolute we
1324 append it to the current working directory. */
1326 newdir = 0;
1328 if (nm[0] == '~') /* prefix ~ */
1330 if (IS_DIRECTORY_SEP (nm[1])
1331 #ifdef VMS
1332 || nm[1] == ':'
1333 #endif /* VMS */
1334 || nm[1] == 0) /* ~ by itself */
1336 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1337 newdir = (unsigned char *) "";
1338 nm++;
1339 #ifdef DOS_NT
1340 collapse_newdir = 0;
1341 #endif
1342 #ifdef VMS
1343 nm++; /* Don't leave the slash in nm. */
1344 #endif /* VMS */
1346 else /* ~user/filename */
1348 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
1349 #ifdef VMS
1350 && *p != ':'
1351 #endif /* VMS */
1352 ); p++);
1353 o = (unsigned char *) alloca (p - nm + 1);
1354 bcopy ((char *) nm, o, p - nm);
1355 o [p - nm] = 0;
1357 pw = (struct passwd *) getpwnam (o + 1);
1358 if (pw)
1360 newdir = (unsigned char *) pw -> pw_dir;
1361 #ifdef VMS
1362 nm = p + 1; /* skip the terminator */
1363 #else
1364 nm = p;
1365 #ifdef DOS_NT
1366 collapse_newdir = 0;
1367 #endif
1368 #endif /* VMS */
1371 /* If we don't find a user of that name, leave the name
1372 unchanged; don't move nm forward to p. */
1376 #ifdef DOS_NT
1377 /* On DOS and Windows, nm is absolute if a drive name was specified;
1378 use the drive's current directory as the prefix if needed. */
1379 if (!newdir && drive)
1381 /* Get default directory if needed to make nm absolute. */
1382 if (!IS_DIRECTORY_SEP (nm[0]))
1384 newdir = alloca (MAXPATHLEN + 1);
1385 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1386 newdir = NULL;
1388 if (!newdir)
1390 /* Either nm starts with /, or drive isn't mounted. */
1391 newdir = alloca (4);
1392 newdir[0] = DRIVE_LETTER (drive);
1393 newdir[1] = ':';
1394 newdir[2] = '/';
1395 newdir[3] = 0;
1398 #endif /* DOS_NT */
1400 /* Finally, if no prefix has been specified and nm is not absolute,
1401 then it must be expanded relative to default_directory. */
1403 if (1
1404 #ifndef DOS_NT
1405 /* /... alone is not absolute on DOS and Windows. */
1406 && !IS_DIRECTORY_SEP (nm[0])
1407 #endif
1408 #ifdef WINDOWSNT
1409 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1410 #endif
1411 #ifdef VMS
1412 && !index (nm, ':')
1413 #endif
1414 && !newdir)
1416 newdir = XSTRING (default_directory)->data;
1417 #ifdef DOS_NT
1418 /* Note if special escape prefix is present, but remove for now. */
1419 if (newdir[0] == '/' && newdir[1] == ':')
1421 is_escaped = 1;
1422 newdir += 2;
1424 #endif
1427 #ifdef DOS_NT
1428 if (newdir)
1430 /* First ensure newdir is an absolute name. */
1431 if (
1432 /* Detect MSDOS file names with drive specifiers. */
1433 ! (IS_DRIVE (newdir[0])
1434 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1435 #ifdef WINDOWSNT
1436 /* Detect Windows file names in UNC format. */
1437 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1438 #endif
1441 /* Effectively, let newdir be (expand-file-name newdir cwd).
1442 Because of the admonition against calling expand-file-name
1443 when we have pointers into lisp strings, we accomplish this
1444 indirectly by prepending newdir to nm if necessary, and using
1445 cwd (or the wd of newdir's drive) as the new newdir. */
1447 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1449 drive = newdir[0];
1450 newdir += 2;
1452 if (!IS_DIRECTORY_SEP (nm[0]))
1454 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1455 file_name_as_directory (tmp, newdir);
1456 strcat (tmp, nm);
1457 nm = tmp;
1459 newdir = alloca (MAXPATHLEN + 1);
1460 if (drive)
1462 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1463 newdir = "/";
1465 else
1466 getwd (newdir);
1469 /* Strip off drive name from prefix, if present. */
1470 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1472 drive = newdir[0];
1473 newdir += 2;
1476 /* Keep only a prefix from newdir if nm starts with slash
1477 (//server/share for UNC, nothing otherwise). */
1478 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1480 #ifdef WINDOWSNT
1481 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1483 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1484 p = newdir + 2;
1485 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1486 p++;
1487 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1488 *p = 0;
1490 else
1491 #endif
1492 newdir = "";
1495 #endif /* DOS_NT */
1497 if (newdir)
1499 /* Get rid of any slash at the end of newdir, unless newdir is
1500 just / or // (an incomplete UNC name). */
1501 length = strlen (newdir);
1502 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1503 #ifdef WINDOWSNT
1504 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1505 #endif
1508 unsigned char *temp = (unsigned char *) alloca (length);
1509 bcopy (newdir, temp, length - 1);
1510 temp[length - 1] = 0;
1511 newdir = temp;
1513 tlen = length + 1;
1515 else
1516 tlen = 0;
1518 /* Now concatenate the directory and name to new space in the stack frame */
1519 tlen += strlen (nm) + 1;
1520 #ifdef DOS_NT
1521 /* Reserve space for drive specifier and escape prefix, since either
1522 or both may need to be inserted. (The Microsoft x86 compiler
1523 produces incorrect code if the following two lines are combined.) */
1524 target = (unsigned char *) alloca (tlen + 4);
1525 target += 4;
1526 #else /* not DOS_NT */
1527 target = (unsigned char *) alloca (tlen);
1528 #endif /* not DOS_NT */
1529 *target = 0;
1531 if (newdir)
1533 #ifndef VMS
1534 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1536 #ifdef DOS_NT
1537 /* If newdir is effectively "C:/", then the drive letter will have
1538 been stripped and newdir will be "/". Concatenating with an
1539 absolute directory in nm produces "//", which will then be
1540 incorrectly treated as a network share. Ignore newdir in
1541 this case (keeping the drive letter). */
1542 if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0])
1543 && newdir[1] == '\0'))
1544 #endif
1545 strcpy (target, newdir);
1547 else
1548 #endif
1549 file_name_as_directory (target, newdir);
1552 strcat (target, nm);
1553 #ifdef VMS
1554 if (index (target, '/'))
1555 strcpy (target, sys_translate_unix (target));
1556 #endif /* VMS */
1558 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1560 /* Now canonicalize by removing `//', `/.' and `/foo/..' if they
1561 appear. */
1563 p = target;
1564 o = target;
1566 while (*p)
1568 #ifdef VMS
1569 if (*p != ']' && *p != '>' && *p != '-')
1571 if (*p == '\\')
1572 p++;
1573 *o++ = *p++;
1575 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1576 /* brackets are offset from each other by 2 */
1578 p += 2;
1579 if (*p != '.' && *p != '-' && o[-1] != '.')
1580 /* convert [foo][bar] to [bar] */
1581 while (o[-1] != '[' && o[-1] != '<')
1582 o--;
1583 else if (*p == '-' && *o != '.')
1584 *--p = '.';
1586 else if (p[0] == '-' && o[-1] == '.' &&
1587 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1588 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1591 o--;
1592 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1593 if (p[1] == '.') /* foo.-.bar ==> bar. */
1594 p += 2;
1595 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1596 p++, o--;
1597 /* else [foo.-] ==> [-] */
1599 else
1601 #ifndef VMS4_4
1602 if (*p == '-' &&
1603 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1604 p[1] != ']' && p[1] != '>' && p[1] != '.')
1605 *p = '_';
1606 #endif /* VMS4_4 */
1607 *o++ = *p++;
1609 #else /* not VMS */
1610 if (!IS_DIRECTORY_SEP (*p))
1612 *o++ = *p++;
1614 else if (IS_DIRECTORY_SEP (p[0])
1615 && p[1] == '.'
1616 && (IS_DIRECTORY_SEP (p[2])
1617 || p[2] == 0))
1619 /* If "/." is the entire filename, keep the "/". Otherwise,
1620 just delete the whole "/.". */
1621 if (o == target && p[2] == '\0')
1622 *o++ = *p;
1623 p += 2;
1625 else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1626 /* `/../' is the "superroot" on certain file systems. */
1627 && o != target
1628 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1630 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1632 /* Keep initial / only if this is the whole name. */
1633 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1634 ++o;
1635 p += 3;
1637 else if (p > target
1638 && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
1640 /* Collapse multiple `/' in a row. */
1641 *o++ = *p++;
1642 while (IS_DIRECTORY_SEP (*p))
1643 ++p;
1645 else
1647 *o++ = *p++;
1649 #endif /* not VMS */
1652 #ifdef DOS_NT
1653 /* At last, set drive name. */
1654 #ifdef WINDOWSNT
1655 /* Except for network file name. */
1656 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1657 #endif /* WINDOWSNT */
1659 if (!drive) abort ();
1660 target -= 2;
1661 target[0] = DRIVE_LETTER (drive);
1662 target[1] = ':';
1664 /* Reinsert the escape prefix if required. */
1665 if (is_escaped)
1667 target -= 2;
1668 target[0] = '/';
1669 target[1] = ':';
1671 CORRECT_DIR_SEPS (target);
1672 #endif /* DOS_NT */
1674 return make_string (target, o - target);
1677 #if 0
1678 /* PLEASE DO NOT DELETE THIS COMMENTED-OUT VERSION!
1679 This is the old version of expand-file-name, before it was thoroughly
1680 rewritten for Emacs 10.31. We leave this version here commented-out,
1681 because the code is very complex and likely to have subtle bugs. If
1682 bugs _are_ found, it might be of interest to look at the old code and
1683 see what did it do in the relevant situation.
1685 Don't remove this code: it's true that it will be accessible via CVS,
1686 but a few years from deletion, people will forget it is there. */
1688 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1689 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1690 "Convert FILENAME to absolute, and canonicalize it.\n\
1691 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1692 (does not start with slash); if DEFAULT is nil or missing,\n\
1693 the current buffer's value of default-directory is used.\n\
1694 Filenames containing `.' or `..' as components are simplified;\n\
1695 initial `~/' expands to your home directory.\n\
1696 See also the function `substitute-in-file-name'.")
1697 (name, defalt)
1698 Lisp_Object name, defalt;
1700 unsigned char *nm;
1702 register unsigned char *newdir, *p, *o;
1703 int tlen;
1704 unsigned char *target;
1705 struct passwd *pw;
1706 int lose;
1707 #ifdef VMS
1708 unsigned char * colon = 0;
1709 unsigned char * close = 0;
1710 unsigned char * slash = 0;
1711 unsigned char * brack = 0;
1712 int lbrack = 0, rbrack = 0;
1713 int dots = 0;
1714 #endif /* VMS */
1716 CHECK_STRING (name);
1718 #ifdef VMS
1719 /* Filenames on VMS are always upper case. */
1720 name = Fupcase (name);
1721 #endif
1723 nm = XSTRING (name)->data;
1725 /* If nm is absolute, flush ...// and detect /./ and /../.
1726 If no /./ or /../ we can return right away. */
1727 if (
1728 nm[0] == '/'
1729 #ifdef VMS
1730 || index (nm, ':')
1731 #endif /* VMS */
1734 p = nm;
1735 lose = 0;
1736 while (*p)
1738 if (p[0] == '/' && p[1] == '/'
1739 #ifdef APOLLO
1740 /* // at start of filename is meaningful on Apollo system. */
1741 && nm != p
1742 #endif /* APOLLO */
1744 nm = p + 1;
1745 if (p[0] == '/' && p[1] == '~')
1746 nm = p + 1, lose = 1;
1747 if (p[0] == '/' && p[1] == '.'
1748 && (p[2] == '/' || p[2] == 0
1749 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1750 lose = 1;
1751 #ifdef VMS
1752 if (p[0] == '\\')
1753 lose = 1;
1754 if (p[0] == '/') {
1755 /* if dev:[dir]/, move nm to / */
1756 if (!slash && p > nm && (brack || colon)) {
1757 nm = (brack ? brack + 1 : colon + 1);
1758 lbrack = rbrack = 0;
1759 brack = 0;
1760 colon = 0;
1762 slash = p;
1764 if (p[0] == '-')
1765 #ifndef VMS4_4
1766 /* VMS pre V4.4,convert '-'s in filenames. */
1767 if (lbrack == rbrack)
1769 if (dots < 2) /* this is to allow negative version numbers */
1770 p[0] = '_';
1772 else
1773 #endif /* VMS4_4 */
1774 if (lbrack > rbrack &&
1775 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1776 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1777 lose = 1;
1778 #ifndef VMS4_4
1779 else
1780 p[0] = '_';
1781 #endif /* VMS4_4 */
1782 /* count open brackets, reset close bracket pointer */
1783 if (p[0] == '[' || p[0] == '<')
1784 lbrack++, brack = 0;
1785 /* count close brackets, set close bracket pointer */
1786 if (p[0] == ']' || p[0] == '>')
1787 rbrack++, brack = p;
1788 /* detect ][ or >< */
1789 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1790 lose = 1;
1791 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1792 nm = p + 1, lose = 1;
1793 if (p[0] == ':' && (colon || slash))
1794 /* if dev1:[dir]dev2:, move nm to dev2: */
1795 if (brack)
1797 nm = brack + 1;
1798 brack = 0;
1800 /* If /name/dev:, move nm to dev: */
1801 else if (slash)
1802 nm = slash + 1;
1803 /* If node::dev:, move colon following dev */
1804 else if (colon && colon[-1] == ':')
1805 colon = p;
1806 /* If dev1:dev2:, move nm to dev2: */
1807 else if (colon && colon[-1] != ':')
1809 nm = colon + 1;
1810 colon = 0;
1812 if (p[0] == ':' && !colon)
1814 if (p[1] == ':')
1815 p++;
1816 colon = p;
1818 if (lbrack == rbrack)
1819 if (p[0] == ';')
1820 dots = 2;
1821 else if (p[0] == '.')
1822 dots++;
1823 #endif /* VMS */
1824 p++;
1826 if (!lose)
1828 #ifdef VMS
1829 if (index (nm, '/'))
1830 return build_string (sys_translate_unix (nm));
1831 #endif /* VMS */
1832 if (nm == XSTRING (name)->data)
1833 return name;
1834 return build_string (nm);
1838 /* Now determine directory to start with and put it in NEWDIR */
1840 newdir = 0;
1842 if (nm[0] == '~') /* prefix ~ */
1843 if (nm[1] == '/'
1844 #ifdef VMS
1845 || nm[1] == ':'
1846 #endif /* VMS */
1847 || nm[1] == 0)/* ~/filename */
1849 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1850 newdir = (unsigned char *) "";
1851 nm++;
1852 #ifdef VMS
1853 nm++; /* Don't leave the slash in nm. */
1854 #endif /* VMS */
1856 else /* ~user/filename */
1858 /* Get past ~ to user */
1859 unsigned char *user = nm + 1;
1860 /* Find end of name. */
1861 unsigned char *ptr = (unsigned char *) index (user, '/');
1862 int len = ptr ? ptr - user : strlen (user);
1863 #ifdef VMS
1864 unsigned char *ptr1 = index (user, ':');
1865 if (ptr1 != 0 && ptr1 - user < len)
1866 len = ptr1 - user;
1867 #endif /* VMS */
1868 /* Copy the user name into temp storage. */
1869 o = (unsigned char *) alloca (len + 1);
1870 bcopy ((char *) user, o, len);
1871 o[len] = 0;
1873 /* Look up the user name. */
1874 pw = (struct passwd *) getpwnam (o + 1);
1875 if (!pw)
1876 error ("\"%s\" isn't a registered user", o + 1);
1878 newdir = (unsigned char *) pw->pw_dir;
1880 /* Discard the user name from NM. */
1881 nm += len;
1884 if (nm[0] != '/'
1885 #ifdef VMS
1886 && !index (nm, ':')
1887 #endif /* not VMS */
1888 && !newdir)
1890 if (NILP (defalt))
1891 defalt = current_buffer->directory;
1892 CHECK_STRING (defalt);
1893 newdir = XSTRING (defalt)->data;
1896 /* Now concatenate the directory and name to new space in the stack frame */
1898 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1899 target = (unsigned char *) alloca (tlen);
1900 *target = 0;
1902 if (newdir)
1904 #ifndef VMS
1905 if (nm[0] == 0 || nm[0] == '/')
1906 strcpy (target, newdir);
1907 else
1908 #endif
1909 file_name_as_directory (target, newdir);
1912 strcat (target, nm);
1913 #ifdef VMS
1914 if (index (target, '/'))
1915 strcpy (target, sys_translate_unix (target));
1916 #endif /* VMS */
1918 /* Now canonicalize by removing /. and /foo/.. if they appear */
1920 p = target;
1921 o = target;
1923 while (*p)
1925 #ifdef VMS
1926 if (*p != ']' && *p != '>' && *p != '-')
1928 if (*p == '\\')
1929 p++;
1930 *o++ = *p++;
1932 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1933 /* brackets are offset from each other by 2 */
1935 p += 2;
1936 if (*p != '.' && *p != '-' && o[-1] != '.')
1937 /* convert [foo][bar] to [bar] */
1938 while (o[-1] != '[' && o[-1] != '<')
1939 o--;
1940 else if (*p == '-' && *o != '.')
1941 *--p = '.';
1943 else if (p[0] == '-' && o[-1] == '.' &&
1944 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1945 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1948 o--;
1949 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1950 if (p[1] == '.') /* foo.-.bar ==> bar. */
1951 p += 2;
1952 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1953 p++, o--;
1954 /* else [foo.-] ==> [-] */
1956 else
1958 #ifndef VMS4_4
1959 if (*p == '-' &&
1960 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1961 p[1] != ']' && p[1] != '>' && p[1] != '.')
1962 *p = '_';
1963 #endif /* VMS4_4 */
1964 *o++ = *p++;
1966 #else /* not VMS */
1967 if (*p != '/')
1969 *o++ = *p++;
1971 else if (!strncmp (p, "//", 2)
1972 #ifdef APOLLO
1973 /* // at start of filename is meaningful in Apollo system. */
1974 && o != target
1975 #endif /* APOLLO */
1978 o = target;
1979 p++;
1981 else if (p[0] == '/' && p[1] == '.' &&
1982 (p[2] == '/' || p[2] == 0))
1983 p += 2;
1984 else if (!strncmp (p, "/..", 3)
1985 /* `/../' is the "superroot" on certain file systems. */
1986 && o != target
1987 && (p[3] == '/' || p[3] == 0))
1989 while (o != target && *--o != '/')
1991 #ifdef APOLLO
1992 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1993 ++o;
1994 else
1995 #endif /* APOLLO */
1996 if (o == target && *o == '/')
1997 ++o;
1998 p += 3;
2000 else
2002 *o++ = *p++;
2004 #endif /* not VMS */
2007 return make_string (target, o - target);
2009 #endif
2011 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
2012 Ssubstitute_in_file_name, 1, 1, 0,
2013 doc: /* Substitute environment variables referred to in FILENAME.
2014 `$FOO' where FOO is an environment variable name means to substitute
2015 the value of that variable. The variable name should be terminated
2016 with a character not a letter, digit or underscore; otherwise, enclose
2017 the entire variable name in braces.
2018 If `/~' appears, all of FILENAME through that `/' is discarded.
2020 On VMS, `$' substitution is not done; this function does little and only
2021 duplicates what `expand-file-name' does. */)
2022 (filename)
2023 Lisp_Object filename;
2025 unsigned char *nm;
2027 register unsigned char *s, *p, *o, *x, *endp;
2028 unsigned char *target = NULL;
2029 int total = 0;
2030 int substituted = 0;
2031 unsigned char *xnm;
2032 struct passwd *pw;
2033 Lisp_Object handler;
2035 CHECK_STRING (filename);
2037 /* If the file name has special constructs in it,
2038 call the corresponding file handler. */
2039 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
2040 if (!NILP (handler))
2041 return call2 (handler, Qsubstitute_in_file_name, filename);
2043 nm = XSTRING (filename)->data;
2044 #ifdef DOS_NT
2045 nm = strcpy (alloca (strlen (nm) + 1), nm);
2046 CORRECT_DIR_SEPS (nm);
2047 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
2048 #endif
2049 endp = nm + STRING_BYTES (XSTRING (filename));
2051 /* If /~ or // appears, discard everything through first slash. */
2053 for (p = nm; p != endp; p++)
2055 if ((p[0] == '~'
2056 #if defined (APOLLO) || defined (WINDOWSNT)
2057 /* // at start of file name is meaningful in Apollo and
2058 WindowsNT systems. */
2059 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
2060 #else /* not (APOLLO || WINDOWSNT) */
2061 || IS_DIRECTORY_SEP (p[0])
2062 #endif /* not (APOLLO || WINDOWSNT) */
2064 && p != nm
2065 && (0
2066 #ifdef VMS
2067 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
2068 #endif /* VMS */
2069 || IS_DIRECTORY_SEP (p[-1])))
2071 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
2072 #ifdef VMS
2073 && *s != ':'
2074 #endif /* VMS */
2075 ); s++);
2076 if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
2078 o = (unsigned char *) alloca (s - p + 1);
2079 bcopy ((char *) p, o, s - p);
2080 o [s - p] = 0;
2082 pw = (struct passwd *) getpwnam (o + 1);
2084 /* If we have ~/ or ~user and `user' exists, discard
2085 everything up to ~. But if `user' does not exist, leave
2086 ~user alone, it might be a literal file name. */
2087 if (IS_DIRECTORY_SEP (p[0]) || s == p + 1 || pw)
2089 nm = p;
2090 substituted = 1;
2093 #ifdef DOS_NT
2094 /* see comment in expand-file-name about drive specifiers */
2095 else if (IS_DRIVE (p[0]) && p[1] == ':'
2096 && p > nm && IS_DIRECTORY_SEP (p[-1]))
2098 nm = p;
2099 substituted = 1;
2101 #endif /* DOS_NT */
2104 #ifdef VMS
2105 return build_string (nm);
2106 #else
2108 /* See if any variables are substituted into the string
2109 and find the total length of their values in `total' */
2111 for (p = nm; p != endp;)
2112 if (*p != '$')
2113 p++;
2114 else
2116 p++;
2117 if (p == endp)
2118 goto badsubst;
2119 else if (*p == '$')
2121 /* "$$" means a single "$" */
2122 p++;
2123 total -= 1;
2124 substituted = 1;
2125 continue;
2127 else if (*p == '{')
2129 o = ++p;
2130 while (p != endp && *p != '}') p++;
2131 if (*p != '}') goto missingclose;
2132 s = p;
2134 else
2136 o = p;
2137 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2138 s = p;
2141 /* Copy out the variable name */
2142 target = (unsigned char *) alloca (s - o + 1);
2143 strncpy (target, o, s - o);
2144 target[s - o] = 0;
2145 #ifdef DOS_NT
2146 strupr (target); /* $home == $HOME etc. */
2147 #endif /* DOS_NT */
2149 /* Get variable value */
2150 o = (unsigned char *) egetenv (target);
2151 if (o)
2153 total += strlen (o);
2154 substituted = 1;
2156 else if (*p == '}')
2157 goto badvar;
2160 if (!substituted)
2161 return filename;
2163 /* If substitution required, recopy the string and do it */
2164 /* Make space in stack frame for the new copy */
2165 xnm = (unsigned char *) alloca (STRING_BYTES (XSTRING (filename)) + total + 1);
2166 x = xnm;
2168 /* Copy the rest of the name through, replacing $ constructs with values */
2169 for (p = nm; *p;)
2170 if (*p != '$')
2171 *x++ = *p++;
2172 else
2174 p++;
2175 if (p == endp)
2176 goto badsubst;
2177 else if (*p == '$')
2179 *x++ = *p++;
2180 continue;
2182 else if (*p == '{')
2184 o = ++p;
2185 while (p != endp && *p != '}') p++;
2186 if (*p != '}') goto missingclose;
2187 s = p++;
2189 else
2191 o = p;
2192 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2193 s = p;
2196 /* Copy out the variable name */
2197 target = (unsigned char *) alloca (s - o + 1);
2198 strncpy (target, o, s - o);
2199 target[s - o] = 0;
2200 #ifdef DOS_NT
2201 strupr (target); /* $home == $HOME etc. */
2202 #endif /* DOS_NT */
2204 /* Get variable value */
2205 o = (unsigned char *) egetenv (target);
2206 if (!o)
2208 *x++ = '$';
2209 strcpy (x, target); x+= strlen (target);
2211 else if (STRING_MULTIBYTE (filename))
2213 /* If the original string is multibyte,
2214 convert what we substitute into multibyte. */
2215 while (*o)
2217 int c = unibyte_char_to_multibyte (*o++);
2218 x += CHAR_STRING (c, x);
2221 else
2223 strcpy (x, o);
2224 x += strlen (o);
2228 *x = 0;
2230 /* If /~ or // appears, discard everything through first slash. */
2232 for (p = xnm; p != x; p++)
2233 if ((p[0] == '~'
2234 #if defined (APOLLO) || defined (WINDOWSNT)
2235 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
2236 #else /* not (APOLLO || WINDOWSNT) */
2237 || IS_DIRECTORY_SEP (p[0])
2238 #endif /* not (APOLLO || WINDOWSNT) */
2240 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
2241 xnm = p;
2242 #ifdef DOS_NT
2243 else if (IS_DRIVE (p[0]) && p[1] == ':'
2244 && p > xnm && IS_DIRECTORY_SEP (p[-1]))
2245 xnm = p;
2246 #endif
2248 if (STRING_MULTIBYTE (filename))
2249 return make_string (xnm, x - xnm);
2250 return make_unibyte_string (xnm, x - xnm);
2252 badsubst:
2253 error ("Bad format environment-variable substitution");
2254 missingclose:
2255 error ("Missing \"}\" in environment-variable substitution");
2256 badvar:
2257 error ("Substituting nonexistent environment variable \"%s\"", target);
2259 /* NOTREACHED */
2260 #endif /* not VMS */
2261 return Qnil;
2264 /* A slightly faster and more convenient way to get
2265 (directory-file-name (expand-file-name FOO)). */
2267 Lisp_Object
2268 expand_and_dir_to_file (filename, defdir)
2269 Lisp_Object filename, defdir;
2271 register Lisp_Object absname;
2273 absname = Fexpand_file_name (filename, defdir);
2274 #ifdef VMS
2276 register int c = XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1];
2277 if (c == ':' || c == ']' || c == '>')
2278 absname = Fdirectory_file_name (absname);
2280 #else
2281 /* Remove final slash, if any (unless this is the root dir).
2282 stat behaves differently depending! */
2283 if (XSTRING (absname)->size > 1
2284 && IS_DIRECTORY_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1])
2285 && !IS_DEVICE_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname))-2]))
2286 /* We cannot take shortcuts; they might be wrong for magic file names. */
2287 absname = Fdirectory_file_name (absname);
2288 #endif
2289 return absname;
2292 /* Signal an error if the file ABSNAME already exists.
2293 If INTERACTIVE is nonzero, ask the user whether to proceed,
2294 and bypass the error if the user says to go ahead.
2295 QUERYSTRING is a name for the action that is being considered
2296 to alter the file.
2298 *STATPTR is used to store the stat information if the file exists.
2299 If the file does not exist, STATPTR->st_mode is set to 0.
2300 If STATPTR is null, we don't store into it.
2302 If QUICK is nonzero, we ask for y or n, not yes or no. */
2304 void
2305 barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
2306 Lisp_Object absname;
2307 unsigned char *querystring;
2308 int interactive;
2309 struct stat *statptr;
2310 int quick;
2312 register Lisp_Object tem, encoded_filename;
2313 struct stat statbuf;
2314 struct gcpro gcpro1;
2316 encoded_filename = ENCODE_FILE (absname);
2318 /* stat is a good way to tell whether the file exists,
2319 regardless of what access permissions it has. */
2320 if (stat (XSTRING (encoded_filename)->data, &statbuf) >= 0)
2322 if (! interactive)
2323 Fsignal (Qfile_already_exists,
2324 Fcons (build_string ("File already exists"),
2325 Fcons (absname, Qnil)));
2326 GCPRO1 (absname);
2327 tem = format1 ("File %s already exists; %s anyway? ",
2328 XSTRING (absname)->data, querystring);
2329 if (quick)
2330 tem = Fy_or_n_p (tem);
2331 else
2332 tem = do_yes_or_no_p (tem);
2333 UNGCPRO;
2334 if (NILP (tem))
2335 Fsignal (Qfile_already_exists,
2336 Fcons (build_string ("File already exists"),
2337 Fcons (absname, Qnil)));
2338 if (statptr)
2339 *statptr = statbuf;
2341 else
2343 if (statptr)
2344 statptr->st_mode = 0;
2346 return;
2349 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2350 "fCopy file: \nFCopy %s to file: \np\nP",
2351 doc: /* Copy FILE to NEWNAME. Both args must be strings.
2352 If NEWNAME names a directory, copy FILE there.
2353 Signals a `file-already-exists' error if file NEWNAME already exists,
2354 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
2355 A number as third arg means request confirmation if NEWNAME already exists.
2356 This is what happens in interactive use with M-x.
2357 Fourth arg KEEP-TIME non-nil means give the new file the same
2358 last-modified time as the old one. (This works on only some systems.)
2359 A prefix arg makes KEEP-TIME non-nil. */)
2360 (file, newname, ok_if_already_exists, keep_time)
2361 Lisp_Object file, newname, ok_if_already_exists, keep_time;
2363 int ifd, ofd, n;
2364 char buf[16 * 1024];
2365 struct stat st, out_st;
2366 Lisp_Object handler;
2367 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2368 int count = specpdl_ptr - specpdl;
2369 int input_file_statable_p;
2370 Lisp_Object encoded_file, encoded_newname;
2372 encoded_file = encoded_newname = Qnil;
2373 GCPRO4 (file, newname, encoded_file, encoded_newname);
2374 CHECK_STRING (file);
2375 CHECK_STRING (newname);
2377 if (!NILP (Ffile_directory_p (newname)))
2378 newname = Fexpand_file_name (file, newname);
2379 else
2380 newname = Fexpand_file_name (newname, Qnil);
2382 file = Fexpand_file_name (file, Qnil);
2384 /* If the input file name has special constructs in it,
2385 call the corresponding file handler. */
2386 handler = Ffind_file_name_handler (file, Qcopy_file);
2387 /* Likewise for output file name. */
2388 if (NILP (handler))
2389 handler = Ffind_file_name_handler (newname, Qcopy_file);
2390 if (!NILP (handler))
2391 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2392 ok_if_already_exists, keep_time));
2394 encoded_file = ENCODE_FILE (file);
2395 encoded_newname = ENCODE_FILE (newname);
2397 if (NILP (ok_if_already_exists)
2398 || INTEGERP (ok_if_already_exists))
2399 barf_or_query_if_file_exists (encoded_newname, "copy to it",
2400 INTEGERP (ok_if_already_exists), &out_st, 0);
2401 else if (stat (XSTRING (encoded_newname)->data, &out_st) < 0)
2402 out_st.st_mode = 0;
2404 #ifdef WINDOWSNT
2405 if (!CopyFile (XSTRING (encoded_file)->data,
2406 XSTRING (encoded_newname)->data,
2407 FALSE))
2408 report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
2409 else if (NILP (keep_time))
2411 EMACS_TIME now;
2412 EMACS_GET_TIME (now);
2413 if (set_file_times (XSTRING (encoded_newname)->data,
2414 now, now))
2415 Fsignal (Qfile_date_error,
2416 Fcons (build_string ("Cannot set file date"),
2417 Fcons (newname, Qnil)));
2419 #else /* not WINDOWSNT */
2420 ifd = emacs_open (XSTRING (encoded_file)->data, O_RDONLY, 0);
2421 if (ifd < 0)
2422 report_file_error ("Opening input file", Fcons (file, Qnil));
2424 record_unwind_protect (close_file_unwind, make_number (ifd));
2426 /* We can only copy regular files and symbolic links. Other files are not
2427 copyable by us. */
2428 input_file_statable_p = (fstat (ifd, &st) >= 0);
2430 #if !defined (DOS_NT) || __DJGPP__ > 1
2431 if (out_st.st_mode != 0
2432 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2434 errno = 0;
2435 report_file_error ("Input and output files are the same",
2436 Fcons (file, Fcons (newname, Qnil)));
2438 #endif
2440 #if defined (S_ISREG) && defined (S_ISLNK)
2441 if (input_file_statable_p)
2443 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2445 #if defined (EISDIR)
2446 /* Get a better looking error message. */
2447 errno = EISDIR;
2448 #endif /* EISDIR */
2449 report_file_error ("Non-regular file", Fcons (file, Qnil));
2452 #endif /* S_ISREG && S_ISLNK */
2454 #ifdef VMS
2455 /* Create the copy file with the same record format as the input file */
2456 ofd = sys_creat (XSTRING (encoded_newname)->data, 0666, ifd);
2457 #else
2458 #ifdef MSDOS
2459 /* System's default file type was set to binary by _fmode in emacs.c. */
2460 ofd = creat (XSTRING (encoded_newname)->data, S_IREAD | S_IWRITE);
2461 #else /* not MSDOS */
2462 ofd = creat (XSTRING (encoded_newname)->data, 0666);
2463 #endif /* not MSDOS */
2464 #endif /* VMS */
2465 if (ofd < 0)
2466 report_file_error ("Opening output file", Fcons (newname, Qnil));
2468 record_unwind_protect (close_file_unwind, make_number (ofd));
2470 immediate_quit = 1;
2471 QUIT;
2472 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2473 if (emacs_write (ofd, buf, n) != n)
2474 report_file_error ("I/O error", Fcons (newname, Qnil));
2475 immediate_quit = 0;
2477 /* Closing the output clobbers the file times on some systems. */
2478 if (emacs_close (ofd) < 0)
2479 report_file_error ("I/O error", Fcons (newname, Qnil));
2481 if (input_file_statable_p)
2483 if (!NILP (keep_time))
2485 EMACS_TIME atime, mtime;
2486 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2487 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2488 if (set_file_times (XSTRING (encoded_newname)->data,
2489 atime, mtime))
2490 Fsignal (Qfile_date_error,
2491 Fcons (build_string ("Cannot set file date"),
2492 Fcons (newname, Qnil)));
2494 #ifndef MSDOS
2495 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2496 #else /* MSDOS */
2497 #if defined (__DJGPP__) && __DJGPP__ > 1
2498 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2499 and if it can't, it tells so. Otherwise, under MSDOS we usually
2500 get only the READ bit, which will make the copied file read-only,
2501 so it's better not to chmod at all. */
2502 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2503 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2504 #endif /* DJGPP version 2 or newer */
2505 #endif /* MSDOS */
2508 emacs_close (ifd);
2509 #endif /* WINDOWSNT */
2511 /* Discard the unwind protects. */
2512 specpdl_ptr = specpdl + count;
2514 UNGCPRO;
2515 return Qnil;
2518 DEFUN ("make-directory-internal", Fmake_directory_internal,
2519 Smake_directory_internal, 1, 1, 0,
2520 doc: /* Create a new directory named DIRECTORY. */)
2521 (directory)
2522 Lisp_Object directory;
2524 unsigned char *dir;
2525 Lisp_Object handler;
2526 Lisp_Object encoded_dir;
2528 CHECK_STRING (directory);
2529 directory = Fexpand_file_name (directory, Qnil);
2531 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2532 if (!NILP (handler))
2533 return call2 (handler, Qmake_directory_internal, directory);
2535 encoded_dir = ENCODE_FILE (directory);
2537 dir = XSTRING (encoded_dir)->data;
2539 #ifdef WINDOWSNT
2540 if (mkdir (dir) != 0)
2541 #else
2542 if (mkdir (dir, 0777) != 0)
2543 #endif
2544 report_file_error ("Creating directory", Flist (1, &directory));
2546 return Qnil;
2549 DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2550 doc: /* Delete the directory named DIRECTORY. */)
2551 (directory)
2552 Lisp_Object directory;
2554 unsigned char *dir;
2555 Lisp_Object handler;
2556 Lisp_Object encoded_dir;
2558 CHECK_STRING (directory);
2559 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2561 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2562 if (!NILP (handler))
2563 return call2 (handler, Qdelete_directory, directory);
2565 encoded_dir = ENCODE_FILE (directory);
2567 dir = XSTRING (encoded_dir)->data;
2569 if (rmdir (dir) != 0)
2570 report_file_error ("Removing directory", Flist (1, &directory));
2572 return Qnil;
2575 DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2576 doc: /* Delete file named FILENAME.
2577 If file has multiple names, it continues to exist with the other names. */)
2578 (filename)
2579 Lisp_Object filename;
2581 Lisp_Object handler;
2582 Lisp_Object encoded_file;
2584 CHECK_STRING (filename);
2585 filename = Fexpand_file_name (filename, Qnil);
2587 handler = Ffind_file_name_handler (filename, Qdelete_file);
2588 if (!NILP (handler))
2589 return call2 (handler, Qdelete_file, filename);
2591 encoded_file = ENCODE_FILE (filename);
2593 if (0 > unlink (XSTRING (encoded_file)->data))
2594 report_file_error ("Removing old name", Flist (1, &filename));
2595 return Qnil;
2598 static Lisp_Object
2599 internal_delete_file_1 (ignore)
2600 Lisp_Object ignore;
2602 return Qt;
2605 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2608 internal_delete_file (filename)
2609 Lisp_Object filename;
2611 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2612 Qt, internal_delete_file_1));
2615 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2616 "fRename file: \nFRename %s to file: \np",
2617 doc: /* Rename FILE as NEWNAME. Both args strings.
2618 If file has names other than FILE, it continues to have those names.
2619 Signals a `file-already-exists' error if a file NEWNAME already exists
2620 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2621 A number as third arg means request confirmation if NEWNAME already exists.
2622 This is what happens in interactive use with M-x. */)
2623 (file, newname, ok_if_already_exists)
2624 Lisp_Object file, newname, ok_if_already_exists;
2626 #ifdef NO_ARG_ARRAY
2627 Lisp_Object args[2];
2628 #endif
2629 Lisp_Object handler;
2630 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2631 Lisp_Object encoded_file, encoded_newname;
2633 encoded_file = encoded_newname = Qnil;
2634 GCPRO4 (file, newname, encoded_file, encoded_newname);
2635 CHECK_STRING (file);
2636 CHECK_STRING (newname);
2637 file = Fexpand_file_name (file, Qnil);
2638 newname = Fexpand_file_name (newname, Qnil);
2640 /* If the file name has special constructs in it,
2641 call the corresponding file handler. */
2642 handler = Ffind_file_name_handler (file, Qrename_file);
2643 if (NILP (handler))
2644 handler = Ffind_file_name_handler (newname, Qrename_file);
2645 if (!NILP (handler))
2646 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2647 file, newname, ok_if_already_exists));
2649 encoded_file = ENCODE_FILE (file);
2650 encoded_newname = ENCODE_FILE (newname);
2652 #ifdef DOS_NT
2653 /* If the file names are identical but for the case, don't ask for
2654 confirmation: they simply want to change the letter-case of the
2655 file name. */
2656 if (NILP (Fstring_equal (Fdowncase (file), Fdowncase (newname))))
2657 #endif
2658 if (NILP (ok_if_already_exists)
2659 || INTEGERP (ok_if_already_exists))
2660 barf_or_query_if_file_exists (encoded_newname, "rename to it",
2661 INTEGERP (ok_if_already_exists), 0, 0);
2662 #ifndef BSD4_1
2663 if (0 > rename (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2664 #else
2665 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)
2666 || 0 > unlink (XSTRING (encoded_file)->data))
2667 #endif
2669 if (errno == EXDEV)
2671 Fcopy_file (file, newname,
2672 /* We have already prompted if it was an integer,
2673 so don't have copy-file prompt again. */
2674 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2675 Fdelete_file (file);
2677 else
2678 #ifdef NO_ARG_ARRAY
2680 args[0] = file;
2681 args[1] = newname;
2682 report_file_error ("Renaming", Flist (2, args));
2684 #else
2685 report_file_error ("Renaming", Flist (2, &file));
2686 #endif
2688 UNGCPRO;
2689 return Qnil;
2692 DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2693 "fAdd name to file: \nFName to add to %s: \np",
2694 doc: /* Give FILE additional name NEWNAME. Both args strings.
2695 Signals a `file-already-exists' error if a file NEWNAME already exists
2696 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2697 A number as third arg means request confirmation if NEWNAME already exists.
2698 This is what happens in interactive use with M-x. */)
2699 (file, newname, ok_if_already_exists)
2700 Lisp_Object file, newname, ok_if_already_exists;
2702 #ifdef NO_ARG_ARRAY
2703 Lisp_Object args[2];
2704 #endif
2705 Lisp_Object handler;
2706 Lisp_Object encoded_file, encoded_newname;
2707 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2709 GCPRO4 (file, newname, encoded_file, encoded_newname);
2710 encoded_file = encoded_newname = Qnil;
2711 CHECK_STRING (file);
2712 CHECK_STRING (newname);
2713 file = Fexpand_file_name (file, Qnil);
2714 newname = Fexpand_file_name (newname, Qnil);
2716 /* If the file name has special constructs in it,
2717 call the corresponding file handler. */
2718 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2719 if (!NILP (handler))
2720 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2721 newname, ok_if_already_exists));
2723 /* If the new name has special constructs in it,
2724 call the corresponding file handler. */
2725 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2726 if (!NILP (handler))
2727 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2728 newname, ok_if_already_exists));
2730 encoded_file = ENCODE_FILE (file);
2731 encoded_newname = ENCODE_FILE (newname);
2733 if (NILP (ok_if_already_exists)
2734 || INTEGERP (ok_if_already_exists))
2735 barf_or_query_if_file_exists (encoded_newname, "make it a new name",
2736 INTEGERP (ok_if_already_exists), 0, 0);
2738 unlink (XSTRING (newname)->data);
2739 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2741 #ifdef NO_ARG_ARRAY
2742 args[0] = file;
2743 args[1] = newname;
2744 report_file_error ("Adding new name", Flist (2, args));
2745 #else
2746 report_file_error ("Adding new name", Flist (2, &file));
2747 #endif
2750 UNGCPRO;
2751 return Qnil;
2754 #ifdef S_IFLNK
2755 DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2756 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2757 doc: /* Make a symbolic link to FILENAME, named LINKNAME. Both args strings.
2758 Signals a `file-already-exists' error if a file LINKNAME already exists
2759 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2760 A number as third arg means request confirmation if LINKNAME already exists.
2761 This happens for interactive use with M-x. */)
2762 (filename, linkname, ok_if_already_exists)
2763 Lisp_Object filename, linkname, ok_if_already_exists;
2765 #ifdef NO_ARG_ARRAY
2766 Lisp_Object args[2];
2767 #endif
2768 Lisp_Object handler;
2769 Lisp_Object encoded_filename, encoded_linkname;
2770 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2772 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2773 encoded_filename = encoded_linkname = Qnil;
2774 CHECK_STRING (filename);
2775 CHECK_STRING (linkname);
2776 /* If the link target has a ~, we must expand it to get
2777 a truly valid file name. Otherwise, do not expand;
2778 we want to permit links to relative file names. */
2779 if (XSTRING (filename)->data[0] == '~')
2780 filename = Fexpand_file_name (filename, Qnil);
2781 linkname = Fexpand_file_name (linkname, Qnil);
2783 /* If the file name has special constructs in it,
2784 call the corresponding file handler. */
2785 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2786 if (!NILP (handler))
2787 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2788 linkname, ok_if_already_exists));
2790 /* If the new link name has special constructs in it,
2791 call the corresponding file handler. */
2792 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2793 if (!NILP (handler))
2794 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2795 linkname, ok_if_already_exists));
2797 encoded_filename = ENCODE_FILE (filename);
2798 encoded_linkname = ENCODE_FILE (linkname);
2800 if (NILP (ok_if_already_exists)
2801 || INTEGERP (ok_if_already_exists))
2802 barf_or_query_if_file_exists (encoded_linkname, "make it a link",
2803 INTEGERP (ok_if_already_exists), 0, 0);
2804 if (0 > symlink (XSTRING (encoded_filename)->data,
2805 XSTRING (encoded_linkname)->data))
2807 /* If we didn't complain already, silently delete existing file. */
2808 if (errno == EEXIST)
2810 unlink (XSTRING (encoded_linkname)->data);
2811 if (0 <= symlink (XSTRING (encoded_filename)->data,
2812 XSTRING (encoded_linkname)->data))
2814 UNGCPRO;
2815 return Qnil;
2819 #ifdef NO_ARG_ARRAY
2820 args[0] = filename;
2821 args[1] = linkname;
2822 report_file_error ("Making symbolic link", Flist (2, args));
2823 #else
2824 report_file_error ("Making symbolic link", Flist (2, &filename));
2825 #endif
2827 UNGCPRO;
2828 return Qnil;
2830 #endif /* S_IFLNK */
2832 #ifdef VMS
2834 DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2835 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2836 doc: /* Define the job-wide logical name NAME to have the value STRING.
2837 If STRING is nil or a null string, the logical name NAME is deleted. */)
2838 (name, string)
2839 Lisp_Object name;
2840 Lisp_Object string;
2842 CHECK_STRING (name);
2843 if (NILP (string))
2844 delete_logical_name (XSTRING (name)->data);
2845 else
2847 CHECK_STRING (string);
2849 if (XSTRING (string)->size == 0)
2850 delete_logical_name (XSTRING (name)->data);
2851 else
2852 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2855 return string;
2857 #endif /* VMS */
2859 #ifdef HPUX_NET
2861 DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2862 doc: /* Open a network connection to PATH using LOGIN as the login string. */)
2863 (path, login)
2864 Lisp_Object path, login;
2866 int netresult;
2868 CHECK_STRING (path);
2869 CHECK_STRING (login);
2871 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2873 if (netresult == -1)
2874 return Qnil;
2875 else
2876 return Qt;
2878 #endif /* HPUX_NET */
2880 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2881 1, 1, 0,
2882 doc: /* Return t if file FILENAME specifies an absolute file name.
2883 On Unix, this is a name starting with a `/' or a `~'. */)
2884 (filename)
2885 Lisp_Object filename;
2887 unsigned char *ptr;
2889 CHECK_STRING (filename);
2890 ptr = XSTRING (filename)->data;
2891 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2892 #ifdef VMS
2893 /* ??? This criterion is probably wrong for '<'. */
2894 || index (ptr, ':') || index (ptr, '<')
2895 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2896 && ptr[1] != '.')
2897 #endif /* VMS */
2898 #ifdef DOS_NT
2899 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2900 #endif
2902 return Qt;
2903 else
2904 return Qnil;
2907 /* Return nonzero if file FILENAME exists and can be executed. */
2909 static int
2910 check_executable (filename)
2911 char *filename;
2913 #ifdef DOS_NT
2914 int len = strlen (filename);
2915 char *suffix;
2916 struct stat st;
2917 if (stat (filename, &st) < 0)
2918 return 0;
2919 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2920 return ((st.st_mode & S_IEXEC) != 0);
2921 #else
2922 return (S_ISREG (st.st_mode)
2923 && len >= 5
2924 && (stricmp ((suffix = filename + len-4), ".com") == 0
2925 || stricmp (suffix, ".exe") == 0
2926 || stricmp (suffix, ".bat") == 0)
2927 || (st.st_mode & S_IFMT) == S_IFDIR);
2928 #endif /* not WINDOWSNT */
2929 #else /* not DOS_NT */
2930 #ifdef HAVE_EUIDACCESS
2931 return (euidaccess (filename, 1) >= 0);
2932 #else
2933 /* Access isn't quite right because it uses the real uid
2934 and we really want to test with the effective uid.
2935 But Unix doesn't give us a right way to do it. */
2936 return (access (filename, 1) >= 0);
2937 #endif
2938 #endif /* not DOS_NT */
2941 /* Return nonzero if file FILENAME exists and can be written. */
2943 static int
2944 check_writable (filename)
2945 char *filename;
2947 #ifdef MSDOS
2948 struct stat st;
2949 if (stat (filename, &st) < 0)
2950 return 0;
2951 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2952 #else /* not MSDOS */
2953 #ifdef HAVE_EUIDACCESS
2954 return (euidaccess (filename, 2) >= 0);
2955 #else
2956 /* Access isn't quite right because it uses the real uid
2957 and we really want to test with the effective uid.
2958 But Unix doesn't give us a right way to do it.
2959 Opening with O_WRONLY could work for an ordinary file,
2960 but would lose for directories. */
2961 return (access (filename, 2) >= 0);
2962 #endif
2963 #endif /* not MSDOS */
2966 DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2967 doc: /* Return t if file FILENAME exists. (This does not mean you can read it.)
2968 See also `file-readable-p' and `file-attributes'. */)
2969 (filename)
2970 Lisp_Object filename;
2972 Lisp_Object absname;
2973 Lisp_Object handler;
2974 struct stat statbuf;
2976 CHECK_STRING (filename);
2977 absname = Fexpand_file_name (filename, Qnil);
2979 /* If the file name has special constructs in it,
2980 call the corresponding file handler. */
2981 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2982 if (!NILP (handler))
2983 return call2 (handler, Qfile_exists_p, absname);
2985 absname = ENCODE_FILE (absname);
2987 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2990 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2991 doc: /* Return t if FILENAME can be executed by you.
2992 For a directory, this means you can access files in that directory. */)
2993 (filename)
2994 Lisp_Object filename;
2996 Lisp_Object absname;
2997 Lisp_Object handler;
2999 CHECK_STRING (filename);
3000 absname = Fexpand_file_name (filename, Qnil);
3002 /* If the file name has special constructs in it,
3003 call the corresponding file handler. */
3004 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
3005 if (!NILP (handler))
3006 return call2 (handler, Qfile_executable_p, absname);
3008 absname = ENCODE_FILE (absname);
3010 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
3013 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
3014 doc: /* Return t if file FILENAME exists and you can read it.
3015 See also `file-exists-p' and `file-attributes'. */)
3016 (filename)
3017 Lisp_Object filename;
3019 Lisp_Object absname;
3020 Lisp_Object handler;
3021 int desc;
3022 int flags;
3023 struct stat statbuf;
3025 CHECK_STRING (filename);
3026 absname = Fexpand_file_name (filename, Qnil);
3028 /* If the file name has special constructs in it,
3029 call the corresponding file handler. */
3030 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
3031 if (!NILP (handler))
3032 return call2 (handler, Qfile_readable_p, absname);
3034 absname = ENCODE_FILE (absname);
3036 #if defined(DOS_NT) || defined(macintosh)
3037 /* Under MS-DOS, Windows, and Macintosh, open does not work for
3038 directories. */
3039 if (access (XSTRING (absname)->data, 0) == 0)
3040 return Qt;
3041 return Qnil;
3042 #else /* not DOS_NT and not macintosh */
3043 flags = O_RDONLY;
3044 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
3045 /* Opening a fifo without O_NONBLOCK can wait.
3046 We don't want to wait. But we don't want to mess wth O_NONBLOCK
3047 except in the case of a fifo, on a system which handles it. */
3048 desc = stat (XSTRING (absname)->data, &statbuf);
3049 if (desc < 0)
3050 return Qnil;
3051 if (S_ISFIFO (statbuf.st_mode))
3052 flags |= O_NONBLOCK;
3053 #endif
3054 desc = emacs_open (XSTRING (absname)->data, flags, 0);
3055 if (desc < 0)
3056 return Qnil;
3057 emacs_close (desc);
3058 return Qt;
3059 #endif /* not DOS_NT and not macintosh */
3062 /* Having this before file-symlink-p mysteriously caused it to be forgotten
3063 on the RT/PC. */
3064 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
3065 doc: /* Return t if file FILENAME can be written or created by you. */)
3066 (filename)
3067 Lisp_Object filename;
3069 Lisp_Object absname, dir, encoded;
3070 Lisp_Object handler;
3071 struct stat statbuf;
3073 CHECK_STRING (filename);
3074 absname = Fexpand_file_name (filename, Qnil);
3076 /* If the file name has special constructs in it,
3077 call the corresponding file handler. */
3078 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
3079 if (!NILP (handler))
3080 return call2 (handler, Qfile_writable_p, absname);
3082 encoded = ENCODE_FILE (absname);
3083 if (stat (XSTRING (encoded)->data, &statbuf) >= 0)
3084 return (check_writable (XSTRING (encoded)->data)
3085 ? Qt : Qnil);
3087 dir = Ffile_name_directory (absname);
3088 #ifdef VMS
3089 if (!NILP (dir))
3090 dir = Fdirectory_file_name (dir);
3091 #endif /* VMS */
3092 #ifdef MSDOS
3093 if (!NILP (dir))
3094 dir = Fdirectory_file_name (dir);
3095 #endif /* MSDOS */
3097 dir = ENCODE_FILE (dir);
3098 #ifdef WINDOWSNT
3099 /* The read-only attribute of the parent directory doesn't affect
3100 whether a file or directory can be created within it. Some day we
3101 should check ACLs though, which do affect this. */
3102 if (stat (XSTRING (dir)->data, &statbuf) < 0)
3103 return Qnil;
3104 return (statbuf.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3105 #else
3106 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
3107 ? Qt : Qnil);
3108 #endif
3111 DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
3112 doc: /* Access file FILENAME, and get an error if that does not work.
3113 The second argument STRING is used in the error message.
3114 If there is no error, we return nil. */)
3115 (filename, string)
3116 Lisp_Object filename, string;
3118 Lisp_Object handler, encoded_filename, absname;
3119 int fd;
3121 CHECK_STRING (filename);
3122 absname = Fexpand_file_name (filename, Qnil);
3124 CHECK_STRING (string);
3126 /* If the file name has special constructs in it,
3127 call the corresponding file handler. */
3128 handler = Ffind_file_name_handler (absname, Qaccess_file);
3129 if (!NILP (handler))
3130 return call3 (handler, Qaccess_file, absname, string);
3132 encoded_filename = ENCODE_FILE (absname);
3134 fd = emacs_open (XSTRING (encoded_filename)->data, O_RDONLY, 0);
3135 if (fd < 0)
3136 report_file_error (XSTRING (string)->data, Fcons (filename, Qnil));
3137 emacs_close (fd);
3139 return Qnil;
3142 DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
3143 doc: /* Return non-nil if file FILENAME is the name of a symbolic link.
3144 The value is the name of the file to which it is linked.
3145 Otherwise returns nil. */)
3146 (filename)
3147 Lisp_Object filename;
3149 #ifdef S_IFLNK
3150 char *buf;
3151 int bufsize;
3152 int valsize;
3153 Lisp_Object val;
3154 Lisp_Object handler;
3156 CHECK_STRING (filename);
3157 filename = Fexpand_file_name (filename, Qnil);
3159 /* If the file name has special constructs in it,
3160 call the corresponding file handler. */
3161 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
3162 if (!NILP (handler))
3163 return call2 (handler, Qfile_symlink_p, filename);
3165 filename = ENCODE_FILE (filename);
3167 bufsize = 50;
3168 buf = NULL;
3171 bufsize *= 2;
3172 buf = (char *) xrealloc (buf, bufsize);
3173 bzero (buf, bufsize);
3175 errno = 0;
3176 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
3177 if (valsize == -1)
3179 #ifdef ERANGE
3180 /* HP-UX reports ERANGE if buffer is too small. */
3181 if (errno == ERANGE)
3182 valsize = bufsize;
3183 else
3184 #endif
3186 xfree (buf);
3187 return Qnil;
3191 while (valsize >= bufsize);
3193 val = make_string (buf, valsize);
3194 if (buf[0] == '/' && index (buf, ':'))
3195 val = concat2 (build_string ("/:"), val);
3196 xfree (buf);
3197 val = DECODE_FILE (val);
3198 return val;
3199 #else /* not S_IFLNK */
3200 return Qnil;
3201 #endif /* not S_IFLNK */
3204 DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
3205 doc: /* Return t if FILENAME names an existing directory.
3206 Symbolic links to directories count as directories.
3207 See `file-symlink-p' to distinguish symlinks. */)
3208 (filename)
3209 Lisp_Object filename;
3211 register Lisp_Object absname;
3212 struct stat st;
3213 Lisp_Object handler;
3215 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3217 /* If the file name has special constructs in it,
3218 call the corresponding file handler. */
3219 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
3220 if (!NILP (handler))
3221 return call2 (handler, Qfile_directory_p, absname);
3223 absname = ENCODE_FILE (absname);
3225 if (stat (XSTRING (absname)->data, &st) < 0)
3226 return Qnil;
3227 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3230 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
3231 doc: /* Return t if file FILENAME names a directory you can open.
3232 For the value to be t, FILENAME must specify the name of a directory as a file,
3233 and the directory must allow you to open files in it. In order to use a
3234 directory as a buffer's current directory, this predicate must return true.
3235 A directory name spec may be given instead; then the value is t
3236 if the directory so specified exists and really is a readable and
3237 searchable directory. */)
3238 (filename)
3239 Lisp_Object filename;
3241 Lisp_Object handler;
3242 int tem;
3243 struct gcpro gcpro1;
3245 /* If the file name has special constructs in it,
3246 call the corresponding file handler. */
3247 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
3248 if (!NILP (handler))
3249 return call2 (handler, Qfile_accessible_directory_p, filename);
3251 /* It's an unlikely combination, but yes we really do need to gcpro:
3252 Suppose that file-accessible-directory-p has no handler, but
3253 file-directory-p does have a handler; this handler causes a GC which
3254 relocates the string in `filename'; and finally file-directory-p
3255 returns non-nil. Then we would end up passing a garbaged string
3256 to file-executable-p. */
3257 GCPRO1 (filename);
3258 tem = (NILP (Ffile_directory_p (filename))
3259 || NILP (Ffile_executable_p (filename)));
3260 UNGCPRO;
3261 return tem ? Qnil : Qt;
3264 DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
3265 doc: /* Return t if file FILENAME is the name of a regular file.
3266 This is the sort of file that holds an ordinary stream of data bytes. */)
3267 (filename)
3268 Lisp_Object filename;
3270 register Lisp_Object absname;
3271 struct stat st;
3272 Lisp_Object handler;
3274 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3276 /* If the file name has special constructs in it,
3277 call the corresponding file handler. */
3278 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
3279 if (!NILP (handler))
3280 return call2 (handler, Qfile_regular_p, absname);
3282 absname = ENCODE_FILE (absname);
3284 #ifdef WINDOWSNT
3286 int result;
3287 Lisp_Object tem = Vw32_get_true_file_attributes;
3289 /* Tell stat to use expensive method to get accurate info. */
3290 Vw32_get_true_file_attributes = Qt;
3291 result = stat (XSTRING (absname)->data, &st);
3292 Vw32_get_true_file_attributes = tem;
3294 if (result < 0)
3295 return Qnil;
3296 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3298 #else
3299 if (stat (XSTRING (absname)->data, &st) < 0)
3300 return Qnil;
3301 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3302 #endif
3305 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
3306 doc: /* Return mode bits of file named FILENAME, as an integer. */)
3307 (filename)
3308 Lisp_Object filename;
3310 Lisp_Object absname;
3311 struct stat st;
3312 Lisp_Object handler;
3314 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3316 /* If the file name has special constructs in it,
3317 call the corresponding file handler. */
3318 handler = Ffind_file_name_handler (absname, Qfile_modes);
3319 if (!NILP (handler))
3320 return call2 (handler, Qfile_modes, absname);
3322 absname = ENCODE_FILE (absname);
3324 if (stat (XSTRING (absname)->data, &st) < 0)
3325 return Qnil;
3326 #if defined (MSDOS) && __DJGPP__ < 2
3327 if (check_executable (XSTRING (absname)->data))
3328 st.st_mode |= S_IEXEC;
3329 #endif /* MSDOS && __DJGPP__ < 2 */
3331 return make_number (st.st_mode & 07777);
3334 DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
3335 doc: /* Set mode bits of file named FILENAME to MODE (an integer).
3336 Only the 12 low bits of MODE are used. */)
3337 (filename, mode)
3338 Lisp_Object filename, mode;
3340 Lisp_Object absname, encoded_absname;
3341 Lisp_Object handler;
3343 absname = Fexpand_file_name (filename, current_buffer->directory);
3344 CHECK_NUMBER (mode);
3346 /* If the file name has special constructs in it,
3347 call the corresponding file handler. */
3348 handler = Ffind_file_name_handler (absname, Qset_file_modes);
3349 if (!NILP (handler))
3350 return call3 (handler, Qset_file_modes, absname, mode);
3352 encoded_absname = ENCODE_FILE (absname);
3354 if (chmod (XSTRING (encoded_absname)->data, XINT (mode)) < 0)
3355 report_file_error ("Doing chmod", Fcons (absname, Qnil));
3357 return Qnil;
3360 DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
3361 doc: /* Set the file permission bits for newly created files.
3362 The argument MODE should be an integer; only the low 9 bits are used.
3363 This setting is inherited by subprocesses. */)
3364 (mode)
3365 Lisp_Object mode;
3367 CHECK_NUMBER (mode);
3369 umask ((~ XINT (mode)) & 0777);
3371 return Qnil;
3374 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
3375 doc: /* Return the default file protection for created files.
3376 The value is an integer. */)
3379 int realmask;
3380 Lisp_Object value;
3382 realmask = umask (0);
3383 umask (realmask);
3385 XSETINT (value, (~ realmask) & 0777);
3386 return value;
3390 #ifdef __NetBSD__
3391 #define unix 42
3392 #endif
3394 #ifdef unix
3395 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
3396 doc: /* Tell Unix to finish all pending disk updates. */)
3399 sync ();
3400 return Qnil;
3403 #endif /* unix */
3405 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
3406 doc: /* Return t if file FILE1 is newer than file FILE2.
3407 If FILE1 does not exist, the answer is nil;
3408 otherwise, if FILE2 does not exist, the answer is t. */)
3409 (file1, file2)
3410 Lisp_Object file1, file2;
3412 Lisp_Object absname1, absname2;
3413 struct stat st;
3414 int mtime1;
3415 Lisp_Object handler;
3416 struct gcpro gcpro1, gcpro2;
3418 CHECK_STRING (file1);
3419 CHECK_STRING (file2);
3421 absname1 = Qnil;
3422 GCPRO2 (absname1, file2);
3423 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3424 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
3425 UNGCPRO;
3427 /* If the file name has special constructs in it,
3428 call the corresponding file handler. */
3429 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
3430 if (NILP (handler))
3431 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
3432 if (!NILP (handler))
3433 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
3435 GCPRO2 (absname1, absname2);
3436 absname1 = ENCODE_FILE (absname1);
3437 absname2 = ENCODE_FILE (absname2);
3438 UNGCPRO;
3440 if (stat (XSTRING (absname1)->data, &st) < 0)
3441 return Qnil;
3443 mtime1 = st.st_mtime;
3445 if (stat (XSTRING (absname2)->data, &st) < 0)
3446 return Qt;
3448 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3451 #ifdef DOS_NT
3452 Lisp_Object Qfind_buffer_file_type;
3453 #endif /* DOS_NT */
3455 #ifndef READ_BUF_SIZE
3456 #define READ_BUF_SIZE (64 << 10)
3457 #endif
3459 extern void adjust_markers_for_delete P_ ((int, int, int, int));
3461 /* This function is called after Lisp functions to decide a coding
3462 system are called, or when they cause an error. Before they are
3463 called, the current buffer is set unibyte and it contains only a
3464 newly inserted text (thus the buffer was empty before the
3465 insertion).
3467 The functions may set markers, overlays, text properties, or even
3468 alter the buffer contents, change the current buffer.
3470 Here, we reset all those changes by:
3471 o set back the current buffer.
3472 o move all markers and overlays to BEG.
3473 o remove all text properties.
3474 o set back the buffer multibyteness. */
3476 static Lisp_Object
3477 decide_coding_unwind (unwind_data)
3478 Lisp_Object unwind_data;
3480 Lisp_Object multibyte, undo_list, buffer;
3482 multibyte = XCAR (unwind_data);
3483 unwind_data = XCDR (unwind_data);
3484 undo_list = XCAR (unwind_data);
3485 buffer = XCDR (unwind_data);
3487 if (current_buffer != XBUFFER (buffer))
3488 set_buffer_internal (XBUFFER (buffer));
3489 adjust_markers_for_delete (BEG, BEG_BYTE, Z, Z_BYTE);
3490 adjust_overlays_for_delete (BEG, Z - BEG);
3491 BUF_INTERVALS (current_buffer) = 0;
3492 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3494 /* Now we are safe to change the buffer's multibyteness directly. */
3495 current_buffer->enable_multibyte_characters = multibyte;
3496 current_buffer->undo_list = undo_list;
3498 return Qnil;
3502 /* Used to pass values from insert-file-contents to read_non_regular. */
3504 static int non_regular_fd;
3505 static int non_regular_inserted;
3506 static int non_regular_nbytes;
3509 /* Read from a non-regular file.
3510 Read non_regular_trytry bytes max from non_regular_fd.
3511 Non_regular_inserted specifies where to put the read bytes.
3512 Value is the number of bytes read. */
3514 static Lisp_Object
3515 read_non_regular ()
3517 int nbytes;
3519 immediate_quit = 1;
3520 QUIT;
3521 nbytes = emacs_read (non_regular_fd,
3522 BEG_ADDR + PT_BYTE - 1 + non_regular_inserted,
3523 non_regular_nbytes);
3524 immediate_quit = 0;
3525 return make_number (nbytes);
3529 /* Condition-case handler used when reading from non-regular files
3530 in insert-file-contents. */
3532 static Lisp_Object
3533 read_non_regular_quit ()
3535 return Qnil;
3539 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3540 1, 5, 0,
3541 doc: /* Insert contents of file FILENAME after point.
3542 Returns list of absolute file name and number of bytes inserted.
3543 If second argument VISIT is non-nil, the buffer's visited filename
3544 and last save file modtime are set, and it is marked unmodified.
3545 If visiting and the file does not exist, visiting is completed
3546 before the error is signaled.
3547 The optional third and fourth arguments BEG and END
3548 specify what portion of the file to insert.
3549 These arguments count bytes in the file, not characters in the buffer.
3550 If VISIT is non-nil, BEG and END must be nil.
3552 If optional fifth argument REPLACE is non-nil,
3553 it means replace the current buffer contents (in the accessible portion)
3554 with the file contents. This is better than simply deleting and inserting
3555 the whole thing because (1) it preserves some marker positions
3556 and (2) it puts less data in the undo list.
3557 When REPLACE is non-nil, the value is the number of characters actually read,
3558 which is often less than the number of characters to be read.
3560 This does code conversion according to the value of
3561 `coding-system-for-read' or `file-coding-system-alist',
3562 and sets the variable `last-coding-system-used' to the coding system
3563 actually used. */)
3564 (filename, visit, beg, end, replace)
3565 Lisp_Object filename, visit, beg, end, replace;
3567 struct stat st;
3568 register int fd;
3569 int inserted = 0;
3570 register int how_much;
3571 register int unprocessed;
3572 int count = BINDING_STACK_SIZE ();
3573 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3574 Lisp_Object handler, val, insval, orig_filename;
3575 Lisp_Object p;
3576 int total = 0;
3577 int not_regular = 0;
3578 unsigned char read_buf[READ_BUF_SIZE];
3579 struct coding_system coding;
3580 unsigned char buffer[1 << 14];
3581 int replace_handled = 0;
3582 int set_coding_system = 0;
3583 int coding_system_decided = 0;
3584 int read_quit = 0;
3586 if (current_buffer->base_buffer && ! NILP (visit))
3587 error ("Cannot do file visiting in an indirect buffer");
3589 if (!NILP (current_buffer->read_only))
3590 Fbarf_if_buffer_read_only ();
3592 val = Qnil;
3593 p = Qnil;
3594 orig_filename = Qnil;
3596 GCPRO4 (filename, val, p, orig_filename);
3598 CHECK_STRING (filename);
3599 filename = Fexpand_file_name (filename, Qnil);
3601 /* If the file name has special constructs in it,
3602 call the corresponding file handler. */
3603 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3604 if (!NILP (handler))
3606 val = call6 (handler, Qinsert_file_contents, filename,
3607 visit, beg, end, replace);
3608 if (CONSP (val) && CONSP (XCDR (val)))
3609 inserted = XINT (XCAR (XCDR (val)));
3610 goto handled;
3613 orig_filename = filename;
3614 filename = ENCODE_FILE (filename);
3616 fd = -1;
3618 #ifdef WINDOWSNT
3620 Lisp_Object tem = Vw32_get_true_file_attributes;
3622 /* Tell stat to use expensive method to get accurate info. */
3623 Vw32_get_true_file_attributes = Qt;
3624 total = stat (XSTRING (filename)->data, &st);
3625 Vw32_get_true_file_attributes = tem;
3627 if (total < 0)
3628 #else
3629 #ifndef APOLLO
3630 if (stat (XSTRING (filename)->data, &st) < 0)
3631 #else
3632 if ((fd = emacs_open (XSTRING (filename)->data, O_RDONLY, 0)) < 0
3633 || fstat (fd, &st) < 0)
3634 #endif /* not APOLLO */
3635 #endif /* WINDOWSNT */
3637 if (fd >= 0) emacs_close (fd);
3638 badopen:
3639 if (NILP (visit))
3640 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3641 st.st_mtime = -1;
3642 how_much = 0;
3643 if (!NILP (Vcoding_system_for_read))
3644 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
3645 goto notfound;
3648 #ifdef S_IFREG
3649 /* This code will need to be changed in order to work on named
3650 pipes, and it's probably just not worth it. So we should at
3651 least signal an error. */
3652 if (!S_ISREG (st.st_mode))
3654 not_regular = 1;
3656 if (! NILP (visit))
3657 goto notfound;
3659 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
3660 Fsignal (Qfile_error,
3661 Fcons (build_string ("not a regular file"),
3662 Fcons (orig_filename, Qnil)));
3664 #endif
3666 if (fd < 0)
3667 if ((fd = emacs_open (XSTRING (filename)->data, O_RDONLY, 0)) < 0)
3668 goto badopen;
3670 /* Replacement should preserve point as it preserves markers. */
3671 if (!NILP (replace))
3672 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3674 record_unwind_protect (close_file_unwind, make_number (fd));
3676 /* Supposedly happens on VMS. */
3677 if (! not_regular && st.st_size < 0)
3678 error ("File size is negative");
3680 /* Prevent redisplay optimizations. */
3681 current_buffer->clip_changed = 1;
3683 if (!NILP (visit))
3685 if (!NILP (beg) || !NILP (end))
3686 error ("Attempt to visit less than an entire file");
3687 if (BEG < Z && NILP (replace))
3688 error ("Cannot do file visiting in a non-empty buffer");
3691 if (!NILP (beg))
3692 CHECK_NUMBER (beg);
3693 else
3694 XSETFASTINT (beg, 0);
3696 if (!NILP (end))
3697 CHECK_NUMBER (end);
3698 else
3700 if (! not_regular)
3702 XSETINT (end, st.st_size);
3704 /* Arithmetic overflow can occur if an Emacs integer cannot
3705 represent the file size, or if the calculations below
3706 overflow. The calculations below double the file size
3707 twice, so check that it can be multiplied by 4 safely. */
3708 if (XINT (end) != st.st_size
3709 || ((int) st.st_size * 4) / 4 != st.st_size)
3710 error ("Maximum buffer size exceeded");
3712 /* The file size returned from stat may be zero, but data
3713 may be readable nonetheless, for example when this is a
3714 file in the /proc filesystem. */
3715 if (st.st_size == 0)
3716 XSETINT (end, READ_BUF_SIZE);
3720 if (BEG < Z)
3722 /* Decide the coding system to use for reading the file now
3723 because we can't use an optimized method for handling
3724 `coding:' tag if the current buffer is not empty. */
3725 Lisp_Object val;
3726 val = Qnil;
3728 if (!NILP (Vcoding_system_for_read))
3729 val = Vcoding_system_for_read;
3730 else if (! NILP (replace))
3731 /* In REPLACE mode, we can use the same coding system
3732 that was used to visit the file. */
3733 val = current_buffer->buffer_file_coding_system;
3734 else
3736 /* Don't try looking inside a file for a coding system
3737 specification if it is not seekable. */
3738 if (! not_regular && ! NILP (Vset_auto_coding_function))
3740 /* Find a coding system specified in the heading two
3741 lines or in the tailing several lines of the file.
3742 We assume that the 1K-byte and 3K-byte for heading
3743 and tailing respectively are sufficient for this
3744 purpose. */
3745 int nread;
3747 if (st.st_size <= (1024 * 4))
3748 nread = emacs_read (fd, read_buf, 1024 * 4);
3749 else
3751 nread = emacs_read (fd, read_buf, 1024);
3752 if (nread >= 0)
3754 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3755 report_file_error ("Setting file position",
3756 Fcons (orig_filename, Qnil));
3757 nread += emacs_read (fd, read_buf + nread, 1024 * 3);
3761 if (nread < 0)
3762 error ("IO error reading %s: %s",
3763 XSTRING (orig_filename)->data, emacs_strerror (errno));
3764 else if (nread > 0)
3766 struct buffer *prev = current_buffer;
3767 int count1;
3769 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
3771 /* The call to temp_output_buffer_setup binds
3772 standard-output. */
3773 count1 = specpdl_ptr - specpdl;
3774 temp_output_buffer_setup (" *code-converting-work*");
3776 set_buffer_internal (XBUFFER (Vstandard_output));
3777 current_buffer->enable_multibyte_characters = Qnil;
3778 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3779 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3780 val = call2 (Vset_auto_coding_function,
3781 filename, make_number (nread));
3782 set_buffer_internal (prev);
3784 /* Remove the binding for standard-output. */
3785 unbind_to (count1, Qnil);
3787 /* Discard the unwind protect for recovering the
3788 current buffer. */
3789 specpdl_ptr--;
3791 /* Rewind the file for the actual read done later. */
3792 if (lseek (fd, 0, 0) < 0)
3793 report_file_error ("Setting file position",
3794 Fcons (orig_filename, Qnil));
3798 if (NILP (val))
3800 /* If we have not yet decided a coding system, check
3801 file-coding-system-alist. */
3802 Lisp_Object args[6], coding_systems;
3804 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3805 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3806 coding_systems = Ffind_operation_coding_system (6, args);
3807 if (CONSP (coding_systems))
3808 val = XCAR (coding_systems);
3812 setup_coding_system (Fcheck_coding_system (val), &coding);
3813 /* Ensure we set Vlast_coding_system_used. */
3814 set_coding_system = 1;
3816 if (NILP (current_buffer->enable_multibyte_characters)
3817 && ! NILP (val))
3818 /* We must suppress all character code conversion except for
3819 end-of-line conversion. */
3820 setup_raw_text_coding_system (&coding);
3822 coding.src_multibyte = 0;
3823 coding.dst_multibyte
3824 = !NILP (current_buffer->enable_multibyte_characters);
3825 coding_system_decided = 1;
3828 /* If requested, replace the accessible part of the buffer
3829 with the file contents. Avoid replacing text at the
3830 beginning or end of the buffer that matches the file contents;
3831 that preserves markers pointing to the unchanged parts.
3833 Here we implement this feature in an optimized way
3834 for the case where code conversion is NOT needed.
3835 The following if-statement handles the case of conversion
3836 in a less optimal way.
3838 If the code conversion is "automatic" then we try using this
3839 method and hope for the best.
3840 But if we discover the need for conversion, we give up on this method
3841 and let the following if-statement handle the replace job. */
3842 if (!NILP (replace)
3843 && BEGV < ZV
3844 && !(coding.common_flags & CODING_REQUIRE_DECODING_MASK))
3846 /* same_at_start and same_at_end count bytes,
3847 because file access counts bytes
3848 and BEG and END count bytes. */
3849 int same_at_start = BEGV_BYTE;
3850 int same_at_end = ZV_BYTE;
3851 int overlap;
3852 /* There is still a possibility we will find the need to do code
3853 conversion. If that happens, we set this variable to 1 to
3854 give up on handling REPLACE in the optimized way. */
3855 int giveup_match_end = 0;
3857 if (XINT (beg) != 0)
3859 if (lseek (fd, XINT (beg), 0) < 0)
3860 report_file_error ("Setting file position",
3861 Fcons (orig_filename, Qnil));
3864 immediate_quit = 1;
3865 QUIT;
3866 /* Count how many chars at the start of the file
3867 match the text at the beginning of the buffer. */
3868 while (1)
3870 int nread, bufpos;
3872 nread = emacs_read (fd, buffer, sizeof buffer);
3873 if (nread < 0)
3874 error ("IO error reading %s: %s",
3875 XSTRING (orig_filename)->data, emacs_strerror (errno));
3876 else if (nread == 0)
3877 break;
3879 if (coding.type == coding_type_undecided)
3880 detect_coding (&coding, buffer, nread);
3881 if (coding.common_flags & CODING_REQUIRE_DECODING_MASK)
3882 /* We found that the file should be decoded somehow.
3883 Let's give up here. */
3885 giveup_match_end = 1;
3886 break;
3889 if (coding.eol_type == CODING_EOL_UNDECIDED)
3890 detect_eol (&coding, buffer, nread);
3891 if (coding.eol_type != CODING_EOL_UNDECIDED
3892 && coding.eol_type != CODING_EOL_LF)
3893 /* We found that the format of eol should be decoded.
3894 Let's give up here. */
3896 giveup_match_end = 1;
3897 break;
3900 bufpos = 0;
3901 while (bufpos < nread && same_at_start < ZV_BYTE
3902 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3903 same_at_start++, bufpos++;
3904 /* If we found a discrepancy, stop the scan.
3905 Otherwise loop around and scan the next bufferful. */
3906 if (bufpos != nread)
3907 break;
3909 immediate_quit = 0;
3910 /* If the file matches the buffer completely,
3911 there's no need to replace anything. */
3912 if (same_at_start - BEGV_BYTE == XINT (end))
3914 emacs_close (fd);
3915 specpdl_ptr--;
3916 /* Truncate the buffer to the size of the file. */
3917 del_range_1 (same_at_start, same_at_end, 0, 0);
3918 goto handled;
3920 immediate_quit = 1;
3921 QUIT;
3922 /* Count how many chars at the end of the file
3923 match the text at the end of the buffer. But, if we have
3924 already found that decoding is necessary, don't waste time. */
3925 while (!giveup_match_end)
3927 int total_read, nread, bufpos, curpos, trial;
3929 /* At what file position are we now scanning? */
3930 curpos = XINT (end) - (ZV_BYTE - same_at_end);
3931 /* If the entire file matches the buffer tail, stop the scan. */
3932 if (curpos == 0)
3933 break;
3934 /* How much can we scan in the next step? */
3935 trial = min (curpos, sizeof buffer);
3936 if (lseek (fd, curpos - trial, 0) < 0)
3937 report_file_error ("Setting file position",
3938 Fcons (orig_filename, Qnil));
3940 total_read = nread = 0;
3941 while (total_read < trial)
3943 nread = emacs_read (fd, buffer + total_read, trial - total_read);
3944 if (nread < 0)
3945 error ("IO error reading %s: %s",
3946 XSTRING (orig_filename)->data, emacs_strerror (errno));
3947 else if (nread == 0)
3948 break;
3949 total_read += nread;
3952 /* Scan this bufferful from the end, comparing with
3953 the Emacs buffer. */
3954 bufpos = total_read;
3956 /* Compare with same_at_start to avoid counting some buffer text
3957 as matching both at the file's beginning and at the end. */
3958 while (bufpos > 0 && same_at_end > same_at_start
3959 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3960 same_at_end--, bufpos--;
3962 /* If we found a discrepancy, stop the scan.
3963 Otherwise loop around and scan the preceding bufferful. */
3964 if (bufpos != 0)
3966 /* If this discrepancy is because of code conversion,
3967 we cannot use this method; giveup and try the other. */
3968 if (same_at_end > same_at_start
3969 && FETCH_BYTE (same_at_end - 1) >= 0200
3970 && ! NILP (current_buffer->enable_multibyte_characters)
3971 && (CODING_MAY_REQUIRE_DECODING (&coding)))
3972 giveup_match_end = 1;
3973 break;
3976 if (nread == 0)
3977 break;
3979 immediate_quit = 0;
3981 if (! giveup_match_end)
3983 int temp;
3985 /* We win! We can handle REPLACE the optimized way. */
3987 /* Extend the start of non-matching text area to multibyte
3988 character boundary. */
3989 if (! NILP (current_buffer->enable_multibyte_characters))
3990 while (same_at_start > BEGV_BYTE
3991 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
3992 same_at_start--;
3994 /* Extend the end of non-matching text area to multibyte
3995 character boundary. */
3996 if (! NILP (current_buffer->enable_multibyte_characters))
3997 while (same_at_end < ZV_BYTE
3998 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3999 same_at_end++;
4001 /* Don't try to reuse the same piece of text twice. */
4002 overlap = (same_at_start - BEGV_BYTE
4003 - (same_at_end + st.st_size - ZV));
4004 if (overlap > 0)
4005 same_at_end += overlap;
4007 /* Arrange to read only the nonmatching middle part of the file. */
4008 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
4009 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
4011 del_range_byte (same_at_start, same_at_end, 0);
4012 /* Insert from the file at the proper position. */
4013 temp = BYTE_TO_CHAR (same_at_start);
4014 SET_PT_BOTH (temp, same_at_start);
4016 /* If display currently starts at beginning of line,
4017 keep it that way. */
4018 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4019 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4021 replace_handled = 1;
4025 /* If requested, replace the accessible part of the buffer
4026 with the file contents. Avoid replacing text at the
4027 beginning or end of the buffer that matches the file contents;
4028 that preserves markers pointing to the unchanged parts.
4030 Here we implement this feature for the case where code conversion
4031 is needed, in a simple way that needs a lot of memory.
4032 The preceding if-statement handles the case of no conversion
4033 in a more optimized way. */
4034 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
4036 int same_at_start = BEGV_BYTE;
4037 int same_at_end = ZV_BYTE;
4038 int overlap;
4039 int bufpos;
4040 /* Make sure that the gap is large enough. */
4041 int bufsize = 2 * st.st_size;
4042 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
4043 int temp;
4045 /* First read the whole file, performing code conversion into
4046 CONVERSION_BUFFER. */
4048 if (lseek (fd, XINT (beg), 0) < 0)
4050 xfree (conversion_buffer);
4051 report_file_error ("Setting file position",
4052 Fcons (orig_filename, Qnil));
4055 total = st.st_size; /* Total bytes in the file. */
4056 how_much = 0; /* Bytes read from file so far. */
4057 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
4058 unprocessed = 0; /* Bytes not processed in previous loop. */
4060 while (how_much < total)
4062 /* try is reserved in some compilers (Microsoft C) */
4063 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
4064 unsigned char *destination = read_buf + unprocessed;
4065 int this;
4067 /* Allow quitting out of the actual I/O. */
4068 immediate_quit = 1;
4069 QUIT;
4070 this = emacs_read (fd, destination, trytry);
4071 immediate_quit = 0;
4073 if (this < 0 || this + unprocessed == 0)
4075 how_much = this;
4076 break;
4079 how_much += this;
4081 if (CODING_MAY_REQUIRE_DECODING (&coding))
4083 int require, result;
4085 this += unprocessed;
4087 /* If we are using more space than estimated,
4088 make CONVERSION_BUFFER bigger. */
4089 require = decoding_buffer_size (&coding, this);
4090 if (inserted + require + 2 * (total - how_much) > bufsize)
4092 bufsize = inserted + require + 2 * (total - how_much);
4093 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
4096 /* Convert this batch with results in CONVERSION_BUFFER. */
4097 if (how_much >= total) /* This is the last block. */
4098 coding.mode |= CODING_MODE_LAST_BLOCK;
4099 if (coding.composing != COMPOSITION_DISABLED)
4100 coding_allocate_composition_data (&coding, BEGV);
4101 result = decode_coding (&coding, read_buf,
4102 conversion_buffer + inserted,
4103 this, bufsize - inserted);
4105 /* Save for next iteration whatever we didn't convert. */
4106 unprocessed = this - coding.consumed;
4107 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
4108 if (!NILP (current_buffer->enable_multibyte_characters))
4109 this = coding.produced;
4110 else
4111 this = str_as_unibyte (conversion_buffer + inserted,
4112 coding.produced);
4115 inserted += this;
4118 /* At this point, INSERTED is how many characters (i.e. bytes)
4119 are present in CONVERSION_BUFFER.
4120 HOW_MUCH should equal TOTAL,
4121 or should be <= 0 if we couldn't read the file. */
4123 if (how_much < 0)
4125 xfree (conversion_buffer);
4127 if (how_much == -1)
4128 error ("IO error reading %s: %s",
4129 XSTRING (orig_filename)->data, emacs_strerror (errno));
4130 else if (how_much == -2)
4131 error ("maximum buffer size exceeded");
4134 /* Compare the beginning of the converted file
4135 with the buffer text. */
4137 bufpos = 0;
4138 while (bufpos < inserted && same_at_start < same_at_end
4139 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
4140 same_at_start++, bufpos++;
4142 /* If the file matches the buffer completely,
4143 there's no need to replace anything. */
4145 if (bufpos == inserted)
4147 xfree (conversion_buffer);
4148 emacs_close (fd);
4149 specpdl_ptr--;
4150 /* Truncate the buffer to the size of the file. */
4151 del_range_byte (same_at_start, same_at_end, 0);
4152 inserted = 0;
4153 goto handled;
4156 /* Extend the start of non-matching text area to multibyte
4157 character boundary. */
4158 if (! NILP (current_buffer->enable_multibyte_characters))
4159 while (same_at_start > BEGV_BYTE
4160 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
4161 same_at_start--;
4163 /* Scan this bufferful from the end, comparing with
4164 the Emacs buffer. */
4165 bufpos = inserted;
4167 /* Compare with same_at_start to avoid counting some buffer text
4168 as matching both at the file's beginning and at the end. */
4169 while (bufpos > 0 && same_at_end > same_at_start
4170 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
4171 same_at_end--, bufpos--;
4173 /* Extend the end of non-matching text area to multibyte
4174 character boundary. */
4175 if (! NILP (current_buffer->enable_multibyte_characters))
4176 while (same_at_end < ZV_BYTE
4177 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
4178 same_at_end++;
4180 /* Don't try to reuse the same piece of text twice. */
4181 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
4182 if (overlap > 0)
4183 same_at_end += overlap;
4185 /* If display currently starts at beginning of line,
4186 keep it that way. */
4187 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
4188 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
4190 /* Replace the chars that we need to replace,
4191 and update INSERTED to equal the number of bytes
4192 we are taking from the file. */
4193 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
4195 if (same_at_end != same_at_start)
4197 del_range_byte (same_at_start, same_at_end, 0);
4198 temp = GPT;
4199 same_at_start = GPT_BYTE;
4201 else
4203 temp = BYTE_TO_CHAR (same_at_start);
4205 /* Insert from the file at the proper position. */
4206 SET_PT_BOTH (temp, same_at_start);
4207 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,
4208 0, 0, 0);
4209 if (coding.cmp_data && coding.cmp_data->used)
4210 coding_restore_composition (&coding, Fcurrent_buffer ());
4211 coding_free_composition_data (&coding);
4213 /* Set `inserted' to the number of inserted characters. */
4214 inserted = PT - temp;
4216 xfree (conversion_buffer);
4217 emacs_close (fd);
4218 specpdl_ptr--;
4220 goto handled;
4223 if (! not_regular)
4225 register Lisp_Object temp;
4227 total = XINT (end) - XINT (beg);
4229 /* Make sure point-max won't overflow after this insertion. */
4230 XSETINT (temp, total);
4231 if (total != XINT (temp))
4232 error ("Maximum buffer size exceeded");
4234 else
4235 /* For a special file, all we can do is guess. */
4236 total = READ_BUF_SIZE;
4238 if (NILP (visit) && total > 0)
4239 prepare_to_modify_buffer (PT, PT, NULL);
4241 move_gap (PT);
4242 if (GAP_SIZE < total)
4243 make_gap (total - GAP_SIZE);
4245 if (XINT (beg) != 0 || !NILP (replace))
4247 if (lseek (fd, XINT (beg), 0) < 0)
4248 report_file_error ("Setting file position",
4249 Fcons (orig_filename, Qnil));
4252 /* In the following loop, HOW_MUCH contains the total bytes read so
4253 far for a regular file, and not changed for a special file. But,
4254 before exiting the loop, it is set to a negative value if I/O
4255 error occurs. */
4256 how_much = 0;
4258 /* Total bytes inserted. */
4259 inserted = 0;
4261 /* Here, we don't do code conversion in the loop. It is done by
4262 code_convert_region after all data are read into the buffer. */
4264 int gap_size = GAP_SIZE;
4266 while (how_much < total)
4268 /* try is reserved in some compilers (Microsoft C) */
4269 int trytry = min (total - how_much, READ_BUF_SIZE);
4270 int this;
4272 if (not_regular)
4274 Lisp_Object val;
4276 /* Maybe make more room. */
4277 if (gap_size < trytry)
4279 make_gap (total - gap_size);
4280 gap_size = GAP_SIZE;
4283 /* Read from the file, capturing `quit'. When an
4284 error occurs, end the loop, and arrange for a quit
4285 to be signaled after decoding the text we read. */
4286 non_regular_fd = fd;
4287 non_regular_inserted = inserted;
4288 non_regular_nbytes = trytry;
4289 val = internal_condition_case_1 (read_non_regular, Qnil, Qerror,
4290 read_non_regular_quit);
4291 if (NILP (val))
4293 read_quit = 1;
4294 break;
4297 this = XINT (val);
4299 else
4301 /* Allow quitting out of the actual I/O. We don't make text
4302 part of the buffer until all the reading is done, so a C-g
4303 here doesn't do any harm. */
4304 immediate_quit = 1;
4305 QUIT;
4306 this = emacs_read (fd, BEG_ADDR + PT_BYTE - 1 + inserted, trytry);
4307 immediate_quit = 0;
4310 if (this <= 0)
4312 how_much = this;
4313 break;
4316 gap_size -= this;
4318 /* For a regular file, where TOTAL is the real size,
4319 count HOW_MUCH to compare with it.
4320 For a special file, where TOTAL is just a buffer size,
4321 so don't bother counting in HOW_MUCH.
4322 (INSERTED is where we count the number of characters inserted.) */
4323 if (! not_regular)
4324 how_much += this;
4325 inserted += this;
4329 /* Make the text read part of the buffer. */
4330 GAP_SIZE -= inserted;
4331 GPT += inserted;
4332 GPT_BYTE += inserted;
4333 ZV += inserted;
4334 ZV_BYTE += inserted;
4335 Z += inserted;
4336 Z_BYTE += inserted;
4338 if (GAP_SIZE > 0)
4339 /* Put an anchor to ensure multi-byte form ends at gap. */
4340 *GPT_ADDR = 0;
4342 emacs_close (fd);
4344 /* Discard the unwind protect for closing the file. */
4345 specpdl_ptr--;
4347 if (how_much < 0)
4348 error ("IO error reading %s: %s",
4349 XSTRING (orig_filename)->data, emacs_strerror (errno));
4351 notfound:
4353 if (! coding_system_decided)
4355 /* The coding system is not yet decided. Decide it by an
4356 optimized method for handling `coding:' tag.
4358 Note that we can get here only if the buffer was empty
4359 before the insertion. */
4360 Lisp_Object val;
4361 val = Qnil;
4363 if (!NILP (Vcoding_system_for_read))
4364 val = Vcoding_system_for_read;
4365 else
4367 /* Since we are sure that the current buffer was empty
4368 before the insertion, we can toggle
4369 enable-multibyte-characters directly here without taking
4370 care of marker adjustment and byte combining problem. By
4371 this way, we can run Lisp program safely before decoding
4372 the inserted text. */
4373 Lisp_Object unwind_data;
4374 int count = specpdl_ptr - specpdl;
4376 unwind_data = Fcons (current_buffer->enable_multibyte_characters,
4377 Fcons (current_buffer->undo_list,
4378 Fcurrent_buffer ()));
4379 current_buffer->enable_multibyte_characters = Qnil;
4380 current_buffer->undo_list = Qt;
4381 record_unwind_protect (decide_coding_unwind, unwind_data);
4383 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4385 val = call2 (Vset_auto_coding_function,
4386 filename, make_number (inserted));
4389 if (NILP (val))
4391 /* If the coding system is not yet decided, check
4392 file-coding-system-alist. */
4393 Lisp_Object args[6], coding_systems;
4395 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4396 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4397 coding_systems = Ffind_operation_coding_system (6, args);
4398 if (CONSP (coding_systems))
4399 val = XCAR (coding_systems);
4402 unbind_to (count, Qnil);
4403 inserted = Z_BYTE - BEG_BYTE;
4406 /* The following kludgy code is to avoid some compiler bug.
4407 We can't simply do
4408 setup_coding_system (val, &coding);
4409 on some system. */
4411 struct coding_system temp_coding;
4412 setup_coding_system (val, &temp_coding);
4413 bcopy (&temp_coding, &coding, sizeof coding);
4415 /* Ensure we set Vlast_coding_system_used. */
4416 set_coding_system = 1;
4418 if (NILP (current_buffer->enable_multibyte_characters)
4419 && ! NILP (val))
4420 /* We must suppress all character code conversion except for
4421 end-of-line conversion. */
4422 setup_raw_text_coding_system (&coding);
4423 coding.src_multibyte = 0;
4424 coding.dst_multibyte
4425 = !NILP (current_buffer->enable_multibyte_characters);
4428 if (!NILP (visit)
4429 /* Can't do this if part of the buffer might be preserved. */
4430 && NILP (replace)
4431 && (coding.type == coding_type_no_conversion
4432 || coding.type == coding_type_raw_text))
4434 /* Visiting a file with these coding system makes the buffer
4435 unibyte. */
4436 current_buffer->enable_multibyte_characters = Qnil;
4437 coding.dst_multibyte = 0;
4440 if (inserted > 0 || coding.type == coding_type_ccl)
4442 if (CODING_MAY_REQUIRE_DECODING (&coding))
4444 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4445 &coding, 0, 0);
4446 inserted = coding.produced_char;
4448 else
4449 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4450 inserted);
4453 #ifdef DOS_NT
4454 /* Use the conversion type to determine buffer-file-type
4455 (find-buffer-file-type is now used to help determine the
4456 conversion). */
4457 if ((coding.eol_type == CODING_EOL_UNDECIDED
4458 || coding.eol_type == CODING_EOL_LF)
4459 && ! CODING_REQUIRE_DECODING (&coding))
4460 current_buffer->buffer_file_type = Qt;
4461 else
4462 current_buffer->buffer_file_type = Qnil;
4463 #endif
4465 handled:
4467 if (!NILP (visit))
4469 if (!EQ (current_buffer->undo_list, Qt))
4470 current_buffer->undo_list = Qnil;
4471 #ifdef APOLLO
4472 stat (XSTRING (filename)->data, &st);
4473 #endif
4475 if (NILP (handler))
4477 current_buffer->modtime = st.st_mtime;
4478 current_buffer->filename = orig_filename;
4481 SAVE_MODIFF = MODIFF;
4482 current_buffer->auto_save_modified = MODIFF;
4483 XSETFASTINT (current_buffer->save_length, Z - BEG);
4484 #ifdef CLASH_DETECTION
4485 if (NILP (handler))
4487 if (!NILP (current_buffer->file_truename))
4488 unlock_file (current_buffer->file_truename);
4489 unlock_file (filename);
4491 #endif /* CLASH_DETECTION */
4492 if (not_regular)
4493 Fsignal (Qfile_error,
4494 Fcons (build_string ("not a regular file"),
4495 Fcons (orig_filename, Qnil)));
4498 /* Decode file format */
4499 if (inserted > 0)
4501 int empty_undo_list_p = 0;
4503 /* If we're anyway going to discard undo information, don't
4504 record it in the first place. The buffer's undo list at this
4505 point is either nil or t when visiting a file. */
4506 if (!NILP (visit))
4508 empty_undo_list_p = NILP (current_buffer->undo_list);
4509 current_buffer->undo_list = Qt;
4512 insval = call3 (Qformat_decode,
4513 Qnil, make_number (inserted), visit);
4514 CHECK_NUMBER (insval);
4515 inserted = XFASTINT (insval);
4517 if (!NILP (visit))
4518 current_buffer->undo_list = empty_undo_list_p ? Qnil : Qt;
4521 if (set_coding_system)
4522 Vlast_coding_system_used = coding.symbol;
4524 /* Call after-change hooks for the inserted text, aside from the case
4525 of normal visiting (not with REPLACE), which is done in a new buffer
4526 "before" the buffer is changed. */
4527 if (inserted > 0 && total > 0
4528 && (NILP (visit) || !NILP (replace)))
4530 signal_after_change (PT, 0, inserted);
4531 update_compositions (PT, PT, CHECK_BORDER);
4534 p = Vafter_insert_file_functions;
4535 while (!NILP (p))
4537 insval = call1 (Fcar (p), make_number (inserted));
4538 if (!NILP (insval))
4540 CHECK_NUMBER (insval);
4541 inserted = XFASTINT (insval);
4543 QUIT;
4544 p = Fcdr (p);
4547 if (!NILP (visit)
4548 && current_buffer->modtime == -1)
4550 /* If visiting nonexistent file, return nil. */
4551 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
4554 if (read_quit)
4555 Fsignal (Qquit, Qnil);
4557 /* ??? Retval needs to be dealt with in all cases consistently. */
4558 if (NILP (val))
4559 val = Fcons (orig_filename,
4560 Fcons (make_number (inserted),
4561 Qnil));
4563 RETURN_UNGCPRO (unbind_to (count, val));
4566 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object));
4567 static Lisp_Object build_annotations_2 P_ ((Lisp_Object, Lisp_Object,
4568 Lisp_Object, Lisp_Object));
4570 /* If build_annotations switched buffers, switch back to BUF.
4571 Kill the temporary buffer that was selected in the meantime.
4573 Since this kill only the last temporary buffer, some buffers remain
4574 not killed if build_annotations switched buffers more than once.
4575 -- K.Handa */
4577 static Lisp_Object
4578 build_annotations_unwind (buf)
4579 Lisp_Object buf;
4581 Lisp_Object tembuf;
4583 if (XBUFFER (buf) == current_buffer)
4584 return Qnil;
4585 tembuf = Fcurrent_buffer ();
4586 Fset_buffer (buf);
4587 Fkill_buffer (tembuf);
4588 return Qnil;
4591 /* Decide the coding-system to encode the data with. */
4593 void
4594 choose_write_coding_system (start, end, filename,
4595 append, visit, lockname, coding)
4596 Lisp_Object start, end, filename, append, visit, lockname;
4597 struct coding_system *coding;
4599 Lisp_Object val;
4601 if (auto_saving)
4602 val = Qnil;
4603 else if (!NILP (Vcoding_system_for_write))
4604 val = Vcoding_system_for_write;
4605 else
4607 /* If the variable `buffer-file-coding-system' is set locally,
4608 it means that the file was read with some kind of code
4609 conversion or the variable is explicitly set by users. We
4610 had better write it out with the same coding system even if
4611 `enable-multibyte-characters' is nil.
4613 If it is not set locally, we anyway have to convert EOL
4614 format if the default value of `buffer-file-coding-system'
4615 tells that it is not Unix-like (LF only) format. */
4616 int using_default_coding = 0;
4617 int force_raw_text = 0;
4619 val = current_buffer->buffer_file_coding_system;
4620 if (NILP (val)
4621 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4623 val = Qnil;
4624 if (NILP (current_buffer->enable_multibyte_characters))
4625 force_raw_text = 1;
4628 if (NILP (val))
4630 /* Check file-coding-system-alist. */
4631 Lisp_Object args[7], coding_systems;
4633 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4634 args[3] = filename; args[4] = append; args[5] = visit;
4635 args[6] = lockname;
4636 coding_systems = Ffind_operation_coding_system (7, args);
4637 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4638 val = XCDR (coding_systems);
4641 if (NILP (val)
4642 && !NILP (current_buffer->buffer_file_coding_system))
4644 /* If we still have not decided a coding system, use the
4645 default value of buffer-file-coding-system. */
4646 val = current_buffer->buffer_file_coding_system;
4647 using_default_coding = 1;
4650 if (!force_raw_text
4651 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4652 /* Confirm that VAL can surely encode the current region. */
4653 val = call3 (Vselect_safe_coding_system_function, start, end, val);
4655 setup_coding_system (Fcheck_coding_system (val), coding);
4656 if (coding->eol_type == CODING_EOL_UNDECIDED
4657 && !using_default_coding)
4659 if (! EQ (default_buffer_file_coding.symbol,
4660 buffer_defaults.buffer_file_coding_system))
4661 setup_coding_system (buffer_defaults.buffer_file_coding_system,
4662 &default_buffer_file_coding);
4663 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)
4665 Lisp_Object subsidiaries;
4667 coding->eol_type = default_buffer_file_coding.eol_type;
4668 subsidiaries = Fget (coding->symbol, Qeol_type);
4669 if (VECTORP (subsidiaries)
4670 && XVECTOR (subsidiaries)->size == 3)
4671 coding->symbol
4672 = XVECTOR (subsidiaries)->contents[coding->eol_type];
4676 if (force_raw_text)
4677 setup_raw_text_coding_system (coding);
4678 goto done_setup_coding;
4681 setup_coding_system (Fcheck_coding_system (val), coding);
4683 done_setup_coding:
4684 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4685 coding->mode |= CODING_MODE_SELECTIVE_DISPLAY;
4688 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
4689 "r\nFWrite region to file: \ni\ni\ni\np",
4690 doc: /* Write current region into specified file.
4691 When called from a program, requires three arguments:
4692 START, END and FILENAME. START and END are normally buffer positions
4693 specifying the part of the buffer to write.
4694 If START is nil, that means to use the entire buffer contents.
4695 If START is a string, then output that string to the file
4696 instead of any buffer contents; END is ignored.
4698 Optional fourth argument APPEND if non-nil means
4699 append to existing file contents (if any). If it is an integer,
4700 seek to that offset in the file before writing.
4701 Optional fifth argument VISIT if t means
4702 set the last-save-file-modtime of buffer to this file's modtime
4703 and mark buffer not modified.
4704 If VISIT is a string, it is a second file name;
4705 the output goes to FILENAME, but the buffer is marked as visiting VISIT.
4706 VISIT is also the file name to lock and unlock for clash detection.
4707 If VISIT is neither t nor nil nor a string,
4708 that means do not print the \"Wrote file\" message.
4709 The optional sixth arg LOCKNAME, if non-nil, specifies the name to
4710 use for locking and unlocking, overriding FILENAME and VISIT.
4711 The optional seventh arg MUSTBENEW, if non-nil, insists on a check
4712 for an existing file with the same name. If MUSTBENEW is `excl',
4713 that means to get an error if the file already exists; never overwrite.
4714 If MUSTBENEW is neither nil nor `excl', that means ask for
4715 confirmation before overwriting, but do go ahead and overwrite the file
4716 if the user confirms.
4718 This does code conversion according to the value of
4719 `coding-system-for-write', `buffer-file-coding-system', or
4720 `file-coding-system-alist', and sets the variable
4721 `last-coding-system-used' to the coding system actually used. */)
4722 (start, end, filename, append, visit, lockname, mustbenew)
4723 Lisp_Object start, end, filename, append, visit, lockname, mustbenew;
4725 register int desc;
4726 int failure;
4727 int save_errno = 0;
4728 unsigned char *fn;
4729 struct stat st;
4730 int tem;
4731 int count = specpdl_ptr - specpdl;
4732 int count1;
4733 #ifdef VMS
4734 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
4735 #endif /* VMS */
4736 Lisp_Object handler;
4737 Lisp_Object visit_file;
4738 Lisp_Object annotations;
4739 Lisp_Object encoded_filename;
4740 int visiting = (EQ (visit, Qt) || STRINGP (visit));
4741 int quietly = !NILP (visit);
4742 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4743 struct buffer *given_buffer;
4744 #ifdef DOS_NT
4745 int buffer_file_type = O_BINARY;
4746 #endif /* DOS_NT */
4747 struct coding_system coding;
4749 if (current_buffer->base_buffer && visiting)
4750 error ("Cannot do file visiting in an indirect buffer");
4752 if (!NILP (start) && !STRINGP (start))
4753 validate_region (&start, &end);
4755 GCPRO5 (start, filename, visit, visit_file, lockname);
4757 filename = Fexpand_file_name (filename, Qnil);
4759 if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl))
4760 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
4762 if (STRINGP (visit))
4763 visit_file = Fexpand_file_name (visit, Qnil);
4764 else
4765 visit_file = filename;
4767 if (NILP (lockname))
4768 lockname = visit_file;
4770 annotations = Qnil;
4772 /* If the file name has special constructs in it,
4773 call the corresponding file handler. */
4774 handler = Ffind_file_name_handler (filename, Qwrite_region);
4775 /* If FILENAME has no handler, see if VISIT has one. */
4776 if (NILP (handler) && STRINGP (visit))
4777 handler = Ffind_file_name_handler (visit, Qwrite_region);
4779 if (!NILP (handler))
4781 Lisp_Object val;
4782 val = call6 (handler, Qwrite_region, start, end,
4783 filename, append, visit);
4785 if (visiting)
4787 SAVE_MODIFF = MODIFF;
4788 XSETFASTINT (current_buffer->save_length, Z - BEG);
4789 current_buffer->filename = visit_file;
4791 UNGCPRO;
4792 return val;
4795 /* Special kludge to simplify auto-saving. */
4796 if (NILP (start))
4798 XSETFASTINT (start, BEG);
4799 XSETFASTINT (end, Z);
4802 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
4803 count1 = specpdl_ptr - specpdl;
4805 given_buffer = current_buffer;
4806 annotations = build_annotations (start, end);
4807 if (current_buffer != given_buffer)
4809 XSETFASTINT (start, BEGV);
4810 XSETFASTINT (end, ZV);
4813 UNGCPRO;
4815 GCPRO5 (start, filename, annotations, visit_file, lockname);
4817 /* Decide the coding-system to encode the data with.
4818 We used to make this choice before calling build_annotations, but that
4819 leads to problems when a write-annotate-function takes care of
4820 unsavable chars (as was the case with X-Symbol). */
4821 choose_write_coding_system (start, end, filename,
4822 append, visit, lockname, &coding);
4823 Vlast_coding_system_used = coding.symbol;
4825 given_buffer = current_buffer;
4826 annotations = build_annotations_2 (start, end,
4827 coding.pre_write_conversion, annotations);
4828 if (current_buffer != given_buffer)
4830 XSETFASTINT (start, BEGV);
4831 XSETFASTINT (end, ZV);
4834 #ifdef CLASH_DETECTION
4835 if (!auto_saving)
4837 #if 0 /* This causes trouble for GNUS. */
4838 /* If we've locked this file for some other buffer,
4839 query before proceeding. */
4840 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
4841 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
4842 #endif
4844 lock_file (lockname);
4846 #endif /* CLASH_DETECTION */
4848 encoded_filename = ENCODE_FILE (filename);
4850 fn = XSTRING (encoded_filename)->data;
4851 desc = -1;
4852 if (!NILP (append))
4853 #ifdef DOS_NT
4854 desc = emacs_open (fn, O_WRONLY | buffer_file_type, 0);
4855 #else /* not DOS_NT */
4856 desc = emacs_open (fn, O_WRONLY, 0);
4857 #endif /* not DOS_NT */
4859 if (desc < 0 && (NILP (append) || errno == ENOENT))
4860 #ifdef VMS
4861 if (auto_saving) /* Overwrite any previous version of autosave file */
4863 vms_truncate (fn); /* if fn exists, truncate to zero length */
4864 desc = emacs_open (fn, O_RDWR, 0);
4865 if (desc < 0)
4866 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
4867 ? XSTRING (current_buffer->filename)->data : 0,
4868 fn);
4870 else /* Write to temporary name and rename if no errors */
4872 Lisp_Object temp_name;
4873 temp_name = Ffile_name_directory (filename);
4875 if (!NILP (temp_name))
4877 temp_name = Fmake_temp_name (concat2 (temp_name,
4878 build_string ("$$SAVE$$")));
4879 fname = XSTRING (filename)->data;
4880 fn = XSTRING (temp_name)->data;
4881 desc = creat_copy_attrs (fname, fn);
4882 if (desc < 0)
4884 /* If we can't open the temporary file, try creating a new
4885 version of the original file. VMS "creat" creates a
4886 new version rather than truncating an existing file. */
4887 fn = fname;
4888 fname = 0;
4889 desc = creat (fn, 0666);
4890 #if 0 /* This can clobber an existing file and fail to replace it,
4891 if the user runs out of space. */
4892 if (desc < 0)
4894 /* We can't make a new version;
4895 try to truncate and rewrite existing version if any. */
4896 vms_truncate (fn);
4897 desc = emacs_open (fn, O_RDWR, 0);
4899 #endif
4902 else
4903 desc = creat (fn, 0666);
4905 #else /* not VMS */
4906 #ifdef DOS_NT
4907 desc = emacs_open (fn,
4908 O_WRONLY | O_CREAT | buffer_file_type
4909 | (EQ (mustbenew, Qexcl) ? O_EXCL : O_TRUNC),
4910 S_IREAD | S_IWRITE);
4911 #else /* not DOS_NT */
4912 desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT
4913 | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
4914 auto_saving ? auto_save_mode_bits : 0666);
4915 #endif /* not DOS_NT */
4916 #endif /* not VMS */
4918 if (desc < 0)
4920 #ifdef CLASH_DETECTION
4921 save_errno = errno;
4922 if (!auto_saving) unlock_file (lockname);
4923 errno = save_errno;
4924 #endif /* CLASH_DETECTION */
4925 UNGCPRO;
4926 report_file_error ("Opening output file", Fcons (filename, Qnil));
4929 record_unwind_protect (close_file_unwind, make_number (desc));
4931 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
4933 long ret;
4935 if (NUMBERP (append))
4936 ret = lseek (desc, XINT (append), 1);
4937 else
4938 ret = lseek (desc, 0, 2);
4939 if (ret < 0)
4941 #ifdef CLASH_DETECTION
4942 if (!auto_saving) unlock_file (lockname);
4943 #endif /* CLASH_DETECTION */
4944 UNGCPRO;
4945 report_file_error ("Lseek error", Fcons (filename, Qnil));
4949 UNGCPRO;
4951 #ifdef VMS
4953 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4954 * if we do writes that don't end with a carriage return. Furthermore
4955 * it cannot handle writes of more then 16K. The modified
4956 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4957 * this EXCEPT for the last record (iff it doesn't end with a carriage
4958 * return). This implies that if your buffer doesn't end with a carriage
4959 * return, you get one free... tough. However it also means that if
4960 * we make two calls to sys_write (a la the following code) you can
4961 * get one at the gap as well. The easiest way to fix this (honest)
4962 * is to move the gap to the next newline (or the end of the buffer).
4963 * Thus this change.
4965 * Yech!
4967 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4968 move_gap (find_next_newline (GPT, 1));
4969 #else
4970 /* Whether VMS or not, we must move the gap to the next of newline
4971 when we must put designation sequences at beginning of line. */
4972 if (INTEGERP (start)
4973 && coding.type == coding_type_iso2022
4974 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4975 && GPT > BEG && GPT_ADDR[-1] != '\n')
4977 int opoint = PT, opoint_byte = PT_BYTE;
4978 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
4979 move_gap_both (PT, PT_BYTE);
4980 SET_PT_BOTH (opoint, opoint_byte);
4982 #endif
4984 failure = 0;
4985 immediate_quit = 1;
4987 if (STRINGP (start))
4989 failure = 0 > a_write (desc, start, 0, XSTRING (start)->size,
4990 &annotations, &coding);
4991 save_errno = errno;
4993 else if (XINT (start) != XINT (end))
4995 tem = CHAR_TO_BYTE (XINT (start));
4997 if (XINT (start) < GPT)
4999 failure = 0 > a_write (desc, Qnil, XINT (start),
5000 min (GPT, XINT (end)) - XINT (start),
5001 &annotations, &coding);
5002 save_errno = errno;
5005 if (XINT (end) > GPT && !failure)
5007 tem = max (XINT (start), GPT);
5008 failure = 0 > a_write (desc, Qnil, tem , XINT (end) - tem,
5009 &annotations, &coding);
5010 save_errno = errno;
5013 else
5015 /* If file was empty, still need to write the annotations */
5016 coding.mode |= CODING_MODE_LAST_BLOCK;
5017 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
5018 save_errno = errno;
5021 if (CODING_REQUIRE_FLUSHING (&coding)
5022 && !(coding.mode & CODING_MODE_LAST_BLOCK)
5023 && ! failure)
5025 /* We have to flush out a data. */
5026 coding.mode |= CODING_MODE_LAST_BLOCK;
5027 failure = 0 > e_write (desc, Qnil, 0, 0, &coding);
5028 save_errno = errno;
5031 immediate_quit = 0;
5033 #ifdef HAVE_FSYNC
5034 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
5035 Disk full in NFS may be reported here. */
5036 /* mib says that closing the file will try to write as fast as NFS can do
5037 it, and that means the fsync here is not crucial for autosave files. */
5038 if (!auto_saving && fsync (desc) < 0)
5040 /* If fsync fails with EINTR, don't treat that as serious. */
5041 if (errno != EINTR)
5042 failure = 1, save_errno = errno;
5044 #endif
5046 /* Spurious "file has changed on disk" warnings have been
5047 observed on Suns as well.
5048 It seems that `close' can change the modtime, under nfs.
5050 (This has supposedly been fixed in Sunos 4,
5051 but who knows about all the other machines with NFS?) */
5052 #if 0
5054 /* On VMS and APOLLO, must do the stat after the close
5055 since closing changes the modtime. */
5056 #ifndef VMS
5057 #ifndef APOLLO
5058 /* Recall that #if defined does not work on VMS. */
5059 #define FOO
5060 fstat (desc, &st);
5061 #endif
5062 #endif
5063 #endif
5065 /* NFS can report a write failure now. */
5066 if (emacs_close (desc) < 0)
5067 failure = 1, save_errno = errno;
5069 #ifdef VMS
5070 /* If we wrote to a temporary name and had no errors, rename to real name. */
5071 if (fname)
5073 if (!failure)
5074 failure = (rename (fn, fname) != 0), save_errno = errno;
5075 fn = fname;
5077 #endif /* VMS */
5079 #ifndef FOO
5080 stat (fn, &st);
5081 #endif
5082 /* Discard the unwind protect for close_file_unwind. */
5083 specpdl_ptr = specpdl + count1;
5084 /* Restore the original current buffer. */
5085 visit_file = unbind_to (count, visit_file);
5087 #ifdef CLASH_DETECTION
5088 if (!auto_saving)
5089 unlock_file (lockname);
5090 #endif /* CLASH_DETECTION */
5092 /* Do this before reporting IO error
5093 to avoid a "file has changed on disk" warning on
5094 next attempt to save. */
5095 if (visiting)
5096 current_buffer->modtime = st.st_mtime;
5098 if (failure)
5099 error ("IO error writing %s: %s", XSTRING (filename)->data,
5100 emacs_strerror (save_errno));
5102 if (visiting)
5104 SAVE_MODIFF = MODIFF;
5105 XSETFASTINT (current_buffer->save_length, Z - BEG);
5106 current_buffer->filename = visit_file;
5107 update_mode_lines++;
5109 else if (quietly)
5110 return Qnil;
5112 if (!auto_saving)
5113 message_with_string ("Wrote %s", visit_file, 1);
5115 return Qnil;
5118 Lisp_Object merge ();
5120 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
5121 doc: /* Return t if (car A) is numerically less than (car B). */)
5122 (a, b)
5123 Lisp_Object a, b;
5125 return Flss (Fcar (a), Fcar (b));
5128 /* Build the complete list of annotations appropriate for writing out
5129 the text between START and END, by calling all the functions in
5130 write-region-annotate-functions and merging the lists they return.
5131 If one of these functions switches to a different buffer, we assume
5132 that buffer contains altered text. Therefore, the caller must
5133 make sure to restore the current buffer in all cases,
5134 as save-excursion would do. */
5136 static Lisp_Object
5137 build_annotations (start, end)
5138 Lisp_Object start, end;
5140 Lisp_Object annotations;
5141 Lisp_Object p, res;
5142 struct gcpro gcpro1, gcpro2;
5143 Lisp_Object original_buffer;
5144 int i;
5146 XSETBUFFER (original_buffer, current_buffer);
5148 annotations = Qnil;
5149 p = Vwrite_region_annotate_functions;
5150 GCPRO2 (annotations, p);
5151 while (!NILP (p))
5153 struct buffer *given_buffer = current_buffer;
5154 Vwrite_region_annotations_so_far = annotations;
5155 res = call2 (Fcar (p), start, end);
5156 /* If the function makes a different buffer current,
5157 assume that means this buffer contains altered text to be output.
5158 Reset START and END from the buffer bounds
5159 and discard all previous annotations because they should have
5160 been dealt with by this function. */
5161 if (current_buffer != given_buffer)
5163 XSETFASTINT (start, BEGV);
5164 XSETFASTINT (end, ZV);
5165 annotations = Qnil;
5167 Flength (res); /* Check basic validity of return value */
5168 annotations = merge (annotations, res, Qcar_less_than_car);
5169 p = Fcdr (p);
5172 /* Now do the same for annotation functions implied by the file-format */
5173 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
5174 p = Vauto_save_file_format;
5175 else
5176 p = current_buffer->file_format;
5177 for (i = 0; !NILP (p); p = Fcdr (p), ++i)
5179 struct buffer *given_buffer = current_buffer;
5181 Vwrite_region_annotations_so_far = annotations;
5183 /* Value is either a list of annotations or nil if the function
5184 has written annotations to a temporary buffer, which is now
5185 current. */
5186 res = call5 (Qformat_annotate_function, Fcar (p), start, end,
5187 original_buffer, make_number (i));
5188 if (current_buffer != given_buffer)
5190 XSETFASTINT (start, BEGV);
5191 XSETFASTINT (end, ZV);
5192 annotations = Qnil;
5195 if (CONSP (res))
5196 annotations = merge (annotations, res, Qcar_less_than_car);
5199 UNGCPRO;
5200 return annotations;
5203 static Lisp_Object
5204 build_annotations_2 (start, end, pre_write_conversion, annotations)
5205 Lisp_Object start, end, pre_write_conversion, annotations;
5207 struct gcpro gcpro1;
5208 Lisp_Object res;
5210 GCPRO1 (annotations);
5211 /* At last, do the same for the function PRE_WRITE_CONVERSION
5212 implied by the current coding-system. */
5213 if (!NILP (pre_write_conversion))
5215 struct buffer *given_buffer = current_buffer;
5216 Vwrite_region_annotations_so_far = annotations;
5217 res = call2 (pre_write_conversion, start, end);
5218 Flength (res);
5219 annotations = (current_buffer != given_buffer
5220 ? res
5221 : merge (annotations, res, Qcar_less_than_car));
5224 UNGCPRO;
5225 return annotations;
5228 /* Write to descriptor DESC the NCHARS chars starting at POS of STRING.
5229 If STRING is nil, POS is the character position in the current buffer.
5230 Intersperse with them the annotations from *ANNOT
5231 which fall within the range of POS to POS + NCHARS,
5232 each at its appropriate position.
5234 We modify *ANNOT by discarding elements as we use them up.
5236 The return value is negative in case of system call failure. */
5238 static int
5239 a_write (desc, string, pos, nchars, annot, coding)
5240 int desc;
5241 Lisp_Object string;
5242 register int nchars;
5243 int pos;
5244 Lisp_Object *annot;
5245 struct coding_system *coding;
5247 Lisp_Object tem;
5248 int nextpos;
5249 int lastpos = pos + nchars;
5251 while (NILP (*annot) || CONSP (*annot))
5253 tem = Fcar_safe (Fcar (*annot));
5254 nextpos = pos - 1;
5255 if (INTEGERP (tem))
5256 nextpos = XFASTINT (tem);
5258 /* If there are no more annotations in this range,
5259 output the rest of the range all at once. */
5260 if (! (nextpos >= pos && nextpos <= lastpos))
5261 return e_write (desc, string, pos, lastpos, coding);
5263 /* Output buffer text up to the next annotation's position. */
5264 if (nextpos > pos)
5266 if (0 > e_write (desc, string, pos, nextpos, coding))
5267 return -1;
5268 pos = nextpos;
5270 /* Output the annotation. */
5271 tem = Fcdr (Fcar (*annot));
5272 if (STRINGP (tem))
5274 if (0 > e_write (desc, tem, 0, XSTRING (tem)->size, coding))
5275 return -1;
5277 *annot = Fcdr (*annot);
5279 return 0;
5282 #ifndef WRITE_BUF_SIZE
5283 #define WRITE_BUF_SIZE (16 * 1024)
5284 #endif
5286 /* Write text in the range START and END into descriptor DESC,
5287 encoding them with coding system CODING. If STRING is nil, START
5288 and END are character positions of the current buffer, else they
5289 are indexes to the string STRING. */
5291 static int
5292 e_write (desc, string, start, end, coding)
5293 int desc;
5294 Lisp_Object string;
5295 int start, end;
5296 struct coding_system *coding;
5298 register char *addr;
5299 register int nbytes;
5300 char buf[WRITE_BUF_SIZE];
5301 int return_val = 0;
5303 if (start >= end)
5304 coding->composing = COMPOSITION_DISABLED;
5305 if (coding->composing != COMPOSITION_DISABLED)
5306 coding_save_composition (coding, start, end, string);
5308 if (STRINGP (string))
5310 addr = XSTRING (string)->data;
5311 nbytes = STRING_BYTES (XSTRING (string));
5312 coding->src_multibyte = STRING_MULTIBYTE (string);
5314 else if (start < end)
5316 /* It is assured that the gap is not in the range START and END-1. */
5317 addr = CHAR_POS_ADDR (start);
5318 nbytes = CHAR_TO_BYTE (end) - CHAR_TO_BYTE (start);
5319 coding->src_multibyte
5320 = !NILP (current_buffer->enable_multibyte_characters);
5322 else
5324 addr = "";
5325 nbytes = 0;
5326 coding->src_multibyte = 1;
5329 /* We used to have a code for handling selective display here. But,
5330 now it is handled within encode_coding. */
5331 while (1)
5333 int result;
5335 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
5336 if (coding->produced > 0)
5338 coding->produced -= emacs_write (desc, buf, coding->produced);
5339 if (coding->produced)
5341 return_val = -1;
5342 break;
5345 nbytes -= coding->consumed;
5346 addr += coding->consumed;
5347 if (result == CODING_FINISH_INSUFFICIENT_SRC
5348 && nbytes > 0)
5350 /* The source text ends by an incomplete multibyte form.
5351 There's no way other than write it out as is. */
5352 nbytes -= emacs_write (desc, addr, nbytes);
5353 if (nbytes)
5355 return_val = -1;
5356 break;
5359 if (nbytes <= 0)
5360 break;
5361 start += coding->consumed_char;
5362 if (coding->cmp_data)
5363 coding_adjust_composition_offset (coding, start);
5366 if (coding->cmp_data)
5367 coding_free_composition_data (coding);
5369 return return_val;
5372 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
5373 Sverify_visited_file_modtime, 1, 1, 0,
5374 doc: /* Return t if last mod time of BUF's visited file matches what BUF records.
5375 This means that the file has not been changed since it was visited or saved. */)
5376 (buf)
5377 Lisp_Object buf;
5379 struct buffer *b;
5380 struct stat st;
5381 Lisp_Object handler;
5382 Lisp_Object filename;
5384 CHECK_BUFFER (buf);
5385 b = XBUFFER (buf);
5387 if (!STRINGP (b->filename)) return Qt;
5388 if (b->modtime == 0) return Qt;
5390 /* If the file name has special constructs in it,
5391 call the corresponding file handler. */
5392 handler = Ffind_file_name_handler (b->filename,
5393 Qverify_visited_file_modtime);
5394 if (!NILP (handler))
5395 return call2 (handler, Qverify_visited_file_modtime, buf);
5397 filename = ENCODE_FILE (b->filename);
5399 if (stat (XSTRING (filename)->data, &st) < 0)
5401 /* If the file doesn't exist now and didn't exist before,
5402 we say that it isn't modified, provided the error is a tame one. */
5403 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
5404 st.st_mtime = -1;
5405 else
5406 st.st_mtime = 0;
5408 if (st.st_mtime == b->modtime
5409 /* If both are positive, accept them if they are off by one second. */
5410 || (st.st_mtime > 0 && b->modtime > 0
5411 && (st.st_mtime == b->modtime + 1
5412 || st.st_mtime == b->modtime - 1)))
5413 return Qt;
5414 return Qnil;
5417 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
5418 Sclear_visited_file_modtime, 0, 0, 0,
5419 doc: /* Clear out records of last mod time of visited file.
5420 Next attempt to save will certainly not complain of a discrepancy. */)
5423 current_buffer->modtime = 0;
5424 return Qnil;
5427 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5428 Svisited_file_modtime, 0, 0, 0,
5429 doc: /* Return the current buffer's recorded visited file modification time.
5430 The value is a list of the form (HIGH . LOW), like the time values
5431 that `file-attributes' returns. */)
5434 return long_to_cons ((unsigned long) current_buffer->modtime);
5437 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
5438 Sset_visited_file_modtime, 0, 1, 0,
5439 doc: /* Update buffer's recorded modification time from the visited file's time.
5440 Useful if the buffer was not read from the file normally
5441 or if the file itself has been changed for some known benign reason.
5442 An argument specifies the modification time value to use
5443 \(instead of that of the visited file), in the form of a list
5444 \(HIGH . LOW) or (HIGH LOW). */)
5445 (time_list)
5446 Lisp_Object time_list;
5448 if (!NILP (time_list))
5449 current_buffer->modtime = cons_to_long (time_list);
5450 else
5452 register Lisp_Object filename;
5453 struct stat st;
5454 Lisp_Object handler;
5456 filename = Fexpand_file_name (current_buffer->filename, Qnil);
5458 /* If the file name has special constructs in it,
5459 call the corresponding file handler. */
5460 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
5461 if (!NILP (handler))
5462 /* The handler can find the file name the same way we did. */
5463 return call2 (handler, Qset_visited_file_modtime, Qnil);
5465 filename = ENCODE_FILE (filename);
5467 if (stat (XSTRING (filename)->data, &st) >= 0)
5468 current_buffer->modtime = st.st_mtime;
5471 return Qnil;
5474 Lisp_Object
5475 auto_save_error (error)
5476 Lisp_Object error;
5478 Lisp_Object args[3], msg;
5479 int i, nbytes;
5480 struct gcpro gcpro1;
5482 ring_bell ();
5484 args[0] = build_string ("Auto-saving %s: %s");
5485 args[1] = current_buffer->name;
5486 args[2] = Ferror_message_string (error);
5487 msg = Fformat (3, args);
5488 GCPRO1 (msg);
5489 nbytes = STRING_BYTES (XSTRING (msg));
5491 for (i = 0; i < 3; ++i)
5493 if (i == 0)
5494 message2 (XSTRING (msg)->data, nbytes, STRING_MULTIBYTE (msg));
5495 else
5496 message2_nolog (XSTRING (msg)->data, nbytes, STRING_MULTIBYTE (msg));
5497 Fsleep_for (make_number (1), Qnil);
5500 UNGCPRO;
5501 return Qnil;
5504 Lisp_Object
5505 auto_save_1 ()
5507 struct stat st;
5509 /* Get visited file's mode to become the auto save file's mode. */
5510 if (! NILP (current_buffer->filename)
5511 && stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
5512 /* But make sure we can overwrite it later! */
5513 auto_save_mode_bits = st.st_mode | 0600;
5514 else
5515 auto_save_mode_bits = 0666;
5517 return
5518 Fwrite_region (Qnil, Qnil,
5519 current_buffer->auto_save_file_name,
5520 Qnil, Qlambda, Qnil, Qnil);
5523 static Lisp_Object
5524 do_auto_save_unwind (stream) /* used as unwind-protect function */
5525 Lisp_Object stream;
5527 auto_saving = 0;
5528 if (!NILP (stream))
5529 fclose ((FILE *) (XFASTINT (XCAR (stream)) << 16
5530 | XFASTINT (XCDR (stream))));
5531 pop_message ();
5532 return Qnil;
5535 static Lisp_Object
5536 do_auto_save_unwind_1 (value) /* used as unwind-protect function */
5537 Lisp_Object value;
5539 minibuffer_auto_raise = XINT (value);
5540 return Qnil;
5543 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
5544 doc: /* Auto-save all buffers that need it.
5545 This is all buffers that have auto-saving enabled
5546 and are changed since last auto-saved.
5547 Auto-saving writes the buffer into a file
5548 so that your editing is not lost if the system crashes.
5549 This file is not the file you visited; that changes only when you save.
5550 Normally we run the normal hook `auto-save-hook' before saving.
5552 A non-nil NO-MESSAGE argument means do not print any message if successful.
5553 A non-nil CURRENT-ONLY argument means save only current buffer. */)
5554 (no_message, current_only)
5555 Lisp_Object no_message, current_only;
5557 struct buffer *old = current_buffer, *b;
5558 Lisp_Object tail, buf;
5559 int auto_saved = 0;
5560 int do_handled_files;
5561 Lisp_Object oquit;
5562 FILE *stream;
5563 Lisp_Object lispstream;
5564 int count = specpdl_ptr - specpdl;
5565 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
5566 int message_p = 0;
5568 if (max_specpdl_size < specpdl_size + 40)
5569 max_specpdl_size = specpdl_size + 40;
5571 if (minibuf_level)
5572 no_message = Qt;
5574 if (NILP (no_message));
5575 message_p = push_message ();
5577 /* Ordinarily don't quit within this function,
5578 but don't make it impossible to quit (in case we get hung in I/O). */
5579 oquit = Vquit_flag;
5580 Vquit_flag = Qnil;
5582 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
5583 point to non-strings reached from Vbuffer_alist. */
5585 if (!NILP (Vrun_hooks))
5586 call1 (Vrun_hooks, intern ("auto-save-hook"));
5588 if (STRINGP (Vauto_save_list_file_name))
5590 Lisp_Object listfile;
5592 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
5594 /* Don't try to create the directory when shutting down Emacs,
5595 because creating the directory might signal an error, and
5596 that would leave Emacs in a strange state. */
5597 if (!NILP (Vrun_hooks))
5599 Lisp_Object dir;
5600 dir = Ffile_name_directory (listfile);
5601 if (NILP (Ffile_directory_p (dir)))
5602 call2 (Qmake_directory, dir, Qt);
5605 stream = fopen (XSTRING (listfile)->data, "w");
5606 if (stream != NULL)
5608 /* Arrange to close that file whether or not we get an error.
5609 Also reset auto_saving to 0. */
5610 lispstream = Fcons (Qnil, Qnil);
5611 XSETCARFASTINT (lispstream, (EMACS_UINT)stream >> 16);
5612 XSETCDRFASTINT (lispstream, (EMACS_UINT)stream & 0xffff);
5614 else
5615 lispstream = Qnil;
5617 else
5619 stream = NULL;
5620 lispstream = Qnil;
5623 record_unwind_protect (do_auto_save_unwind, lispstream);
5624 record_unwind_protect (do_auto_save_unwind_1,
5625 make_number (minibuffer_auto_raise));
5626 minibuffer_auto_raise = 0;
5627 auto_saving = 1;
5629 /* First, save all files which don't have handlers. If Emacs is
5630 crashing, the handlers may tweak what is causing Emacs to crash
5631 in the first place, and it would be a shame if Emacs failed to
5632 autosave perfectly ordinary files because it couldn't handle some
5633 ange-ftp'd file. */
5634 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
5635 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCDR (tail))
5637 buf = XCDR (XCAR (tail));
5638 b = XBUFFER (buf);
5640 /* Record all the buffers that have auto save mode
5641 in the special file that lists them. For each of these buffers,
5642 Record visited name (if any) and auto save name. */
5643 if (STRINGP (b->auto_save_file_name)
5644 && stream != NULL && do_handled_files == 0)
5646 if (!NILP (b->filename))
5648 fwrite (XSTRING (b->filename)->data, 1,
5649 STRING_BYTES (XSTRING (b->filename)), stream);
5651 putc ('\n', stream);
5652 fwrite (XSTRING (b->auto_save_file_name)->data, 1,
5653 STRING_BYTES (XSTRING (b->auto_save_file_name)), stream);
5654 putc ('\n', stream);
5657 if (!NILP (current_only)
5658 && b != current_buffer)
5659 continue;
5661 /* Don't auto-save indirect buffers.
5662 The base buffer takes care of it. */
5663 if (b->base_buffer)
5664 continue;
5666 /* Check for auto save enabled
5667 and file changed since last auto save
5668 and file changed since last real save. */
5669 if (STRINGP (b->auto_save_file_name)
5670 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
5671 && b->auto_save_modified < BUF_MODIFF (b)
5672 /* -1 means we've turned off autosaving for a while--see below. */
5673 && XINT (b->save_length) >= 0
5674 && (do_handled_files
5675 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
5676 Qwrite_region))))
5678 EMACS_TIME before_time, after_time;
5680 EMACS_GET_TIME (before_time);
5682 /* If we had a failure, don't try again for 20 minutes. */
5683 if (b->auto_save_failure_time >= 0
5684 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
5685 continue;
5687 if ((XFASTINT (b->save_length) * 10
5688 > (BUF_Z (b) - BUF_BEG (b)) * 13)
5689 /* A short file is likely to change a large fraction;
5690 spare the user annoying messages. */
5691 && XFASTINT (b->save_length) > 5000
5692 /* These messages are frequent and annoying for `*mail*'. */
5693 && !EQ (b->filename, Qnil)
5694 && NILP (no_message))
5696 /* It has shrunk too much; turn off auto-saving here. */
5697 minibuffer_auto_raise = orig_minibuffer_auto_raise;
5698 message_with_string ("Buffer %s has shrunk a lot; auto save disabled in that buffer until next real save",
5699 b->name, 1);
5700 minibuffer_auto_raise = 0;
5701 /* Turn off auto-saving until there's a real save,
5702 and prevent any more warnings. */
5703 XSETINT (b->save_length, -1);
5704 Fsleep_for (make_number (1), Qnil);
5705 continue;
5707 set_buffer_internal (b);
5708 if (!auto_saved && NILP (no_message))
5709 message1 ("Auto-saving...");
5710 internal_condition_case (auto_save_1, Qt, auto_save_error);
5711 auto_saved++;
5712 b->auto_save_modified = BUF_MODIFF (b);
5713 XSETFASTINT (current_buffer->save_length, Z - BEG);
5714 set_buffer_internal (old);
5716 EMACS_GET_TIME (after_time);
5718 /* If auto-save took more than 60 seconds,
5719 assume it was an NFS failure that got a timeout. */
5720 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
5721 b->auto_save_failure_time = EMACS_SECS (after_time);
5725 /* Prevent another auto save till enough input events come in. */
5726 record_auto_save ();
5728 if (auto_saved && NILP (no_message))
5730 if (message_p)
5732 sit_for (1, 0, 0, 0, 0);
5733 restore_message ();
5735 else
5736 message1 ("Auto-saving...done");
5739 Vquit_flag = oquit;
5741 unbind_to (count, Qnil);
5742 return Qnil;
5745 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
5746 Sset_buffer_auto_saved, 0, 0, 0,
5747 doc: /* Mark current buffer as auto-saved with its current text.
5748 No auto-save file will be written until the buffer changes again. */)
5751 current_buffer->auto_save_modified = MODIFF;
5752 XSETFASTINT (current_buffer->save_length, Z - BEG);
5753 current_buffer->auto_save_failure_time = -1;
5754 return Qnil;
5757 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
5758 Sclear_buffer_auto_save_failure, 0, 0, 0,
5759 doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
5762 current_buffer->auto_save_failure_time = -1;
5763 return Qnil;
5766 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
5767 0, 0, 0,
5768 doc: /* Return t if buffer has been auto-saved since last read in or saved. */)
5771 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
5774 /* Reading and completing file names */
5775 extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
5777 /* In the string VAL, change each $ to $$ and return the result. */
5779 static Lisp_Object
5780 double_dollars (val)
5781 Lisp_Object val;
5783 register unsigned char *old, *new;
5784 register int n;
5785 int osize, count;
5787 osize = STRING_BYTES (XSTRING (val));
5789 /* Count the number of $ characters. */
5790 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
5791 if (*old++ == '$') count++;
5792 if (count > 0)
5794 old = XSTRING (val)->data;
5795 val = make_uninit_multibyte_string (XSTRING (val)->size + count,
5796 osize + count);
5797 new = XSTRING (val)->data;
5798 for (n = osize; n > 0; n--)
5799 if (*old != '$')
5800 *new++ = *old++;
5801 else
5803 *new++ = '$';
5804 *new++ = '$';
5805 old++;
5808 return val;
5811 DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
5812 3, 3, 0,
5813 doc: /* Internal subroutine for read-file-name. Do not call this. */)
5814 (string, dir, action)
5815 Lisp_Object string, dir, action;
5816 /* action is nil for complete, t for return list of completions,
5817 lambda for verify final value */
5819 Lisp_Object name, specdir, realdir, val, orig_string;
5820 int changed;
5821 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
5823 CHECK_STRING (string);
5825 realdir = dir;
5826 name = string;
5827 orig_string = Qnil;
5828 specdir = Qnil;
5829 changed = 0;
5830 /* No need to protect ACTION--we only compare it with t and nil. */
5831 GCPRO5 (string, realdir, name, specdir, orig_string);
5833 if (XSTRING (string)->size == 0)
5835 if (EQ (action, Qlambda))
5837 UNGCPRO;
5838 return Qnil;
5841 else
5843 orig_string = string;
5844 string = Fsubstitute_in_file_name (string);
5845 changed = NILP (Fstring_equal (string, orig_string));
5846 name = Ffile_name_nondirectory (string);
5847 val = Ffile_name_directory (string);
5848 if (! NILP (val))
5849 realdir = Fexpand_file_name (val, realdir);
5852 if (NILP (action))
5854 specdir = Ffile_name_directory (string);
5855 val = Ffile_name_completion (name, realdir);
5856 UNGCPRO;
5857 if (!STRINGP (val))
5859 if (changed)
5860 return double_dollars (string);
5861 return val;
5864 if (!NILP (specdir))
5865 val = concat2 (specdir, val);
5866 #ifndef VMS
5867 return double_dollars (val);
5868 #else /* not VMS */
5869 return val;
5870 #endif /* not VMS */
5872 UNGCPRO;
5874 if (EQ (action, Qt))
5875 return Ffile_name_all_completions (name, realdir);
5876 /* Only other case actually used is ACTION = lambda */
5877 #ifdef VMS
5878 /* Supposedly this helps commands such as `cd' that read directory names,
5879 but can someone explain how it helps them? -- RMS */
5880 if (XSTRING (name)->size == 0)
5881 return Qt;
5882 #endif /* VMS */
5883 return Ffile_exists_p (string);
5886 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
5887 doc: /* Read file name, prompting with PROMPT and completing in directory DIR.
5888 Value is not expanded---you must call `expand-file-name' yourself.
5889 Default name to DEFAULT-FILENAME if user enters a null string.
5890 (If DEFAULT-FILENAME is omitted, the visited file name is used,
5891 except that if INITIAL is specified, that combined with DIR is used.)
5892 Fourth arg MUSTMATCH non-nil means require existing file's name.
5893 Non-nil and non-t means also require confirmation after completion.
5894 Fifth arg INITIAL specifies text to start with.
5895 DIR defaults to current buffer's directory default.
5897 If this command was invoked with the mouse, use a file dialog box if
5898 `use-dialog-box' is non-nil, and the window system or X toolkit in use
5899 provides a file dialog box. */)
5900 (prompt, dir, default_filename, mustmatch, initial)
5901 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
5903 Lisp_Object val, insdef, tem;
5904 struct gcpro gcpro1, gcpro2;
5905 register char *homedir;
5906 int replace_in_history = 0;
5907 int add_to_history = 0;
5908 int count;
5910 if (NILP (dir))
5911 dir = current_buffer->directory;
5912 if (NILP (default_filename))
5914 if (! NILP (initial))
5915 default_filename = Fexpand_file_name (initial, dir);
5916 else
5917 default_filename = current_buffer->filename;
5920 /* If dir starts with user's homedir, change that to ~. */
5921 homedir = (char *) egetenv ("HOME");
5922 #ifdef DOS_NT
5923 /* homedir can be NULL in temacs, since Vprocess_environment is not
5924 yet set up. We shouldn't crash in that case. */
5925 if (homedir != 0)
5927 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
5928 CORRECT_DIR_SEPS (homedir);
5930 #endif
5931 if (homedir != 0
5932 && STRINGP (dir)
5933 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
5934 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
5936 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
5937 STRING_BYTES (XSTRING (dir)) - strlen (homedir) + 1);
5938 XSTRING (dir)->data[0] = '~';
5940 /* Likewise for default_filename. */
5941 if (homedir != 0
5942 && STRINGP (default_filename)
5943 && !strncmp (homedir, XSTRING (default_filename)->data, strlen (homedir))
5944 && IS_DIRECTORY_SEP (XSTRING (default_filename)->data[strlen (homedir)]))
5946 default_filename
5947 = make_string (XSTRING (default_filename)->data + strlen (homedir) - 1,
5948 STRING_BYTES (XSTRING (default_filename)) - strlen (homedir) + 1);
5949 XSTRING (default_filename)->data[0] = '~';
5951 if (!NILP (default_filename))
5953 CHECK_STRING (default_filename);
5954 default_filename = double_dollars (default_filename);
5957 if (insert_default_directory && STRINGP (dir))
5959 insdef = dir;
5960 if (!NILP (initial))
5962 Lisp_Object args[2], pos;
5964 args[0] = insdef;
5965 args[1] = initial;
5966 insdef = Fconcat (2, args);
5967 pos = make_number (XSTRING (double_dollars (dir))->size);
5968 insdef = Fcons (double_dollars (insdef), pos);
5970 else
5971 insdef = double_dollars (insdef);
5973 else if (STRINGP (initial))
5974 insdef = Fcons (double_dollars (initial), make_number (0));
5975 else
5976 insdef = Qnil;
5978 count = specpdl_ptr - specpdl;
5979 #ifdef VMS
5980 specbind (intern ("completion-ignore-case"), Qt);
5981 #endif
5983 specbind (intern ("minibuffer-completing-file-name"), Qt);
5985 GCPRO2 (insdef, default_filename);
5987 #if defined (USE_MOTIF) || defined (HAVE_NTGUI)
5988 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
5989 && use_dialog_box
5990 && have_menus_p ())
5992 /* If DIR contains a file name, split it. */
5993 Lisp_Object file;
5994 file = Ffile_name_nondirectory (dir);
5995 if (XSTRING (file)->size && NILP (default_filename))
5997 default_filename = file;
5998 dir = Ffile_name_directory (dir);
6000 if (!NILP(default_filename))
6001 default_filename = Fexpand_file_name (default_filename, dir);
6002 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch);
6003 add_to_history = 1;
6005 else
6006 #endif
6007 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
6008 dir, mustmatch, insdef,
6009 Qfile_name_history, default_filename, Qnil);
6011 tem = Fsymbol_value (Qfile_name_history);
6012 if (CONSP (tem) && EQ (XCAR (tem), val))
6013 replace_in_history = 1;
6015 /* If Fcompleting_read returned the inserted default string itself
6016 (rather than a new string with the same contents),
6017 it has to mean that the user typed RET with the minibuffer empty.
6018 In that case, we really want to return ""
6019 so that commands such as set-visited-file-name can distinguish. */
6020 if (EQ (val, default_filename))
6022 /* In this case, Fcompleting_read has not added an element
6023 to the history. Maybe we should. */
6024 if (! replace_in_history)
6025 add_to_history = 1;
6027 val = build_string ("");
6030 unbind_to (count, Qnil);
6031 UNGCPRO;
6032 if (NILP (val))
6033 error ("No file name specified");
6035 tem = Fstring_equal (val, CONSP (insdef) ? XCAR (insdef) : insdef);
6037 if (!NILP (tem) && !NILP (default_filename))
6038 val = default_filename;
6039 else if (XSTRING (val)->size == 0 && NILP (insdef))
6041 if (!NILP (default_filename))
6042 val = default_filename;
6043 else
6044 error ("No default file name");
6046 val = Fsubstitute_in_file_name (val);
6048 if (replace_in_history)
6049 /* Replace what Fcompleting_read added to the history
6050 with what we will actually return. */
6051 XSETCAR (Fsymbol_value (Qfile_name_history), double_dollars (val));
6052 else if (add_to_history)
6054 /* Add the value to the history--but not if it matches
6055 the last value already there. */
6056 Lisp_Object val1 = double_dollars (val);
6057 tem = Fsymbol_value (Qfile_name_history);
6058 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
6059 Fset (Qfile_name_history,
6060 Fcons (val1, tem));
6063 return val;
6067 void
6068 init_fileio_once ()
6070 /* Must be set before any path manipulation is performed. */
6071 XSETFASTINT (Vdirectory_sep_char, '/');
6075 void
6076 syms_of_fileio ()
6078 Qexpand_file_name = intern ("expand-file-name");
6079 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
6080 Qdirectory_file_name = intern ("directory-file-name");
6081 Qfile_name_directory = intern ("file-name-directory");
6082 Qfile_name_nondirectory = intern ("file-name-nondirectory");
6083 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
6084 Qfile_name_as_directory = intern ("file-name-as-directory");
6085 Qcopy_file = intern ("copy-file");
6086 Qmake_directory_internal = intern ("make-directory-internal");
6087 Qmake_directory = intern ("make-directory");
6088 Qdelete_directory = intern ("delete-directory");
6089 Qdelete_file = intern ("delete-file");
6090 Qrename_file = intern ("rename-file");
6091 Qadd_name_to_file = intern ("add-name-to-file");
6092 Qmake_symbolic_link = intern ("make-symbolic-link");
6093 Qfile_exists_p = intern ("file-exists-p");
6094 Qfile_executable_p = intern ("file-executable-p");
6095 Qfile_readable_p = intern ("file-readable-p");
6096 Qfile_writable_p = intern ("file-writable-p");
6097 Qfile_symlink_p = intern ("file-symlink-p");
6098 Qaccess_file = intern ("access-file");
6099 Qfile_directory_p = intern ("file-directory-p");
6100 Qfile_regular_p = intern ("file-regular-p");
6101 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
6102 Qfile_modes = intern ("file-modes");
6103 Qset_file_modes = intern ("set-file-modes");
6104 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
6105 Qinsert_file_contents = intern ("insert-file-contents");
6106 Qwrite_region = intern ("write-region");
6107 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
6108 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
6110 staticpro (&Qexpand_file_name);
6111 staticpro (&Qsubstitute_in_file_name);
6112 staticpro (&Qdirectory_file_name);
6113 staticpro (&Qfile_name_directory);
6114 staticpro (&Qfile_name_nondirectory);
6115 staticpro (&Qunhandled_file_name_directory);
6116 staticpro (&Qfile_name_as_directory);
6117 staticpro (&Qcopy_file);
6118 staticpro (&Qmake_directory_internal);
6119 staticpro (&Qmake_directory);
6120 staticpro (&Qdelete_directory);
6121 staticpro (&Qdelete_file);
6122 staticpro (&Qrename_file);
6123 staticpro (&Qadd_name_to_file);
6124 staticpro (&Qmake_symbolic_link);
6125 staticpro (&Qfile_exists_p);
6126 staticpro (&Qfile_executable_p);
6127 staticpro (&Qfile_readable_p);
6128 staticpro (&Qfile_writable_p);
6129 staticpro (&Qaccess_file);
6130 staticpro (&Qfile_symlink_p);
6131 staticpro (&Qfile_directory_p);
6132 staticpro (&Qfile_regular_p);
6133 staticpro (&Qfile_accessible_directory_p);
6134 staticpro (&Qfile_modes);
6135 staticpro (&Qset_file_modes);
6136 staticpro (&Qfile_newer_than_file_p);
6137 staticpro (&Qinsert_file_contents);
6138 staticpro (&Qwrite_region);
6139 staticpro (&Qverify_visited_file_modtime);
6140 staticpro (&Qset_visited_file_modtime);
6142 Qfile_name_history = intern ("file-name-history");
6143 Fset (Qfile_name_history, Qnil);
6144 staticpro (&Qfile_name_history);
6146 Qfile_error = intern ("file-error");
6147 staticpro (&Qfile_error);
6148 Qfile_already_exists = intern ("file-already-exists");
6149 staticpro (&Qfile_already_exists);
6150 Qfile_date_error = intern ("file-date-error");
6151 staticpro (&Qfile_date_error);
6152 Qexcl = intern ("excl");
6153 staticpro (&Qexcl);
6155 #ifdef DOS_NT
6156 Qfind_buffer_file_type = intern ("find-buffer-file-type");
6157 staticpro (&Qfind_buffer_file_type);
6158 #endif /* DOS_NT */
6160 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
6161 doc: /* *Coding system for encoding file names.
6162 If it is nil, `default-file-name-coding-system' (which see) is used. */);
6163 Vfile_name_coding_system = Qnil;
6165 DEFVAR_LISP ("default-file-name-coding-system",
6166 &Vdefault_file_name_coding_system,
6167 doc: /* Default coding system for encoding file names.
6168 This variable is used only when `file-name-coding-system' is nil.
6170 This variable is set/changed by the command `set-language-environment'.
6171 User should not set this variable manually,
6172 instead use `file-name-coding-system' to get a constant encoding
6173 of file names regardless of the current language environment. */);
6174 Vdefault_file_name_coding_system = Qnil;
6176 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
6177 doc: /* *Format in which to write auto-save files.
6178 Should be a list of symbols naming formats that are defined in `format-alist'.
6179 If it is t, which is the default, auto-save files are written in the
6180 same format as a regular save would use. */);
6181 Vauto_save_file_format = Qt;
6183 Qformat_decode = intern ("format-decode");
6184 staticpro (&Qformat_decode);
6185 Qformat_annotate_function = intern ("format-annotate-function");
6186 staticpro (&Qformat_annotate_function);
6188 Qcar_less_than_car = intern ("car-less-than-car");
6189 staticpro (&Qcar_less_than_car);
6191 Fput (Qfile_error, Qerror_conditions,
6192 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
6193 Fput (Qfile_error, Qerror_message,
6194 build_string ("File error"));
6196 Fput (Qfile_already_exists, Qerror_conditions,
6197 Fcons (Qfile_already_exists,
6198 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
6199 Fput (Qfile_already_exists, Qerror_message,
6200 build_string ("File already exists"));
6202 Fput (Qfile_date_error, Qerror_conditions,
6203 Fcons (Qfile_date_error,
6204 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
6205 Fput (Qfile_date_error, Qerror_message,
6206 build_string ("Cannot set file date"));
6208 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
6209 doc: /* *Non-nil means when reading a filename start with default dir in minibuffer. */);
6210 insert_default_directory = 1;
6212 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
6213 doc: /* *Non-nil means write new files with record format `stmlf'.
6214 nil means use format `var'. This variable is meaningful only on VMS. */);
6215 vms_stmlf_recfm = 0;
6217 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
6218 doc: /* Directory separator character for built-in functions that return file names.
6219 The value should be either ?/ or ?\\ (any other value is treated as ?\\).
6220 This variable affects the built-in functions only on Windows,
6221 on other platforms, it is initialized so that Lisp code can find out
6222 what the normal separator is.
6224 WARNING: This variable is deprecated and will be removed in the near
6225 future. DO NOT USE IT. */);
6227 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
6228 doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially.
6229 If a file name matches REGEXP, then all I/O on that file is done by calling
6230 HANDLER.
6232 The first argument given to HANDLER is the name of the I/O primitive
6233 to be handled; the remaining arguments are the arguments that were
6234 passed to that primitive. For example, if you do
6235 (file-exists-p FILENAME)
6236 and FILENAME is handled by HANDLER, then HANDLER is called like this:
6237 (funcall HANDLER 'file-exists-p FILENAME)
6238 The function `find-file-name-handler' checks this list for a handler
6239 for its argument. */);
6240 Vfile_name_handler_alist = Qnil;
6242 DEFVAR_LISP ("set-auto-coding-function",
6243 &Vset_auto_coding_function,
6244 doc: /* If non-nil, a function to call to decide a coding system of file.
6245 Two arguments are passed to this function: the file name
6246 and the length of a file contents following the point.
6247 This function should return a coding system to decode the file contents.
6248 It should check the file name against `auto-coding-alist'.
6249 If no coding system is decided, it should check a coding system
6250 specified in the heading lines with the format:
6251 -*- ... coding: CODING-SYSTEM; ... -*-
6252 or local variable spec of the tailing lines with `coding:' tag. */);
6253 Vset_auto_coding_function = Qnil;
6255 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
6256 doc: /* A list of functions to be called at the end of `insert-file-contents'.
6257 Each is passed one argument, the number of bytes inserted. It should return
6258 the new byte count, and leave point the same. If `insert-file-contents' is
6259 intercepted by a handler from `file-name-handler-alist', that handler is
6260 responsible for calling the after-insert-file-functions if appropriate. */);
6261 Vafter_insert_file_functions = Qnil;
6263 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
6264 doc: /* A list of functions to be called at the start of `write-region'.
6265 Each is passed two arguments, START and END as for `write-region'.
6266 These are usually two numbers but not always; see the documentation
6267 for `write-region'. The function should return a list of pairs
6268 of the form (POSITION . STRING), consisting of strings to be effectively
6269 inserted at the specified positions of the file being written (1 means to
6270 insert before the first byte written). The POSITIONs must be sorted into
6271 increasing order. If there are several functions in the list, the several
6272 lists are merged destructively. */);
6273 Vwrite_region_annotate_functions = Qnil;
6275 DEFVAR_LISP ("write-region-annotations-so-far",
6276 &Vwrite_region_annotations_so_far,
6277 doc: /* When an annotation function is called, this holds the previous annotations.
6278 These are the annotations made by other annotation functions
6279 that were already called. See also `write-region-annotate-functions'. */);
6280 Vwrite_region_annotations_so_far = Qnil;
6282 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
6283 doc: /* A list of file name handlers that temporarily should not be used.
6284 This applies only to the operation `inhibit-file-name-operation'. */);
6285 Vinhibit_file_name_handlers = Qnil;
6287 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
6288 doc: /* The operation for which `inhibit-file-name-handlers' is applicable. */);
6289 Vinhibit_file_name_operation = Qnil;
6291 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
6292 doc: /* File name in which we write a list of all auto save file names.
6293 This variable is initialized automatically from `auto-save-list-file-prefix'
6294 shortly after Emacs reads your `.emacs' file, if you have not yet given it
6295 a non-nil value. */);
6296 Vauto_save_list_file_name = Qnil;
6298 defsubr (&Sfind_file_name_handler);
6299 defsubr (&Sfile_name_directory);
6300 defsubr (&Sfile_name_nondirectory);
6301 defsubr (&Sunhandled_file_name_directory);
6302 defsubr (&Sfile_name_as_directory);
6303 defsubr (&Sdirectory_file_name);
6304 defsubr (&Smake_temp_name);
6305 defsubr (&Sexpand_file_name);
6306 defsubr (&Ssubstitute_in_file_name);
6307 defsubr (&Scopy_file);
6308 defsubr (&Smake_directory_internal);
6309 defsubr (&Sdelete_directory);
6310 defsubr (&Sdelete_file);
6311 defsubr (&Srename_file);
6312 defsubr (&Sadd_name_to_file);
6313 #ifdef S_IFLNK
6314 defsubr (&Smake_symbolic_link);
6315 #endif /* S_IFLNK */
6316 #ifdef VMS
6317 defsubr (&Sdefine_logical_name);
6318 #endif /* VMS */
6319 #ifdef HPUX_NET
6320 defsubr (&Ssysnetunam);
6321 #endif /* HPUX_NET */
6322 defsubr (&Sfile_name_absolute_p);
6323 defsubr (&Sfile_exists_p);
6324 defsubr (&Sfile_executable_p);
6325 defsubr (&Sfile_readable_p);
6326 defsubr (&Sfile_writable_p);
6327 defsubr (&Saccess_file);
6328 defsubr (&Sfile_symlink_p);
6329 defsubr (&Sfile_directory_p);
6330 defsubr (&Sfile_accessible_directory_p);
6331 defsubr (&Sfile_regular_p);
6332 defsubr (&Sfile_modes);
6333 defsubr (&Sset_file_modes);
6334 defsubr (&Sset_default_file_modes);
6335 defsubr (&Sdefault_file_modes);
6336 defsubr (&Sfile_newer_than_file_p);
6337 defsubr (&Sinsert_file_contents);
6338 defsubr (&Swrite_region);
6339 defsubr (&Scar_less_than_car);
6340 defsubr (&Sverify_visited_file_modtime);
6341 defsubr (&Sclear_visited_file_modtime);
6342 defsubr (&Svisited_file_modtime);
6343 defsubr (&Sset_visited_file_modtime);
6344 defsubr (&Sdo_auto_save);
6345 defsubr (&Sset_buffer_auto_saved);
6346 defsubr (&Sclear_buffer_auto_save_failure);
6347 defsubr (&Srecent_auto_save_p);
6349 defsubr (&Sread_file_name_internal);
6350 defsubr (&Sread_file_name);
6352 #ifdef unix
6353 defsubr (&Sunix_sync);
6354 #endif