(kill-comment): Fixed by rewriting it with syntax-tables rather than regexps
[emacs.git] / src / fileio.c
blobeafb1e61840395f03c5c0dd211608cbbb573f020
1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <config.h>
23 #if defined (USG5) || defined (BSD_SYSTEM) || defined (LINUX)
24 #include <fcntl.h>
25 #endif
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
35 #if !defined (S_ISLNK) && defined (S_IFLNK)
36 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
37 #endif
39 #if !defined (S_ISFIFO) && defined (S_IFIFO)
40 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
41 #endif
43 #if !defined (S_ISREG) && defined (S_IFREG)
44 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
45 #endif
47 #ifdef VMS
48 #include "vms-pwd.h"
49 #else
50 #include <pwd.h>
51 #endif
53 #include <ctype.h>
55 #ifdef VMS
56 #include "vmsdir.h"
57 #include <perror.h>
58 #include <stddef.h>
59 #include <string.h>
60 #endif
62 #include <errno.h>
64 #ifndef vax11c
65 extern int errno;
66 #endif
68 #ifdef APOLLO
69 #include <sys/time.h>
70 #endif
72 #ifndef USG
73 #ifndef VMS
74 #ifndef BSD4_1
75 #ifndef WINDOWSNT
76 #define HAVE_FSYNC
77 #endif
78 #endif
79 #endif
80 #endif
82 #include "lisp.h"
83 #include "intervals.h"
84 #include "buffer.h"
85 #include "charset.h"
86 #include "coding.h"
87 #include "window.h"
89 #ifdef WINDOWSNT
90 #define NOMINMAX 1
91 #include <windows.h>
92 #include <stdlib.h>
93 #include <fcntl.h>
94 #endif /* not WINDOWSNT */
96 #ifdef MSDOS
97 #include "msdos.h"
98 #include <sys/param.h>
99 #if __DJGPP__ >= 2
100 #include <fcntl.h>
101 #include <string.h>
102 #endif
103 #endif
105 #ifdef DOS_NT
106 #define CORRECT_DIR_SEPS(s) \
107 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
108 else unixtodos_filename (s); \
109 } while (0)
110 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
111 redirector allows the six letters between 'Z' and 'a' as well. */
112 #ifdef MSDOS
113 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
114 #endif
115 #ifdef WINDOWSNT
116 #define IS_DRIVE(x) isalpha (x)
117 #endif
118 /* Need to lower-case the drive letter, or else expanded
119 filenames will sometimes compare inequal, because
120 `expand-file-name' doesn't always down-case the drive letter. */
121 #define DRIVE_LETTER(x) (tolower (x))
122 #endif
124 #ifdef VMS
125 #include <file.h>
126 #include <rmsdef.h>
127 #include <fab.h>
128 #include <nam.h>
129 #endif
131 #include "systime.h"
133 #ifdef HPUX
134 #include <netio.h>
135 #ifndef HPUX8
136 #ifndef HPUX9
137 #include <errnet.h>
138 #endif
139 #endif
140 #endif
142 #include "commands.h"
143 extern int use_dialog_box;
145 #ifndef O_WRONLY
146 #define O_WRONLY 1
147 #endif
149 #ifndef O_RDONLY
150 #define O_RDONLY 0
151 #endif
153 #ifndef S_ISLNK
154 # define lstat stat
155 #endif
157 #define min(a, b) ((a) < (b) ? (a) : (b))
158 #define max(a, b) ((a) > (b) ? (a) : (b))
160 /* Nonzero during writing of auto-save files */
161 int auto_saving;
163 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
164 a new file with the same mode as the original */
165 int auto_save_mode_bits;
167 /* Coding system for file names, or nil if none. */
168 Lisp_Object Vfile_name_coding_system;
170 /* Coding system for file names used only when
171 Vfile_name_coding_system is nil. */
172 Lisp_Object Vdefault_file_name_coding_system;
174 /* Alist of elements (REGEXP . HANDLER) for file names
175 whose I/O is done with a special handler. */
176 Lisp_Object Vfile_name_handler_alist;
178 /* Format for auto-save files */
179 Lisp_Object Vauto_save_file_format;
181 /* Lisp functions for translating file formats */
182 Lisp_Object Qformat_decode, Qformat_annotate_function;
184 /* Function to be called to decide a coding system of a reading file. */
185 Lisp_Object Vset_auto_coding_function;
187 /* Functions to be called to process text properties in inserted file. */
188 Lisp_Object Vafter_insert_file_functions;
190 /* Functions to be called to create text property annotations for file. */
191 Lisp_Object Vwrite_region_annotate_functions;
193 /* During build_annotations, each time an annotation function is called,
194 this holds the annotations made by the previous functions. */
195 Lisp_Object Vwrite_region_annotations_so_far;
197 /* File name in which we write a list of all our auto save files. */
198 Lisp_Object Vauto_save_list_file_name;
200 /* Nonzero means, when reading a filename in the minibuffer,
201 start out by inserting the default directory into the minibuffer. */
202 int insert_default_directory;
204 /* On VMS, nonzero means write new files with record format stmlf.
205 Zero means use var format. */
206 int vms_stmlf_recfm;
208 /* On NT, specifies the directory separator character, used (eg.) when
209 expanding file names. This can be bound to / or \. */
210 Lisp_Object Vdirectory_sep_char;
212 extern Lisp_Object Vuser_login_name;
214 #ifdef WINDOWSNT
215 extern Lisp_Object Vw32_get_true_file_attributes;
216 #endif
218 extern int minibuf_level;
220 extern int minibuffer_auto_raise;
222 /* These variables describe handlers that have "already" had a chance
223 to handle the current operation.
225 Vinhibit_file_name_handlers is a list of file name handlers.
226 Vinhibit_file_name_operation is the operation being handled.
227 If we try to handle that operation, we ignore those handlers. */
229 static Lisp_Object Vinhibit_file_name_handlers;
230 static Lisp_Object Vinhibit_file_name_operation;
232 Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
233 Lisp_Object Qexcl;
234 Lisp_Object Qfile_name_history;
236 Lisp_Object Qcar_less_than_car;
238 static int a_write P_ ((int, char *, int, int,
239 Lisp_Object *, struct coding_system *));
240 static int e_write P_ ((int, char *, int, struct coding_system *));
242 void
243 report_file_error (string, data)
244 char *string;
245 Lisp_Object data;
247 Lisp_Object errstring;
248 int errorno = errno;
250 synchronize_system_messages_locale ();
251 errstring = code_convert_string_norecord (build_string (strerror (errorno)),
252 Vlocale_coding_system, 0);
254 while (1)
255 switch (errorno)
257 case EEXIST:
258 Fsignal (Qfile_already_exists, Fcons (errstring, data));
259 break;
260 default:
261 /* System error messages are capitalized. Downcase the initial
262 unless it is followed by a slash. */
263 if (XSTRING (errstring)->data[1] != '/')
264 XSTRING (errstring)->data[0] = DOWNCASE (XSTRING (errstring)->data[0]);
266 Fsignal (Qfile_error,
267 Fcons (build_string (string), Fcons (errstring, data)));
271 Lisp_Object
272 close_file_unwind (fd)
273 Lisp_Object fd;
275 emacs_close (XFASTINT (fd));
276 return Qnil;
279 /* Restore point, having saved it as a marker. */
281 static Lisp_Object
282 restore_point_unwind (location)
283 Lisp_Object location;
285 Fgoto_char (location);
286 Fset_marker (location, Qnil, Qnil);
287 return Qnil;
290 Lisp_Object Qexpand_file_name;
291 Lisp_Object Qsubstitute_in_file_name;
292 Lisp_Object Qdirectory_file_name;
293 Lisp_Object Qfile_name_directory;
294 Lisp_Object Qfile_name_nondirectory;
295 Lisp_Object Qunhandled_file_name_directory;
296 Lisp_Object Qfile_name_as_directory;
297 Lisp_Object Qcopy_file;
298 Lisp_Object Qmake_directory_internal;
299 Lisp_Object Qdelete_directory;
300 Lisp_Object Qdelete_file;
301 Lisp_Object Qrename_file;
302 Lisp_Object Qadd_name_to_file;
303 Lisp_Object Qmake_symbolic_link;
304 Lisp_Object Qfile_exists_p;
305 Lisp_Object Qfile_executable_p;
306 Lisp_Object Qfile_readable_p;
307 Lisp_Object Qfile_writable_p;
308 Lisp_Object Qfile_symlink_p;
309 Lisp_Object Qaccess_file;
310 Lisp_Object Qfile_directory_p;
311 Lisp_Object Qfile_regular_p;
312 Lisp_Object Qfile_accessible_directory_p;
313 Lisp_Object Qfile_modes;
314 Lisp_Object Qset_file_modes;
315 Lisp_Object Qfile_newer_than_file_p;
316 Lisp_Object Qinsert_file_contents;
317 Lisp_Object Qwrite_region;
318 Lisp_Object Qverify_visited_file_modtime;
319 Lisp_Object Qset_visited_file_modtime;
321 DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
322 "Return FILENAME's handler function for OPERATION, if it has one.\n\
323 Otherwise, return nil.\n\
324 A file name is handled if one of the regular expressions in\n\
325 `file-name-handler-alist' matches it.\n\n\
326 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
327 any handlers that are members of `inhibit-file-name-handlers',\n\
328 but we still do run any other handlers. This lets handlers\n\
329 use the standard functions without calling themselves recursively.")
330 (filename, operation)
331 Lisp_Object filename, operation;
333 /* This function must not munge the match data. */
334 Lisp_Object chain, inhibited_handlers;
336 CHECK_STRING (filename, 0);
338 if (EQ (operation, Vinhibit_file_name_operation))
339 inhibited_handlers = Vinhibit_file_name_handlers;
340 else
341 inhibited_handlers = Qnil;
343 for (chain = Vfile_name_handler_alist; CONSP (chain);
344 chain = XCDR (chain))
346 Lisp_Object elt;
347 elt = XCAR (chain);
348 if (CONSP (elt))
350 Lisp_Object string;
351 string = XCAR (elt);
352 if (STRINGP (string) && fast_string_match (string, filename) >= 0)
354 Lisp_Object handler, tem;
356 handler = XCDR (elt);
357 tem = Fmemq (handler, inhibited_handlers);
358 if (NILP (tem))
359 return handler;
363 QUIT;
365 return Qnil;
368 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
369 1, 1, 0,
370 "Return the directory component in file name FILENAME.\n\
371 Return nil if FILENAME does not include a directory.\n\
372 Otherwise return a directory spec.\n\
373 Given a Unix syntax file name, returns a string ending in slash;\n\
374 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
375 (filename)
376 Lisp_Object filename;
378 register unsigned char *beg;
379 register unsigned char *p;
380 Lisp_Object handler;
382 CHECK_STRING (filename, 0);
384 /* If the file name has special constructs in it,
385 call the corresponding file handler. */
386 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
387 if (!NILP (handler))
388 return call2 (handler, Qfile_name_directory, filename);
390 #ifdef FILE_SYSTEM_CASE
391 filename = FILE_SYSTEM_CASE (filename);
392 #endif
393 beg = XSTRING (filename)->data;
394 #ifdef DOS_NT
395 beg = strcpy (alloca (strlen (beg) + 1), beg);
396 #endif
397 p = beg + STRING_BYTES (XSTRING (filename));
399 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
400 #ifdef VMS
401 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
402 #endif /* VMS */
403 #ifdef DOS_NT
404 /* only recognise drive specifier at the beginning */
405 && !(p[-1] == ':'
406 /* handle the "/:d:foo" and "/:foo" cases correctly */
407 && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
408 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
409 #endif
410 ) p--;
412 if (p == beg)
413 return Qnil;
414 #ifdef DOS_NT
415 /* Expansion of "c:" to drive and default directory. */
416 if (p[-1] == ':')
418 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
419 unsigned char *res = alloca (MAXPATHLEN + 1);
420 unsigned char *r = res;
422 if (p == beg + 4 && IS_DIRECTORY_SEP (*beg) && beg[1] == ':')
424 strncpy (res, beg, 2);
425 beg += 2;
426 r += 2;
429 if (getdefdir (toupper (*beg) - 'A' + 1, r))
431 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
432 strcat (res, "/");
433 beg = res;
434 p = beg + strlen (beg);
437 CORRECT_DIR_SEPS (beg);
438 #endif /* DOS_NT */
440 if (STRING_MULTIBYTE (filename))
441 return make_string (beg, p - beg);
442 return make_unibyte_string (beg, p - beg);
445 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
446 Sfile_name_nondirectory, 1, 1, 0,
447 "Return file name FILENAME sans its directory.\n\
448 For example, in a Unix-syntax file name,\n\
449 this is everything after the last slash,\n\
450 or the entire name if it contains no slash.")
451 (filename)
452 Lisp_Object filename;
454 register unsigned char *beg, *p, *end;
455 Lisp_Object handler;
457 CHECK_STRING (filename, 0);
459 /* If the file name has special constructs in it,
460 call the corresponding file handler. */
461 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
462 if (!NILP (handler))
463 return call2 (handler, Qfile_name_nondirectory, filename);
465 beg = XSTRING (filename)->data;
466 end = p = beg + STRING_BYTES (XSTRING (filename));
468 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
469 #ifdef VMS
470 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
471 #endif /* VMS */
472 #ifdef DOS_NT
473 /* only recognise drive specifier at beginning */
474 && !(p[-1] == ':'
475 /* handle the "/:d:foo" case correctly */
476 && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
477 #endif
479 p--;
481 if (STRING_MULTIBYTE (filename))
482 return make_string (p, end - p);
483 return make_unibyte_string (p, end - p);
486 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory,
487 Sunhandled_file_name_directory, 1, 1, 0,
488 "Return a directly usable directory name somehow associated with FILENAME.\n\
489 A `directly usable' directory name is one that may be used without the\n\
490 intervention of any file handler.\n\
491 If FILENAME is a directly usable file itself, return\n\
492 \(file-name-directory FILENAME).\n\
493 The `call-process' and `start-process' functions use this function to\n\
494 get a current directory to run processes in.")
495 (filename)
496 Lisp_Object filename;
498 Lisp_Object handler;
500 /* If the file name has special constructs in it,
501 call the corresponding file handler. */
502 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
503 if (!NILP (handler))
504 return call2 (handler, Qunhandled_file_name_directory, filename);
506 return Ffile_name_directory (filename);
510 char *
511 file_name_as_directory (out, in)
512 char *out, *in;
514 int size = strlen (in) - 1;
516 strcpy (out, in);
518 if (size < 0)
520 out[0] = '.';
521 out[1] = '/';
522 out[2] = 0;
523 return out;
526 #ifdef VMS
527 /* Is it already a directory string? */
528 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
529 return out;
530 /* Is it a VMS directory file name? If so, hack VMS syntax. */
531 else if (! index (in, '/')
532 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
533 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
534 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
535 || ! strncmp (&in[size - 5], ".dir", 4))
536 && (in[size - 1] == '.' || in[size - 1] == ';')
537 && in[size] == '1')))
539 register char *p, *dot;
540 char brack;
542 /* x.dir -> [.x]
543 dir:x.dir --> dir:[x]
544 dir:[x]y.dir --> dir:[x.y] */
545 p = in + size;
546 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
547 if (p != in)
549 strncpy (out, in, p - in);
550 out[p - in] = '\0';
551 if (*p == ':')
553 brack = ']';
554 strcat (out, ":[");
556 else
558 brack = *p;
559 strcat (out, ".");
561 p++;
563 else
565 brack = ']';
566 strcpy (out, "[.");
568 dot = index (p, '.');
569 if (dot)
571 /* blindly remove any extension */
572 size = strlen (out) + (dot - p);
573 strncat (out, p, dot - p);
575 else
577 strcat (out, p);
578 size = strlen (out);
580 out[size++] = brack;
581 out[size] = '\0';
583 #else /* not VMS */
584 /* For Unix syntax, Append a slash if necessary */
585 if (!IS_DIRECTORY_SEP (out[size]))
587 out[size + 1] = DIRECTORY_SEP;
588 out[size + 2] = '\0';
590 #ifdef DOS_NT
591 CORRECT_DIR_SEPS (out);
592 #endif
593 #endif /* not VMS */
594 return out;
597 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
598 Sfile_name_as_directory, 1, 1, 0,
599 "Return a string representing file FILENAME interpreted as a directory.\n\
600 This operation exists because a directory is also a file, but its name as\n\
601 a directory is different from its name as a file.\n\
602 The result can be used as the value of `default-directory'\n\
603 or passed as second argument to `expand-file-name'.\n\
604 For a Unix-syntax file name, just appends a slash.\n\
605 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
606 (file)
607 Lisp_Object file;
609 char *buf;
610 Lisp_Object handler;
612 CHECK_STRING (file, 0);
613 if (NILP (file))
614 return Qnil;
616 /* If the file name has special constructs in it,
617 call the corresponding file handler. */
618 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
619 if (!NILP (handler))
620 return call2 (handler, Qfile_name_as_directory, file);
622 buf = (char *) alloca (STRING_BYTES (XSTRING (file)) + 10);
623 return build_string (file_name_as_directory (buf, XSTRING (file)->data));
627 * Convert from directory name to filename.
628 * On VMS:
629 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
630 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
631 * On UNIX, it's simple: just make sure there isn't a terminating /
633 * Value is nonzero if the string output is different from the input.
637 directory_file_name (src, dst)
638 char *src, *dst;
640 long slen;
641 #ifdef VMS
642 long rlen;
643 char * ptr, * rptr;
644 char bracket;
645 struct FAB fab = cc$rms_fab;
646 struct NAM nam = cc$rms_nam;
647 char esa[NAM$C_MAXRSS];
648 #endif /* VMS */
650 slen = strlen (src);
651 #ifdef VMS
652 if (! index (src, '/')
653 && (src[slen - 1] == ']'
654 || src[slen - 1] == ':'
655 || src[slen - 1] == '>'))
657 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
658 fab.fab$l_fna = src;
659 fab.fab$b_fns = slen;
660 fab.fab$l_nam = &nam;
661 fab.fab$l_fop = FAB$M_NAM;
663 nam.nam$l_esa = esa;
664 nam.nam$b_ess = sizeof esa;
665 nam.nam$b_nop |= NAM$M_SYNCHK;
667 /* We call SYS$PARSE to handle such things as [--] for us. */
668 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
670 slen = nam.nam$b_esl;
671 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
672 slen -= 2;
673 esa[slen] = '\0';
674 src = esa;
676 if (src[slen - 1] != ']' && src[slen - 1] != '>')
678 /* what about when we have logical_name:???? */
679 if (src[slen - 1] == ':')
680 { /* Xlate logical name and see what we get */
681 ptr = strcpy (dst, src); /* upper case for getenv */
682 while (*ptr)
684 if ('a' <= *ptr && *ptr <= 'z')
685 *ptr -= 040;
686 ptr++;
688 dst[slen - 1] = 0; /* remove colon */
689 if (!(src = egetenv (dst)))
690 return 0;
691 /* should we jump to the beginning of this procedure?
692 Good points: allows us to use logical names that xlate
693 to Unix names,
694 Bad points: can be a problem if we just translated to a device
695 name...
696 For now, I'll punt and always expect VMS names, and hope for
697 the best! */
698 slen = strlen (src);
699 if (src[slen - 1] != ']' && src[slen - 1] != '>')
700 { /* no recursion here! */
701 strcpy (dst, src);
702 return 0;
705 else
706 { /* not a directory spec */
707 strcpy (dst, src);
708 return 0;
711 bracket = src[slen - 1];
713 /* If bracket is ']' or '>', bracket - 2 is the corresponding
714 opening bracket. */
715 ptr = index (src, bracket - 2);
716 if (ptr == 0)
717 { /* no opening bracket */
718 strcpy (dst, src);
719 return 0;
721 if (!(rptr = rindex (src, '.')))
722 rptr = ptr;
723 slen = rptr - src;
724 strncpy (dst, src, slen);
725 dst[slen] = '\0';
726 if (*rptr == '.')
728 dst[slen++] = bracket;
729 dst[slen] = '\0';
731 else
733 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
734 then translate the device and recurse. */
735 if (dst[slen - 1] == ':'
736 && dst[slen - 2] != ':' /* skip decnet nodes */
737 && strcmp (src + slen, "[000000]") == 0)
739 dst[slen - 1] = '\0';
740 if ((ptr = egetenv (dst))
741 && (rlen = strlen (ptr) - 1) > 0
742 && (ptr[rlen] == ']' || ptr[rlen] == '>')
743 && ptr[rlen - 1] == '.')
745 char * buf = (char *) alloca (strlen (ptr) + 1);
746 strcpy (buf, ptr);
747 buf[rlen - 1] = ']';
748 buf[rlen] = '\0';
749 return directory_file_name (buf, dst);
751 else
752 dst[slen - 1] = ':';
754 strcat (dst, "[000000]");
755 slen += 8;
757 rptr++;
758 rlen = strlen (rptr) - 1;
759 strncat (dst, rptr, rlen);
760 dst[slen + rlen] = '\0';
761 strcat (dst, ".DIR.1");
762 return 1;
764 #endif /* VMS */
765 /* Process as Unix format: just remove any final slash.
766 But leave "/" unchanged; do not change it to "". */
767 strcpy (dst, src);
768 #ifdef APOLLO
769 /* Handle // as root for apollo's. */
770 if ((slen > 2 && dst[slen - 1] == '/')
771 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
772 dst[slen - 1] = 0;
773 #else
774 if (slen > 1
775 && IS_DIRECTORY_SEP (dst[slen - 1])
776 #ifdef DOS_NT
777 && !IS_ANY_SEP (dst[slen - 2])
778 #endif
780 dst[slen - 1] = 0;
781 #endif
782 #ifdef DOS_NT
783 CORRECT_DIR_SEPS (dst);
784 #endif
785 return 1;
788 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
789 1, 1, 0,
790 "Returns the file name of the directory named DIRECTORY.\n\
791 This is the name of the file that holds the data for the directory DIRECTORY.\n\
792 This operation exists because a directory is also a file, but its name as\n\
793 a directory is different from its name as a file.\n\
794 In Unix-syntax, this function just removes the final slash.\n\
795 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
796 it returns a file name such as \"[X]Y.DIR.1\".")
797 (directory)
798 Lisp_Object directory;
800 char *buf;
801 Lisp_Object handler;
803 CHECK_STRING (directory, 0);
805 if (NILP (directory))
806 return Qnil;
808 /* If the file name has special constructs in it,
809 call the corresponding file handler. */
810 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
811 if (!NILP (handler))
812 return call2 (handler, Qdirectory_file_name, directory);
814 #ifdef VMS
815 /* 20 extra chars is insufficient for VMS, since we might perform a
816 logical name translation. an equivalence string can be up to 255
817 chars long, so grab that much extra space... - sss */
818 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20 + 255);
819 #else
820 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20);
821 #endif
822 directory_file_name (XSTRING (directory)->data, buf);
823 return build_string (buf);
826 static char make_temp_name_tbl[64] =
828 'A','B','C','D','E','F','G','H',
829 'I','J','K','L','M','N','O','P',
830 'Q','R','S','T','U','V','W','X',
831 'Y','Z','a','b','c','d','e','f',
832 'g','h','i','j','k','l','m','n',
833 'o','p','q','r','s','t','u','v',
834 'w','x','y','z','0','1','2','3',
835 '4','5','6','7','8','9','-','_'
837 static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
839 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
840 "Generate temporary file name (string) starting with PREFIX (a string).\n\
841 The Emacs process number forms part of the result,\n\
842 so there is no danger of generating a name being used by another process.\n\
844 In addition, this function makes an attempt to choose a name\n\
845 which has no existing file. To make this work,\n\
846 PREFIX should be an absolute file name.\n\
848 There is a race condition between calling `make-temp-name' and creating the\n\
849 file which opens all kinds of security holes. For that reason, you should\n\
850 probably use `make-temp-file' instead.")
851 (prefix)
852 Lisp_Object prefix;
854 Lisp_Object val;
855 int len;
856 int pid;
857 unsigned char *p, *data;
858 char pidbuf[20];
859 int pidlen;
861 CHECK_STRING (prefix, 0);
863 /* VAL is created by adding 6 characters to PREFIX. The first
864 three are the PID of this process, in base 64, and the second
865 three are incremented if the file already exists. This ensures
866 262144 unique file names per PID per PREFIX. */
868 pid = (int) getpid ();
870 #ifdef HAVE_LONG_FILE_NAMES
871 sprintf (pidbuf, "%d", pid);
872 pidlen = strlen (pidbuf);
873 #else
874 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
875 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
876 pidbuf[2] = make_temp_name_tbl[pid & 63], pid >>= 6;
877 pidlen = 3;
878 #endif
880 len = XSTRING (prefix)->size;
881 val = make_uninit_string (len + 3 + pidlen);
882 data = XSTRING (val)->data;
883 bcopy(XSTRING (prefix)->data, data, len);
884 p = data + len;
886 bcopy (pidbuf, p, pidlen);
887 p += pidlen;
889 /* Here we try to minimize useless stat'ing when this function is
890 invoked many times successively with the same PREFIX. We achieve
891 this by initializing count to a random value, and incrementing it
892 afterwards.
894 We don't want make-temp-name to be called while dumping,
895 because then make_temp_name_count_initialized_p would get set
896 and then make_temp_name_count would not be set when Emacs starts. */
898 if (!make_temp_name_count_initialized_p)
900 make_temp_name_count = (unsigned) time (NULL);
901 make_temp_name_count_initialized_p = 1;
904 while (1)
906 struct stat ignored;
907 unsigned num = make_temp_name_count;
909 p[0] = make_temp_name_tbl[num & 63], num >>= 6;
910 p[1] = make_temp_name_tbl[num & 63], num >>= 6;
911 p[2] = make_temp_name_tbl[num & 63], num >>= 6;
913 /* Poor man's congruential RN generator. Replace with
914 ++make_temp_name_count for debugging. */
915 make_temp_name_count += 25229;
916 make_temp_name_count %= 225307;
918 if (stat (data, &ignored) < 0)
920 /* We want to return only if errno is ENOENT. */
921 if (errno == ENOENT)
922 return val;
923 else
924 /* The error here is dubious, but there is little else we
925 can do. The alternatives are to return nil, which is
926 as bad as (and in many cases worse than) throwing the
927 error, or to ignore the error, which will likely result
928 in looping through 225307 stat's, which is not only
929 dog-slow, but also useless since it will fallback to
930 the errow below, anyway. */
931 report_file_error ("Cannot create temporary name for prefix `%s'",
932 Fcons (prefix, Qnil));
933 /* not reached */
937 error ("Cannot create temporary name for prefix `%s'",
938 XSTRING (prefix)->data);
939 return Qnil;
943 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
944 "Convert filename NAME to absolute, and canonicalize it.\n\
945 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
946 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
947 the current buffer's value of default-directory is used.\n\
948 File name components that are `.' are removed, and \n\
949 so are file name components followed by `..', along with the `..' itself;\n\
950 note that these simplifications are done without checking the resulting\n\
951 file names in the file system.\n\
952 An initial `~/' expands to your home directory.\n\
953 An initial `~USER/' expands to USER's home directory.\n\
954 See also the function `substitute-in-file-name'.")
955 (name, default_directory)
956 Lisp_Object name, default_directory;
958 unsigned char *nm;
960 register unsigned char *newdir, *p, *o;
961 int tlen;
962 unsigned char *target;
963 struct passwd *pw;
964 #ifdef VMS
965 unsigned char * colon = 0;
966 unsigned char * close = 0;
967 unsigned char * slash = 0;
968 unsigned char * brack = 0;
969 int lbrack = 0, rbrack = 0;
970 int dots = 0;
971 #endif /* VMS */
972 #ifdef DOS_NT
973 int drive = 0;
974 int collapse_newdir = 1;
975 int is_escaped = 0;
976 #endif /* DOS_NT */
977 int length;
978 Lisp_Object handler;
980 CHECK_STRING (name, 0);
982 /* If the file name has special constructs in it,
983 call the corresponding file handler. */
984 handler = Ffind_file_name_handler (name, Qexpand_file_name);
985 if (!NILP (handler))
986 return call3 (handler, Qexpand_file_name, name, default_directory);
988 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
989 if (NILP (default_directory))
990 default_directory = current_buffer->directory;
991 if (! STRINGP (default_directory))
992 default_directory = build_string ("/");
994 if (!NILP (default_directory))
996 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
997 if (!NILP (handler))
998 return call3 (handler, Qexpand_file_name, name, default_directory);
1001 o = XSTRING (default_directory)->data;
1003 /* Make sure DEFAULT_DIRECTORY is properly expanded.
1004 It would be better to do this down below where we actually use
1005 default_directory. Unfortunately, calling Fexpand_file_name recursively
1006 could invoke GC, and the strings might be relocated. This would
1007 be annoying because we have pointers into strings lying around
1008 that would need adjusting, and people would add new pointers to
1009 the code and forget to adjust them, resulting in intermittent bugs.
1010 Putting this call here avoids all that crud.
1012 The EQ test avoids infinite recursion. */
1013 if (! NILP (default_directory) && !EQ (default_directory, name)
1014 /* Save time in some common cases - as long as default_directory
1015 is not relative, it can be canonicalized with name below (if it
1016 is needed at all) without requiring it to be expanded now. */
1017 #ifdef DOS_NT
1018 /* Detect MSDOS file names with drive specifiers. */
1019 && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))
1020 #ifdef WINDOWSNT
1021 /* Detect Windows file names in UNC format. */
1022 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
1023 #endif
1024 #else /* not DOS_NT */
1025 /* Detect Unix absolute file names (/... alone is not absolute on
1026 DOS or Windows). */
1027 && ! (IS_DIRECTORY_SEP (o[0]))
1028 #endif /* not DOS_NT */
1031 struct gcpro gcpro1;
1033 GCPRO1 (name);
1034 default_directory = Fexpand_file_name (default_directory, Qnil);
1035 UNGCPRO;
1038 #ifdef VMS
1039 /* Filenames on VMS are always upper case. */
1040 name = Fupcase (name);
1041 #endif
1042 #ifdef FILE_SYSTEM_CASE
1043 name = FILE_SYSTEM_CASE (name);
1044 #endif
1046 nm = XSTRING (name)->data;
1048 #ifdef DOS_NT
1049 /* We will force directory separators to be either all \ or /, so make
1050 a local copy to modify, even if there ends up being no change. */
1051 nm = strcpy (alloca (strlen (nm) + 1), nm);
1053 /* Note if special escape prefix is present, but remove for now. */
1054 if (nm[0] == '/' && nm[1] == ':')
1056 is_escaped = 1;
1057 nm += 2;
1060 /* Find and remove drive specifier if present; this makes nm absolute
1061 even if the rest of the name appears to be relative. Only look for
1062 drive specifier at the beginning. */
1063 if (IS_DRIVE (nm[0]) && IS_DEVICE_SEP (nm[1]))
1065 drive = nm[0];
1066 nm += 2;
1069 #ifdef WINDOWSNT
1070 /* If we see "c://somedir", we want to strip the first slash after the
1071 colon when stripping the drive letter. Otherwise, this expands to
1072 "//somedir". */
1073 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1074 nm++;
1075 #endif /* WINDOWSNT */
1076 #endif /* DOS_NT */
1078 #ifdef WINDOWSNT
1079 /* Discard any previous drive specifier if nm is now in UNC format. */
1080 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1082 drive = 0;
1084 #endif
1086 /* If nm is absolute, look for /./ or /../ sequences; if none are
1087 found, we can probably return right away. We will avoid allocating
1088 a new string if name is already fully expanded. */
1089 if (
1090 IS_DIRECTORY_SEP (nm[0])
1091 #ifdef MSDOS
1092 && drive && !is_escaped
1093 #endif
1094 #ifdef WINDOWSNT
1095 && (drive || IS_DIRECTORY_SEP (nm[1])) && !is_escaped
1096 #endif
1097 #ifdef VMS
1098 || index (nm, ':')
1099 #endif /* VMS */
1102 /* If it turns out that the filename we want to return is just a
1103 suffix of FILENAME, we don't need to go through and edit
1104 things; we just need to construct a new string using data
1105 starting at the middle of FILENAME. If we set lose to a
1106 non-zero value, that means we've discovered that we can't do
1107 that cool trick. */
1108 int lose = 0;
1110 p = nm;
1111 while (*p)
1113 /* Since we know the name is absolute, we can assume that each
1114 element starts with a "/". */
1116 /* "." and ".." are hairy. */
1117 if (IS_DIRECTORY_SEP (p[0])
1118 && p[1] == '.'
1119 && (IS_DIRECTORY_SEP (p[2])
1120 || p[2] == 0
1121 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
1122 || p[3] == 0))))
1123 lose = 1;
1124 #ifdef VMS
1125 if (p[0] == '\\')
1126 lose = 1;
1127 if (p[0] == '/') {
1128 /* if dev:[dir]/, move nm to / */
1129 if (!slash && p > nm && (brack || colon)) {
1130 nm = (brack ? brack + 1 : colon + 1);
1131 lbrack = rbrack = 0;
1132 brack = 0;
1133 colon = 0;
1135 slash = p;
1137 if (p[0] == '-')
1138 #ifndef VMS4_4
1139 /* VMS pre V4.4,convert '-'s in filenames. */
1140 if (lbrack == rbrack)
1142 if (dots < 2) /* this is to allow negative version numbers */
1143 p[0] = '_';
1145 else
1146 #endif /* VMS4_4 */
1147 if (lbrack > rbrack &&
1148 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1149 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1150 lose = 1;
1151 #ifndef VMS4_4
1152 else
1153 p[0] = '_';
1154 #endif /* VMS4_4 */
1155 /* count open brackets, reset close bracket pointer */
1156 if (p[0] == '[' || p[0] == '<')
1157 lbrack++, brack = 0;
1158 /* count close brackets, set close bracket pointer */
1159 if (p[0] == ']' || p[0] == '>')
1160 rbrack++, brack = p;
1161 /* detect ][ or >< */
1162 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1163 lose = 1;
1164 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1165 nm = p + 1, lose = 1;
1166 if (p[0] == ':' && (colon || slash))
1167 /* if dev1:[dir]dev2:, move nm to dev2: */
1168 if (brack)
1170 nm = brack + 1;
1171 brack = 0;
1173 /* if /name/dev:, move nm to dev: */
1174 else if (slash)
1175 nm = slash + 1;
1176 /* if node::dev:, move colon following dev */
1177 else if (colon && colon[-1] == ':')
1178 colon = p;
1179 /* if dev1:dev2:, move nm to dev2: */
1180 else if (colon && colon[-1] != ':')
1182 nm = colon + 1;
1183 colon = 0;
1185 if (p[0] == ':' && !colon)
1187 if (p[1] == ':')
1188 p++;
1189 colon = p;
1191 if (lbrack == rbrack)
1192 if (p[0] == ';')
1193 dots = 2;
1194 else if (p[0] == '.')
1195 dots++;
1196 #endif /* VMS */
1197 p++;
1199 if (!lose)
1201 #ifdef VMS
1202 if (index (nm, '/'))
1203 return build_string (sys_translate_unix (nm));
1204 #endif /* VMS */
1205 #ifdef DOS_NT
1206 /* Make sure directories are all separated with / or \ as
1207 desired, but avoid allocation of a new string when not
1208 required. */
1209 CORRECT_DIR_SEPS (nm);
1210 #ifdef WINDOWSNT
1211 if (IS_DIRECTORY_SEP (nm[1]))
1213 if (strcmp (nm, XSTRING (name)->data) != 0)
1214 name = build_string (nm);
1216 else
1217 #endif
1218 /* drive must be set, so this is okay */
1219 if (strcmp (nm - 2, XSTRING (name)->data) != 0)
1221 name = make_string (nm - 2, p - nm + 2);
1222 XSTRING (name)->data[0] = DRIVE_LETTER (drive);
1223 XSTRING (name)->data[1] = ':';
1225 return name;
1226 #else /* not DOS_NT */
1227 if (nm == XSTRING (name)->data)
1228 return name;
1229 return build_string (nm);
1230 #endif /* not DOS_NT */
1234 /* At this point, nm might or might not be an absolute file name. We
1235 need to expand ~ or ~user if present, otherwise prefix nm with
1236 default_directory if nm is not absolute, and finally collapse /./
1237 and /foo/../ sequences.
1239 We set newdir to be the appropriate prefix if one is needed:
1240 - the relevant user directory if nm starts with ~ or ~user
1241 - the specified drive's working dir (DOS/NT only) if nm does not
1242 start with /
1243 - the value of default_directory.
1245 Note that these prefixes are not guaranteed to be absolute (except
1246 for the working dir of a drive). Therefore, to ensure we always
1247 return an absolute name, if the final prefix is not absolute we
1248 append it to the current working directory. */
1250 newdir = 0;
1252 if (nm[0] == '~') /* prefix ~ */
1254 if (IS_DIRECTORY_SEP (nm[1])
1255 #ifdef VMS
1256 || nm[1] == ':'
1257 #endif /* VMS */
1258 || nm[1] == 0) /* ~ by itself */
1260 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1261 newdir = (unsigned char *) "";
1262 nm++;
1263 #ifdef DOS_NT
1264 collapse_newdir = 0;
1265 #endif
1266 #ifdef VMS
1267 nm++; /* Don't leave the slash in nm. */
1268 #endif /* VMS */
1270 else /* ~user/filename */
1272 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
1273 #ifdef VMS
1274 && *p != ':'
1275 #endif /* VMS */
1276 ); p++);
1277 o = (unsigned char *) alloca (p - nm + 1);
1278 bcopy ((char *) nm, o, p - nm);
1279 o [p - nm] = 0;
1281 pw = (struct passwd *) getpwnam (o + 1);
1282 if (pw)
1284 newdir = (unsigned char *) pw -> pw_dir;
1285 #ifdef VMS
1286 nm = p + 1; /* skip the terminator */
1287 #else
1288 nm = p;
1289 #ifdef DOS_NT
1290 collapse_newdir = 0;
1291 #endif
1292 #endif /* VMS */
1295 /* If we don't find a user of that name, leave the name
1296 unchanged; don't move nm forward to p. */
1300 #ifdef DOS_NT
1301 /* On DOS and Windows, nm is absolute if a drive name was specified;
1302 use the drive's current directory as the prefix if needed. */
1303 if (!newdir && drive)
1305 /* Get default directory if needed to make nm absolute. */
1306 if (!IS_DIRECTORY_SEP (nm[0]))
1308 newdir = alloca (MAXPATHLEN + 1);
1309 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1310 newdir = NULL;
1312 if (!newdir)
1314 /* Either nm starts with /, or drive isn't mounted. */
1315 newdir = alloca (4);
1316 newdir[0] = DRIVE_LETTER (drive);
1317 newdir[1] = ':';
1318 newdir[2] = '/';
1319 newdir[3] = 0;
1322 #endif /* DOS_NT */
1324 /* Finally, if no prefix has been specified and nm is not absolute,
1325 then it must be expanded relative to default_directory. */
1327 if (1
1328 #ifndef DOS_NT
1329 /* /... alone is not absolute on DOS and Windows. */
1330 && !IS_DIRECTORY_SEP (nm[0])
1331 #endif
1332 #ifdef WINDOWSNT
1333 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1334 #endif
1335 #ifdef VMS
1336 && !index (nm, ':')
1337 #endif
1338 && !newdir)
1340 newdir = XSTRING (default_directory)->data;
1341 #ifdef DOS_NT
1342 /* Note if special escape prefix is present, but remove for now. */
1343 if (newdir[0] == '/' && newdir[1] == ':')
1345 is_escaped = 1;
1346 newdir += 2;
1348 #endif
1351 #ifdef DOS_NT
1352 if (newdir)
1354 /* First ensure newdir is an absolute name. */
1355 if (
1356 /* Detect MSDOS file names with drive specifiers. */
1357 ! (IS_DRIVE (newdir[0])
1358 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1359 #ifdef WINDOWSNT
1360 /* Detect Windows file names in UNC format. */
1361 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1362 #endif
1365 /* Effectively, let newdir be (expand-file-name newdir cwd).
1366 Because of the admonition against calling expand-file-name
1367 when we have pointers into lisp strings, we accomplish this
1368 indirectly by prepending newdir to nm if necessary, and using
1369 cwd (or the wd of newdir's drive) as the new newdir. */
1371 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1373 drive = newdir[0];
1374 newdir += 2;
1376 if (!IS_DIRECTORY_SEP (nm[0]))
1378 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1379 file_name_as_directory (tmp, newdir);
1380 strcat (tmp, nm);
1381 nm = tmp;
1383 newdir = alloca (MAXPATHLEN + 1);
1384 if (drive)
1386 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1387 newdir = "/";
1389 else
1390 getwd (newdir);
1393 /* Strip off drive name from prefix, if present. */
1394 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1396 drive = newdir[0];
1397 newdir += 2;
1400 /* Keep only a prefix from newdir if nm starts with slash
1401 (//server/share for UNC, nothing otherwise). */
1402 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1404 #ifdef WINDOWSNT
1405 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1407 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1408 p = newdir + 2;
1409 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1410 p++;
1411 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1412 *p = 0;
1414 else
1415 #endif
1416 newdir = "";
1419 #endif /* DOS_NT */
1421 if (newdir)
1423 /* Get rid of any slash at the end of newdir, unless newdir is
1424 just / or // (an incomplete UNC name). */
1425 length = strlen (newdir);
1426 if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1427 #ifdef WINDOWSNT
1428 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1429 #endif
1432 unsigned char *temp = (unsigned char *) alloca (length);
1433 bcopy (newdir, temp, length - 1);
1434 temp[length - 1] = 0;
1435 newdir = temp;
1437 tlen = length + 1;
1439 else
1440 tlen = 0;
1442 /* Now concatenate the directory and name to new space in the stack frame */
1443 tlen += strlen (nm) + 1;
1444 #ifdef DOS_NT
1445 /* Reserve space for drive specifier and escape prefix, since either
1446 or both may need to be inserted. (The Microsoft x86 compiler
1447 produces incorrect code if the following two lines are combined.) */
1448 target = (unsigned char *) alloca (tlen + 4);
1449 target += 4;
1450 #else /* not DOS_NT */
1451 target = (unsigned char *) alloca (tlen);
1452 #endif /* not DOS_NT */
1453 *target = 0;
1455 if (newdir)
1457 #ifndef VMS
1458 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1460 #ifdef DOS_NT
1461 /* If newdir is effectively "C:/", then the drive letter will have
1462 been stripped and newdir will be "/". Concatenating with an
1463 absolute directory in nm produces "//", which will then be
1464 incorrectly treated as a network share. Ignore newdir in
1465 this case (keeping the drive letter). */
1466 if (!(drive && nm[0] && IS_DIRECTORY_SEP (newdir[0])
1467 && newdir[1] == '\0'))
1468 #endif
1469 strcpy (target, newdir);
1471 else
1472 #endif
1473 file_name_as_directory (target, newdir);
1476 strcat (target, nm);
1477 #ifdef VMS
1478 if (index (target, '/'))
1479 strcpy (target, sys_translate_unix (target));
1480 #endif /* VMS */
1482 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1484 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1486 p = target;
1487 o = target;
1489 while (*p)
1491 #ifdef VMS
1492 if (*p != ']' && *p != '>' && *p != '-')
1494 if (*p == '\\')
1495 p++;
1496 *o++ = *p++;
1498 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1499 /* brackets are offset from each other by 2 */
1501 p += 2;
1502 if (*p != '.' && *p != '-' && o[-1] != '.')
1503 /* convert [foo][bar] to [bar] */
1504 while (o[-1] != '[' && o[-1] != '<')
1505 o--;
1506 else if (*p == '-' && *o != '.')
1507 *--p = '.';
1509 else if (p[0] == '-' && o[-1] == '.' &&
1510 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1511 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1514 o--;
1515 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1516 if (p[1] == '.') /* foo.-.bar ==> bar. */
1517 p += 2;
1518 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1519 p++, o--;
1520 /* else [foo.-] ==> [-] */
1522 else
1524 #ifndef VMS4_4
1525 if (*p == '-' &&
1526 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1527 p[1] != ']' && p[1] != '>' && p[1] != '.')
1528 *p = '_';
1529 #endif /* VMS4_4 */
1530 *o++ = *p++;
1532 #else /* not VMS */
1533 if (!IS_DIRECTORY_SEP (*p))
1535 *o++ = *p++;
1537 else if (IS_DIRECTORY_SEP (p[0])
1538 && p[1] == '.'
1539 && (IS_DIRECTORY_SEP (p[2])
1540 || p[2] == 0))
1542 /* If "/." is the entire filename, keep the "/". Otherwise,
1543 just delete the whole "/.". */
1544 if (o == target && p[2] == '\0')
1545 *o++ = *p;
1546 p += 2;
1548 else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1549 /* `/../' is the "superroot" on certain file systems. */
1550 && o != target
1551 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1553 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1555 /* Keep initial / only if this is the whole name. */
1556 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1557 ++o;
1558 p += 3;
1560 else
1562 *o++ = *p++;
1564 #endif /* not VMS */
1567 #ifdef DOS_NT
1568 /* At last, set drive name. */
1569 #ifdef WINDOWSNT
1570 /* Except for network file name. */
1571 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1572 #endif /* WINDOWSNT */
1574 if (!drive) abort ();
1575 target -= 2;
1576 target[0] = DRIVE_LETTER (drive);
1577 target[1] = ':';
1579 /* Reinsert the escape prefix if required. */
1580 if (is_escaped)
1582 target -= 2;
1583 target[0] = '/';
1584 target[1] = ':';
1586 CORRECT_DIR_SEPS (target);
1587 #endif /* DOS_NT */
1589 return make_string (target, o - target);
1592 #if 0
1593 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1594 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1595 "Convert FILENAME to absolute, and canonicalize it.\n\
1596 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1597 (does not start with slash); if DEFAULT is nil or missing,\n\
1598 the current buffer's value of default-directory is used.\n\
1599 Filenames containing `.' or `..' as components are simplified;\n\
1600 initial `~/' expands to your home directory.\n\
1601 See also the function `substitute-in-file-name'.")
1602 (name, defalt)
1603 Lisp_Object name, defalt;
1605 unsigned char *nm;
1607 register unsigned char *newdir, *p, *o;
1608 int tlen;
1609 unsigned char *target;
1610 struct passwd *pw;
1611 int lose;
1612 #ifdef VMS
1613 unsigned char * colon = 0;
1614 unsigned char * close = 0;
1615 unsigned char * slash = 0;
1616 unsigned char * brack = 0;
1617 int lbrack = 0, rbrack = 0;
1618 int dots = 0;
1619 #endif /* VMS */
1621 CHECK_STRING (name, 0);
1623 #ifdef VMS
1624 /* Filenames on VMS are always upper case. */
1625 name = Fupcase (name);
1626 #endif
1628 nm = XSTRING (name)->data;
1630 /* If nm is absolute, flush ...// and detect /./ and /../.
1631 If no /./ or /../ we can return right away. */
1632 if (
1633 nm[0] == '/'
1634 #ifdef VMS
1635 || index (nm, ':')
1636 #endif /* VMS */
1639 p = nm;
1640 lose = 0;
1641 while (*p)
1643 if (p[0] == '/' && p[1] == '/'
1644 #ifdef APOLLO
1645 /* // at start of filename is meaningful on Apollo system. */
1646 && nm != p
1647 #endif /* APOLLO */
1649 nm = p + 1;
1650 if (p[0] == '/' && p[1] == '~')
1651 nm = p + 1, lose = 1;
1652 if (p[0] == '/' && p[1] == '.'
1653 && (p[2] == '/' || p[2] == 0
1654 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1655 lose = 1;
1656 #ifdef VMS
1657 if (p[0] == '\\')
1658 lose = 1;
1659 if (p[0] == '/') {
1660 /* if dev:[dir]/, move nm to / */
1661 if (!slash && p > nm && (brack || colon)) {
1662 nm = (brack ? brack + 1 : colon + 1);
1663 lbrack = rbrack = 0;
1664 brack = 0;
1665 colon = 0;
1667 slash = p;
1669 if (p[0] == '-')
1670 #ifndef VMS4_4
1671 /* VMS pre V4.4,convert '-'s in filenames. */
1672 if (lbrack == rbrack)
1674 if (dots < 2) /* this is to allow negative version numbers */
1675 p[0] = '_';
1677 else
1678 #endif /* VMS4_4 */
1679 if (lbrack > rbrack &&
1680 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1681 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1682 lose = 1;
1683 #ifndef VMS4_4
1684 else
1685 p[0] = '_';
1686 #endif /* VMS4_4 */
1687 /* count open brackets, reset close bracket pointer */
1688 if (p[0] == '[' || p[0] == '<')
1689 lbrack++, brack = 0;
1690 /* count close brackets, set close bracket pointer */
1691 if (p[0] == ']' || p[0] == '>')
1692 rbrack++, brack = p;
1693 /* detect ][ or >< */
1694 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1695 lose = 1;
1696 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1697 nm = p + 1, lose = 1;
1698 if (p[0] == ':' && (colon || slash))
1699 /* if dev1:[dir]dev2:, move nm to dev2: */
1700 if (brack)
1702 nm = brack + 1;
1703 brack = 0;
1705 /* If /name/dev:, move nm to dev: */
1706 else if (slash)
1707 nm = slash + 1;
1708 /* If node::dev:, move colon following dev */
1709 else if (colon && colon[-1] == ':')
1710 colon = p;
1711 /* If dev1:dev2:, move nm to dev2: */
1712 else if (colon && colon[-1] != ':')
1714 nm = colon + 1;
1715 colon = 0;
1717 if (p[0] == ':' && !colon)
1719 if (p[1] == ':')
1720 p++;
1721 colon = p;
1723 if (lbrack == rbrack)
1724 if (p[0] == ';')
1725 dots = 2;
1726 else if (p[0] == '.')
1727 dots++;
1728 #endif /* VMS */
1729 p++;
1731 if (!lose)
1733 #ifdef VMS
1734 if (index (nm, '/'))
1735 return build_string (sys_translate_unix (nm));
1736 #endif /* VMS */
1737 if (nm == XSTRING (name)->data)
1738 return name;
1739 return build_string (nm);
1743 /* Now determine directory to start with and put it in NEWDIR */
1745 newdir = 0;
1747 if (nm[0] == '~') /* prefix ~ */
1748 if (nm[1] == '/'
1749 #ifdef VMS
1750 || nm[1] == ':'
1751 #endif /* VMS */
1752 || nm[1] == 0)/* ~/filename */
1754 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1755 newdir = (unsigned char *) "";
1756 nm++;
1757 #ifdef VMS
1758 nm++; /* Don't leave the slash in nm. */
1759 #endif /* VMS */
1761 else /* ~user/filename */
1763 /* Get past ~ to user */
1764 unsigned char *user = nm + 1;
1765 /* Find end of name. */
1766 unsigned char *ptr = (unsigned char *) index (user, '/');
1767 int len = ptr ? ptr - user : strlen (user);
1768 #ifdef VMS
1769 unsigned char *ptr1 = index (user, ':');
1770 if (ptr1 != 0 && ptr1 - user < len)
1771 len = ptr1 - user;
1772 #endif /* VMS */
1773 /* Copy the user name into temp storage. */
1774 o = (unsigned char *) alloca (len + 1);
1775 bcopy ((char *) user, o, len);
1776 o[len] = 0;
1778 /* Look up the user name. */
1779 pw = (struct passwd *) getpwnam (o + 1);
1780 if (!pw)
1781 error ("\"%s\" isn't a registered user", o + 1);
1783 newdir = (unsigned char *) pw->pw_dir;
1785 /* Discard the user name from NM. */
1786 nm += len;
1789 if (nm[0] != '/'
1790 #ifdef VMS
1791 && !index (nm, ':')
1792 #endif /* not VMS */
1793 && !newdir)
1795 if (NILP (defalt))
1796 defalt = current_buffer->directory;
1797 CHECK_STRING (defalt, 1);
1798 newdir = XSTRING (defalt)->data;
1801 /* Now concatenate the directory and name to new space in the stack frame */
1803 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1804 target = (unsigned char *) alloca (tlen);
1805 *target = 0;
1807 if (newdir)
1809 #ifndef VMS
1810 if (nm[0] == 0 || nm[0] == '/')
1811 strcpy (target, newdir);
1812 else
1813 #endif
1814 file_name_as_directory (target, newdir);
1817 strcat (target, nm);
1818 #ifdef VMS
1819 if (index (target, '/'))
1820 strcpy (target, sys_translate_unix (target));
1821 #endif /* VMS */
1823 /* Now canonicalize by removing /. and /foo/.. if they appear */
1825 p = target;
1826 o = target;
1828 while (*p)
1830 #ifdef VMS
1831 if (*p != ']' && *p != '>' && *p != '-')
1833 if (*p == '\\')
1834 p++;
1835 *o++ = *p++;
1837 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1838 /* brackets are offset from each other by 2 */
1840 p += 2;
1841 if (*p != '.' && *p != '-' && o[-1] != '.')
1842 /* convert [foo][bar] to [bar] */
1843 while (o[-1] != '[' && o[-1] != '<')
1844 o--;
1845 else if (*p == '-' && *o != '.')
1846 *--p = '.';
1848 else if (p[0] == '-' && o[-1] == '.' &&
1849 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1850 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1853 o--;
1854 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1855 if (p[1] == '.') /* foo.-.bar ==> bar. */
1856 p += 2;
1857 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1858 p++, o--;
1859 /* else [foo.-] ==> [-] */
1861 else
1863 #ifndef VMS4_4
1864 if (*p == '-' &&
1865 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1866 p[1] != ']' && p[1] != '>' && p[1] != '.')
1867 *p = '_';
1868 #endif /* VMS4_4 */
1869 *o++ = *p++;
1871 #else /* not VMS */
1872 if (*p != '/')
1874 *o++ = *p++;
1876 else if (!strncmp (p, "//", 2)
1877 #ifdef APOLLO
1878 /* // at start of filename is meaningful in Apollo system. */
1879 && o != target
1880 #endif /* APOLLO */
1883 o = target;
1884 p++;
1886 else if (p[0] == '/' && p[1] == '.' &&
1887 (p[2] == '/' || p[2] == 0))
1888 p += 2;
1889 else if (!strncmp (p, "/..", 3)
1890 /* `/../' is the "superroot" on certain file systems. */
1891 && o != target
1892 && (p[3] == '/' || p[3] == 0))
1894 while (o != target && *--o != '/')
1896 #ifdef APOLLO
1897 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1898 ++o;
1899 else
1900 #endif /* APOLLO */
1901 if (o == target && *o == '/')
1902 ++o;
1903 p += 3;
1905 else
1907 *o++ = *p++;
1909 #endif /* not VMS */
1912 return make_string (target, o - target);
1914 #endif
1916 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1917 Ssubstitute_in_file_name, 1, 1, 0,
1918 "Substitute environment variables referred to in FILENAME.\n\
1919 `$FOO' where FOO is an environment variable name means to substitute\n\
1920 the value of that variable. The variable name should be terminated\n\
1921 with a character not a letter, digit or underscore; otherwise, enclose\n\
1922 the entire variable name in braces.\n\
1923 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1924 On VMS, `$' substitution is not done; this function does little and only\n\
1925 duplicates what `expand-file-name' does.")
1926 (filename)
1927 Lisp_Object filename;
1929 unsigned char *nm;
1931 register unsigned char *s, *p, *o, *x, *endp;
1932 unsigned char *target;
1933 int total = 0;
1934 int substituted = 0;
1935 unsigned char *xnm;
1936 Lisp_Object handler;
1938 CHECK_STRING (filename, 0);
1940 /* If the file name has special constructs in it,
1941 call the corresponding file handler. */
1942 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1943 if (!NILP (handler))
1944 return call2 (handler, Qsubstitute_in_file_name, filename);
1946 nm = XSTRING (filename)->data;
1947 #ifdef DOS_NT
1948 nm = strcpy (alloca (strlen (nm) + 1), nm);
1949 CORRECT_DIR_SEPS (nm);
1950 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
1951 #endif
1952 endp = nm + STRING_BYTES (XSTRING (filename));
1954 /* If /~ or // appears, discard everything through first slash. */
1956 for (p = nm; p != endp; p++)
1958 if ((p[0] == '~'
1959 #if defined (APOLLO) || defined (WINDOWSNT)
1960 /* // at start of file name is meaningful in Apollo and
1961 WindowsNT systems. */
1962 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1963 #else /* not (APOLLO || WINDOWSNT) */
1964 || IS_DIRECTORY_SEP (p[0])
1965 #endif /* not (APOLLO || WINDOWSNT) */
1967 && p != nm
1968 && (0
1969 #ifdef VMS
1970 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
1971 #endif /* VMS */
1972 || IS_DIRECTORY_SEP (p[-1])))
1974 nm = p;
1975 substituted = 1;
1977 #ifdef DOS_NT
1978 /* see comment in expand-file-name about drive specifiers */
1979 else if (IS_DRIVE (p[0]) && p[1] == ':'
1980 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1982 nm = p;
1983 substituted = 1;
1985 #endif /* DOS_NT */
1988 #ifdef VMS
1989 return build_string (nm);
1990 #else
1992 /* See if any variables are substituted into the string
1993 and find the total length of their values in `total' */
1995 for (p = nm; p != endp;)
1996 if (*p != '$')
1997 p++;
1998 else
2000 p++;
2001 if (p == endp)
2002 goto badsubst;
2003 else if (*p == '$')
2005 /* "$$" means a single "$" */
2006 p++;
2007 total -= 1;
2008 substituted = 1;
2009 continue;
2011 else if (*p == '{')
2013 o = ++p;
2014 while (p != endp && *p != '}') p++;
2015 if (*p != '}') goto missingclose;
2016 s = p;
2018 else
2020 o = p;
2021 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2022 s = p;
2025 /* Copy out the variable name */
2026 target = (unsigned char *) alloca (s - o + 1);
2027 strncpy (target, o, s - o);
2028 target[s - o] = 0;
2029 #ifdef DOS_NT
2030 strupr (target); /* $home == $HOME etc. */
2031 #endif /* DOS_NT */
2033 /* Get variable value */
2034 o = (unsigned char *) egetenv (target);
2035 if (!o) goto badvar;
2036 total += strlen (o);
2037 substituted = 1;
2040 if (!substituted)
2041 return filename;
2043 /* If substitution required, recopy the string and do it */
2044 /* Make space in stack frame for the new copy */
2045 xnm = (unsigned char *) alloca (STRING_BYTES (XSTRING (filename)) + total + 1);
2046 x = xnm;
2048 /* Copy the rest of the name through, replacing $ constructs with values */
2049 for (p = nm; *p;)
2050 if (*p != '$')
2051 *x++ = *p++;
2052 else
2054 p++;
2055 if (p == endp)
2056 goto badsubst;
2057 else if (*p == '$')
2059 *x++ = *p++;
2060 continue;
2062 else if (*p == '{')
2064 o = ++p;
2065 while (p != endp && *p != '}') p++;
2066 if (*p != '}') goto missingclose;
2067 s = p++;
2069 else
2071 o = p;
2072 while (p != endp && (isalnum (*p) || *p == '_')) p++;
2073 s = p;
2076 /* Copy out the variable name */
2077 target = (unsigned char *) alloca (s - o + 1);
2078 strncpy (target, o, s - o);
2079 target[s - o] = 0;
2080 #ifdef DOS_NT
2081 strupr (target); /* $home == $HOME etc. */
2082 #endif /* DOS_NT */
2084 /* Get variable value */
2085 o = (unsigned char *) egetenv (target);
2086 if (!o)
2087 goto badvar;
2089 if (STRING_MULTIBYTE (filename))
2091 /* If the original string is multibyte,
2092 convert what we substitute into multibyte. */
2093 unsigned char workbuf[4], *str;
2094 int len;
2096 while (*o)
2098 int c = *o++;
2099 c = unibyte_char_to_multibyte (c);
2100 if (! SINGLE_BYTE_CHAR_P (c))
2102 len = CHAR_STRING (c, workbuf, str);
2103 bcopy (str, x, len);
2104 x += len;
2106 else
2107 *x++ = c;
2110 else
2112 strcpy (x, o);
2113 x += strlen (o);
2117 *x = 0;
2119 /* If /~ or // appears, discard everything through first slash. */
2121 for (p = xnm; p != x; p++)
2122 if ((p[0] == '~'
2123 #if defined (APOLLO) || defined (WINDOWSNT)
2124 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
2125 #else /* not (APOLLO || WINDOWSNT) */
2126 || IS_DIRECTORY_SEP (p[0])
2127 #endif /* not (APOLLO || WINDOWSNT) */
2129 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
2130 xnm = p;
2131 #ifdef DOS_NT
2132 else if (IS_DRIVE (p[0]) && p[1] == ':'
2133 && p > xnm && IS_DIRECTORY_SEP (p[-1]))
2134 xnm = p;
2135 #endif
2137 if (STRING_MULTIBYTE (filename))
2138 return make_string (xnm, x - xnm);
2139 return make_unibyte_string (xnm, x - xnm);
2141 badsubst:
2142 error ("Bad format environment-variable substitution");
2143 missingclose:
2144 error ("Missing \"}\" in environment-variable substitution");
2145 badvar:
2146 error ("Substituting nonexistent environment variable \"%s\"", target);
2148 /* NOTREACHED */
2149 #endif /* not VMS */
2152 /* A slightly faster and more convenient way to get
2153 (directory-file-name (expand-file-name FOO)). */
2155 Lisp_Object
2156 expand_and_dir_to_file (filename, defdir)
2157 Lisp_Object filename, defdir;
2159 register Lisp_Object absname;
2161 absname = Fexpand_file_name (filename, defdir);
2162 #ifdef VMS
2164 register int c = XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1];
2165 if (c == ':' || c == ']' || c == '>')
2166 absname = Fdirectory_file_name (absname);
2168 #else
2169 /* Remove final slash, if any (unless this is the root dir).
2170 stat behaves differently depending! */
2171 if (XSTRING (absname)->size > 1
2172 && IS_DIRECTORY_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1])
2173 && !IS_DEVICE_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname))-2]))
2174 /* We cannot take shortcuts; they might be wrong for magic file names. */
2175 absname = Fdirectory_file_name (absname);
2176 #endif
2177 return absname;
2180 /* Signal an error if the file ABSNAME already exists.
2181 If INTERACTIVE is nonzero, ask the user whether to proceed,
2182 and bypass the error if the user says to go ahead.
2183 QUERYSTRING is a name for the action that is being considered
2184 to alter the file.
2186 *STATPTR is used to store the stat information if the file exists.
2187 If the file does not exist, STATPTR->st_mode is set to 0.
2188 If STATPTR is null, we don't store into it.
2190 If QUICK is nonzero, we ask for y or n, not yes or no. */
2192 void
2193 barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
2194 Lisp_Object absname;
2195 unsigned char *querystring;
2196 int interactive;
2197 struct stat *statptr;
2198 int quick;
2200 register Lisp_Object tem, encoded_filename;
2201 struct stat statbuf;
2202 struct gcpro gcpro1;
2204 encoded_filename = ENCODE_FILE (absname);
2206 /* stat is a good way to tell whether the file exists,
2207 regardless of what access permissions it has. */
2208 if (stat (XSTRING (encoded_filename)->data, &statbuf) >= 0)
2210 if (! interactive)
2211 Fsignal (Qfile_already_exists,
2212 Fcons (build_string ("File already exists"),
2213 Fcons (absname, Qnil)));
2214 GCPRO1 (absname);
2215 tem = format1 ("File %s already exists; %s anyway? ",
2216 XSTRING (absname)->data, querystring);
2217 if (quick)
2218 tem = Fy_or_n_p (tem);
2219 else
2220 tem = do_yes_or_no_p (tem);
2221 UNGCPRO;
2222 if (NILP (tem))
2223 Fsignal (Qfile_already_exists,
2224 Fcons (build_string ("File already exists"),
2225 Fcons (absname, Qnil)));
2226 if (statptr)
2227 *statptr = statbuf;
2229 else
2231 if (statptr)
2232 statptr->st_mode = 0;
2234 return;
2237 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2238 "fCopy file: \nFCopy %s to file: \np\nP",
2239 "Copy FILE to NEWNAME. Both args must be strings.\n\
2240 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2241 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2242 A number as third arg means request confirmation if NEWNAME already exists.\n\
2243 This is what happens in interactive use with M-x.\n\
2244 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2245 last-modified time as the old one. (This works on only some systems.)\n\
2246 A prefix arg makes KEEP-TIME non-nil.")
2247 (file, newname, ok_if_already_exists, keep_date)
2248 Lisp_Object file, newname, ok_if_already_exists, keep_date;
2250 int ifd, ofd, n;
2251 char buf[16 * 1024];
2252 struct stat st, out_st;
2253 Lisp_Object handler;
2254 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2255 int count = specpdl_ptr - specpdl;
2256 int input_file_statable_p;
2257 Lisp_Object encoded_file, encoded_newname;
2259 encoded_file = encoded_newname = Qnil;
2260 GCPRO4 (file, newname, encoded_file, encoded_newname);
2261 CHECK_STRING (file, 0);
2262 CHECK_STRING (newname, 1);
2264 file = Fexpand_file_name (file, Qnil);
2265 newname = Fexpand_file_name (newname, Qnil);
2267 /* If the input file name has special constructs in it,
2268 call the corresponding file handler. */
2269 handler = Ffind_file_name_handler (file, Qcopy_file);
2270 /* Likewise for output file name. */
2271 if (NILP (handler))
2272 handler = Ffind_file_name_handler (newname, Qcopy_file);
2273 if (!NILP (handler))
2274 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2275 ok_if_already_exists, keep_date));
2277 encoded_file = ENCODE_FILE (file);
2278 encoded_newname = ENCODE_FILE (newname);
2280 if (NILP (ok_if_already_exists)
2281 || INTEGERP (ok_if_already_exists))
2282 barf_or_query_if_file_exists (encoded_newname, "copy to it",
2283 INTEGERP (ok_if_already_exists), &out_st, 0);
2284 else if (stat (XSTRING (encoded_newname)->data, &out_st) < 0)
2285 out_st.st_mode = 0;
2287 ifd = emacs_open (XSTRING (encoded_file)->data, O_RDONLY, 0);
2288 if (ifd < 0)
2289 report_file_error ("Opening input file", Fcons (file, Qnil));
2291 record_unwind_protect (close_file_unwind, make_number (ifd));
2293 /* We can only copy regular files and symbolic links. Other files are not
2294 copyable by us. */
2295 input_file_statable_p = (fstat (ifd, &st) >= 0);
2297 #if !defined (DOS_NT) || __DJGPP__ > 1
2298 if (out_st.st_mode != 0
2299 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2301 errno = 0;
2302 report_file_error ("Input and output files are the same",
2303 Fcons (file, Fcons (newname, Qnil)));
2305 #endif
2307 #if defined (S_ISREG) && defined (S_ISLNK)
2308 if (input_file_statable_p)
2310 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2312 #if defined (EISDIR)
2313 /* Get a better looking error message. */
2314 errno = EISDIR;
2315 #endif /* EISDIR */
2316 report_file_error ("Non-regular file", Fcons (file, Qnil));
2319 #endif /* S_ISREG && S_ISLNK */
2321 #ifdef VMS
2322 /* Create the copy file with the same record format as the input file */
2323 ofd = sys_creat (XSTRING (encoded_newname)->data, 0666, ifd);
2324 #else
2325 #ifdef MSDOS
2326 /* System's default file type was set to binary by _fmode in emacs.c. */
2327 ofd = creat (XSTRING (encoded_newname)->data, S_IREAD | S_IWRITE);
2328 #else /* not MSDOS */
2329 ofd = creat (XSTRING (encoded_newname)->data, 0666);
2330 #endif /* not MSDOS */
2331 #endif /* VMS */
2332 if (ofd < 0)
2333 report_file_error ("Opening output file", Fcons (newname, Qnil));
2335 record_unwind_protect (close_file_unwind, make_number (ofd));
2337 immediate_quit = 1;
2338 QUIT;
2339 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2340 if (emacs_write (ofd, buf, n) != n)
2341 report_file_error ("I/O error", Fcons (newname, Qnil));
2342 immediate_quit = 0;
2344 /* Closing the output clobbers the file times on some systems. */
2345 if (emacs_close (ofd) < 0)
2346 report_file_error ("I/O error", Fcons (newname, Qnil));
2348 if (input_file_statable_p)
2350 if (!NILP (keep_date))
2352 EMACS_TIME atime, mtime;
2353 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2354 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2355 if (set_file_times (XSTRING (encoded_newname)->data,
2356 atime, mtime))
2357 Fsignal (Qfile_date_error,
2358 Fcons (build_string ("Cannot set file date"),
2359 Fcons (newname, Qnil)));
2361 #ifndef MSDOS
2362 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2363 #else /* MSDOS */
2364 #if defined (__DJGPP__) && __DJGPP__ > 1
2365 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2366 and if it can't, it tells so. Otherwise, under MSDOS we usually
2367 get only the READ bit, which will make the copied file read-only,
2368 so it's better not to chmod at all. */
2369 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2370 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2371 #endif /* DJGPP version 2 or newer */
2372 #endif /* MSDOS */
2375 emacs_close (ifd);
2377 /* Discard the unwind protects. */
2378 specpdl_ptr = specpdl + count;
2380 UNGCPRO;
2381 return Qnil;
2384 DEFUN ("make-directory-internal", Fmake_directory_internal,
2385 Smake_directory_internal, 1, 1, 0,
2386 "Create a new directory named DIRECTORY.")
2387 (directory)
2388 Lisp_Object directory;
2390 unsigned char *dir;
2391 Lisp_Object handler;
2392 Lisp_Object encoded_dir;
2394 CHECK_STRING (directory, 0);
2395 directory = Fexpand_file_name (directory, Qnil);
2397 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2398 if (!NILP (handler))
2399 return call2 (handler, Qmake_directory_internal, directory);
2401 encoded_dir = ENCODE_FILE (directory);
2403 dir = XSTRING (encoded_dir)->data;
2405 #ifdef WINDOWSNT
2406 if (mkdir (dir) != 0)
2407 #else
2408 if (mkdir (dir, 0777) != 0)
2409 #endif
2410 report_file_error ("Creating directory", Flist (1, &directory));
2412 return Qnil;
2415 DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2416 "Delete the directory named DIRECTORY.")
2417 (directory)
2418 Lisp_Object directory;
2420 unsigned char *dir;
2421 Lisp_Object handler;
2422 Lisp_Object encoded_dir;
2424 CHECK_STRING (directory, 0);
2425 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2427 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2428 if (!NILP (handler))
2429 return call2 (handler, Qdelete_directory, directory);
2431 encoded_dir = ENCODE_FILE (directory);
2433 dir = XSTRING (encoded_dir)->data;
2435 if (rmdir (dir) != 0)
2436 report_file_error ("Removing directory", Flist (1, &directory));
2438 return Qnil;
2441 DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2442 "Delete file named FILENAME.\n\
2443 If file has multiple names, it continues to exist with the other names.")
2444 (filename)
2445 Lisp_Object filename;
2447 Lisp_Object handler;
2448 Lisp_Object encoded_file;
2450 CHECK_STRING (filename, 0);
2451 filename = Fexpand_file_name (filename, Qnil);
2453 handler = Ffind_file_name_handler (filename, Qdelete_file);
2454 if (!NILP (handler))
2455 return call2 (handler, Qdelete_file, filename);
2457 encoded_file = ENCODE_FILE (filename);
2459 if (0 > unlink (XSTRING (encoded_file)->data))
2460 report_file_error ("Removing old name", Flist (1, &filename));
2461 return Qnil;
2464 static Lisp_Object
2465 internal_delete_file_1 (ignore)
2466 Lisp_Object ignore;
2468 return Qt;
2471 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2474 internal_delete_file (filename)
2475 Lisp_Object filename;
2477 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2478 Qt, internal_delete_file_1));
2481 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2482 "fRename file: \nFRename %s to file: \np",
2483 "Rename FILE as NEWNAME. Both args strings.\n\
2484 If file has names other than FILE, it continues to have those names.\n\
2485 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2486 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2487 A number as third arg means request confirmation if NEWNAME already exists.\n\
2488 This is what happens in interactive use with M-x.")
2489 (file, newname, ok_if_already_exists)
2490 Lisp_Object file, newname, ok_if_already_exists;
2492 #ifdef NO_ARG_ARRAY
2493 Lisp_Object args[2];
2494 #endif
2495 Lisp_Object handler;
2496 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2497 Lisp_Object encoded_file, encoded_newname;
2499 encoded_file = encoded_newname = Qnil;
2500 GCPRO4 (file, newname, encoded_file, encoded_newname);
2501 CHECK_STRING (file, 0);
2502 CHECK_STRING (newname, 1);
2503 file = Fexpand_file_name (file, Qnil);
2504 newname = Fexpand_file_name (newname, Qnil);
2506 /* If the file name has special constructs in it,
2507 call the corresponding file handler. */
2508 handler = Ffind_file_name_handler (file, Qrename_file);
2509 if (NILP (handler))
2510 handler = Ffind_file_name_handler (newname, Qrename_file);
2511 if (!NILP (handler))
2512 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2513 file, newname, ok_if_already_exists));
2515 encoded_file = ENCODE_FILE (file);
2516 encoded_newname = ENCODE_FILE (newname);
2518 if (NILP (ok_if_already_exists)
2519 || INTEGERP (ok_if_already_exists))
2520 barf_or_query_if_file_exists (encoded_newname, "rename to it",
2521 INTEGERP (ok_if_already_exists), 0, 0);
2522 #ifndef BSD4_1
2523 if (0 > rename (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2524 #else
2525 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)
2526 || 0 > unlink (XSTRING (encoded_file)->data))
2527 #endif
2529 if (errno == EXDEV)
2531 Fcopy_file (file, newname,
2532 /* We have already prompted if it was an integer,
2533 so don't have copy-file prompt again. */
2534 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2535 Fdelete_file (file);
2537 else
2538 #ifdef NO_ARG_ARRAY
2540 args[0] = file;
2541 args[1] = newname;
2542 report_file_error ("Renaming", Flist (2, args));
2544 #else
2545 report_file_error ("Renaming", Flist (2, &file));
2546 #endif
2548 UNGCPRO;
2549 return Qnil;
2552 DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2553 "fAdd name to file: \nFName to add to %s: \np",
2554 "Give FILE additional name NEWNAME. Both args strings.\n\
2555 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2556 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2557 A number as third arg means request confirmation if NEWNAME already exists.\n\
2558 This is what happens in interactive use with M-x.")
2559 (file, newname, ok_if_already_exists)
2560 Lisp_Object file, newname, ok_if_already_exists;
2562 #ifdef NO_ARG_ARRAY
2563 Lisp_Object args[2];
2564 #endif
2565 Lisp_Object handler;
2566 Lisp_Object encoded_file, encoded_newname;
2567 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2569 GCPRO4 (file, newname, encoded_file, encoded_newname);
2570 encoded_file = encoded_newname = Qnil;
2571 CHECK_STRING (file, 0);
2572 CHECK_STRING (newname, 1);
2573 file = Fexpand_file_name (file, Qnil);
2574 newname = Fexpand_file_name (newname, Qnil);
2576 /* If the file name has special constructs in it,
2577 call the corresponding file handler. */
2578 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2579 if (!NILP (handler))
2580 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2581 newname, ok_if_already_exists));
2583 /* If the new name has special constructs in it,
2584 call the corresponding file handler. */
2585 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2586 if (!NILP (handler))
2587 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2588 newname, ok_if_already_exists));
2590 encoded_file = ENCODE_FILE (file);
2591 encoded_newname = ENCODE_FILE (newname);
2593 if (NILP (ok_if_already_exists)
2594 || INTEGERP (ok_if_already_exists))
2595 barf_or_query_if_file_exists (encoded_newname, "make it a new name",
2596 INTEGERP (ok_if_already_exists), 0, 0);
2598 unlink (XSTRING (newname)->data);
2599 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2601 #ifdef NO_ARG_ARRAY
2602 args[0] = file;
2603 args[1] = newname;
2604 report_file_error ("Adding new name", Flist (2, args));
2605 #else
2606 report_file_error ("Adding new name", Flist (2, &file));
2607 #endif
2610 UNGCPRO;
2611 return Qnil;
2614 #ifdef S_IFLNK
2615 DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2616 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2617 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2618 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2619 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2620 A number as third arg means request confirmation if LINKNAME already exists.\n\
2621 This happens for interactive use with M-x.")
2622 (filename, linkname, ok_if_already_exists)
2623 Lisp_Object filename, linkname, ok_if_already_exists;
2625 #ifdef NO_ARG_ARRAY
2626 Lisp_Object args[2];
2627 #endif
2628 Lisp_Object handler;
2629 Lisp_Object encoded_filename, encoded_linkname;
2630 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2632 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2633 encoded_filename = encoded_linkname = Qnil;
2634 CHECK_STRING (filename, 0);
2635 CHECK_STRING (linkname, 1);
2636 /* If the link target has a ~, we must expand it to get
2637 a truly valid file name. Otherwise, do not expand;
2638 we want to permit links to relative file names. */
2639 if (XSTRING (filename)->data[0] == '~')
2640 filename = Fexpand_file_name (filename, Qnil);
2641 linkname = Fexpand_file_name (linkname, Qnil);
2643 /* If the file name has special constructs in it,
2644 call the corresponding file handler. */
2645 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2646 if (!NILP (handler))
2647 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2648 linkname, ok_if_already_exists));
2650 /* If the new link name has special constructs in it,
2651 call the corresponding file handler. */
2652 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2653 if (!NILP (handler))
2654 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2655 linkname, ok_if_already_exists));
2657 encoded_filename = ENCODE_FILE (filename);
2658 encoded_linkname = ENCODE_FILE (linkname);
2660 if (NILP (ok_if_already_exists)
2661 || INTEGERP (ok_if_already_exists))
2662 barf_or_query_if_file_exists (encoded_linkname, "make it a link",
2663 INTEGERP (ok_if_already_exists), 0, 0);
2664 if (0 > symlink (XSTRING (encoded_filename)->data,
2665 XSTRING (encoded_linkname)->data))
2667 /* If we didn't complain already, silently delete existing file. */
2668 if (errno == EEXIST)
2670 unlink (XSTRING (encoded_linkname)->data);
2671 if (0 <= symlink (XSTRING (encoded_filename)->data,
2672 XSTRING (encoded_linkname)->data))
2674 UNGCPRO;
2675 return Qnil;
2679 #ifdef NO_ARG_ARRAY
2680 args[0] = filename;
2681 args[1] = linkname;
2682 report_file_error ("Making symbolic link", Flist (2, args));
2683 #else
2684 report_file_error ("Making symbolic link", Flist (2, &filename));
2685 #endif
2687 UNGCPRO;
2688 return Qnil;
2690 #endif /* S_IFLNK */
2692 #ifdef VMS
2694 DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2695 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2696 "Define the job-wide logical name NAME to have the value STRING.\n\
2697 If STRING is nil or a null string, the logical name NAME is deleted.")
2698 (name, string)
2699 Lisp_Object name;
2700 Lisp_Object string;
2702 CHECK_STRING (name, 0);
2703 if (NILP (string))
2704 delete_logical_name (XSTRING (name)->data);
2705 else
2707 CHECK_STRING (string, 1);
2709 if (XSTRING (string)->size == 0)
2710 delete_logical_name (XSTRING (name)->data);
2711 else
2712 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2715 return string;
2717 #endif /* VMS */
2719 #ifdef HPUX_NET
2721 DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2722 "Open a network connection to PATH using LOGIN as the login string.")
2723 (path, login)
2724 Lisp_Object path, login;
2726 int netresult;
2728 CHECK_STRING (path, 0);
2729 CHECK_STRING (login, 0);
2731 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2733 if (netresult == -1)
2734 return Qnil;
2735 else
2736 return Qt;
2738 #endif /* HPUX_NET */
2740 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2741 1, 1, 0,
2742 "Return t if file FILENAME specifies an absolute file name.\n\
2743 On Unix, this is a name starting with a `/' or a `~'.")
2744 (filename)
2745 Lisp_Object filename;
2747 unsigned char *ptr;
2749 CHECK_STRING (filename, 0);
2750 ptr = XSTRING (filename)->data;
2751 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2752 #ifdef VMS
2753 /* ??? This criterion is probably wrong for '<'. */
2754 || index (ptr, ':') || index (ptr, '<')
2755 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2756 && ptr[1] != '.')
2757 #endif /* VMS */
2758 #ifdef DOS_NT
2759 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2760 #endif
2762 return Qt;
2763 else
2764 return Qnil;
2767 /* Return nonzero if file FILENAME exists and can be executed. */
2769 static int
2770 check_executable (filename)
2771 char *filename;
2773 #ifdef DOS_NT
2774 int len = strlen (filename);
2775 char *suffix;
2776 struct stat st;
2777 if (stat (filename, &st) < 0)
2778 return 0;
2779 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2780 return ((st.st_mode & S_IEXEC) != 0);
2781 #else
2782 return (S_ISREG (st.st_mode)
2783 && len >= 5
2784 && (stricmp ((suffix = filename + len-4), ".com") == 0
2785 || stricmp (suffix, ".exe") == 0
2786 || stricmp (suffix, ".bat") == 0)
2787 || (st.st_mode & S_IFMT) == S_IFDIR);
2788 #endif /* not WINDOWSNT */
2789 #else /* not DOS_NT */
2790 #ifdef HAVE_EUIDACCESS
2791 return (euidaccess (filename, 1) >= 0);
2792 #else
2793 /* Access isn't quite right because it uses the real uid
2794 and we really want to test with the effective uid.
2795 But Unix doesn't give us a right way to do it. */
2796 return (access (filename, 1) >= 0);
2797 #endif
2798 #endif /* not DOS_NT */
2801 /* Return nonzero if file FILENAME exists and can be written. */
2803 static int
2804 check_writable (filename)
2805 char *filename;
2807 #ifdef MSDOS
2808 struct stat st;
2809 if (stat (filename, &st) < 0)
2810 return 0;
2811 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2812 #else /* not MSDOS */
2813 #ifdef HAVE_EUIDACCESS
2814 return (euidaccess (filename, 2) >= 0);
2815 #else
2816 /* Access isn't quite right because it uses the real uid
2817 and we really want to test with the effective uid.
2818 But Unix doesn't give us a right way to do it.
2819 Opening with O_WRONLY could work for an ordinary file,
2820 but would lose for directories. */
2821 return (access (filename, 2) >= 0);
2822 #endif
2823 #endif /* not MSDOS */
2826 DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2827 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2828 See also `file-readable-p' and `file-attributes'.")
2829 (filename)
2830 Lisp_Object filename;
2832 Lisp_Object absname;
2833 Lisp_Object handler;
2834 struct stat statbuf;
2836 CHECK_STRING (filename, 0);
2837 absname = Fexpand_file_name (filename, Qnil);
2839 /* If the file name has special constructs in it,
2840 call the corresponding file handler. */
2841 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2842 if (!NILP (handler))
2843 return call2 (handler, Qfile_exists_p, absname);
2845 absname = ENCODE_FILE (absname);
2847 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2850 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2851 "Return t if FILENAME can be executed by you.\n\
2852 For a directory, this means you can access files in that directory.")
2853 (filename)
2854 Lisp_Object filename;
2857 Lisp_Object absname;
2858 Lisp_Object handler;
2860 CHECK_STRING (filename, 0);
2861 absname = Fexpand_file_name (filename, Qnil);
2863 /* If the file name has special constructs in it,
2864 call the corresponding file handler. */
2865 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
2866 if (!NILP (handler))
2867 return call2 (handler, Qfile_executable_p, absname);
2869 absname = ENCODE_FILE (absname);
2871 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
2874 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
2875 "Return t if file FILENAME exists and you can read it.\n\
2876 See also `file-exists-p' and `file-attributes'.")
2877 (filename)
2878 Lisp_Object filename;
2880 Lisp_Object absname;
2881 Lisp_Object handler;
2882 int desc;
2883 int flags;
2884 struct stat statbuf;
2886 CHECK_STRING (filename, 0);
2887 absname = Fexpand_file_name (filename, Qnil);
2889 /* If the file name has special constructs in it,
2890 call the corresponding file handler. */
2891 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
2892 if (!NILP (handler))
2893 return call2 (handler, Qfile_readable_p, absname);
2895 absname = ENCODE_FILE (absname);
2897 #ifdef DOS_NT
2898 /* Under MS-DOS and Windows, open does not work for directories. */
2899 if (access (XSTRING (absname)->data, 0) == 0)
2900 return Qt;
2901 return Qnil;
2902 #else /* not DOS_NT */
2903 flags = O_RDONLY;
2904 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
2905 /* Opening a fifo without O_NONBLOCK can wait.
2906 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2907 except in the case of a fifo, on a system which handles it. */
2908 desc = stat (XSTRING (absname)->data, &statbuf);
2909 if (desc < 0)
2910 return Qnil;
2911 if (S_ISFIFO (statbuf.st_mode))
2912 flags |= O_NONBLOCK;
2913 #endif
2914 desc = emacs_open (XSTRING (absname)->data, flags, 0);
2915 if (desc < 0)
2916 return Qnil;
2917 emacs_close (desc);
2918 return Qt;
2919 #endif /* not DOS_NT */
2922 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2923 on the RT/PC. */
2924 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2925 "Return t if file FILENAME can be written or created by you.")
2926 (filename)
2927 Lisp_Object filename;
2929 Lisp_Object absname, dir, encoded;
2930 Lisp_Object handler;
2931 struct stat statbuf;
2933 CHECK_STRING (filename, 0);
2934 absname = Fexpand_file_name (filename, Qnil);
2936 /* If the file name has special constructs in it,
2937 call the corresponding file handler. */
2938 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
2939 if (!NILP (handler))
2940 return call2 (handler, Qfile_writable_p, absname);
2942 encoded = ENCODE_FILE (absname);
2943 if (stat (XSTRING (encoded)->data, &statbuf) >= 0)
2944 return (check_writable (XSTRING (encoded)->data)
2945 ? Qt : Qnil);
2947 dir = Ffile_name_directory (absname);
2948 #ifdef VMS
2949 if (!NILP (dir))
2950 dir = Fdirectory_file_name (dir);
2951 #endif /* VMS */
2952 #ifdef MSDOS
2953 if (!NILP (dir))
2954 dir = Fdirectory_file_name (dir);
2955 #endif /* MSDOS */
2957 dir = ENCODE_FILE (dir);
2958 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
2959 ? Qt : Qnil);
2962 DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
2963 "Access file FILENAME, and get an error if that does not work.\n\
2964 The second argument STRING is used in the error message.\n\
2965 If there is no error, we return nil.")
2966 (filename, string)
2967 Lisp_Object filename, string;
2969 Lisp_Object handler, encoded_filename;
2970 int fd;
2972 CHECK_STRING (filename, 0);
2973 CHECK_STRING (string, 1);
2975 /* If the file name has special constructs in it,
2976 call the corresponding file handler. */
2977 handler = Ffind_file_name_handler (filename, Qaccess_file);
2978 if (!NILP (handler))
2979 return call3 (handler, Qaccess_file, filename, string);
2981 encoded_filename = ENCODE_FILE (filename);
2983 fd = emacs_open (XSTRING (encoded_filename)->data, O_RDONLY, 0);
2984 if (fd < 0)
2985 report_file_error (XSTRING (string)->data, Fcons (filename, Qnil));
2986 emacs_close (fd);
2988 return Qnil;
2991 DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2992 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2993 The value is the name of the file to which it is linked.\n\
2994 Otherwise returns nil.")
2995 (filename)
2996 Lisp_Object filename;
2998 #ifdef S_IFLNK
2999 char *buf;
3000 int bufsize;
3001 int valsize;
3002 Lisp_Object val;
3003 Lisp_Object handler;
3005 CHECK_STRING (filename, 0);
3006 filename = Fexpand_file_name (filename, Qnil);
3008 /* If the file name has special constructs in it,
3009 call the corresponding file handler. */
3010 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
3011 if (!NILP (handler))
3012 return call2 (handler, Qfile_symlink_p, filename);
3014 filename = ENCODE_FILE (filename);
3016 bufsize = 100;
3017 while (1)
3019 buf = (char *) xmalloc (bufsize);
3020 bzero (buf, bufsize);
3021 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
3022 if (valsize < bufsize) break;
3023 /* Buffer was not long enough */
3024 xfree (buf);
3025 bufsize *= 2;
3027 if (valsize == -1)
3029 xfree (buf);
3030 return Qnil;
3032 val = make_string (buf, valsize);
3033 xfree (buf);
3034 val = DECODE_FILE (val);
3035 return val;
3036 #else /* not S_IFLNK */
3037 return Qnil;
3038 #endif /* not S_IFLNK */
3041 DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
3042 "Return t if FILENAME names an existing directory.\n\
3043 Symbolic links to directories count as directories.\n\
3044 See `file-symlink-p' to distinguish symlinks.")
3045 (filename)
3046 Lisp_Object filename;
3048 register Lisp_Object absname;
3049 struct stat st;
3050 Lisp_Object handler;
3052 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3054 /* If the file name has special constructs in it,
3055 call the corresponding file handler. */
3056 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
3057 if (!NILP (handler))
3058 return call2 (handler, Qfile_directory_p, absname);
3060 absname = ENCODE_FILE (absname);
3062 if (stat (XSTRING (absname)->data, &st) < 0)
3063 return Qnil;
3064 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
3067 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
3068 "Return t if file FILENAME is the name of a directory as a file,\n\
3069 and files in that directory can be opened by you. In order to use a\n\
3070 directory as a buffer's current directory, this predicate must return true.\n\
3071 A directory name spec may be given instead; then the value is t\n\
3072 if the directory so specified exists and really is a readable and\n\
3073 searchable directory.")
3074 (filename)
3075 Lisp_Object filename;
3077 Lisp_Object handler;
3078 int tem;
3079 struct gcpro gcpro1;
3081 /* If the file name has special constructs in it,
3082 call the corresponding file handler. */
3083 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
3084 if (!NILP (handler))
3085 return call2 (handler, Qfile_accessible_directory_p, filename);
3087 /* It's an unlikely combination, but yes we really do need to gcpro:
3088 Suppose that file-accessible-directory-p has no handler, but
3089 file-directory-p does have a handler; this handler causes a GC which
3090 relocates the string in `filename'; and finally file-directory-p
3091 returns non-nil. Then we would end up passing a garbaged string
3092 to file-executable-p. */
3093 GCPRO1 (filename);
3094 tem = (NILP (Ffile_directory_p (filename))
3095 || NILP (Ffile_executable_p (filename)));
3096 UNGCPRO;
3097 return tem ? Qnil : Qt;
3100 DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
3101 "Return t if file FILENAME is the name of a regular file.\n\
3102 This is the sort of file that holds an ordinary stream of data bytes.")
3103 (filename)
3104 Lisp_Object filename;
3106 register Lisp_Object absname;
3107 struct stat st;
3108 Lisp_Object handler;
3110 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3112 /* If the file name has special constructs in it,
3113 call the corresponding file handler. */
3114 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
3115 if (!NILP (handler))
3116 return call2 (handler, Qfile_regular_p, absname);
3118 absname = ENCODE_FILE (absname);
3120 #ifdef WINDOWSNT
3122 int result;
3123 Lisp_Object tem = Vw32_get_true_file_attributes;
3125 /* Tell stat to use expensive method to get accurate info. */
3126 Vw32_get_true_file_attributes = Qt;
3127 result = stat (XSTRING (absname)->data, &st);
3128 Vw32_get_true_file_attributes = tem;
3130 if (result < 0)
3131 return Qnil;
3132 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3134 #else
3135 if (stat (XSTRING (absname)->data, &st) < 0)
3136 return Qnil;
3137 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
3138 #endif
3141 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
3142 "Return mode bits of file named FILENAME, as an integer.")
3143 (filename)
3144 Lisp_Object filename;
3146 Lisp_Object absname;
3147 struct stat st;
3148 Lisp_Object handler;
3150 absname = expand_and_dir_to_file (filename, current_buffer->directory);
3152 /* If the file name has special constructs in it,
3153 call the corresponding file handler. */
3154 handler = Ffind_file_name_handler (absname, Qfile_modes);
3155 if (!NILP (handler))
3156 return call2 (handler, Qfile_modes, absname);
3158 absname = ENCODE_FILE (absname);
3160 if (stat (XSTRING (absname)->data, &st) < 0)
3161 return Qnil;
3162 #if defined (MSDOS) && __DJGPP__ < 2
3163 if (check_executable (XSTRING (absname)->data))
3164 st.st_mode |= S_IEXEC;
3165 #endif /* MSDOS && __DJGPP__ < 2 */
3167 return make_number (st.st_mode & 07777);
3170 DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
3171 "Set mode bits of file named FILENAME to MODE (an integer).\n\
3172 Only the 12 low bits of MODE are used.")
3173 (filename, mode)
3174 Lisp_Object filename, mode;
3176 Lisp_Object absname, encoded_absname;
3177 Lisp_Object handler;
3179 absname = Fexpand_file_name (filename, current_buffer->directory);
3180 CHECK_NUMBER (mode, 1);
3182 /* If the file name has special constructs in it,
3183 call the corresponding file handler. */
3184 handler = Ffind_file_name_handler (absname, Qset_file_modes);
3185 if (!NILP (handler))
3186 return call3 (handler, Qset_file_modes, absname, mode);
3188 encoded_absname = ENCODE_FILE (absname);
3190 if (chmod (XSTRING (encoded_absname)->data, XINT (mode)) < 0)
3191 report_file_error ("Doing chmod", Fcons (absname, Qnil));
3193 return Qnil;
3196 DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
3197 "Set the file permission bits for newly created files.\n\
3198 The argument MODE should be an integer; only the low 9 bits are used.\n\
3199 This setting is inherited by subprocesses.")
3200 (mode)
3201 Lisp_Object mode;
3203 CHECK_NUMBER (mode, 0);
3205 umask ((~ XINT (mode)) & 0777);
3207 return Qnil;
3210 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
3211 "Return the default file protection for created files.\n\
3212 The value is an integer.")
3215 int realmask;
3216 Lisp_Object value;
3218 realmask = umask (0);
3219 umask (realmask);
3221 XSETINT (value, (~ realmask) & 0777);
3222 return value;
3225 #ifdef unix
3227 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
3228 "Tell Unix to finish all pending disk updates.")
3231 sync ();
3232 return Qnil;
3235 #endif /* unix */
3237 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
3238 "Return t if file FILE1 is newer than file FILE2.\n\
3239 If FILE1 does not exist, the answer is nil;\n\
3240 otherwise, if FILE2 does not exist, the answer is t.")
3241 (file1, file2)
3242 Lisp_Object file1, file2;
3244 Lisp_Object absname1, absname2;
3245 struct stat st;
3246 int mtime1;
3247 Lisp_Object handler;
3248 struct gcpro gcpro1, gcpro2;
3250 CHECK_STRING (file1, 0);
3251 CHECK_STRING (file2, 0);
3253 absname1 = Qnil;
3254 GCPRO2 (absname1, file2);
3255 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3256 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
3257 UNGCPRO;
3259 /* If the file name has special constructs in it,
3260 call the corresponding file handler. */
3261 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
3262 if (NILP (handler))
3263 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
3264 if (!NILP (handler))
3265 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
3267 GCPRO2 (absname1, absname2);
3268 absname1 = ENCODE_FILE (absname1);
3269 absname2 = ENCODE_FILE (absname2);
3270 UNGCPRO;
3272 if (stat (XSTRING (absname1)->data, &st) < 0)
3273 return Qnil;
3275 mtime1 = st.st_mtime;
3277 if (stat (XSTRING (absname2)->data, &st) < 0)
3278 return Qt;
3280 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3283 #ifdef DOS_NT
3284 Lisp_Object Qfind_buffer_file_type;
3285 #endif /* DOS_NT */
3287 #ifndef READ_BUF_SIZE
3288 #define READ_BUF_SIZE (64 << 10)
3289 #endif
3291 /* This function is called when a function bound to
3292 Vset_auto_coding_function causes some error. At that time, a text
3293 of a file has already been inserted in the current buffer, but,
3294 markers has not yet been adjusted. Thus we must adjust markers
3295 here. We are sure that the buffer was empty before the text of the
3296 file was inserted. */
3298 static Lisp_Object
3299 set_auto_coding_unwind (multibyte)
3300 Lisp_Object multibyte;
3302 int inserted = Z_BYTE - BEG_BYTE;
3304 if (!NILP (multibyte))
3305 inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted);
3306 adjust_after_insert (PT, PT_BYTE, Z, Z_BYTE, inserted);
3308 return Qnil;
3311 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3312 1, 5, 0,
3313 "Insert contents of file FILENAME after point.\n\
3314 Returns list of absolute file name and number of bytes inserted.\n\
3315 If second argument VISIT is non-nil, the buffer's visited filename\n\
3316 and last save file modtime are set, and it is marked unmodified.\n\
3317 If visiting and the file does not exist, visiting is completed\n\
3318 before the error is signaled.\n\
3319 The optional third and fourth arguments BEG and END\n\
3320 specify what portion of the file to insert.\n\
3321 These arguments count bytes in the file, not characters in the buffer.\n\
3322 If VISIT is non-nil, BEG and END must be nil.\n\
3324 If optional fifth argument REPLACE is non-nil,\n\
3325 it means replace the current buffer contents (in the accessible portion)\n\
3326 with the file contents. This is better than simply deleting and inserting\n\
3327 the whole thing because (1) it preserves some marker positions\n\
3328 and (2) it puts less data in the undo list.\n\
3329 When REPLACE is non-nil, the value is the number of characters actually read,\n\
3330 which is often less than the number of characters to be read.\n\
3332 This does code conversion according to the value of\n\
3333 `coding-system-for-read' or `file-coding-system-alist',\n\
3334 and sets the variable `last-coding-system-used' to the coding system\n\
3335 actually used.")
3336 (filename, visit, beg, end, replace)
3337 Lisp_Object filename, visit, beg, end, replace;
3339 struct stat st;
3340 register int fd;
3341 int inserted = 0;
3342 register int how_much;
3343 register int unprocessed;
3344 int count = specpdl_ptr - specpdl;
3345 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3346 Lisp_Object handler, val, insval, orig_filename;
3347 Lisp_Object p;
3348 int total;
3349 int not_regular = 0;
3350 unsigned char read_buf[READ_BUF_SIZE];
3351 struct coding_system coding;
3352 unsigned char buffer[1 << 14];
3353 int replace_handled = 0;
3354 int set_coding_system = 0;
3355 int coding_system_decided = 0;
3357 if (current_buffer->base_buffer && ! NILP (visit))
3358 error ("Cannot do file visiting in an indirect buffer");
3360 if (!NILP (current_buffer->read_only))
3361 Fbarf_if_buffer_read_only ();
3363 val = Qnil;
3364 p = Qnil;
3365 orig_filename = Qnil;
3367 GCPRO4 (filename, val, p, orig_filename);
3369 CHECK_STRING (filename, 0);
3370 filename = Fexpand_file_name (filename, Qnil);
3372 /* If the file name has special constructs in it,
3373 call the corresponding file handler. */
3374 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3375 if (!NILP (handler))
3377 val = call6 (handler, Qinsert_file_contents, filename,
3378 visit, beg, end, replace);
3379 if (CONSP (val) && CONSP (XCDR (val)))
3380 inserted = XINT (XCAR (XCDR (val)));
3381 goto handled;
3384 orig_filename = filename;
3385 filename = ENCODE_FILE (filename);
3387 fd = -1;
3389 #ifdef WINDOWSNT
3391 Lisp_Object tem = Vw32_get_true_file_attributes;
3393 /* Tell stat to use expensive method to get accurate info. */
3394 Vw32_get_true_file_attributes = Qt;
3395 total = stat (XSTRING (filename)->data, &st);
3396 Vw32_get_true_file_attributes = tem;
3398 if (total < 0)
3399 #else
3400 #ifndef APOLLO
3401 if (stat (XSTRING (filename)->data, &st) < 0)
3402 #else
3403 if ((fd = emacs_open (XSTRING (filename)->data, O_RDONLY, 0)) < 0
3404 || fstat (fd, &st) < 0)
3405 #endif /* not APOLLO */
3406 #endif /* WINDOWSNT */
3408 if (fd >= 0) emacs_close (fd);
3409 badopen:
3410 if (NILP (visit))
3411 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3412 st.st_mtime = -1;
3413 how_much = 0;
3414 if (!NILP (Vcoding_system_for_read))
3415 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
3416 goto notfound;
3419 #ifdef S_IFREG
3420 /* This code will need to be changed in order to work on named
3421 pipes, and it's probably just not worth it. So we should at
3422 least signal an error. */
3423 if (!S_ISREG (st.st_mode))
3425 not_regular = 1;
3427 if (! NILP (visit))
3428 goto notfound;
3430 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
3431 Fsignal (Qfile_error,
3432 Fcons (build_string ("not a regular file"),
3433 Fcons (orig_filename, Qnil)));
3435 #endif
3437 if (fd < 0)
3438 if ((fd = emacs_open (XSTRING (filename)->data, O_RDONLY, 0)) < 0)
3439 goto badopen;
3441 /* Replacement should preserve point as it preserves markers. */
3442 if (!NILP (replace))
3443 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3445 record_unwind_protect (close_file_unwind, make_number (fd));
3447 /* Supposedly happens on VMS. */
3448 if (! not_regular && st.st_size < 0)
3449 error ("File size is negative");
3451 /* Prevent redisplay optimizations. */
3452 current_buffer->clip_changed = 1;
3454 if (!NILP (beg) || !NILP (end))
3455 if (!NILP (visit))
3456 error ("Attempt to visit less than an entire file");
3458 if (!NILP (beg))
3459 CHECK_NUMBER (beg, 0);
3460 else
3461 XSETFASTINT (beg, 0);
3463 if (!NILP (end))
3464 CHECK_NUMBER (end, 0);
3465 else
3467 if (! not_regular)
3469 XSETINT (end, st.st_size);
3471 /* Arithmetic overflow can occur if an Emacs integer cannot
3472 represent the file size, or if the calculations below
3473 overflow. The calculations below double the file size
3474 twice, so check that it can be multiplied by 4 safely. */
3475 if (XINT (end) != st.st_size
3476 || ((int) st.st_size * 4) / 4 != st.st_size)
3477 error ("Maximum buffer size exceeded");
3481 if (BEG < Z)
3483 /* Decide the coding system to use for reading the file now
3484 because we can't use an optimized method for handling
3485 `coding:' tag if the current buffer is not empty. */
3486 Lisp_Object val;
3487 val = Qnil;
3489 if (!NILP (Vcoding_system_for_read))
3490 val = Vcoding_system_for_read;
3491 else if (! NILP (replace))
3492 /* In REPLACE mode, we can use the same coding system
3493 that was used to visit the file. */
3494 val = current_buffer->buffer_file_coding_system;
3495 else
3497 /* Don't try looking inside a file for a coding system
3498 specification if it is not seekable. */
3499 if (! not_regular && ! NILP (Vset_auto_coding_function))
3501 /* Find a coding system specified in the heading two
3502 lines or in the tailing several lines of the file.
3503 We assume that the 1K-byte and 3K-byte for heading
3504 and tailing respectively are sufficient for this
3505 purpose. */
3506 int how_many, nread;
3508 if (st.st_size <= (1024 * 4))
3509 nread = emacs_read (fd, read_buf, 1024 * 4);
3510 else
3512 nread = emacs_read (fd, read_buf, 1024);
3513 if (nread >= 0)
3515 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3516 report_file_error ("Setting file position",
3517 Fcons (orig_filename, Qnil));
3518 nread += emacs_read (fd, read_buf + nread, 1024 * 3);
3522 if (nread < 0)
3523 error ("IO error reading %s: %s",
3524 XSTRING (orig_filename)->data, emacs_strerror (errno));
3525 else if (nread > 0)
3527 int count = specpdl_ptr - specpdl;
3528 struct buffer *prev = current_buffer;
3530 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
3531 temp_output_buffer_setup (" *code-converting-work*");
3532 set_buffer_internal (XBUFFER (Vstandard_output));
3533 current_buffer->enable_multibyte_characters = Qnil;
3534 insert_1_both (read_buf, nread, nread, 0, 0, 0);
3535 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
3536 val = call2 (Vset_auto_coding_function,
3537 filename, make_number (nread));
3538 set_buffer_internal (prev);
3539 /* Discard the unwind protect for recovering the
3540 current buffer. */
3541 specpdl_ptr--;
3543 /* Rewind the file for the actual read done later. */
3544 if (lseek (fd, 0, 0) < 0)
3545 report_file_error ("Setting file position",
3546 Fcons (orig_filename, Qnil));
3550 if (NILP (val))
3552 /* If we have not yet decided a coding system, check
3553 file-coding-system-alist. */
3554 Lisp_Object args[6], coding_systems;
3556 args[0] = Qinsert_file_contents, args[1] = orig_filename;
3557 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3558 coding_systems = Ffind_operation_coding_system (6, args);
3559 if (CONSP (coding_systems))
3560 val = XCAR (coding_systems);
3564 setup_coding_system (Fcheck_coding_system (val), &coding);
3566 if (NILP (current_buffer->enable_multibyte_characters)
3567 && ! NILP (val))
3568 /* We must suppress all character code conversion except for
3569 end-of-line conversion. */
3570 setup_raw_text_coding_system (&coding);
3572 coding_system_decided = 1;
3575 /* Ensure we always set Vlast_coding_system_used. */
3576 set_coding_system = 1;
3578 /* If requested, replace the accessible part of the buffer
3579 with the file contents. Avoid replacing text at the
3580 beginning or end of the buffer that matches the file contents;
3581 that preserves markers pointing to the unchanged parts.
3583 Here we implement this feature in an optimized way
3584 for the case where code conversion is NOT needed.
3585 The following if-statement handles the case of conversion
3586 in a less optimal way.
3588 If the code conversion is "automatic" then we try using this
3589 method and hope for the best.
3590 But if we discover the need for conversion, we give up on this method
3591 and let the following if-statement handle the replace job. */
3592 if (!NILP (replace)
3593 && BEGV < ZV
3594 && ! CODING_REQUIRE_DECODING (&coding)
3595 && (coding.eol_type == CODING_EOL_UNDECIDED
3596 || coding.eol_type == CODING_EOL_LF))
3598 /* same_at_start and same_at_end count bytes,
3599 because file access counts bytes
3600 and BEG and END count bytes. */
3601 int same_at_start = BEGV_BYTE;
3602 int same_at_end = ZV_BYTE;
3603 int overlap;
3604 /* There is still a possibility we will find the need to do code
3605 conversion. If that happens, we set this variable to 1 to
3606 give up on handling REPLACE in the optimized way. */
3607 int giveup_match_end = 0;
3609 if (XINT (beg) != 0)
3611 if (lseek (fd, XINT (beg), 0) < 0)
3612 report_file_error ("Setting file position",
3613 Fcons (orig_filename, Qnil));
3616 immediate_quit = 1;
3617 QUIT;
3618 /* Count how many chars at the start of the file
3619 match the text at the beginning of the buffer. */
3620 while (1)
3622 int nread, bufpos;
3624 nread = emacs_read (fd, buffer, sizeof buffer);
3625 if (nread < 0)
3626 error ("IO error reading %s: %s",
3627 XSTRING (orig_filename)->data, emacs_strerror (errno));
3628 else if (nread == 0)
3629 break;
3631 if (coding.type == coding_type_undecided)
3632 detect_coding (&coding, buffer, nread);
3633 if (CODING_REQUIRE_DECODING (&coding))
3634 /* We found that the file should be decoded somehow.
3635 Let's give up here. */
3637 giveup_match_end = 1;
3638 break;
3641 if (coding.eol_type == CODING_EOL_UNDECIDED)
3642 detect_eol (&coding, buffer, nread);
3643 if (coding.eol_type != CODING_EOL_UNDECIDED
3644 && coding.eol_type != CODING_EOL_LF)
3645 /* We found that the format of eol should be decoded.
3646 Let's give up here. */
3648 giveup_match_end = 1;
3649 break;
3652 bufpos = 0;
3653 while (bufpos < nread && same_at_start < ZV_BYTE
3654 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3655 same_at_start++, bufpos++;
3656 /* If we found a discrepancy, stop the scan.
3657 Otherwise loop around and scan the next bufferful. */
3658 if (bufpos != nread)
3659 break;
3661 immediate_quit = 0;
3662 /* If the file matches the buffer completely,
3663 there's no need to replace anything. */
3664 if (same_at_start - BEGV_BYTE == XINT (end))
3666 emacs_close (fd);
3667 specpdl_ptr--;
3668 /* Truncate the buffer to the size of the file. */
3669 del_range_1 (same_at_start, same_at_end, 0);
3670 goto handled;
3672 immediate_quit = 1;
3673 QUIT;
3674 /* Count how many chars at the end of the file
3675 match the text at the end of the buffer. But, if we have
3676 already found that decoding is necessary, don't waste time. */
3677 while (!giveup_match_end)
3679 int total_read, nread, bufpos, curpos, trial;
3681 /* At what file position are we now scanning? */
3682 curpos = XINT (end) - (ZV_BYTE - same_at_end);
3683 /* If the entire file matches the buffer tail, stop the scan. */
3684 if (curpos == 0)
3685 break;
3686 /* How much can we scan in the next step? */
3687 trial = min (curpos, sizeof buffer);
3688 if (lseek (fd, curpos - trial, 0) < 0)
3689 report_file_error ("Setting file position",
3690 Fcons (orig_filename, Qnil));
3692 total_read = 0;
3693 while (total_read < trial)
3695 nread = emacs_read (fd, buffer + total_read, trial - total_read);
3696 if (nread <= 0)
3697 error ("IO error reading %s: %s",
3698 XSTRING (orig_filename)->data, emacs_strerror (errno));
3699 total_read += nread;
3701 /* Scan this bufferful from the end, comparing with
3702 the Emacs buffer. */
3703 bufpos = total_read;
3704 /* Compare with same_at_start to avoid counting some buffer text
3705 as matching both at the file's beginning and at the end. */
3706 while (bufpos > 0 && same_at_end > same_at_start
3707 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3708 same_at_end--, bufpos--;
3710 /* If we found a discrepancy, stop the scan.
3711 Otherwise loop around and scan the preceding bufferful. */
3712 if (bufpos != 0)
3714 /* If this discrepancy is because of code conversion,
3715 we cannot use this method; giveup and try the other. */
3716 if (same_at_end > same_at_start
3717 && FETCH_BYTE (same_at_end - 1) >= 0200
3718 && ! NILP (current_buffer->enable_multibyte_characters)
3719 && (CODING_MAY_REQUIRE_DECODING (&coding)))
3720 giveup_match_end = 1;
3721 break;
3724 immediate_quit = 0;
3726 if (! giveup_match_end)
3728 int temp;
3730 /* We win! We can handle REPLACE the optimized way. */
3732 /* Extend the start of non-matching text area to multibyte
3733 character boundary. */
3734 if (! NILP (current_buffer->enable_multibyte_characters))
3735 while (same_at_start > BEGV_BYTE
3736 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
3737 same_at_start--;
3739 /* Extend the end of non-matching text area to multibyte
3740 character boundary. */
3741 if (! NILP (current_buffer->enable_multibyte_characters))
3742 while (same_at_end < ZV_BYTE
3743 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3744 same_at_end++;
3746 /* Don't try to reuse the same piece of text twice. */
3747 overlap = (same_at_start - BEGV_BYTE
3748 - (same_at_end + st.st_size - ZV));
3749 if (overlap > 0)
3750 same_at_end += overlap;
3752 /* Arrange to read only the nonmatching middle part of the file. */
3753 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
3754 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3756 del_range_byte (same_at_start, same_at_end, 0);
3757 /* Insert from the file at the proper position. */
3758 temp = BYTE_TO_CHAR (same_at_start);
3759 SET_PT_BOTH (temp, same_at_start);
3761 /* If display currently starts at beginning of line,
3762 keep it that way. */
3763 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3764 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3766 replace_handled = 1;
3770 /* If requested, replace the accessible part of the buffer
3771 with the file contents. Avoid replacing text at the
3772 beginning or end of the buffer that matches the file contents;
3773 that preserves markers pointing to the unchanged parts.
3775 Here we implement this feature for the case where code conversion
3776 is needed, in a simple way that needs a lot of memory.
3777 The preceding if-statement handles the case of no conversion
3778 in a more optimized way. */
3779 if (!NILP (replace) && ! replace_handled && BEGV < ZV)
3781 int same_at_start = BEGV_BYTE;
3782 int same_at_end = ZV_BYTE;
3783 int overlap;
3784 int bufpos;
3785 /* Make sure that the gap is large enough. */
3786 int bufsize = 2 * st.st_size;
3787 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
3788 int temp;
3790 /* First read the whole file, performing code conversion into
3791 CONVERSION_BUFFER. */
3793 if (lseek (fd, XINT (beg), 0) < 0)
3795 xfree (conversion_buffer);
3796 report_file_error ("Setting file position",
3797 Fcons (orig_filename, Qnil));
3800 total = st.st_size; /* Total bytes in the file. */
3801 how_much = 0; /* Bytes read from file so far. */
3802 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3803 unprocessed = 0; /* Bytes not processed in previous loop. */
3805 while (how_much < total)
3807 /* try is reserved in some compilers (Microsoft C) */
3808 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
3809 unsigned char *destination = read_buf + unprocessed;
3810 int this;
3812 /* Allow quitting out of the actual I/O. */
3813 immediate_quit = 1;
3814 QUIT;
3815 this = emacs_read (fd, destination, trytry);
3816 immediate_quit = 0;
3818 if (this < 0 || this + unprocessed == 0)
3820 how_much = this;
3821 break;
3824 how_much += this;
3826 if (CODING_MAY_REQUIRE_DECODING (&coding))
3828 int require, result;
3830 this += unprocessed;
3832 /* If we are using more space than estimated,
3833 make CONVERSION_BUFFER bigger. */
3834 require = decoding_buffer_size (&coding, this);
3835 if (inserted + require + 2 * (total - how_much) > bufsize)
3837 bufsize = inserted + require + 2 * (total - how_much);
3838 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
3841 /* Convert this batch with results in CONVERSION_BUFFER. */
3842 if (how_much >= total) /* This is the last block. */
3843 coding.mode |= CODING_MODE_LAST_BLOCK;
3844 result = decode_coding (&coding, read_buf,
3845 conversion_buffer + inserted,
3846 this, bufsize - inserted);
3848 /* Save for next iteration whatever we didn't convert. */
3849 unprocessed = this - coding.consumed;
3850 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
3851 this = coding.produced;
3854 inserted += this;
3857 /* At this point, INSERTED is how many characters (i.e. bytes)
3858 are present in CONVERSION_BUFFER.
3859 HOW_MUCH should equal TOTAL,
3860 or should be <= 0 if we couldn't read the file. */
3862 if (how_much < 0)
3864 xfree (conversion_buffer);
3866 if (how_much == -1)
3867 error ("IO error reading %s: %s",
3868 XSTRING (orig_filename)->data, emacs_strerror (errno));
3869 else if (how_much == -2)
3870 error ("maximum buffer size exceeded");
3873 /* Compare the beginning of the converted file
3874 with the buffer text. */
3876 bufpos = 0;
3877 while (bufpos < inserted && same_at_start < same_at_end
3878 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
3879 same_at_start++, bufpos++;
3881 /* If the file matches the buffer completely,
3882 there's no need to replace anything. */
3884 if (bufpos == inserted)
3886 xfree (conversion_buffer);
3887 emacs_close (fd);
3888 specpdl_ptr--;
3889 /* Truncate the buffer to the size of the file. */
3890 del_range_byte (same_at_start, same_at_end, 0);
3891 inserted = 0;
3892 goto handled;
3895 /* Extend the start of non-matching text area to multibyte
3896 character boundary. */
3897 if (! NILP (current_buffer->enable_multibyte_characters))
3898 while (same_at_start > BEGV_BYTE
3899 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_start)))
3900 same_at_start--;
3902 /* Scan this bufferful from the end, comparing with
3903 the Emacs buffer. */
3904 bufpos = inserted;
3906 /* Compare with same_at_start to avoid counting some buffer text
3907 as matching both at the file's beginning and at the end. */
3908 while (bufpos > 0 && same_at_end > same_at_start
3909 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
3910 same_at_end--, bufpos--;
3912 /* Extend the end of non-matching text area to multibyte
3913 character boundary. */
3914 if (! NILP (current_buffer->enable_multibyte_characters))
3915 while (same_at_end < ZV_BYTE
3916 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3917 same_at_end++;
3919 /* Don't try to reuse the same piece of text twice. */
3920 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3921 if (overlap > 0)
3922 same_at_end += overlap;
3924 /* If display currently starts at beginning of line,
3925 keep it that way. */
3926 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3927 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3929 /* Replace the chars that we need to replace,
3930 and update INSERTED to equal the number of bytes
3931 we are taking from the file. */
3932 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
3934 if (same_at_end != same_at_start)
3936 del_range_byte (same_at_start, same_at_end, 0);
3937 temp = GPT;
3938 same_at_start = GPT_BYTE;
3940 else
3942 temp = BYTE_TO_CHAR (same_at_start);
3944 /* Insert from the file at the proper position. */
3945 SET_PT_BOTH (temp, same_at_start);
3946 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,
3947 0, 0, 0);
3948 /* Set `inserted' to the number of inserted characters. */
3949 inserted = PT - temp;
3951 free (conversion_buffer);
3952 emacs_close (fd);
3953 specpdl_ptr--;
3955 goto handled;
3958 if (! not_regular)
3960 register Lisp_Object temp;
3962 total = XINT (end) - XINT (beg);
3964 /* Make sure point-max won't overflow after this insertion. */
3965 XSETINT (temp, total);
3966 if (total != XINT (temp))
3967 error ("Maximum buffer size exceeded");
3969 else
3970 /* For a special file, all we can do is guess. */
3971 total = READ_BUF_SIZE;
3973 if (NILP (visit) && total > 0)
3974 prepare_to_modify_buffer (PT, PT, NULL);
3976 move_gap (PT);
3977 if (GAP_SIZE < total)
3978 make_gap (total - GAP_SIZE);
3980 if (XINT (beg) != 0 || !NILP (replace))
3982 if (lseek (fd, XINT (beg), 0) < 0)
3983 report_file_error ("Setting file position",
3984 Fcons (orig_filename, Qnil));
3987 /* In the following loop, HOW_MUCH contains the total bytes read so
3988 far for a regular file, and not changed for a special file. But,
3989 before exiting the loop, it is set to a negative value if I/O
3990 error occurs. */
3991 how_much = 0;
3992 /* Total bytes inserted. */
3993 inserted = 0;
3994 /* Here, we don't do code conversion in the loop. It is done by
3995 code_convert_region after all data are read into the buffer. */
3996 while (how_much < total)
3998 /* try is reserved in some compilers (Microsoft C) */
3999 int trytry = min (total - how_much, READ_BUF_SIZE);
4000 int this;
4002 /* For a special file, GAP_SIZE should be checked every time. */
4003 if (not_regular && GAP_SIZE < trytry)
4004 make_gap (total - GAP_SIZE);
4006 /* Allow quitting out of the actual I/O. */
4007 immediate_quit = 1;
4008 QUIT;
4009 this = emacs_read (fd, BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1,
4010 trytry);
4011 immediate_quit = 0;
4013 if (this <= 0)
4015 how_much = this;
4016 break;
4019 GAP_SIZE -= this;
4020 GPT_BYTE += this;
4021 ZV_BYTE += this;
4022 Z_BYTE += this;
4023 GPT += this;
4024 ZV += this;
4025 Z += this;
4027 /* For a regular file, where TOTAL is the real size,
4028 count HOW_MUCH to compare with it.
4029 For a special file, where TOTAL is just a buffer size,
4030 so don't bother counting in HOW_MUCH.
4031 (INSERTED is where we count the number of characters inserted.) */
4032 if (! not_regular)
4033 how_much += this;
4034 inserted += this;
4037 if (GAP_SIZE > 0)
4038 /* Put an anchor to ensure multi-byte form ends at gap. */
4039 *GPT_ADDR = 0;
4041 emacs_close (fd);
4043 /* Discard the unwind protect for closing the file. */
4044 specpdl_ptr--;
4046 if (how_much < 0)
4047 error ("IO error reading %s: %s",
4048 XSTRING (orig_filename)->data, emacs_strerror (errno));
4050 if (! coding_system_decided)
4052 /* The coding system is not yet decided. Decide it by an
4053 optimized method for handling `coding:' tag.
4055 Note that we can get here only if the buffer was empty
4056 before the insertion. */
4057 Lisp_Object val;
4058 val = Qnil;
4060 if (!NILP (Vcoding_system_for_read))
4061 val = Vcoding_system_for_read;
4062 else
4064 if (inserted > 0 && ! NILP (Vset_auto_coding_function))
4066 /* Since we are sure that the current buffer was
4067 empty before the insertion, we can toggle
4068 enable-multibyte-characters directly here without
4069 taking care of marker adjustment and byte
4070 combining problem. */
4071 Lisp_Object prev_multibyte;
4072 int count = specpdl_ptr - specpdl;
4074 prev_multibyte = current_buffer->enable_multibyte_characters;
4075 current_buffer->enable_multibyte_characters = Qnil;
4076 record_unwind_protect (set_auto_coding_unwind,
4077 prev_multibyte);
4078 val = call2 (Vset_auto_coding_function,
4079 filename, make_number (inserted));
4080 /* Discard the unwind protect for recovering the
4081 error of Vset_auto_coding_function. */
4082 specpdl_ptr--;
4083 current_buffer->enable_multibyte_characters = prev_multibyte;
4084 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
4087 if (NILP (val))
4089 /* If the coding system is not yet decided, check
4090 file-coding-system-alist. */
4091 Lisp_Object args[6], coding_systems;
4093 args[0] = Qinsert_file_contents, args[1] = orig_filename;
4094 args[2] = visit, args[3] = beg, args[4] = end, args[5] = Qnil;
4095 coding_systems = Ffind_operation_coding_system (6, args);
4096 if (CONSP (coding_systems))
4097 val = XCAR (coding_systems);
4101 /* The following kludgy code is to avoid some compiler bug.
4102 We can't simply do
4103 setup_coding_system (val, &coding);
4104 on some system. */
4106 struct coding_system temp_coding;
4107 setup_coding_system (val, &temp_coding);
4108 bcopy (&temp_coding, &coding, sizeof coding);
4111 if (NILP (current_buffer->enable_multibyte_characters)
4112 && ! NILP (val))
4113 /* We must suppress all character code conversion except for
4114 end-of-line conversion. */
4115 setup_raw_text_coding_system (&coding);
4118 if (inserted > 0 || coding.type == coding_type_ccl)
4120 if (CODING_MAY_REQUIRE_DECODING (&coding))
4122 /* Here, we don't have to consider byte combining (see the
4123 comment below) because code_convert_region takes care of
4124 it. */
4125 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4126 &coding, 0, 0);
4127 inserted = (NILP (current_buffer->enable_multibyte_characters)
4128 ? coding.produced : coding.produced_char);
4130 else if (!NILP (current_buffer->enable_multibyte_characters))
4132 int inserted_byte = inserted;
4134 /* There's a possibility that we must combine bytes at the
4135 head (resp. the tail) of the just inserted text with the
4136 bytes before (resp. after) the gap to form a single
4137 character. */
4138 inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted);
4139 adjust_after_insert (PT, PT_BYTE,
4140 PT + inserted_byte, PT_BYTE + inserted_byte,
4141 inserted);
4143 else
4144 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4145 inserted);
4148 #ifdef DOS_NT
4149 /* Use the conversion type to determine buffer-file-type
4150 (find-buffer-file-type is now used to help determine the
4151 conversion). */
4152 if ((coding.eol_type == CODING_EOL_UNDECIDED
4153 || coding.eol_type == CODING_EOL_LF)
4154 && ! CODING_REQUIRE_DECODING (&coding))
4155 current_buffer->buffer_file_type = Qt;
4156 else
4157 current_buffer->buffer_file_type = Qnil;
4158 #endif
4160 notfound:
4161 handled:
4163 if (!NILP (visit))
4165 if (!EQ (current_buffer->undo_list, Qt))
4166 current_buffer->undo_list = Qnil;
4167 #ifdef APOLLO
4168 stat (XSTRING (filename)->data, &st);
4169 #endif
4171 if (NILP (handler))
4173 current_buffer->modtime = st.st_mtime;
4174 current_buffer->filename = orig_filename;
4177 SAVE_MODIFF = MODIFF;
4178 current_buffer->auto_save_modified = MODIFF;
4179 XSETFASTINT (current_buffer->save_length, Z - BEG);
4180 #ifdef CLASH_DETECTION
4181 if (NILP (handler))
4183 if (!NILP (current_buffer->file_truename))
4184 unlock_file (current_buffer->file_truename);
4185 unlock_file (filename);
4187 #endif /* CLASH_DETECTION */
4188 if (not_regular)
4189 Fsignal (Qfile_error,
4190 Fcons (build_string ("not a regular file"),
4191 Fcons (orig_filename, Qnil)));
4193 /* If visiting nonexistent file, return nil. */
4194 if (current_buffer->modtime == -1)
4195 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
4198 /* Decode file format */
4199 if (inserted > 0)
4201 insval = call3 (Qformat_decode,
4202 Qnil, make_number (inserted), visit);
4203 CHECK_NUMBER (insval, 0);
4204 inserted = XFASTINT (insval);
4207 /* Call after-change hooks for the inserted text, aside from the case
4208 of normal visiting (not with REPLACE), which is done in a new buffer
4209 "before" the buffer is changed. */
4210 if (inserted > 0 && total > 0
4211 && (NILP (visit) || !NILP (replace)))
4212 signal_after_change (PT, 0, inserted);
4214 if (set_coding_system)
4215 Vlast_coding_system_used = coding.symbol;
4217 if (inserted > 0)
4219 p = Vafter_insert_file_functions;
4220 while (!NILP (p))
4222 insval = call1 (Fcar (p), make_number (inserted));
4223 if (!NILP (insval))
4225 CHECK_NUMBER (insval, 0);
4226 inserted = XFASTINT (insval);
4228 QUIT;
4229 p = Fcdr (p);
4233 /* ??? Retval needs to be dealt with in all cases consistently. */
4234 if (NILP (val))
4235 val = Fcons (orig_filename,
4236 Fcons (make_number (inserted),
4237 Qnil));
4239 RETURN_UNGCPRO (unbind_to (count, val));
4242 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object,
4243 Lisp_Object));
4245 /* If build_annotations switched buffers, switch back to BUF.
4246 Kill the temporary buffer that was selected in the meantime.
4248 Since this kill only the last temporary buffer, some buffers remain
4249 not killed if build_annotations switched buffers more than once.
4250 -- K.Handa */
4252 static Lisp_Object
4253 build_annotations_unwind (buf)
4254 Lisp_Object buf;
4256 Lisp_Object tembuf;
4258 if (XBUFFER (buf) == current_buffer)
4259 return Qnil;
4260 tembuf = Fcurrent_buffer ();
4261 Fset_buffer (buf);
4262 Fkill_buffer (tembuf);
4263 return Qnil;
4266 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
4267 "r\nFWrite region to file: \ni\ni\ni\np",
4268 "Write current region into specified file.\n\
4269 When called from a program, takes three arguments:\n\
4270 START, END and FILENAME. START and END are buffer positions.\n\
4271 Optional fourth argument APPEND if non-nil means\n\
4272 append to existing file contents (if any).\n\
4273 Optional fifth argument VISIT if t means\n\
4274 set the last-save-file-modtime of buffer to this file's modtime\n\
4275 and mark buffer not modified.\n\
4276 If VISIT is a string, it is a second file name;\n\
4277 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
4278 VISIT is also the file name to lock and unlock for clash detection.\n\
4279 If VISIT is neither t nor nil nor a string,\n\
4280 that means do not print the \"Wrote file\" message.\n\
4281 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
4282 use for locking and unlocking, overriding FILENAME and VISIT.\n\
4283 The optional seventh arg MUSTBENEW, if non-nil, insists on a check\n\
4284 for an existing file with the same name. If MUSTBENEW is `excl',\n\
4285 that means to get an error if the file already exists; never overwrite.\n\
4286 If MUSTBENEW is neither nil nor `excl', that means ask for\n\
4287 confirmation before overwriting, but do go ahead and overwrite the file\n\
4288 if the user confirms.\n\
4289 Kludgy feature: if START is a string, then that string is written\n\
4290 to the file, instead of any buffer contents, and END is ignored.\n\
4292 This does code conversion according to the value of\n\
4293 `coding-system-for-write', `buffer-file-coding-system', or\n\
4294 `file-coding-system-alist', and sets the variable\n\
4295 `last-coding-system-used' to the coding system actually used.")
4297 (start, end, filename, append, visit, lockname, mustbenew)
4298 Lisp_Object start, end, filename, append, visit, lockname, mustbenew;
4300 register int desc;
4301 int failure;
4302 int save_errno;
4303 unsigned char *fn;
4304 struct stat st;
4305 int tem;
4306 int count = specpdl_ptr - specpdl;
4307 int count1;
4308 #ifdef VMS
4309 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
4310 #endif /* VMS */
4311 Lisp_Object handler;
4312 Lisp_Object visit_file;
4313 Lisp_Object annotations;
4314 Lisp_Object encoded_filename;
4315 int visiting, quietly;
4316 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4317 struct buffer *given_buffer;
4318 #ifdef DOS_NT
4319 int buffer_file_type = O_BINARY;
4320 #endif /* DOS_NT */
4321 struct coding_system coding;
4323 if (current_buffer->base_buffer && ! NILP (visit))
4324 error ("Cannot do file visiting in an indirect buffer");
4326 if (!NILP (start) && !STRINGP (start))
4327 validate_region (&start, &end);
4329 GCPRO4 (start, filename, visit, lockname);
4331 /* Decide the coding-system to encode the data with. */
4333 Lisp_Object val;
4335 if (auto_saving)
4336 val = Qnil;
4337 else if (!NILP (Vcoding_system_for_write))
4338 val = Vcoding_system_for_write;
4339 else
4341 /* If the variable `buffer-file-coding-system' is set locally,
4342 it means that the file was read with some kind of code
4343 conversion or the varialbe is explicitely set by users. We
4344 had better write it out with the same coding system even if
4345 `enable-multibyte-characters' is nil.
4347 If it is not set locally, we anyway have to convert EOL
4348 format if the default value of `buffer-file-coding-system'
4349 tells that it is not Unix-like (LF only) format. */
4350 int using_default_coding = 0;
4351 int force_raw_text = 0;
4353 val = current_buffer->buffer_file_coding_system;
4354 if (NILP (val)
4355 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4357 val = Qnil;
4358 if (NILP (current_buffer->enable_multibyte_characters))
4359 force_raw_text = 1;
4362 if (NILP (val))
4364 /* Check file-coding-system-alist. */
4365 Lisp_Object args[7], coding_systems;
4367 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4368 args[3] = filename; args[4] = append; args[5] = visit;
4369 args[6] = lockname;
4370 coding_systems = Ffind_operation_coding_system (7, args);
4371 if (CONSP (coding_systems) && !NILP (XCDR (coding_systems)))
4372 val = XCDR (coding_systems);
4375 if (NILP (val)
4376 && !NILP (current_buffer->buffer_file_coding_system))
4378 /* If we still have not decided a coding system, use the
4379 default value of buffer-file-coding-system. */
4380 val = current_buffer->buffer_file_coding_system;
4381 using_default_coding = 1;
4384 if (!force_raw_text
4385 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4386 /* Confirm that VAL can surely encode the current region. */
4387 val = call3 (Vselect_safe_coding_system_function, start, end, val);
4389 setup_coding_system (Fcheck_coding_system (val), &coding);
4390 if (coding.eol_type == CODING_EOL_UNDECIDED
4391 && !using_default_coding)
4393 if (! EQ (default_buffer_file_coding.symbol,
4394 buffer_defaults.buffer_file_coding_system))
4395 setup_coding_system (buffer_defaults.buffer_file_coding_system,
4396 &default_buffer_file_coding);
4397 if (default_buffer_file_coding.eol_type != CODING_EOL_UNDECIDED)
4399 Lisp_Object subsidiaries;
4401 coding.eol_type = default_buffer_file_coding.eol_type;
4402 subsidiaries = Fget (coding.symbol, Qeol_type);
4403 if (VECTORP (subsidiaries)
4404 && XVECTOR (subsidiaries)->size == 3)
4405 coding.symbol
4406 = XVECTOR (subsidiaries)->contents[coding.eol_type];
4410 if (force_raw_text)
4411 setup_raw_text_coding_system (&coding);
4412 goto done_setup_coding;
4415 setup_coding_system (Fcheck_coding_system (val), &coding);
4417 done_setup_coding:
4418 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4419 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY;
4422 Vlast_coding_system_used = coding.symbol;
4424 filename = Fexpand_file_name (filename, Qnil);
4426 if (! NILP (mustbenew) && mustbenew != Qexcl)
4427 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
4429 if (STRINGP (visit))
4430 visit_file = Fexpand_file_name (visit, Qnil);
4431 else
4432 visit_file = filename;
4433 UNGCPRO;
4435 visiting = (EQ (visit, Qt) || STRINGP (visit));
4436 quietly = !NILP (visit);
4438 annotations = Qnil;
4440 if (NILP (lockname))
4441 lockname = visit_file;
4443 GCPRO5 (start, filename, annotations, visit_file, lockname);
4445 /* If the file name has special constructs in it,
4446 call the corresponding file handler. */
4447 handler = Ffind_file_name_handler (filename, Qwrite_region);
4448 /* If FILENAME has no handler, see if VISIT has one. */
4449 if (NILP (handler) && STRINGP (visit))
4450 handler = Ffind_file_name_handler (visit, Qwrite_region);
4452 if (!NILP (handler))
4454 Lisp_Object val;
4455 val = call6 (handler, Qwrite_region, start, end,
4456 filename, append, visit);
4458 if (visiting)
4460 SAVE_MODIFF = MODIFF;
4461 XSETFASTINT (current_buffer->save_length, Z - BEG);
4462 current_buffer->filename = visit_file;
4464 UNGCPRO;
4465 return val;
4468 /* Special kludge to simplify auto-saving. */
4469 if (NILP (start))
4471 XSETFASTINT (start, BEG);
4472 XSETFASTINT (end, Z);
4475 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
4476 count1 = specpdl_ptr - specpdl;
4478 given_buffer = current_buffer;
4479 annotations = build_annotations (start, end, coding.pre_write_conversion);
4480 if (current_buffer != given_buffer)
4482 XSETFASTINT (start, BEGV);
4483 XSETFASTINT (end, ZV);
4486 #ifdef CLASH_DETECTION
4487 if (!auto_saving)
4489 #if 0 /* This causes trouble for GNUS. */
4490 /* If we've locked this file for some other buffer,
4491 query before proceeding. */
4492 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
4493 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
4494 #endif
4496 lock_file (lockname);
4498 #endif /* CLASH_DETECTION */
4500 encoded_filename = ENCODE_FILE (filename);
4502 fn = XSTRING (encoded_filename)->data;
4503 desc = -1;
4504 if (!NILP (append))
4505 #ifdef DOS_NT
4506 desc = emacs_open (fn, O_WRONLY | buffer_file_type, 0);
4507 #else /* not DOS_NT */
4508 desc = emacs_open (fn, O_WRONLY, 0);
4509 #endif /* not DOS_NT */
4511 if (desc < 0 && (NILP (append) || errno == ENOENT))
4512 #ifdef VMS
4513 if (auto_saving) /* Overwrite any previous version of autosave file */
4515 vms_truncate (fn); /* if fn exists, truncate to zero length */
4516 desc = emacs_open (fn, O_RDWR, 0);
4517 if (desc < 0)
4518 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
4519 ? XSTRING (current_buffer->filename)->data : 0,
4520 fn);
4522 else /* Write to temporary name and rename if no errors */
4524 Lisp_Object temp_name;
4525 temp_name = Ffile_name_directory (filename);
4527 if (!NILP (temp_name))
4529 temp_name = Fmake_temp_name (concat2 (temp_name,
4530 build_string ("$$SAVE$$")));
4531 fname = XSTRING (filename)->data;
4532 fn = XSTRING (temp_name)->data;
4533 desc = creat_copy_attrs (fname, fn);
4534 if (desc < 0)
4536 /* If we can't open the temporary file, try creating a new
4537 version of the original file. VMS "creat" creates a
4538 new version rather than truncating an existing file. */
4539 fn = fname;
4540 fname = 0;
4541 desc = creat (fn, 0666);
4542 #if 0 /* This can clobber an existing file and fail to replace it,
4543 if the user runs out of space. */
4544 if (desc < 0)
4546 /* We can't make a new version;
4547 try to truncate and rewrite existing version if any. */
4548 vms_truncate (fn);
4549 desc = emacs_open (fn, O_RDWR, 0);
4551 #endif
4554 else
4555 desc = creat (fn, 0666);
4557 #else /* not VMS */
4558 #ifdef DOS_NT
4559 desc = emacs_open (fn,
4560 O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type
4561 | (mustbenew == Qexcl ? O_EXCL : 0),
4562 S_IREAD | S_IWRITE);
4563 #else /* not DOS_NT */
4564 desc = emacs_open (fn, O_WRONLY | O_TRUNC | O_CREAT
4565 | (mustbenew == Qexcl ? O_EXCL : 0),
4566 auto_saving ? auto_save_mode_bits : 0666);
4567 #endif /* not DOS_NT */
4568 #endif /* not VMS */
4570 UNGCPRO;
4572 if (desc < 0)
4574 #ifdef CLASH_DETECTION
4575 save_errno = errno;
4576 if (!auto_saving) unlock_file (lockname);
4577 errno = save_errno;
4578 #endif /* CLASH_DETECTION */
4579 report_file_error ("Opening output file", Fcons (filename, Qnil));
4582 record_unwind_protect (close_file_unwind, make_number (desc));
4584 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
4585 if (lseek (desc, 0, 2) < 0)
4587 #ifdef CLASH_DETECTION
4588 if (!auto_saving) unlock_file (lockname);
4589 #endif /* CLASH_DETECTION */
4590 report_file_error ("Lseek error", Fcons (filename, Qnil));
4593 #ifdef VMS
4595 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4596 * if we do writes that don't end with a carriage return. Furthermore
4597 * it cannot handle writes of more then 16K. The modified
4598 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4599 * this EXCEPT for the last record (iff it doesn't end with a carriage
4600 * return). This implies that if your buffer doesn't end with a carriage
4601 * return, you get one free... tough. However it also means that if
4602 * we make two calls to sys_write (a la the following code) you can
4603 * get one at the gap as well. The easiest way to fix this (honest)
4604 * is to move the gap to the next newline (or the end of the buffer).
4605 * Thus this change.
4607 * Yech!
4609 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4610 move_gap (find_next_newline (GPT, 1));
4611 #else
4612 /* Whether VMS or not, we must move the gap to the next of newline
4613 when we must put designation sequences at beginning of line. */
4614 if (INTEGERP (start)
4615 && coding.type == coding_type_iso2022
4616 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4617 && GPT > BEG && GPT_ADDR[-1] != '\n')
4619 int opoint = PT, opoint_byte = PT_BYTE;
4620 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
4621 move_gap_both (PT, PT_BYTE);
4622 SET_PT_BOTH (opoint, opoint_byte);
4624 #endif
4626 failure = 0;
4627 immediate_quit = 1;
4629 if (STRINGP (start))
4631 failure = 0 > a_write (desc, XSTRING (start)->data,
4632 STRING_BYTES (XSTRING (start)), 0, &annotations,
4633 &coding);
4634 save_errno = errno;
4636 else if (XINT (start) != XINT (end))
4638 register int end1 = CHAR_TO_BYTE (XINT (end));
4640 tem = CHAR_TO_BYTE (XINT (start));
4642 if (XINT (start) < GPT)
4644 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem),
4645 min (GPT_BYTE, end1) - tem, tem, &annotations,
4646 &coding);
4647 save_errno = errno;
4650 if (XINT (end) > GPT && !failure)
4652 tem = max (tem, GPT_BYTE);
4653 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem,
4654 tem, &annotations, &coding);
4655 save_errno = errno;
4658 else
4660 /* If file was empty, still need to write the annotations */
4661 coding.mode |= CODING_MODE_LAST_BLOCK;
4662 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding);
4663 save_errno = errno;
4666 if (CODING_REQUIRE_FLUSHING (&coding)
4667 && !(coding.mode & CODING_MODE_LAST_BLOCK)
4668 && ! failure)
4670 /* We have to flush out a data. */
4671 coding.mode |= CODING_MODE_LAST_BLOCK;
4672 failure = 0 > e_write (desc, "", 0, &coding);
4673 save_errno = errno;
4676 immediate_quit = 0;
4678 #ifdef HAVE_FSYNC
4679 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4680 Disk full in NFS may be reported here. */
4681 /* mib says that closing the file will try to write as fast as NFS can do
4682 it, and that means the fsync here is not crucial for autosave files. */
4683 if (!auto_saving && fsync (desc) < 0)
4685 /* If fsync fails with EINTR, don't treat that as serious. */
4686 if (errno != EINTR)
4687 failure = 1, save_errno = errno;
4689 #endif
4691 /* Spurious "file has changed on disk" warnings have been
4692 observed on Suns as well.
4693 It seems that `close' can change the modtime, under nfs.
4695 (This has supposedly been fixed in Sunos 4,
4696 but who knows about all the other machines with NFS?) */
4697 #if 0
4699 /* On VMS and APOLLO, must do the stat after the close
4700 since closing changes the modtime. */
4701 #ifndef VMS
4702 #ifndef APOLLO
4703 /* Recall that #if defined does not work on VMS. */
4704 #define FOO
4705 fstat (desc, &st);
4706 #endif
4707 #endif
4708 #endif
4710 /* NFS can report a write failure now. */
4711 if (emacs_close (desc) < 0)
4712 failure = 1, save_errno = errno;
4714 #ifdef VMS
4715 /* If we wrote to a temporary name and had no errors, rename to real name. */
4716 if (fname)
4718 if (!failure)
4719 failure = (rename (fn, fname) != 0), save_errno = errno;
4720 fn = fname;
4722 #endif /* VMS */
4724 #ifndef FOO
4725 stat (fn, &st);
4726 #endif
4727 /* Discard the unwind protect for close_file_unwind. */
4728 specpdl_ptr = specpdl + count1;
4729 /* Restore the original current buffer. */
4730 visit_file = unbind_to (count, visit_file);
4732 #ifdef CLASH_DETECTION
4733 if (!auto_saving)
4734 unlock_file (lockname);
4735 #endif /* CLASH_DETECTION */
4737 /* Do this before reporting IO error
4738 to avoid a "file has changed on disk" warning on
4739 next attempt to save. */
4740 if (visiting)
4741 current_buffer->modtime = st.st_mtime;
4743 if (failure)
4744 error ("IO error writing %s: %s", XSTRING (filename)->data,
4745 emacs_strerror (save_errno));
4747 if (visiting)
4749 SAVE_MODIFF = MODIFF;
4750 XSETFASTINT (current_buffer->save_length, Z - BEG);
4751 current_buffer->filename = visit_file;
4752 update_mode_lines++;
4754 else if (quietly)
4755 return Qnil;
4757 if (!auto_saving)
4758 message_with_string ("Wrote %s", visit_file, 1);
4760 return Qnil;
4763 Lisp_Object merge ();
4765 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
4766 "Return t if (car A) is numerically less than (car B).")
4767 (a, b)
4768 Lisp_Object a, b;
4770 return Flss (Fcar (a), Fcar (b));
4773 /* Build the complete list of annotations appropriate for writing out
4774 the text between START and END, by calling all the functions in
4775 write-region-annotate-functions and merging the lists they return.
4776 If one of these functions switches to a different buffer, we assume
4777 that buffer contains altered text. Therefore, the caller must
4778 make sure to restore the current buffer in all cases,
4779 as save-excursion would do. */
4781 static Lisp_Object
4782 build_annotations (start, end, pre_write_conversion)
4783 Lisp_Object start, end, pre_write_conversion;
4785 Lisp_Object annotations;
4786 Lisp_Object p, res;
4787 struct gcpro gcpro1, gcpro2;
4788 Lisp_Object original_buffer;
4790 XSETBUFFER (original_buffer, current_buffer);
4792 annotations = Qnil;
4793 p = Vwrite_region_annotate_functions;
4794 GCPRO2 (annotations, p);
4795 while (!NILP (p))
4797 struct buffer *given_buffer = current_buffer;
4798 Vwrite_region_annotations_so_far = annotations;
4799 res = call2 (Fcar (p), start, end);
4800 /* If the function makes a different buffer current,
4801 assume that means this buffer contains altered text to be output.
4802 Reset START and END from the buffer bounds
4803 and discard all previous annotations because they should have
4804 been dealt with by this function. */
4805 if (current_buffer != given_buffer)
4807 XSETFASTINT (start, BEGV);
4808 XSETFASTINT (end, ZV);
4809 annotations = Qnil;
4811 Flength (res); /* Check basic validity of return value */
4812 annotations = merge (annotations, res, Qcar_less_than_car);
4813 p = Fcdr (p);
4816 /* Now do the same for annotation functions implied by the file-format */
4817 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
4818 p = Vauto_save_file_format;
4819 else
4820 p = current_buffer->file_format;
4821 while (!NILP (p))
4823 struct buffer *given_buffer = current_buffer;
4824 Vwrite_region_annotations_so_far = annotations;
4825 res = call4 (Qformat_annotate_function, Fcar (p), start, end,
4826 original_buffer);
4827 if (current_buffer != given_buffer)
4829 XSETFASTINT (start, BEGV);
4830 XSETFASTINT (end, ZV);
4831 annotations = Qnil;
4833 Flength (res);
4834 annotations = merge (annotations, res, Qcar_less_than_car);
4835 p = Fcdr (p);
4838 /* At last, do the same for the function PRE_WRITE_CONVERSION
4839 implied by the current coding-system. */
4840 if (!NILP (pre_write_conversion))
4842 struct buffer *given_buffer = current_buffer;
4843 Vwrite_region_annotations_so_far = annotations;
4844 res = call2 (pre_write_conversion, start, end);
4845 Flength (res);
4846 annotations = (current_buffer != given_buffer
4847 ? res
4848 : merge (annotations, res, Qcar_less_than_car));
4851 UNGCPRO;
4852 return annotations;
4855 /* Write to descriptor DESC the NBYTES bytes starting at ADDR,
4856 assuming they start at byte position BYTEPOS in the buffer.
4857 Intersperse with them the annotations from *ANNOT
4858 which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES,
4859 each at its appropriate position.
4861 We modify *ANNOT by discarding elements as we use them up.
4863 The return value is negative in case of system call failure. */
4865 static int
4866 a_write (desc, addr, nbytes, bytepos, annot, coding)
4867 int desc;
4868 register char *addr;
4869 register int nbytes;
4870 int bytepos;
4871 Lisp_Object *annot;
4872 struct coding_system *coding;
4874 Lisp_Object tem;
4875 int nextpos;
4876 int lastpos = bytepos + nbytes;
4878 while (NILP (*annot) || CONSP (*annot))
4880 tem = Fcar_safe (Fcar (*annot));
4881 nextpos = bytepos - 1;
4882 if (INTEGERP (tem))
4883 nextpos = CHAR_TO_BYTE (XFASTINT (tem));
4885 /* If there are no more annotations in this range,
4886 output the rest of the range all at once. */
4887 if (! (nextpos >= bytepos && nextpos <= lastpos))
4888 return e_write (desc, addr, lastpos - bytepos, coding);
4890 /* Output buffer text up to the next annotation's position. */
4891 if (nextpos > bytepos)
4893 if (0 > e_write (desc, addr, nextpos - bytepos, coding))
4894 return -1;
4895 addr += nextpos - bytepos;
4896 bytepos = nextpos;
4898 /* Output the annotation. */
4899 tem = Fcdr (Fcar (*annot));
4900 if (STRINGP (tem))
4902 if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)),
4903 coding))
4904 return -1;
4906 *annot = Fcdr (*annot);
4908 return 0;
4911 #ifndef WRITE_BUF_SIZE
4912 #define WRITE_BUF_SIZE (16 * 1024)
4913 #endif
4915 /* Write NBYTES bytes starting at ADDR into descriptor DESC,
4916 encoding them with coding system CODING. */
4918 static int
4919 e_write (desc, addr, nbytes, coding)
4920 int desc;
4921 register char *addr;
4922 register int nbytes;
4923 struct coding_system *coding;
4925 char buf[WRITE_BUF_SIZE];
4927 /* We used to have a code for handling selective display here. But,
4928 now it is handled within encode_coding. */
4929 while (1)
4931 int result;
4933 result = encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
4934 nbytes -= coding->consumed, addr += coding->consumed;
4935 if (coding->produced > 0)
4937 coding->produced -= emacs_write (desc, buf, coding->produced);
4938 if (coding->produced) return -1;
4940 if (result == CODING_FINISH_INSUFFICIENT_SRC)
4942 /* The source text ends by an incomplete multibyte form.
4943 There's no way other than write it out as is. */
4944 nbytes -= emacs_write (desc, addr, nbytes);
4945 if (nbytes) return -1;
4947 if (nbytes <= 0)
4948 break;
4950 return 0;
4953 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
4954 Sverify_visited_file_modtime, 1, 1, 0,
4955 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4956 This means that the file has not been changed since it was visited or saved.")
4957 (buf)
4958 Lisp_Object buf;
4960 struct buffer *b;
4961 struct stat st;
4962 Lisp_Object handler;
4963 Lisp_Object filename;
4965 CHECK_BUFFER (buf, 0);
4966 b = XBUFFER (buf);
4968 if (!STRINGP (b->filename)) return Qt;
4969 if (b->modtime == 0) return Qt;
4971 /* If the file name has special constructs in it,
4972 call the corresponding file handler. */
4973 handler = Ffind_file_name_handler (b->filename,
4974 Qverify_visited_file_modtime);
4975 if (!NILP (handler))
4976 return call2 (handler, Qverify_visited_file_modtime, buf);
4978 filename = ENCODE_FILE (b->filename);
4980 if (stat (XSTRING (filename)->data, &st) < 0)
4982 /* If the file doesn't exist now and didn't exist before,
4983 we say that it isn't modified, provided the error is a tame one. */
4984 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
4985 st.st_mtime = -1;
4986 else
4987 st.st_mtime = 0;
4989 if (st.st_mtime == b->modtime
4990 /* If both are positive, accept them if they are off by one second. */
4991 || (st.st_mtime > 0 && b->modtime > 0
4992 && (st.st_mtime == b->modtime + 1
4993 || st.st_mtime == b->modtime - 1)))
4994 return Qt;
4995 return Qnil;
4998 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
4999 Sclear_visited_file_modtime, 0, 0, 0,
5000 "Clear out records of last mod time of visited file.\n\
5001 Next attempt to save will certainly not complain of a discrepancy.")
5004 current_buffer->modtime = 0;
5005 return Qnil;
5008 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5009 Svisited_file_modtime, 0, 0, 0,
5010 "Return the current buffer's recorded visited file modification time.\n\
5011 The value is a list of the form (HIGH . LOW), like the time values\n\
5012 that `file-attributes' returns.")
5015 return long_to_cons ((unsigned long) current_buffer->modtime);
5018 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
5019 Sset_visited_file_modtime, 0, 1, 0,
5020 "Update buffer's recorded modification time from the visited file's time.\n\
5021 Useful if the buffer was not read from the file normally\n\
5022 or if the file itself has been changed for some known benign reason.\n\
5023 An argument specifies the modification time value to use\n\
5024 \(instead of that of the visited file), in the form of a list\n\
5025 \(HIGH . LOW) or (HIGH LOW).")
5026 (time_list)
5027 Lisp_Object time_list;
5029 if (!NILP (time_list))
5030 current_buffer->modtime = cons_to_long (time_list);
5031 else
5033 register Lisp_Object filename;
5034 struct stat st;
5035 Lisp_Object handler;
5037 filename = Fexpand_file_name (current_buffer->filename, Qnil);
5039 /* If the file name has special constructs in it,
5040 call the corresponding file handler. */
5041 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
5042 if (!NILP (handler))
5043 /* The handler can find the file name the same way we did. */
5044 return call2 (handler, Qset_visited_file_modtime, Qnil);
5046 filename = ENCODE_FILE (filename);
5048 if (stat (XSTRING (filename)->data, &st) >= 0)
5049 current_buffer->modtime = st.st_mtime;
5052 return Qnil;
5055 Lisp_Object
5056 auto_save_error ()
5058 ring_bell ();
5059 message_with_string ("Autosaving...error for %s", current_buffer->name, 1);
5060 Fsleep_for (make_number (1), Qnil);
5061 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
5062 Fsleep_for (make_number (1), Qnil);
5063 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
5064 Fsleep_for (make_number (1), Qnil);
5065 return Qnil;
5068 Lisp_Object
5069 auto_save_1 ()
5071 unsigned char *fn;
5072 struct stat st;
5074 /* Get visited file's mode to become the auto save file's mode. */
5075 if (stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
5076 /* But make sure we can overwrite it later! */
5077 auto_save_mode_bits = st.st_mode | 0600;
5078 else
5079 auto_save_mode_bits = 0666;
5081 return
5082 Fwrite_region (Qnil, Qnil,
5083 current_buffer->auto_save_file_name,
5084 Qnil, Qlambda, Qnil, Qnil);
5087 static Lisp_Object
5088 do_auto_save_unwind (stream) /* used as unwind-protect function */
5089 Lisp_Object stream;
5091 auto_saving = 0;
5092 if (!NILP (stream))
5093 fclose ((FILE *) (XFASTINT (XCAR (stream)) << 16
5094 | XFASTINT (XCDR (stream))));
5095 return Qnil;
5098 static Lisp_Object
5099 do_auto_save_unwind_1 (value) /* used as unwind-protect function */
5100 Lisp_Object value;
5102 minibuffer_auto_raise = XINT (value);
5103 return Qnil;
5106 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
5107 "Auto-save all buffers that need it.\n\
5108 This is all buffers that have auto-saving enabled\n\
5109 and are changed since last auto-saved.\n\
5110 Auto-saving writes the buffer into a file\n\
5111 so that your editing is not lost if the system crashes.\n\
5112 This file is not the file you visited; that changes only when you save.\n\
5113 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
5114 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
5115 A non-nil CURRENT-ONLY argument means save only current buffer.")
5116 (no_message, current_only)
5117 Lisp_Object no_message, current_only;
5119 struct buffer *old = current_buffer, *b;
5120 Lisp_Object tail, buf;
5121 int auto_saved = 0;
5122 int do_handled_files;
5123 Lisp_Object oquit;
5124 FILE *stream;
5125 Lisp_Object lispstream;
5126 int count = specpdl_ptr - specpdl;
5127 int *ptr;
5128 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
5129 int message_p = push_message ();
5131 /* Ordinarily don't quit within this function,
5132 but don't make it impossible to quit (in case we get hung in I/O). */
5133 oquit = Vquit_flag;
5134 Vquit_flag = Qnil;
5136 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
5137 point to non-strings reached from Vbuffer_alist. */
5139 if (minibuf_level)
5140 no_message = Qt;
5142 if (!NILP (Vrun_hooks))
5143 call1 (Vrun_hooks, intern ("auto-save-hook"));
5145 if (STRINGP (Vauto_save_list_file_name))
5147 Lisp_Object listfile;
5148 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
5149 stream = fopen (XSTRING (listfile)->data, "w");
5150 if (stream != NULL)
5152 /* Arrange to close that file whether or not we get an error.
5153 Also reset auto_saving to 0. */
5154 lispstream = Fcons (Qnil, Qnil);
5155 XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
5156 XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
5158 else
5159 lispstream = Qnil;
5161 else
5163 stream = NULL;
5164 lispstream = Qnil;
5167 record_unwind_protect (do_auto_save_unwind, lispstream);
5168 record_unwind_protect (do_auto_save_unwind_1,
5169 make_number (minibuffer_auto_raise));
5170 minibuffer_auto_raise = 0;
5171 auto_saving = 1;
5173 /* First, save all files which don't have handlers. If Emacs is
5174 crashing, the handlers may tweak what is causing Emacs to crash
5175 in the first place, and it would be a shame if Emacs failed to
5176 autosave perfectly ordinary files because it couldn't handle some
5177 ange-ftp'd file. */
5178 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
5179 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCDR (tail))
5181 buf = XCDR (XCAR (tail));
5182 b = XBUFFER (buf);
5184 /* Record all the buffers that have auto save mode
5185 in the special file that lists them. For each of these buffers,
5186 Record visited name (if any) and auto save name. */
5187 if (STRINGP (b->auto_save_file_name)
5188 && stream != NULL && do_handled_files == 0)
5190 if (!NILP (b->filename))
5192 fwrite (XSTRING (b->filename)->data, 1,
5193 STRING_BYTES (XSTRING (b->filename)), stream);
5195 putc ('\n', stream);
5196 fwrite (XSTRING (b->auto_save_file_name)->data, 1,
5197 STRING_BYTES (XSTRING (b->auto_save_file_name)), stream);
5198 putc ('\n', stream);
5201 if (!NILP (current_only)
5202 && b != current_buffer)
5203 continue;
5205 /* Don't auto-save indirect buffers.
5206 The base buffer takes care of it. */
5207 if (b->base_buffer)
5208 continue;
5210 /* Check for auto save enabled
5211 and file changed since last auto save
5212 and file changed since last real save. */
5213 if (STRINGP (b->auto_save_file_name)
5214 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
5215 && b->auto_save_modified < BUF_MODIFF (b)
5216 /* -1 means we've turned off autosaving for a while--see below. */
5217 && XINT (b->save_length) >= 0
5218 && (do_handled_files
5219 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
5220 Qwrite_region))))
5222 EMACS_TIME before_time, after_time;
5224 EMACS_GET_TIME (before_time);
5226 /* If we had a failure, don't try again for 20 minutes. */
5227 if (b->auto_save_failure_time >= 0
5228 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
5229 continue;
5231 if ((XFASTINT (b->save_length) * 10
5232 > (BUF_Z (b) - BUF_BEG (b)) * 13)
5233 /* A short file is likely to change a large fraction;
5234 spare the user annoying messages. */
5235 && XFASTINT (b->save_length) > 5000
5236 /* These messages are frequent and annoying for `*mail*'. */
5237 && !EQ (b->filename, Qnil)
5238 && NILP (no_message))
5240 /* It has shrunk too much; turn off auto-saving here. */
5241 minibuffer_auto_raise = orig_minibuffer_auto_raise;
5242 message_with_string ("Buffer %s has shrunk a lot; auto save turned off there",
5243 b->name, 1);
5244 minibuffer_auto_raise = 0;
5245 /* Turn off auto-saving until there's a real save,
5246 and prevent any more warnings. */
5247 XSETINT (b->save_length, -1);
5248 Fsleep_for (make_number (1), Qnil);
5249 continue;
5251 set_buffer_internal (b);
5252 if (!auto_saved && NILP (no_message))
5253 message1 ("Auto-saving...");
5254 internal_condition_case (auto_save_1, Qt, auto_save_error);
5255 auto_saved++;
5256 b->auto_save_modified = BUF_MODIFF (b);
5257 XSETFASTINT (current_buffer->save_length, Z - BEG);
5258 set_buffer_internal (old);
5260 EMACS_GET_TIME (after_time);
5262 /* If auto-save took more than 60 seconds,
5263 assume it was an NFS failure that got a timeout. */
5264 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
5265 b->auto_save_failure_time = EMACS_SECS (after_time);
5269 /* Prevent another auto save till enough input events come in. */
5270 record_auto_save ();
5272 if (auto_saved && NILP (no_message))
5274 if (message_p)
5276 sit_for (1, 0, 0, 0, 0);
5277 restore_message ();
5279 else
5280 message1 ("Auto-saving...done");
5283 Vquit_flag = oquit;
5285 pop_message ();
5286 unbind_to (count, Qnil);
5287 return Qnil;
5290 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
5291 Sset_buffer_auto_saved, 0, 0, 0,
5292 "Mark current buffer as auto-saved with its current text.\n\
5293 No auto-save file will be written until the buffer changes again.")
5296 current_buffer->auto_save_modified = MODIFF;
5297 XSETFASTINT (current_buffer->save_length, Z - BEG);
5298 current_buffer->auto_save_failure_time = -1;
5299 return Qnil;
5302 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
5303 Sclear_buffer_auto_save_failure, 0, 0, 0,
5304 "Clear any record of a recent auto-save failure in the current buffer.")
5307 current_buffer->auto_save_failure_time = -1;
5308 return Qnil;
5311 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
5312 0, 0, 0,
5313 "Return t if buffer has been auto-saved since last read in or saved.")
5316 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
5319 /* Reading and completing file names */
5320 extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
5322 /* In the string VAL, change each $ to $$ and return the result. */
5324 static Lisp_Object
5325 double_dollars (val)
5326 Lisp_Object val;
5328 register unsigned char *old, *new;
5329 register int n;
5330 int osize, count;
5332 osize = STRING_BYTES (XSTRING (val));
5334 /* Count the number of $ characters. */
5335 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
5336 if (*old++ == '$') count++;
5337 if (count > 0)
5339 old = XSTRING (val)->data;
5340 val = make_uninit_multibyte_string (XSTRING (val)->size + count,
5341 osize + count);
5342 new = XSTRING (val)->data;
5343 for (n = osize; n > 0; n--)
5344 if (*old != '$')
5345 *new++ = *old++;
5346 else
5348 *new++ = '$';
5349 *new++ = '$';
5350 old++;
5353 return val;
5356 DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
5357 3, 3, 0,
5358 "Internal subroutine for read-file-name. Do not call this.")
5359 (string, dir, action)
5360 Lisp_Object string, dir, action;
5361 /* action is nil for complete, t for return list of completions,
5362 lambda for verify final value */
5364 Lisp_Object name, specdir, realdir, val, orig_string;
5365 int changed;
5366 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
5368 CHECK_STRING (string, 0);
5370 realdir = dir;
5371 name = string;
5372 orig_string = Qnil;
5373 specdir = Qnil;
5374 changed = 0;
5375 /* No need to protect ACTION--we only compare it with t and nil. */
5376 GCPRO5 (string, realdir, name, specdir, orig_string);
5378 if (XSTRING (string)->size == 0)
5380 if (EQ (action, Qlambda))
5382 UNGCPRO;
5383 return Qnil;
5386 else
5388 orig_string = string;
5389 string = Fsubstitute_in_file_name (string);
5390 changed = NILP (Fstring_equal (string, orig_string));
5391 name = Ffile_name_nondirectory (string);
5392 val = Ffile_name_directory (string);
5393 if (! NILP (val))
5394 realdir = Fexpand_file_name (val, realdir);
5397 if (NILP (action))
5399 specdir = Ffile_name_directory (string);
5400 val = Ffile_name_completion (name, realdir);
5401 UNGCPRO;
5402 if (!STRINGP (val))
5404 if (changed)
5405 return double_dollars (string);
5406 return val;
5409 if (!NILP (specdir))
5410 val = concat2 (specdir, val);
5411 #ifndef VMS
5412 return double_dollars (val);
5413 #else /* not VMS */
5414 return val;
5415 #endif /* not VMS */
5417 UNGCPRO;
5419 if (EQ (action, Qt))
5420 return Ffile_name_all_completions (name, realdir);
5421 /* Only other case actually used is ACTION = lambda */
5422 #ifdef VMS
5423 /* Supposedly this helps commands such as `cd' that read directory names,
5424 but can someone explain how it helps them? -- RMS */
5425 if (XSTRING (name)->size == 0)
5426 return Qt;
5427 #endif /* VMS */
5428 return Ffile_exists_p (string);
5431 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
5432 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
5433 Value is not expanded---you must call `expand-file-name' yourself.\n\
5434 Default name to DEFAULT-FILENAME if user enters a null string.\n\
5435 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
5436 except that if INITIAL is specified, that combined with DIR is used.)\n\
5437 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
5438 Non-nil and non-t means also require confirmation after completion.\n\
5439 Fifth arg INITIAL specifies text to start with.\n\
5440 DIR defaults to current buffer's directory default.")
5441 (prompt, dir, default_filename, mustmatch, initial)
5442 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
5444 Lisp_Object val, insdef, tem;
5445 struct gcpro gcpro1, gcpro2;
5446 register char *homedir;
5447 int replace_in_history = 0;
5448 int add_to_history = 0;
5449 int count;
5451 if (NILP (dir))
5452 dir = current_buffer->directory;
5453 if (NILP (default_filename))
5455 if (! NILP (initial))
5456 default_filename = Fexpand_file_name (initial, dir);
5457 else
5458 default_filename = current_buffer->filename;
5461 /* If dir starts with user's homedir, change that to ~. */
5462 homedir = (char *) egetenv ("HOME");
5463 #ifdef DOS_NT
5464 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
5465 CORRECT_DIR_SEPS (homedir);
5466 #endif
5467 if (homedir != 0
5468 && STRINGP (dir)
5469 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
5470 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
5472 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
5473 STRING_BYTES (XSTRING (dir)) - strlen (homedir) + 1);
5474 XSTRING (dir)->data[0] = '~';
5476 /* Likewise for default_filename. */
5477 if (homedir != 0
5478 && STRINGP (default_filename)
5479 && !strncmp (homedir, XSTRING (default_filename)->data, strlen (homedir))
5480 && IS_DIRECTORY_SEP (XSTRING (default_filename)->data[strlen (homedir)]))
5482 default_filename
5483 = make_string (XSTRING (default_filename)->data + strlen (homedir) - 1,
5484 STRING_BYTES (XSTRING (default_filename)) - strlen (homedir) + 1);
5485 XSTRING (default_filename)->data[0] = '~';
5487 if (!NILP (default_filename))
5489 CHECK_STRING (default_filename, 3);
5490 default_filename = double_dollars (default_filename);
5493 if (insert_default_directory && STRINGP (dir))
5495 insdef = dir;
5496 if (!NILP (initial))
5498 Lisp_Object args[2], pos;
5500 args[0] = insdef;
5501 args[1] = initial;
5502 insdef = Fconcat (2, args);
5503 pos = make_number (XSTRING (double_dollars (dir))->size);
5504 insdef = Fcons (double_dollars (insdef), pos);
5506 else
5507 insdef = double_dollars (insdef);
5509 else if (STRINGP (initial))
5510 insdef = Fcons (double_dollars (initial), make_number (0));
5511 else
5512 insdef = Qnil;
5514 count = specpdl_ptr - specpdl;
5515 #ifdef VMS
5516 specbind (intern ("completion-ignore-case"), Qt);
5517 #endif
5519 specbind (intern ("minibuffer-completing-file-name"), Qt);
5521 GCPRO2 (insdef, default_filename);
5523 #ifdef USE_MOTIF
5524 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
5525 && use_dialog_box
5526 && have_menus_p ())
5528 val = Fx_file_dialog (prompt, dir, default_filename, mustmatch);
5529 add_to_history = 1;
5531 else
5532 #endif
5533 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
5534 dir, mustmatch, insdef,
5535 Qfile_name_history, default_filename, Qnil);
5537 tem = Fsymbol_value (Qfile_name_history);
5538 if (CONSP (tem) && EQ (XCAR (tem), val))
5539 replace_in_history = 1;
5541 /* If Fcompleting_read returned the inserted default string itself
5542 (rather than a new string with the same contents),
5543 it has to mean that the user typed RET with the minibuffer empty.
5544 In that case, we really want to return ""
5545 so that commands such as set-visited-file-name can distinguish. */
5546 if (EQ (val, default_filename))
5548 /* In this case, Fcompleting_read has not added an element
5549 to the history. Maybe we should. */
5550 if (! replace_in_history)
5551 add_to_history = 1;
5553 val = build_string ("");
5556 unbind_to (count, Qnil);
5557 UNGCPRO;
5558 if (NILP (val))
5559 error ("No file name specified");
5561 tem = Fstring_equal (val, CONSP (insdef) ? XCAR (insdef) : insdef);
5563 if (!NILP (tem) && !NILP (default_filename))
5564 val = default_filename;
5565 else if (XSTRING (val)->size == 0 && NILP (insdef))
5567 if (!NILP (default_filename))
5568 val = default_filename;
5569 else
5570 error ("No default file name");
5572 val = Fsubstitute_in_file_name (val);
5574 if (replace_in_history)
5575 /* Replace what Fcompleting_read added to the history
5576 with what we will actually return. */
5577 XCAR (Fsymbol_value (Qfile_name_history)) = double_dollars (val);
5578 else if (add_to_history)
5580 /* Add the value to the history--but not if it matches
5581 the last value already there. */
5582 Lisp_Object val1 = double_dollars (val);
5583 tem = Fsymbol_value (Qfile_name_history);
5584 if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1)))
5585 Fset (Qfile_name_history,
5586 Fcons (val1, tem));
5589 return val;
5593 void
5594 init_fileio_once ()
5596 /* Must be set before any path manipulation is performed. */
5597 XSETFASTINT (Vdirectory_sep_char, '/');
5601 void
5602 syms_of_fileio ()
5604 Qexpand_file_name = intern ("expand-file-name");
5605 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
5606 Qdirectory_file_name = intern ("directory-file-name");
5607 Qfile_name_directory = intern ("file-name-directory");
5608 Qfile_name_nondirectory = intern ("file-name-nondirectory");
5609 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
5610 Qfile_name_as_directory = intern ("file-name-as-directory");
5611 Qcopy_file = intern ("copy-file");
5612 Qmake_directory_internal = intern ("make-directory-internal");
5613 Qdelete_directory = intern ("delete-directory");
5614 Qdelete_file = intern ("delete-file");
5615 Qrename_file = intern ("rename-file");
5616 Qadd_name_to_file = intern ("add-name-to-file");
5617 Qmake_symbolic_link = intern ("make-symbolic-link");
5618 Qfile_exists_p = intern ("file-exists-p");
5619 Qfile_executable_p = intern ("file-executable-p");
5620 Qfile_readable_p = intern ("file-readable-p");
5621 Qfile_writable_p = intern ("file-writable-p");
5622 Qfile_symlink_p = intern ("file-symlink-p");
5623 Qaccess_file = intern ("access-file");
5624 Qfile_directory_p = intern ("file-directory-p");
5625 Qfile_regular_p = intern ("file-regular-p");
5626 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
5627 Qfile_modes = intern ("file-modes");
5628 Qset_file_modes = intern ("set-file-modes");
5629 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
5630 Qinsert_file_contents = intern ("insert-file-contents");
5631 Qwrite_region = intern ("write-region");
5632 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
5633 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
5635 staticpro (&Qexpand_file_name);
5636 staticpro (&Qsubstitute_in_file_name);
5637 staticpro (&Qdirectory_file_name);
5638 staticpro (&Qfile_name_directory);
5639 staticpro (&Qfile_name_nondirectory);
5640 staticpro (&Qunhandled_file_name_directory);
5641 staticpro (&Qfile_name_as_directory);
5642 staticpro (&Qcopy_file);
5643 staticpro (&Qmake_directory_internal);
5644 staticpro (&Qdelete_directory);
5645 staticpro (&Qdelete_file);
5646 staticpro (&Qrename_file);
5647 staticpro (&Qadd_name_to_file);
5648 staticpro (&Qmake_symbolic_link);
5649 staticpro (&Qfile_exists_p);
5650 staticpro (&Qfile_executable_p);
5651 staticpro (&Qfile_readable_p);
5652 staticpro (&Qfile_writable_p);
5653 staticpro (&Qaccess_file);
5654 staticpro (&Qfile_symlink_p);
5655 staticpro (&Qfile_directory_p);
5656 staticpro (&Qfile_regular_p);
5657 staticpro (&Qfile_accessible_directory_p);
5658 staticpro (&Qfile_modes);
5659 staticpro (&Qset_file_modes);
5660 staticpro (&Qfile_newer_than_file_p);
5661 staticpro (&Qinsert_file_contents);
5662 staticpro (&Qwrite_region);
5663 staticpro (&Qverify_visited_file_modtime);
5664 staticpro (&Qset_visited_file_modtime);
5666 Qfile_name_history = intern ("file-name-history");
5667 Fset (Qfile_name_history, Qnil);
5668 staticpro (&Qfile_name_history);
5670 Qfile_error = intern ("file-error");
5671 staticpro (&Qfile_error);
5672 Qfile_already_exists = intern ("file-already-exists");
5673 staticpro (&Qfile_already_exists);
5674 Qfile_date_error = intern ("file-date-error");
5675 staticpro (&Qfile_date_error);
5676 Qexcl = intern ("excl");
5677 staticpro (&Qexcl);
5679 #ifdef DOS_NT
5680 Qfind_buffer_file_type = intern ("find-buffer-file-type");
5681 staticpro (&Qfind_buffer_file_type);
5682 #endif /* DOS_NT */
5684 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
5685 "*Coding system for encoding file names.\n\
5686 If it is nil, default-file-name-coding-system (which see) is used.");
5687 Vfile_name_coding_system = Qnil;
5689 DEFVAR_LISP ("default-file-name-coding-system",
5690 &Vdefault_file_name_coding_system,
5691 "Default coding system for encoding file names.\n\
5692 This variable is used only when file-name-coding-system is nil.\n\
5694 This variable is set/changed by the command set-language-environment.\n\
5695 User should not set this variable manually,\n\
5696 instead use file-name-coding-system to get a constant encoding\n\
5697 of file names regardless of the current language environment.");
5698 Vdefault_file_name_coding_system = Qnil;
5700 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
5701 "*Format in which to write auto-save files.\n\
5702 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5703 If it is t, which is the default, auto-save files are written in the\n\
5704 same format as a regular save would use.");
5705 Vauto_save_file_format = Qt;
5707 Qformat_decode = intern ("format-decode");
5708 staticpro (&Qformat_decode);
5709 Qformat_annotate_function = intern ("format-annotate-function");
5710 staticpro (&Qformat_annotate_function);
5712 Qcar_less_than_car = intern ("car-less-than-car");
5713 staticpro (&Qcar_less_than_car);
5715 Fput (Qfile_error, Qerror_conditions,
5716 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
5717 Fput (Qfile_error, Qerror_message,
5718 build_string ("File error"));
5720 Fput (Qfile_already_exists, Qerror_conditions,
5721 Fcons (Qfile_already_exists,
5722 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5723 Fput (Qfile_already_exists, Qerror_message,
5724 build_string ("File already exists"));
5726 Fput (Qfile_date_error, Qerror_conditions,
5727 Fcons (Qfile_date_error,
5728 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5729 Fput (Qfile_date_error, Qerror_message,
5730 build_string ("Cannot set file date"));
5732 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
5733 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5734 insert_default_directory = 1;
5736 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
5737 "*Non-nil means write new files with record format `stmlf'.\n\
5738 nil means use format `var'. This variable is meaningful only on VMS.");
5739 vms_stmlf_recfm = 0;
5741 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
5742 "Directory separator character for built-in functions that return file names.\n\
5743 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5744 This variable affects the built-in functions only on Windows,\n\
5745 on other platforms, it is initialized so that Lisp code can find out\n\
5746 what the normal separator is.");
5748 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
5749 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5750 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5751 HANDLER.\n\
5753 The first argument given to HANDLER is the name of the I/O primitive\n\
5754 to be handled; the remaining arguments are the arguments that were\n\
5755 passed to that primitive. For example, if you do\n\
5756 (file-exists-p FILENAME)\n\
5757 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5758 (funcall HANDLER 'file-exists-p FILENAME)\n\
5759 The function `find-file-name-handler' checks this list for a handler\n\
5760 for its argument.");
5761 Vfile_name_handler_alist = Qnil;
5763 DEFVAR_LISP ("set-auto-coding-function",
5764 &Vset_auto_coding_function,
5765 "If non-nil, a function to call to decide a coding system of file.\n\
5766 Two arguments are passed to this function: the file name\n\
5767 and the length of a file contents following the point.\n\
5768 This function should return a coding system to decode the file contents.\n\
5769 It should check the file name against `auto-coding-alist'.\n\
5770 If no coding system is decided, it should check a coding system\n\
5771 specified in the heading lines with the format:\n\
5772 -*- ... coding: CODING-SYSTEM; ... -*-\n\
5773 or local variable spec of the tailing lines with `coding:' tag.");
5774 Vset_auto_coding_function = Qnil;
5776 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
5777 "A list of functions to be called at the end of `insert-file-contents'.\n\
5778 Each is passed one argument, the number of bytes inserted. It should return\n\
5779 the new byte count, and leave point the same. If `insert-file-contents' is\n\
5780 intercepted by a handler from `file-name-handler-alist', that handler is\n\
5781 responsible for calling the after-insert-file-functions if appropriate.");
5782 Vafter_insert_file_functions = Qnil;
5784 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
5785 "A list of functions to be called at the start of `write-region'.\n\
5786 Each is passed two arguments, START and END as for `write-region'.\n\
5787 These are usually two numbers but not always; see the documentation\n\
5788 for `write-region'. The function should return a list of pairs\n\
5789 of the form (POSITION . STRING), consisting of strings to be effectively\n\
5790 inserted at the specified positions of the file being written (1 means to\n\
5791 insert before the first byte written). The POSITIONs must be sorted into\n\
5792 increasing order. If there are several functions in the list, the several\n\
5793 lists are merged destructively.");
5794 Vwrite_region_annotate_functions = Qnil;
5796 DEFVAR_LISP ("write-region-annotations-so-far",
5797 &Vwrite_region_annotations_so_far,
5798 "When an annotation function is called, this holds the previous annotations.\n\
5799 These are the annotations made by other annotation functions\n\
5800 that were already called. See also `write-region-annotate-functions'.");
5801 Vwrite_region_annotations_so_far = Qnil;
5803 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
5804 "A list of file name handlers that temporarily should not be used.\n\
5805 This applies only to the operation `inhibit-file-name-operation'.");
5806 Vinhibit_file_name_handlers = Qnil;
5808 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
5809 "The operation for which `inhibit-file-name-handlers' is applicable.");
5810 Vinhibit_file_name_operation = Qnil;
5812 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
5813 "File name in which we write a list of all auto save file names.\n\
5814 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5815 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5816 a non-nil value.");
5817 Vauto_save_list_file_name = Qnil;
5819 defsubr (&Sfind_file_name_handler);
5820 defsubr (&Sfile_name_directory);
5821 defsubr (&Sfile_name_nondirectory);
5822 defsubr (&Sunhandled_file_name_directory);
5823 defsubr (&Sfile_name_as_directory);
5824 defsubr (&Sdirectory_file_name);
5825 defsubr (&Smake_temp_name);
5826 defsubr (&Sexpand_file_name);
5827 defsubr (&Ssubstitute_in_file_name);
5828 defsubr (&Scopy_file);
5829 defsubr (&Smake_directory_internal);
5830 defsubr (&Sdelete_directory);
5831 defsubr (&Sdelete_file);
5832 defsubr (&Srename_file);
5833 defsubr (&Sadd_name_to_file);
5834 #ifdef S_IFLNK
5835 defsubr (&Smake_symbolic_link);
5836 #endif /* S_IFLNK */
5837 #ifdef VMS
5838 defsubr (&Sdefine_logical_name);
5839 #endif /* VMS */
5840 #ifdef HPUX_NET
5841 defsubr (&Ssysnetunam);
5842 #endif /* HPUX_NET */
5843 defsubr (&Sfile_name_absolute_p);
5844 defsubr (&Sfile_exists_p);
5845 defsubr (&Sfile_executable_p);
5846 defsubr (&Sfile_readable_p);
5847 defsubr (&Sfile_writable_p);
5848 defsubr (&Saccess_file);
5849 defsubr (&Sfile_symlink_p);
5850 defsubr (&Sfile_directory_p);
5851 defsubr (&Sfile_accessible_directory_p);
5852 defsubr (&Sfile_regular_p);
5853 defsubr (&Sfile_modes);
5854 defsubr (&Sset_file_modes);
5855 defsubr (&Sset_default_file_modes);
5856 defsubr (&Sdefault_file_modes);
5857 defsubr (&Sfile_newer_than_file_p);
5858 defsubr (&Sinsert_file_contents);
5859 defsubr (&Swrite_region);
5860 defsubr (&Scar_less_than_car);
5861 defsubr (&Sverify_visited_file_modtime);
5862 defsubr (&Sclear_visited_file_modtime);
5863 defsubr (&Svisited_file_modtime);
5864 defsubr (&Sset_visited_file_modtime);
5865 defsubr (&Sdo_auto_save);
5866 defsubr (&Sset_buffer_auto_saved);
5867 defsubr (&Sclear_buffer_auto_save_failure);
5868 defsubr (&Srecent_auto_save_p);
5870 defsubr (&Sread_file_name_internal);
5871 defsubr (&Sread_file_name);
5873 #ifdef unix
5874 defsubr (&Sunix_sync);
5875 #endif