07bc4334ebd6e406e2f1176691b9dd56042b3a0f
[bpt/emacs.git] / src / fileio.c
1 /* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96,97,1998 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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. */
20
21 #include <config.h>
22
23 #if defined (USG5) || defined (BSD_SYSTEM) || defined (LINUX)
24 #include <fcntl.h>
25 #endif
26
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #if !defined (S_ISLNK) && defined (S_IFLNK)
36 # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
37 #endif
38
39 #if !defined (S_ISFIFO) && defined (S_IFIFO)
40 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
41 #endif
42
43 #if !defined (S_ISREG) && defined (S_IFREG)
44 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
45 #endif
46
47 #ifdef VMS
48 #include "vms-pwd.h"
49 #else
50 #include <pwd.h>
51 #endif
52
53 #ifdef MSDOS
54 #include "msdos.h"
55 #include <sys/param.h>
56 #if __DJGPP__ >= 2
57 #include <fcntl.h>
58 #include <string.h>
59 #endif
60 #endif
61
62 #include <ctype.h>
63
64 #ifdef VMS
65 #include "vmsdir.h"
66 #include <perror.h>
67 #include <stddef.h>
68 #include <string.h>
69 #endif
70
71 #include <errno.h>
72
73 #ifndef vax11c
74 extern int errno;
75 #endif
76
77 extern char *strerror ();
78
79 #ifdef APOLLO
80 #include <sys/time.h>
81 #endif
82
83 #ifndef USG
84 #ifndef VMS
85 #ifndef BSD4_1
86 #ifndef WINDOWSNT
87 #define HAVE_FSYNC
88 #endif
89 #endif
90 #endif
91 #endif
92
93 #include "lisp.h"
94 #include "intervals.h"
95 #include "buffer.h"
96 #include "charset.h"
97 #include "coding.h"
98 #include "window.h"
99
100 #ifdef WINDOWSNT
101 #define NOMINMAX 1
102 #include <windows.h>
103 #include <stdlib.h>
104 #include <fcntl.h>
105 #endif /* not WINDOWSNT */
106
107 #ifdef DOS_NT
108 #define CORRECT_DIR_SEPS(s) \
109 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
110 else unixtodos_filename (s); \
111 } while (0)
112 /* On Windows, drive letters must be alphabetic - on DOS, the Netware
113 redirector allows the six letters between 'Z' and 'a' as well. */
114 #ifdef MSDOS
115 #define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
116 #endif
117 #ifdef WINDOWSNT
118 #define IS_DRIVE(x) isalpha (x)
119 #endif
120 /* Need to lower-case the drive letter, or else expanded
121 filenames will sometimes compare inequal, because
122 `expand-file-name' doesn't always down-case the drive letter. */
123 #define DRIVE_LETTER(x) (tolower (x))
124 #endif
125
126 #ifdef VMS
127 #include <file.h>
128 #include <rmsdef.h>
129 #include <fab.h>
130 #include <nam.h>
131 #endif
132
133 #include "systime.h"
134
135 #ifdef HPUX
136 #include <netio.h>
137 #ifndef HPUX8
138 #ifndef HPUX9
139 #include <errnet.h>
140 #endif
141 #endif
142 #endif
143
144 #ifndef O_WRONLY
145 #define O_WRONLY 1
146 #endif
147
148 #ifndef O_RDONLY
149 #define O_RDONLY 0
150 #endif
151
152 #define min(a, b) ((a) < (b) ? (a) : (b))
153 #define max(a, b) ((a) > (b) ? (a) : (b))
154
155 /* Nonzero during writing of auto-save files */
156 int auto_saving;
157
158 /* Set by auto_save_1 to mode of original file so Fwrite_region will create
159 a new file with the same mode as the original */
160 int auto_save_mode_bits;
161
162 /* Coding system for file names, or nil if none. */
163 Lisp_Object Vfile_name_coding_system;
164
165 /* Coding system for file names used only when
166 Vfile_name_coding_system is nil. */
167 Lisp_Object Vdefault_file_name_coding_system;
168
169 /* Alist of elements (REGEXP . HANDLER) for file names
170 whose I/O is done with a special handler. */
171 Lisp_Object Vfile_name_handler_alist;
172
173 /* Format for auto-save files */
174 Lisp_Object Vauto_save_file_format;
175
176 /* Lisp functions for translating file formats */
177 Lisp_Object Qformat_decode, Qformat_annotate_function;
178
179 /* Function to be called to decide a coding system of a reading file. */
180 Lisp_Object Vset_auto_coding_function;
181
182 /* Functions to be called to process text properties in inserted file. */
183 Lisp_Object Vafter_insert_file_functions;
184
185 /* Functions to be called to create text property annotations for file. */
186 Lisp_Object Vwrite_region_annotate_functions;
187
188 /* During build_annotations, each time an annotation function is called,
189 this holds the annotations made by the previous functions. */
190 Lisp_Object Vwrite_region_annotations_so_far;
191
192 /* File name in which we write a list of all our auto save files. */
193 Lisp_Object Vauto_save_list_file_name;
194
195 /* Nonzero means, when reading a filename in the minibuffer,
196 start out by inserting the default directory into the minibuffer. */
197 int insert_default_directory;
198
199 /* On VMS, nonzero means write new files with record format stmlf.
200 Zero means use var format. */
201 int vms_stmlf_recfm;
202
203 /* On NT, specifies the directory separator character, used (eg.) when
204 expanding file names. This can be bound to / or \. */
205 Lisp_Object Vdirectory_sep_char;
206
207 extern Lisp_Object Vuser_login_name;
208
209 extern int minibuf_level;
210
211 extern int minibuffer_auto_raise;
212
213 /* These variables describe handlers that have "already" had a chance
214 to handle the current operation.
215
216 Vinhibit_file_name_handlers is a list of file name handlers.
217 Vinhibit_file_name_operation is the operation being handled.
218 If we try to handle that operation, we ignore those handlers. */
219
220 static Lisp_Object Vinhibit_file_name_handlers;
221 static Lisp_Object Vinhibit_file_name_operation;
222
223 Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
224
225 Lisp_Object Qfile_name_history;
226
227 Lisp_Object Qcar_less_than_car;
228
229 static int a_write P_ ((int, char *, int, int,
230 Lisp_Object *, struct coding_system *));
231 static int e_write P_ ((int, char *, int, struct coding_system *));
232 \f
233 void
234 report_file_error (string, data)
235 char *string;
236 Lisp_Object data;
237 {
238 Lisp_Object errstring;
239
240 errstring = build_string (strerror (errno));
241
242 /* System error messages are capitalized. Downcase the initial
243 unless it is followed by a slash. */
244 if (XSTRING (errstring)->data[1] != '/')
245 XSTRING (errstring)->data[0] = DOWNCASE (XSTRING (errstring)->data[0]);
246
247 while (1)
248 Fsignal (Qfile_error,
249 Fcons (build_string (string), Fcons (errstring, data)));
250 }
251
252 Lisp_Object
253 close_file_unwind (fd)
254 Lisp_Object fd;
255 {
256 close (XFASTINT (fd));
257 return Qnil;
258 }
259
260 /* Restore point, having saved it as a marker. */
261
262 static Lisp_Object
263 restore_point_unwind (location)
264 Lisp_Object location;
265 {
266 Fgoto_char (location);
267 Fset_marker (location, Qnil, Qnil);
268 return Qnil;
269 }
270 \f
271 Lisp_Object Qexpand_file_name;
272 Lisp_Object Qsubstitute_in_file_name;
273 Lisp_Object Qdirectory_file_name;
274 Lisp_Object Qfile_name_directory;
275 Lisp_Object Qfile_name_nondirectory;
276 Lisp_Object Qunhandled_file_name_directory;
277 Lisp_Object Qfile_name_as_directory;
278 Lisp_Object Qcopy_file;
279 Lisp_Object Qmake_directory_internal;
280 Lisp_Object Qdelete_directory;
281 Lisp_Object Qdelete_file;
282 Lisp_Object Qrename_file;
283 Lisp_Object Qadd_name_to_file;
284 Lisp_Object Qmake_symbolic_link;
285 Lisp_Object Qfile_exists_p;
286 Lisp_Object Qfile_executable_p;
287 Lisp_Object Qfile_readable_p;
288 Lisp_Object Qfile_writable_p;
289 Lisp_Object Qfile_symlink_p;
290 Lisp_Object Qaccess_file;
291 Lisp_Object Qfile_directory_p;
292 Lisp_Object Qfile_regular_p;
293 Lisp_Object Qfile_accessible_directory_p;
294 Lisp_Object Qfile_modes;
295 Lisp_Object Qset_file_modes;
296 Lisp_Object Qfile_newer_than_file_p;
297 Lisp_Object Qinsert_file_contents;
298 Lisp_Object Qwrite_region;
299 Lisp_Object Qverify_visited_file_modtime;
300 Lisp_Object Qset_visited_file_modtime;
301
302 DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
303 "Return FILENAME's handler function for OPERATION, if it has one.\n\
304 Otherwise, return nil.\n\
305 A file name is handled if one of the regular expressions in\n\
306 `file-name-handler-alist' matches it.\n\n\
307 If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
308 any handlers that are members of `inhibit-file-name-handlers',\n\
309 but we still do run any other handlers. This lets handlers\n\
310 use the standard functions without calling themselves recursively.")
311 (filename, operation)
312 Lisp_Object filename, operation;
313 {
314 /* This function must not munge the match data. */
315 Lisp_Object chain, inhibited_handlers;
316
317 CHECK_STRING (filename, 0);
318
319 if (EQ (operation, Vinhibit_file_name_operation))
320 inhibited_handlers = Vinhibit_file_name_handlers;
321 else
322 inhibited_handlers = Qnil;
323
324 for (chain = Vfile_name_handler_alist; CONSP (chain);
325 chain = XCONS (chain)->cdr)
326 {
327 Lisp_Object elt;
328 elt = XCONS (chain)->car;
329 if (CONSP (elt))
330 {
331 Lisp_Object string;
332 string = XCONS (elt)->car;
333 if (STRINGP (string) && fast_string_match (string, filename) >= 0)
334 {
335 Lisp_Object handler, tem;
336
337 handler = XCONS (elt)->cdr;
338 tem = Fmemq (handler, inhibited_handlers);
339 if (NILP (tem))
340 return handler;
341 }
342 }
343
344 QUIT;
345 }
346 return Qnil;
347 }
348 \f
349 DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
350 1, 1, 0,
351 "Return the directory component in file name FILENAME.\n\
352 Return nil if FILENAME does not include a directory.\n\
353 Otherwise return a directory spec.\n\
354 Given a Unix syntax file name, returns a string ending in slash;\n\
355 on VMS, perhaps instead a string ending in `:', `]' or `>'.")
356 (filename)
357 Lisp_Object filename;
358 {
359 register unsigned char *beg;
360 register unsigned char *p;
361 Lisp_Object handler;
362
363 CHECK_STRING (filename, 0);
364
365 /* If the file name has special constructs in it,
366 call the corresponding file handler. */
367 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
368 if (!NILP (handler))
369 return call2 (handler, Qfile_name_directory, filename);
370
371 #ifdef FILE_SYSTEM_CASE
372 filename = FILE_SYSTEM_CASE (filename);
373 #endif
374 beg = XSTRING (filename)->data;
375 #ifdef DOS_NT
376 beg = strcpy (alloca (strlen (beg) + 1), beg);
377 #endif
378 p = beg + STRING_BYTES (XSTRING (filename));
379
380 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
381 #ifdef VMS
382 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
383 #endif /* VMS */
384 #ifdef DOS_NT
385 /* only recognise drive specifier at beginning */
386 && !(p[-1] == ':' && p == beg + 2)
387 #endif
388 ) p--;
389
390 if (p == beg)
391 return Qnil;
392 #ifdef DOS_NT
393 /* Expansion of "c:" to drive and default directory. */
394 if (p == beg + 2 && beg[1] == ':')
395 {
396 /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
397 unsigned char *res = alloca (MAXPATHLEN + 1);
398 if (getdefdir (toupper (*beg) - 'A' + 1, res))
399 {
400 if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
401 strcat (res, "/");
402 beg = res;
403 p = beg + strlen (beg);
404 }
405 }
406 CORRECT_DIR_SEPS (beg);
407 #endif /* DOS_NT */
408
409 if (STRING_MULTIBYTE (filename))
410 return make_string (beg, p - beg);
411 return make_unibyte_string (beg, p - beg);
412 }
413
414 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory,
415 Sfile_name_nondirectory, 1, 1, 0,
416 "Return file name FILENAME sans its directory.\n\
417 For example, in a Unix-syntax file name,\n\
418 this is everything after the last slash,\n\
419 or the entire name if it contains no slash.")
420 (filename)
421 Lisp_Object filename;
422 {
423 register unsigned char *beg, *p, *end;
424 Lisp_Object handler;
425
426 CHECK_STRING (filename, 0);
427
428 /* If the file name has special constructs in it,
429 call the corresponding file handler. */
430 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
431 if (!NILP (handler))
432 return call2 (handler, Qfile_name_nondirectory, filename);
433
434 beg = XSTRING (filename)->data;
435 end = p = beg + STRING_BYTES (XSTRING (filename));
436
437 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
438 #ifdef VMS
439 && p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
440 #endif /* VMS */
441 #ifdef DOS_NT
442 /* only recognise drive specifier at beginning */
443 && !(p[-1] == ':' && p == beg + 2)
444 #endif
445 )
446 p--;
447
448 if (STRING_MULTIBYTE (filename))
449 return make_string (p, end - p);
450 return make_unibyte_string (p, end - p);
451 }
452
453 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory,
454 Sunhandled_file_name_directory, 1, 1, 0,
455 "Return a directly usable directory name somehow associated with FILENAME.\n\
456 A `directly usable' directory name is one that may be used without the\n\
457 intervention of any file handler.\n\
458 If FILENAME is a directly usable file itself, return\n\
459 \(file-name-directory FILENAME).\n\
460 The `call-process' and `start-process' functions use this function to\n\
461 get a current directory to run processes in.")
462 (filename)
463 Lisp_Object filename;
464 {
465 Lisp_Object handler;
466
467 /* If the file name has special constructs in it,
468 call the corresponding file handler. */
469 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
470 if (!NILP (handler))
471 return call2 (handler, Qunhandled_file_name_directory, filename);
472
473 return Ffile_name_directory (filename);
474 }
475
476 \f
477 char *
478 file_name_as_directory (out, in)
479 char *out, *in;
480 {
481 int size = strlen (in) - 1;
482
483 strcpy (out, in);
484
485 if (size < 0)
486 {
487 out[0] = '/';
488 out[1] = 0;
489 return out;
490 }
491
492 #ifdef VMS
493 /* Is it already a directory string? */
494 if (in[size] == ':' || in[size] == ']' || in[size] == '>')
495 return out;
496 /* Is it a VMS directory file name? If so, hack VMS syntax. */
497 else if (! index (in, '/')
498 && ((size > 3 && ! strcmp (&in[size - 3], ".DIR"))
499 || (size > 3 && ! strcmp (&in[size - 3], ".dir"))
500 || (size > 5 && (! strncmp (&in[size - 5], ".DIR", 4)
501 || ! strncmp (&in[size - 5], ".dir", 4))
502 && (in[size - 1] == '.' || in[size - 1] == ';')
503 && in[size] == '1')))
504 {
505 register char *p, *dot;
506 char brack;
507
508 /* x.dir -> [.x]
509 dir:x.dir --> dir:[x]
510 dir:[x]y.dir --> dir:[x.y] */
511 p = in + size;
512 while (p != in && *p != ':' && *p != '>' && *p != ']') p--;
513 if (p != in)
514 {
515 strncpy (out, in, p - in);
516 out[p - in] = '\0';
517 if (*p == ':')
518 {
519 brack = ']';
520 strcat (out, ":[");
521 }
522 else
523 {
524 brack = *p;
525 strcat (out, ".");
526 }
527 p++;
528 }
529 else
530 {
531 brack = ']';
532 strcpy (out, "[.");
533 }
534 dot = index (p, '.');
535 if (dot)
536 {
537 /* blindly remove any extension */
538 size = strlen (out) + (dot - p);
539 strncat (out, p, dot - p);
540 }
541 else
542 {
543 strcat (out, p);
544 size = strlen (out);
545 }
546 out[size++] = brack;
547 out[size] = '\0';
548 }
549 #else /* not VMS */
550 /* For Unix syntax, Append a slash if necessary */
551 if (!IS_DIRECTORY_SEP (out[size]))
552 {
553 out[size + 1] = DIRECTORY_SEP;
554 out[size + 2] = '\0';
555 }
556 #ifdef DOS_NT
557 CORRECT_DIR_SEPS (out);
558 #endif
559 #endif /* not VMS */
560 return out;
561 }
562
563 DEFUN ("file-name-as-directory", Ffile_name_as_directory,
564 Sfile_name_as_directory, 1, 1, 0,
565 "Return a string representing file FILENAME interpreted as a directory.\n\
566 This operation exists because a directory is also a file, but its name as\n\
567 a directory is different from its name as a file.\n\
568 The result can be used as the value of `default-directory'\n\
569 or passed as second argument to `expand-file-name'.\n\
570 For a Unix-syntax file name, just appends a slash.\n\
571 On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
572 (file)
573 Lisp_Object file;
574 {
575 char *buf;
576 Lisp_Object handler;
577
578 CHECK_STRING (file, 0);
579 if (NILP (file))
580 return Qnil;
581
582 /* If the file name has special constructs in it,
583 call the corresponding file handler. */
584 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
585 if (!NILP (handler))
586 return call2 (handler, Qfile_name_as_directory, file);
587
588 buf = (char *) alloca (STRING_BYTES (XSTRING (file)) + 10);
589 return build_string (file_name_as_directory (buf, XSTRING (file)->data));
590 }
591 \f
592 /*
593 * Convert from directory name to filename.
594 * On VMS:
595 * xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
596 * xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
597 * On UNIX, it's simple: just make sure there isn't a terminating /
598
599 * Value is nonzero if the string output is different from the input.
600 */
601
602 directory_file_name (src, dst)
603 char *src, *dst;
604 {
605 long slen;
606 #ifdef VMS
607 long rlen;
608 char * ptr, * rptr;
609 char bracket;
610 struct FAB fab = cc$rms_fab;
611 struct NAM nam = cc$rms_nam;
612 char esa[NAM$C_MAXRSS];
613 #endif /* VMS */
614
615 slen = strlen (src);
616 #ifdef VMS
617 if (! index (src, '/')
618 && (src[slen - 1] == ']'
619 || src[slen - 1] == ':'
620 || src[slen - 1] == '>'))
621 {
622 /* VMS style - convert [x.y.z] to [x.y]z, [x] to [000000]x */
623 fab.fab$l_fna = src;
624 fab.fab$b_fns = slen;
625 fab.fab$l_nam = &nam;
626 fab.fab$l_fop = FAB$M_NAM;
627
628 nam.nam$l_esa = esa;
629 nam.nam$b_ess = sizeof esa;
630 nam.nam$b_nop |= NAM$M_SYNCHK;
631
632 /* We call SYS$PARSE to handle such things as [--] for us. */
633 if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
634 {
635 slen = nam.nam$b_esl;
636 if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
637 slen -= 2;
638 esa[slen] = '\0';
639 src = esa;
640 }
641 if (src[slen - 1] != ']' && src[slen - 1] != '>')
642 {
643 /* what about when we have logical_name:???? */
644 if (src[slen - 1] == ':')
645 { /* Xlate logical name and see what we get */
646 ptr = strcpy (dst, src); /* upper case for getenv */
647 while (*ptr)
648 {
649 if ('a' <= *ptr && *ptr <= 'z')
650 *ptr -= 040;
651 ptr++;
652 }
653 dst[slen - 1] = 0; /* remove colon */
654 if (!(src = egetenv (dst)))
655 return 0;
656 /* should we jump to the beginning of this procedure?
657 Good points: allows us to use logical names that xlate
658 to Unix names,
659 Bad points: can be a problem if we just translated to a device
660 name...
661 For now, I'll punt and always expect VMS names, and hope for
662 the best! */
663 slen = strlen (src);
664 if (src[slen - 1] != ']' && src[slen - 1] != '>')
665 { /* no recursion here! */
666 strcpy (dst, src);
667 return 0;
668 }
669 }
670 else
671 { /* not a directory spec */
672 strcpy (dst, src);
673 return 0;
674 }
675 }
676 bracket = src[slen - 1];
677
678 /* If bracket is ']' or '>', bracket - 2 is the corresponding
679 opening bracket. */
680 ptr = index (src, bracket - 2);
681 if (ptr == 0)
682 { /* no opening bracket */
683 strcpy (dst, src);
684 return 0;
685 }
686 if (!(rptr = rindex (src, '.')))
687 rptr = ptr;
688 slen = rptr - src;
689 strncpy (dst, src, slen);
690 dst[slen] = '\0';
691 if (*rptr == '.')
692 {
693 dst[slen++] = bracket;
694 dst[slen] = '\0';
695 }
696 else
697 {
698 /* If we have the top-level of a rooted directory (i.e. xx:[000000]),
699 then translate the device and recurse. */
700 if (dst[slen - 1] == ':'
701 && dst[slen - 2] != ':' /* skip decnet nodes */
702 && strcmp (src + slen, "[000000]") == 0)
703 {
704 dst[slen - 1] = '\0';
705 if ((ptr = egetenv (dst))
706 && (rlen = strlen (ptr) - 1) > 0
707 && (ptr[rlen] == ']' || ptr[rlen] == '>')
708 && ptr[rlen - 1] == '.')
709 {
710 char * buf = (char *) alloca (strlen (ptr) + 1);
711 strcpy (buf, ptr);
712 buf[rlen - 1] = ']';
713 buf[rlen] = '\0';
714 return directory_file_name (buf, dst);
715 }
716 else
717 dst[slen - 1] = ':';
718 }
719 strcat (dst, "[000000]");
720 slen += 8;
721 }
722 rptr++;
723 rlen = strlen (rptr) - 1;
724 strncat (dst, rptr, rlen);
725 dst[slen + rlen] = '\0';
726 strcat (dst, ".DIR.1");
727 return 1;
728 }
729 #endif /* VMS */
730 /* Process as Unix format: just remove any final slash.
731 But leave "/" unchanged; do not change it to "". */
732 strcpy (dst, src);
733 #ifdef APOLLO
734 /* Handle // as root for apollo's. */
735 if ((slen > 2 && dst[slen - 1] == '/')
736 || (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
737 dst[slen - 1] = 0;
738 #else
739 if (slen > 1
740 && IS_DIRECTORY_SEP (dst[slen - 1])
741 #ifdef DOS_NT
742 && !IS_ANY_SEP (dst[slen - 2])
743 #endif
744 )
745 dst[slen - 1] = 0;
746 #endif
747 #ifdef DOS_NT
748 CORRECT_DIR_SEPS (dst);
749 #endif
750 return 1;
751 }
752
753 DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
754 1, 1, 0,
755 "Returns the file name of the directory named DIRECTORY.\n\
756 This is the name of the file that holds the data for the directory DIRECTORY.\n\
757 This operation exists because a directory is also a file, but its name as\n\
758 a directory is different from its name as a file.\n\
759 In Unix-syntax, this function just removes the final slash.\n\
760 On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
761 it returns a file name such as \"[X]Y.DIR.1\".")
762 (directory)
763 Lisp_Object directory;
764 {
765 char *buf;
766 Lisp_Object handler;
767
768 CHECK_STRING (directory, 0);
769
770 if (NILP (directory))
771 return Qnil;
772
773 /* If the file name has special constructs in it,
774 call the corresponding file handler. */
775 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
776 if (!NILP (handler))
777 return call2 (handler, Qdirectory_file_name, directory);
778
779 #ifdef VMS
780 /* 20 extra chars is insufficient for VMS, since we might perform a
781 logical name translation. an equivalence string can be up to 255
782 chars long, so grab that much extra space... - sss */
783 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20 + 255);
784 #else
785 buf = (char *) alloca (STRING_BYTES (XSTRING (directory)) + 20);
786 #endif
787 directory_file_name (XSTRING (directory)->data, buf);
788 return build_string (buf);
789 }
790
791 DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
792 "Generate temporary file name (string) starting with PREFIX (a string).\n\
793 The Emacs process number forms part of the result,\n\
794 so there is no danger of generating a name being used by another process.\n\
795 In addition, this function makes an attempt to choose a name\n\
796 which has no existing file.")
797 (prefix)
798 Lisp_Object prefix;
799 {
800 char *temp;
801 Lisp_Object val;
802 #ifdef MSDOS
803 /* Don't use too many characters of the restricted 8+3 DOS
804 filename space. */
805 val = concat2 (prefix, build_string ("a.XXX"));
806 #else
807 val = concat2 (prefix, build_string ("XXXXXX"));
808 #endif
809 temp = mktemp (XSTRING (val)->data);
810 if (! temp)
811 error ("No temporary file names based on %s are available",
812 XSTRING (prefix)->data);
813 #ifdef DOS_NT
814 CORRECT_DIR_SEPS (XSTRING (val)->data);
815 #endif
816 return val;
817 }
818 \f
819 DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
820 "Convert filename NAME to absolute, and canonicalize it.\n\
821 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
822 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
823 the current buffer's value of default-directory is used.\n\
824 File name components that are `.' are removed, and \n\
825 so are file name components followed by `..', along with the `..' itself;\n\
826 note that these simplifications are done without checking the resulting\n\
827 file names in the file system.\n\
828 An initial `~/' expands to your home directory.\n\
829 An initial `~USER/' expands to USER's home directory.\n\
830 See also the function `substitute-in-file-name'.")
831 (name, default_directory)
832 Lisp_Object name, default_directory;
833 {
834 unsigned char *nm;
835
836 register unsigned char *newdir, *p, *o;
837 int tlen;
838 unsigned char *target;
839 struct passwd *pw;
840 #ifdef VMS
841 unsigned char * colon = 0;
842 unsigned char * close = 0;
843 unsigned char * slash = 0;
844 unsigned char * brack = 0;
845 int lbrack = 0, rbrack = 0;
846 int dots = 0;
847 #endif /* VMS */
848 #ifdef DOS_NT
849 int drive = 0;
850 int collapse_newdir = 1;
851 #endif /* DOS_NT */
852 int length;
853 Lisp_Object handler;
854
855 CHECK_STRING (name, 0);
856
857 /* If the file name has special constructs in it,
858 call the corresponding file handler. */
859 handler = Ffind_file_name_handler (name, Qexpand_file_name);
860 if (!NILP (handler))
861 return call3 (handler, Qexpand_file_name, name, default_directory);
862
863 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
864 if (NILP (default_directory))
865 default_directory = current_buffer->directory;
866 if (! STRINGP (default_directory))
867 default_directory = build_string ("/");
868
869 if (!NILP (default_directory))
870 {
871 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
872 if (!NILP (handler))
873 return call3 (handler, Qexpand_file_name, name, default_directory);
874 }
875
876 o = XSTRING (default_directory)->data;
877
878 /* Make sure DEFAULT_DIRECTORY is properly expanded.
879 It would be better to do this down below where we actually use
880 default_directory. Unfortunately, calling Fexpand_file_name recursively
881 could invoke GC, and the strings might be relocated. This would
882 be annoying because we have pointers into strings lying around
883 that would need adjusting, and people would add new pointers to
884 the code and forget to adjust them, resulting in intermittent bugs.
885 Putting this call here avoids all that crud.
886
887 The EQ test avoids infinite recursion. */
888 if (! NILP (default_directory) && !EQ (default_directory, name)
889 /* Save time in some common cases - as long as default_directory
890 is not relative, it can be canonicalized with name below (if it
891 is needed at all) without requiring it to be expanded now. */
892 #ifdef DOS_NT
893 /* Detect MSDOS file names with drive specifiers. */
894 && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
895 #ifdef WINDOWSNT
896 /* Detect Windows file names in UNC format. */
897 && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
898 #endif
899 #else /* not DOS_NT */
900 /* Detect Unix absolute file names (/... alone is not absolute on
901 DOS or Windows). */
902 && ! (IS_DIRECTORY_SEP (o[0]))
903 #endif /* not DOS_NT */
904 )
905 {
906 struct gcpro gcpro1;
907
908 GCPRO1 (name);
909 default_directory = Fexpand_file_name (default_directory, Qnil);
910 UNGCPRO;
911 }
912
913 #ifdef VMS
914 /* Filenames on VMS are always upper case. */
915 name = Fupcase (name);
916 #endif
917 #ifdef FILE_SYSTEM_CASE
918 name = FILE_SYSTEM_CASE (name);
919 #endif
920
921 nm = XSTRING (name)->data;
922
923 #ifdef DOS_NT
924 /* We will force directory separators to be either all \ or /, so make
925 a local copy to modify, even if there ends up being no change. */
926 nm = strcpy (alloca (strlen (nm) + 1), nm);
927
928 /* Find and remove drive specifier if present; this makes nm absolute
929 even if the rest of the name appears to be relative. */
930 {
931 unsigned char *colon = rindex (nm, ':');
932
933 if (colon)
934 /* Only recognize colon as part of drive specifier if there is a
935 single alphabetic character preceeding the colon (and if the
936 character before the drive letter, if present, is a directory
937 separator); this is to support the remote system syntax used by
938 ange-ftp, and the "po:username" syntax for POP mailboxes. */
939 look_again:
940 if (nm == colon)
941 nm++;
942 else if (IS_DRIVE (colon[-1])
943 && (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2])))
944 {
945 drive = colon[-1];
946 nm = colon + 1;
947 }
948 else
949 {
950 while (--colon >= nm)
951 if (colon[0] == ':')
952 goto look_again;
953 }
954 }
955
956 #ifdef WINDOWSNT
957 /* If we see "c://somedir", we want to strip the first slash after the
958 colon when stripping the drive letter. Otherwise, this expands to
959 "//somedir". */
960 if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
961 nm++;
962 #endif /* WINDOWSNT */
963 #endif /* DOS_NT */
964
965 #ifdef WINDOWSNT
966 /* Discard any previous drive specifier if nm is now in UNC format. */
967 if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
968 {
969 drive = 0;
970 }
971 #endif
972
973 /* If nm is absolute, look for /./ or /../ sequences; if none are
974 found, we can probably return right away. We will avoid allocating
975 a new string if name is already fully expanded. */
976 if (
977 IS_DIRECTORY_SEP (nm[0])
978 #ifdef MSDOS
979 && drive
980 #endif
981 #ifdef WINDOWSNT
982 && (drive || IS_DIRECTORY_SEP (nm[1]))
983 #endif
984 #ifdef VMS
985 || index (nm, ':')
986 #endif /* VMS */
987 )
988 {
989 /* If it turns out that the filename we want to return is just a
990 suffix of FILENAME, we don't need to go through and edit
991 things; we just need to construct a new string using data
992 starting at the middle of FILENAME. If we set lose to a
993 non-zero value, that means we've discovered that we can't do
994 that cool trick. */
995 int lose = 0;
996
997 p = nm;
998 while (*p)
999 {
1000 /* Since we know the name is absolute, we can assume that each
1001 element starts with a "/". */
1002
1003 /* "." and ".." are hairy. */
1004 if (IS_DIRECTORY_SEP (p[0])
1005 && p[1] == '.'
1006 && (IS_DIRECTORY_SEP (p[2])
1007 || p[2] == 0
1008 || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
1009 || p[3] == 0))))
1010 lose = 1;
1011 #ifdef VMS
1012 if (p[0] == '\\')
1013 lose = 1;
1014 if (p[0] == '/') {
1015 /* if dev:[dir]/, move nm to / */
1016 if (!slash && p > nm && (brack || colon)) {
1017 nm = (brack ? brack + 1 : colon + 1);
1018 lbrack = rbrack = 0;
1019 brack = 0;
1020 colon = 0;
1021 }
1022 slash = p;
1023 }
1024 if (p[0] == '-')
1025 #ifndef VMS4_4
1026 /* VMS pre V4.4,convert '-'s in filenames. */
1027 if (lbrack == rbrack)
1028 {
1029 if (dots < 2) /* this is to allow negative version numbers */
1030 p[0] = '_';
1031 }
1032 else
1033 #endif /* VMS4_4 */
1034 if (lbrack > rbrack &&
1035 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1036 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1037 lose = 1;
1038 #ifndef VMS4_4
1039 else
1040 p[0] = '_';
1041 #endif /* VMS4_4 */
1042 /* count open brackets, reset close bracket pointer */
1043 if (p[0] == '[' || p[0] == '<')
1044 lbrack++, brack = 0;
1045 /* count close brackets, set close bracket pointer */
1046 if (p[0] == ']' || p[0] == '>')
1047 rbrack++, brack = p;
1048 /* detect ][ or >< */
1049 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1050 lose = 1;
1051 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1052 nm = p + 1, lose = 1;
1053 if (p[0] == ':' && (colon || slash))
1054 /* if dev1:[dir]dev2:, move nm to dev2: */
1055 if (brack)
1056 {
1057 nm = brack + 1;
1058 brack = 0;
1059 }
1060 /* if /name/dev:, move nm to dev: */
1061 else if (slash)
1062 nm = slash + 1;
1063 /* if node::dev:, move colon following dev */
1064 else if (colon && colon[-1] == ':')
1065 colon = p;
1066 /* if dev1:dev2:, move nm to dev2: */
1067 else if (colon && colon[-1] != ':')
1068 {
1069 nm = colon + 1;
1070 colon = 0;
1071 }
1072 if (p[0] == ':' && !colon)
1073 {
1074 if (p[1] == ':')
1075 p++;
1076 colon = p;
1077 }
1078 if (lbrack == rbrack)
1079 if (p[0] == ';')
1080 dots = 2;
1081 else if (p[0] == '.')
1082 dots++;
1083 #endif /* VMS */
1084 p++;
1085 }
1086 if (!lose)
1087 {
1088 #ifdef VMS
1089 if (index (nm, '/'))
1090 return build_string (sys_translate_unix (nm));
1091 #endif /* VMS */
1092 #ifdef DOS_NT
1093 /* Make sure directories are all separated with / or \ as
1094 desired, but avoid allocation of a new string when not
1095 required. */
1096 CORRECT_DIR_SEPS (nm);
1097 #ifdef WINDOWSNT
1098 if (IS_DIRECTORY_SEP (nm[1]))
1099 {
1100 if (strcmp (nm, XSTRING (name)->data) != 0)
1101 name = build_string (nm);
1102 }
1103 else
1104 #endif
1105 /* drive must be set, so this is okay */
1106 if (strcmp (nm - 2, XSTRING (name)->data) != 0)
1107 {
1108 name = make_string (nm - 2, p - nm + 2);
1109 XSTRING (name)->data[0] = DRIVE_LETTER (drive);
1110 XSTRING (name)->data[1] = ':';
1111 }
1112 return name;
1113 #else /* not DOS_NT */
1114 if (nm == XSTRING (name)->data)
1115 return name;
1116 return build_string (nm);
1117 #endif /* not DOS_NT */
1118 }
1119 }
1120
1121 /* At this point, nm might or might not be an absolute file name. We
1122 need to expand ~ or ~user if present, otherwise prefix nm with
1123 default_directory if nm is not absolute, and finally collapse /./
1124 and /foo/../ sequences.
1125
1126 We set newdir to be the appropriate prefix if one is needed:
1127 - the relevant user directory if nm starts with ~ or ~user
1128 - the specified drive's working dir (DOS/NT only) if nm does not
1129 start with /
1130 - the value of default_directory.
1131
1132 Note that these prefixes are not guaranteed to be absolute (except
1133 for the working dir of a drive). Therefore, to ensure we always
1134 return an absolute name, if the final prefix is not absolute we
1135 append it to the current working directory. */
1136
1137 newdir = 0;
1138
1139 if (nm[0] == '~') /* prefix ~ */
1140 {
1141 if (IS_DIRECTORY_SEP (nm[1])
1142 #ifdef VMS
1143 || nm[1] == ':'
1144 #endif /* VMS */
1145 || nm[1] == 0) /* ~ by itself */
1146 {
1147 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1148 newdir = (unsigned char *) "";
1149 nm++;
1150 #ifdef DOS_NT
1151 collapse_newdir = 0;
1152 #endif
1153 #ifdef VMS
1154 nm++; /* Don't leave the slash in nm. */
1155 #endif /* VMS */
1156 }
1157 else /* ~user/filename */
1158 {
1159 for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
1160 #ifdef VMS
1161 && *p != ':'
1162 #endif /* VMS */
1163 ); p++);
1164 o = (unsigned char *) alloca (p - nm + 1);
1165 bcopy ((char *) nm, o, p - nm);
1166 o [p - nm] = 0;
1167
1168 pw = (struct passwd *) getpwnam (o + 1);
1169 if (pw)
1170 {
1171 newdir = (unsigned char *) pw -> pw_dir;
1172 #ifdef VMS
1173 nm = p + 1; /* skip the terminator */
1174 #else
1175 nm = p;
1176 #ifdef DOS_NT
1177 collapse_newdir = 0;
1178 #endif
1179 #endif /* VMS */
1180 }
1181
1182 /* If we don't find a user of that name, leave the name
1183 unchanged; don't move nm forward to p. */
1184 }
1185 }
1186
1187 #ifdef DOS_NT
1188 /* On DOS and Windows, nm is absolute if a drive name was specified;
1189 use the drive's current directory as the prefix if needed. */
1190 if (!newdir && drive)
1191 {
1192 /* Get default directory if needed to make nm absolute. */
1193 if (!IS_DIRECTORY_SEP (nm[0]))
1194 {
1195 newdir = alloca (MAXPATHLEN + 1);
1196 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1197 newdir = NULL;
1198 }
1199 if (!newdir)
1200 {
1201 /* Either nm starts with /, or drive isn't mounted. */
1202 newdir = alloca (4);
1203 newdir[0] = DRIVE_LETTER (drive);
1204 newdir[1] = ':';
1205 newdir[2] = '/';
1206 newdir[3] = 0;
1207 }
1208 }
1209 #endif /* DOS_NT */
1210
1211 /* Finally, if no prefix has been specified and nm is not absolute,
1212 then it must be expanded relative to default_directory. */
1213
1214 if (1
1215 #ifndef DOS_NT
1216 /* /... alone is not absolute on DOS and Windows. */
1217 && !IS_DIRECTORY_SEP (nm[0])
1218 #endif
1219 #ifdef WINDOWSNT
1220 && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1221 #endif
1222 #ifdef VMS
1223 && !index (nm, ':')
1224 #endif
1225 && !newdir)
1226 {
1227 newdir = XSTRING (default_directory)->data;
1228 }
1229
1230 #ifdef DOS_NT
1231 if (newdir)
1232 {
1233 /* First ensure newdir is an absolute name. */
1234 if (
1235 /* Detect MSDOS file names with drive specifiers. */
1236 ! (IS_DRIVE (newdir[0])
1237 && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1238 #ifdef WINDOWSNT
1239 /* Detect Windows file names in UNC format. */
1240 && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1241 #endif
1242 )
1243 {
1244 /* Effectively, let newdir be (expand-file-name newdir cwd).
1245 Because of the admonition against calling expand-file-name
1246 when we have pointers into lisp strings, we accomplish this
1247 indirectly by prepending newdir to nm if necessary, and using
1248 cwd (or the wd of newdir's drive) as the new newdir. */
1249
1250 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1251 {
1252 drive = newdir[0];
1253 newdir += 2;
1254 }
1255 if (!IS_DIRECTORY_SEP (nm[0]))
1256 {
1257 char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1258 file_name_as_directory (tmp, newdir);
1259 strcat (tmp, nm);
1260 nm = tmp;
1261 }
1262 newdir = alloca (MAXPATHLEN + 1);
1263 if (drive)
1264 {
1265 if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1266 newdir = "/";
1267 }
1268 else
1269 getwd (newdir);
1270 }
1271
1272 /* Strip off drive name from prefix, if present. */
1273 if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1274 {
1275 drive = newdir[0];
1276 newdir += 2;
1277 }
1278
1279 /* Keep only a prefix from newdir if nm starts with slash
1280 (//server/share for UNC, nothing otherwise). */
1281 if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1282 {
1283 #ifdef WINDOWSNT
1284 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1285 {
1286 newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1287 p = newdir + 2;
1288 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1289 p++;
1290 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1291 *p = 0;
1292 }
1293 else
1294 #endif
1295 newdir = "";
1296 }
1297 }
1298 #endif /* DOS_NT */
1299
1300 if (newdir)
1301 {
1302 /* Get rid of any slash at the end of newdir, unless newdir is
1303 just // (an incomplete UNC name). */
1304 length = strlen (newdir);
1305 if (length > 0 && IS_DIRECTORY_SEP (newdir[length - 1])
1306 #ifdef WINDOWSNT
1307 && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1308 #endif
1309 )
1310 {
1311 unsigned char *temp = (unsigned char *) alloca (length);
1312 bcopy (newdir, temp, length - 1);
1313 temp[length - 1] = 0;
1314 newdir = temp;
1315 }
1316 tlen = length + 1;
1317 }
1318 else
1319 tlen = 0;
1320
1321 /* Now concatenate the directory and name to new space in the stack frame */
1322 tlen += strlen (nm) + 1;
1323 #ifdef DOS_NT
1324 /* Add reserved space for drive name. (The Microsoft x86 compiler
1325 produces incorrect code if the following two lines are combined.) */
1326 target = (unsigned char *) alloca (tlen + 2);
1327 target += 2;
1328 #else /* not DOS_NT */
1329 target = (unsigned char *) alloca (tlen);
1330 #endif /* not DOS_NT */
1331 *target = 0;
1332
1333 if (newdir)
1334 {
1335 #ifndef VMS
1336 if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1337 strcpy (target, newdir);
1338 else
1339 #endif
1340 file_name_as_directory (target, newdir);
1341 }
1342
1343 strcat (target, nm);
1344 #ifdef VMS
1345 if (index (target, '/'))
1346 strcpy (target, sys_translate_unix (target));
1347 #endif /* VMS */
1348
1349 /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1350
1351 /* Now canonicalize by removing /. and /foo/.. if they appear. */
1352
1353 p = target;
1354 o = target;
1355
1356 while (*p)
1357 {
1358 #ifdef VMS
1359 if (*p != ']' && *p != '>' && *p != '-')
1360 {
1361 if (*p == '\\')
1362 p++;
1363 *o++ = *p++;
1364 }
1365 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1366 /* brackets are offset from each other by 2 */
1367 {
1368 p += 2;
1369 if (*p != '.' && *p != '-' && o[-1] != '.')
1370 /* convert [foo][bar] to [bar] */
1371 while (o[-1] != '[' && o[-1] != '<')
1372 o--;
1373 else if (*p == '-' && *o != '.')
1374 *--p = '.';
1375 }
1376 else if (p[0] == '-' && o[-1] == '.' &&
1377 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1378 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1379 {
1380 do
1381 o--;
1382 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1383 if (p[1] == '.') /* foo.-.bar ==> bar. */
1384 p += 2;
1385 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1386 p++, o--;
1387 /* else [foo.-] ==> [-] */
1388 }
1389 else
1390 {
1391 #ifndef VMS4_4
1392 if (*p == '-' &&
1393 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1394 p[1] != ']' && p[1] != '>' && p[1] != '.')
1395 *p = '_';
1396 #endif /* VMS4_4 */
1397 *o++ = *p++;
1398 }
1399 #else /* not VMS */
1400 if (!IS_DIRECTORY_SEP (*p))
1401 {
1402 *o++ = *p++;
1403 }
1404 else if (IS_DIRECTORY_SEP (p[0])
1405 && p[1] == '.'
1406 && (IS_DIRECTORY_SEP (p[2])
1407 || p[2] == 0))
1408 {
1409 /* If "/." is the entire filename, keep the "/". Otherwise,
1410 just delete the whole "/.". */
1411 if (o == target && p[2] == '\0')
1412 *o++ = *p;
1413 p += 2;
1414 }
1415 else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1416 /* `/../' is the "superroot" on certain file systems. */
1417 && o != target
1418 && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1419 {
1420 while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1421 ;
1422 /* Keep initial / only if this is the whole name. */
1423 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1424 ++o;
1425 p += 3;
1426 }
1427 else
1428 {
1429 *o++ = *p++;
1430 }
1431 #endif /* not VMS */
1432 }
1433
1434 #ifdef DOS_NT
1435 /* At last, set drive name. */
1436 #ifdef WINDOWSNT
1437 /* Except for network file name. */
1438 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1439 #endif /* WINDOWSNT */
1440 {
1441 if (!drive) abort ();
1442 target -= 2;
1443 target[0] = DRIVE_LETTER (drive);
1444 target[1] = ':';
1445 }
1446 CORRECT_DIR_SEPS (target);
1447 #endif /* DOS_NT */
1448
1449 return make_string (target, o - target);
1450 }
1451
1452 #if 0
1453 /* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1454 DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1455 "Convert FILENAME to absolute, and canonicalize it.\n\
1456 Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1457 (does not start with slash); if DEFAULT is nil or missing,\n\
1458 the current buffer's value of default-directory is used.\n\
1459 Filenames containing `.' or `..' as components are simplified;\n\
1460 initial `~/' expands to your home directory.\n\
1461 See also the function `substitute-in-file-name'.")
1462 (name, defalt)
1463 Lisp_Object name, defalt;
1464 {
1465 unsigned char *nm;
1466
1467 register unsigned char *newdir, *p, *o;
1468 int tlen;
1469 unsigned char *target;
1470 struct passwd *pw;
1471 int lose;
1472 #ifdef VMS
1473 unsigned char * colon = 0;
1474 unsigned char * close = 0;
1475 unsigned char * slash = 0;
1476 unsigned char * brack = 0;
1477 int lbrack = 0, rbrack = 0;
1478 int dots = 0;
1479 #endif /* VMS */
1480
1481 CHECK_STRING (name, 0);
1482
1483 #ifdef VMS
1484 /* Filenames on VMS are always upper case. */
1485 name = Fupcase (name);
1486 #endif
1487
1488 nm = XSTRING (name)->data;
1489
1490 /* If nm is absolute, flush ...// and detect /./ and /../.
1491 If no /./ or /../ we can return right away. */
1492 if (
1493 nm[0] == '/'
1494 #ifdef VMS
1495 || index (nm, ':')
1496 #endif /* VMS */
1497 )
1498 {
1499 p = nm;
1500 lose = 0;
1501 while (*p)
1502 {
1503 if (p[0] == '/' && p[1] == '/'
1504 #ifdef APOLLO
1505 /* // at start of filename is meaningful on Apollo system. */
1506 && nm != p
1507 #endif /* APOLLO */
1508 )
1509 nm = p + 1;
1510 if (p[0] == '/' && p[1] == '~')
1511 nm = p + 1, lose = 1;
1512 if (p[0] == '/' && p[1] == '.'
1513 && (p[2] == '/' || p[2] == 0
1514 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1515 lose = 1;
1516 #ifdef VMS
1517 if (p[0] == '\\')
1518 lose = 1;
1519 if (p[0] == '/') {
1520 /* if dev:[dir]/, move nm to / */
1521 if (!slash && p > nm && (brack || colon)) {
1522 nm = (brack ? brack + 1 : colon + 1);
1523 lbrack = rbrack = 0;
1524 brack = 0;
1525 colon = 0;
1526 }
1527 slash = p;
1528 }
1529 if (p[0] == '-')
1530 #ifndef VMS4_4
1531 /* VMS pre V4.4,convert '-'s in filenames. */
1532 if (lbrack == rbrack)
1533 {
1534 if (dots < 2) /* this is to allow negative version numbers */
1535 p[0] = '_';
1536 }
1537 else
1538 #endif /* VMS4_4 */
1539 if (lbrack > rbrack &&
1540 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1541 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1542 lose = 1;
1543 #ifndef VMS4_4
1544 else
1545 p[0] = '_';
1546 #endif /* VMS4_4 */
1547 /* count open brackets, reset close bracket pointer */
1548 if (p[0] == '[' || p[0] == '<')
1549 lbrack++, brack = 0;
1550 /* count close brackets, set close bracket pointer */
1551 if (p[0] == ']' || p[0] == '>')
1552 rbrack++, brack = p;
1553 /* detect ][ or >< */
1554 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1555 lose = 1;
1556 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1557 nm = p + 1, lose = 1;
1558 if (p[0] == ':' && (colon || slash))
1559 /* if dev1:[dir]dev2:, move nm to dev2: */
1560 if (brack)
1561 {
1562 nm = brack + 1;
1563 brack = 0;
1564 }
1565 /* If /name/dev:, move nm to dev: */
1566 else if (slash)
1567 nm = slash + 1;
1568 /* If node::dev:, move colon following dev */
1569 else if (colon && colon[-1] == ':')
1570 colon = p;
1571 /* If dev1:dev2:, move nm to dev2: */
1572 else if (colon && colon[-1] != ':')
1573 {
1574 nm = colon + 1;
1575 colon = 0;
1576 }
1577 if (p[0] == ':' && !colon)
1578 {
1579 if (p[1] == ':')
1580 p++;
1581 colon = p;
1582 }
1583 if (lbrack == rbrack)
1584 if (p[0] == ';')
1585 dots = 2;
1586 else if (p[0] == '.')
1587 dots++;
1588 #endif /* VMS */
1589 p++;
1590 }
1591 if (!lose)
1592 {
1593 #ifdef VMS
1594 if (index (nm, '/'))
1595 return build_string (sys_translate_unix (nm));
1596 #endif /* VMS */
1597 if (nm == XSTRING (name)->data)
1598 return name;
1599 return build_string (nm);
1600 }
1601 }
1602
1603 /* Now determine directory to start with and put it in NEWDIR */
1604
1605 newdir = 0;
1606
1607 if (nm[0] == '~') /* prefix ~ */
1608 if (nm[1] == '/'
1609 #ifdef VMS
1610 || nm[1] == ':'
1611 #endif /* VMS */
1612 || nm[1] == 0)/* ~/filename */
1613 {
1614 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1615 newdir = (unsigned char *) "";
1616 nm++;
1617 #ifdef VMS
1618 nm++; /* Don't leave the slash in nm. */
1619 #endif /* VMS */
1620 }
1621 else /* ~user/filename */
1622 {
1623 /* Get past ~ to user */
1624 unsigned char *user = nm + 1;
1625 /* Find end of name. */
1626 unsigned char *ptr = (unsigned char *) index (user, '/');
1627 int len = ptr ? ptr - user : strlen (user);
1628 #ifdef VMS
1629 unsigned char *ptr1 = index (user, ':');
1630 if (ptr1 != 0 && ptr1 - user < len)
1631 len = ptr1 - user;
1632 #endif /* VMS */
1633 /* Copy the user name into temp storage. */
1634 o = (unsigned char *) alloca (len + 1);
1635 bcopy ((char *) user, o, len);
1636 o[len] = 0;
1637
1638 /* Look up the user name. */
1639 pw = (struct passwd *) getpwnam (o + 1);
1640 if (!pw)
1641 error ("\"%s\" isn't a registered user", o + 1);
1642
1643 newdir = (unsigned char *) pw->pw_dir;
1644
1645 /* Discard the user name from NM. */
1646 nm += len;
1647 }
1648
1649 if (nm[0] != '/'
1650 #ifdef VMS
1651 && !index (nm, ':')
1652 #endif /* not VMS */
1653 && !newdir)
1654 {
1655 if (NILP (defalt))
1656 defalt = current_buffer->directory;
1657 CHECK_STRING (defalt, 1);
1658 newdir = XSTRING (defalt)->data;
1659 }
1660
1661 /* Now concatenate the directory and name to new space in the stack frame */
1662
1663 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1664 target = (unsigned char *) alloca (tlen);
1665 *target = 0;
1666
1667 if (newdir)
1668 {
1669 #ifndef VMS
1670 if (nm[0] == 0 || nm[0] == '/')
1671 strcpy (target, newdir);
1672 else
1673 #endif
1674 file_name_as_directory (target, newdir);
1675 }
1676
1677 strcat (target, nm);
1678 #ifdef VMS
1679 if (index (target, '/'))
1680 strcpy (target, sys_translate_unix (target));
1681 #endif /* VMS */
1682
1683 /* Now canonicalize by removing /. and /foo/.. if they appear */
1684
1685 p = target;
1686 o = target;
1687
1688 while (*p)
1689 {
1690 #ifdef VMS
1691 if (*p != ']' && *p != '>' && *p != '-')
1692 {
1693 if (*p == '\\')
1694 p++;
1695 *o++ = *p++;
1696 }
1697 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1698 /* brackets are offset from each other by 2 */
1699 {
1700 p += 2;
1701 if (*p != '.' && *p != '-' && o[-1] != '.')
1702 /* convert [foo][bar] to [bar] */
1703 while (o[-1] != '[' && o[-1] != '<')
1704 o--;
1705 else if (*p == '-' && *o != '.')
1706 *--p = '.';
1707 }
1708 else if (p[0] == '-' && o[-1] == '.' &&
1709 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1710 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1711 {
1712 do
1713 o--;
1714 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1715 if (p[1] == '.') /* foo.-.bar ==> bar. */
1716 p += 2;
1717 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1718 p++, o--;
1719 /* else [foo.-] ==> [-] */
1720 }
1721 else
1722 {
1723 #ifndef VMS4_4
1724 if (*p == '-' &&
1725 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1726 p[1] != ']' && p[1] != '>' && p[1] != '.')
1727 *p = '_';
1728 #endif /* VMS4_4 */
1729 *o++ = *p++;
1730 }
1731 #else /* not VMS */
1732 if (*p != '/')
1733 {
1734 *o++ = *p++;
1735 }
1736 else if (!strncmp (p, "//", 2)
1737 #ifdef APOLLO
1738 /* // at start of filename is meaningful in Apollo system. */
1739 && o != target
1740 #endif /* APOLLO */
1741 )
1742 {
1743 o = target;
1744 p++;
1745 }
1746 else if (p[0] == '/' && p[1] == '.' &&
1747 (p[2] == '/' || p[2] == 0))
1748 p += 2;
1749 else if (!strncmp (p, "/..", 3)
1750 /* `/../' is the "superroot" on certain file systems. */
1751 && o != target
1752 && (p[3] == '/' || p[3] == 0))
1753 {
1754 while (o != target && *--o != '/')
1755 ;
1756 #ifdef APOLLO
1757 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1758 ++o;
1759 else
1760 #endif /* APOLLO */
1761 if (o == target && *o == '/')
1762 ++o;
1763 p += 3;
1764 }
1765 else
1766 {
1767 *o++ = *p++;
1768 }
1769 #endif /* not VMS */
1770 }
1771
1772 return make_string (target, o - target);
1773 }
1774 #endif
1775 \f
1776 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1777 Ssubstitute_in_file_name, 1, 1, 0,
1778 "Substitute environment variables referred to in FILENAME.\n\
1779 `$FOO' where FOO is an environment variable name means to substitute\n\
1780 the value of that variable. The variable name should be terminated\n\
1781 with a character not a letter, digit or underscore; otherwise, enclose\n\
1782 the entire variable name in braces.\n\
1783 If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1784 On VMS, `$' substitution is not done; this function does little and only\n\
1785 duplicates what `expand-file-name' does.")
1786 (filename)
1787 Lisp_Object filename;
1788 {
1789 unsigned char *nm;
1790
1791 register unsigned char *s, *p, *o, *x, *endp;
1792 unsigned char *target;
1793 int total = 0;
1794 int substituted = 0;
1795 unsigned char *xnm;
1796 Lisp_Object handler;
1797
1798 CHECK_STRING (filename, 0);
1799
1800 /* If the file name has special constructs in it,
1801 call the corresponding file handler. */
1802 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1803 if (!NILP (handler))
1804 return call2 (handler, Qsubstitute_in_file_name, filename);
1805
1806 nm = XSTRING (filename)->data;
1807 #ifdef DOS_NT
1808 nm = strcpy (alloca (strlen (nm) + 1), nm);
1809 CORRECT_DIR_SEPS (nm);
1810 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
1811 #endif
1812 endp = nm + STRING_BYTES (XSTRING (filename));
1813
1814 /* If /~ or // appears, discard everything through first slash. */
1815
1816 for (p = nm; p != endp; p++)
1817 {
1818 if ((p[0] == '~'
1819 #if defined (APOLLO) || defined (WINDOWSNT)
1820 /* // at start of file name is meaningful in Apollo and
1821 WindowsNT systems. */
1822 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1823 #else /* not (APOLLO || WINDOWSNT) */
1824 || IS_DIRECTORY_SEP (p[0])
1825 #endif /* not (APOLLO || WINDOWSNT) */
1826 )
1827 && p != nm
1828 && (0
1829 #ifdef VMS
1830 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
1831 #endif /* VMS */
1832 || IS_DIRECTORY_SEP (p[-1])))
1833 {
1834 nm = p;
1835 substituted = 1;
1836 }
1837 #ifdef DOS_NT
1838 /* see comment in expand-file-name about drive specifiers */
1839 else if (IS_DRIVE (p[0]) && p[1] == ':'
1840 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1841 {
1842 nm = p;
1843 substituted = 1;
1844 }
1845 #endif /* DOS_NT */
1846 }
1847
1848 #ifdef VMS
1849 return build_string (nm);
1850 #else
1851
1852 /* See if any variables are substituted into the string
1853 and find the total length of their values in `total' */
1854
1855 for (p = nm; p != endp;)
1856 if (*p != '$')
1857 p++;
1858 else
1859 {
1860 p++;
1861 if (p == endp)
1862 goto badsubst;
1863 else if (*p == '$')
1864 {
1865 /* "$$" means a single "$" */
1866 p++;
1867 total -= 1;
1868 substituted = 1;
1869 continue;
1870 }
1871 else if (*p == '{')
1872 {
1873 o = ++p;
1874 while (p != endp && *p != '}') p++;
1875 if (*p != '}') goto missingclose;
1876 s = p;
1877 }
1878 else
1879 {
1880 o = p;
1881 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1882 s = p;
1883 }
1884
1885 /* Copy out the variable name */
1886 target = (unsigned char *) alloca (s - o + 1);
1887 strncpy (target, o, s - o);
1888 target[s - o] = 0;
1889 #ifdef DOS_NT
1890 strupr (target); /* $home == $HOME etc. */
1891 #endif /* DOS_NT */
1892
1893 /* Get variable value */
1894 o = (unsigned char *) egetenv (target);
1895 if (!o) goto badvar;
1896 total += strlen (o);
1897 substituted = 1;
1898 }
1899
1900 if (!substituted)
1901 return filename;
1902
1903 /* If substitution required, recopy the string and do it */
1904 /* Make space in stack frame for the new copy */
1905 xnm = (unsigned char *) alloca (STRING_BYTES (XSTRING (filename)) + total + 1);
1906 x = xnm;
1907
1908 /* Copy the rest of the name through, replacing $ constructs with values */
1909 for (p = nm; *p;)
1910 if (*p != '$')
1911 *x++ = *p++;
1912 else
1913 {
1914 p++;
1915 if (p == endp)
1916 goto badsubst;
1917 else if (*p == '$')
1918 {
1919 *x++ = *p++;
1920 continue;
1921 }
1922 else if (*p == '{')
1923 {
1924 o = ++p;
1925 while (p != endp && *p != '}') p++;
1926 if (*p != '}') goto missingclose;
1927 s = p++;
1928 }
1929 else
1930 {
1931 o = p;
1932 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1933 s = p;
1934 }
1935
1936 /* Copy out the variable name */
1937 target = (unsigned char *) alloca (s - o + 1);
1938 strncpy (target, o, s - o);
1939 target[s - o] = 0;
1940 #ifdef DOS_NT
1941 strupr (target); /* $home == $HOME etc. */
1942 #endif /* DOS_NT */
1943
1944 /* Get variable value */
1945 o = (unsigned char *) egetenv (target);
1946 if (!o)
1947 goto badvar;
1948
1949 if (STRING_MULTIBYTE (filename))
1950 {
1951 /* If the original string is multibyte,
1952 convert what we substitute into multibyte. */
1953 unsigned char workbuf[4], *str;
1954 int len;
1955
1956 while (*o)
1957 {
1958 int c = *o++;
1959 c = unibyte_char_to_multibyte (c);
1960 if (! SINGLE_BYTE_CHAR_P (c))
1961 {
1962 len = CHAR_STRING (c, workbuf, str);
1963 bcopy (str, x, len);
1964 x += len;
1965 }
1966 else
1967 *x++ = c;
1968 }
1969 }
1970 else
1971 {
1972 strcpy (x, o);
1973 x += strlen (o);
1974 }
1975 }
1976
1977 *x = 0;
1978
1979 /* If /~ or // appears, discard everything through first slash. */
1980
1981 for (p = xnm; p != x; p++)
1982 if ((p[0] == '~'
1983 #if defined (APOLLO) || defined (WINDOWSNT)
1984 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1985 #else /* not (APOLLO || WINDOWSNT) */
1986 || IS_DIRECTORY_SEP (p[0])
1987 #endif /* not (APOLLO || WINDOWSNT) */
1988 )
1989 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
1990 xnm = p;
1991 #ifdef DOS_NT
1992 else if (IS_DRIVE (p[0]) && p[1] == ':'
1993 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1994 xnm = p;
1995 #endif
1996
1997 if (STRING_MULTIBYTE (filename))
1998 return make_string (xnm, x - xnm);
1999 return make_unibyte_string (xnm, x - xnm);
2000
2001 badsubst:
2002 error ("Bad format environment-variable substitution");
2003 missingclose:
2004 error ("Missing \"}\" in environment-variable substitution");
2005 badvar:
2006 error ("Substituting nonexistent environment variable \"%s\"", target);
2007
2008 /* NOTREACHED */
2009 #endif /* not VMS */
2010 }
2011 \f
2012 /* A slightly faster and more convenient way to get
2013 (directory-file-name (expand-file-name FOO)). */
2014
2015 Lisp_Object
2016 expand_and_dir_to_file (filename, defdir)
2017 Lisp_Object filename, defdir;
2018 {
2019 register Lisp_Object absname;
2020
2021 absname = Fexpand_file_name (filename, defdir);
2022 #ifdef VMS
2023 {
2024 register int c = XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1];
2025 if (c == ':' || c == ']' || c == '>')
2026 absname = Fdirectory_file_name (absname);
2027 }
2028 #else
2029 /* Remove final slash, if any (unless this is the root dir).
2030 stat behaves differently depending! */
2031 if (XSTRING (absname)->size > 1
2032 && IS_DIRECTORY_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname)) - 1])
2033 && !IS_DEVICE_SEP (XSTRING (absname)->data[STRING_BYTES (XSTRING (absname))-2]))
2034 /* We cannot take shortcuts; they might be wrong for magic file names. */
2035 absname = Fdirectory_file_name (absname);
2036 #endif
2037 return absname;
2038 }
2039 \f
2040 /* Signal an error if the file ABSNAME already exists.
2041 If INTERACTIVE is nonzero, ask the user whether to proceed,
2042 and bypass the error if the user says to go ahead.
2043 QUERYSTRING is a name for the action that is being considered
2044 to alter the file.
2045
2046 *STATPTR is used to store the stat information if the file exists.
2047 If the file does not exist, STATPTR->st_mode is set to 0.
2048 If STATPTR is null, we don't store into it.
2049
2050 If QUICK is nonzero, we ask for y or n, not yes or no. */
2051
2052 void
2053 barf_or_query_if_file_exists (absname, querystring, interactive, statptr, quick)
2054 Lisp_Object absname;
2055 unsigned char *querystring;
2056 int interactive;
2057 struct stat *statptr;
2058 int quick;
2059 {
2060 register Lisp_Object tem;
2061 struct stat statbuf;
2062 struct gcpro gcpro1;
2063
2064 /* stat is a good way to tell whether the file exists,
2065 regardless of what access permissions it has. */
2066 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
2067 {
2068 if (! interactive)
2069 Fsignal (Qfile_already_exists,
2070 Fcons (build_string ("File already exists"),
2071 Fcons (absname, Qnil)));
2072 GCPRO1 (absname);
2073 tem = format1 ("File %s already exists; %s anyway? ",
2074 XSTRING (absname)->data, querystring);
2075 if (quick)
2076 tem = Fy_or_n_p (tem);
2077 else
2078 tem = do_yes_or_no_p (tem);
2079 UNGCPRO;
2080 if (NILP (tem))
2081 Fsignal (Qfile_already_exists,
2082 Fcons (build_string ("File already exists"),
2083 Fcons (absname, Qnil)));
2084 if (statptr)
2085 *statptr = statbuf;
2086 }
2087 else
2088 {
2089 if (statptr)
2090 statptr->st_mode = 0;
2091 }
2092 return;
2093 }
2094
2095 DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2096 "fCopy file: \nFCopy %s to file: \np\nP",
2097 "Copy FILE to NEWNAME. Both args must be strings.\n\
2098 Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2099 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2100 A number as third arg means request confirmation if NEWNAME already exists.\n\
2101 This is what happens in interactive use with M-x.\n\
2102 Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2103 last-modified time as the old one. (This works on only some systems.)\n\
2104 A prefix arg makes KEEP-TIME non-nil.")
2105 (file, newname, ok_if_already_exists, keep_date)
2106 Lisp_Object file, newname, ok_if_already_exists, keep_date;
2107 {
2108 int ifd, ofd, n;
2109 char buf[16 * 1024];
2110 struct stat st, out_st;
2111 Lisp_Object handler;
2112 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2113 int count = specpdl_ptr - specpdl;
2114 int input_file_statable_p;
2115 Lisp_Object encoded_file, encoded_newname;
2116
2117 encoded_file = encoded_newname = Qnil;
2118 GCPRO4 (file, newname, encoded_file, encoded_newname);
2119 CHECK_STRING (file, 0);
2120 CHECK_STRING (newname, 1);
2121
2122 file = Fexpand_file_name (file, Qnil);
2123 newname = Fexpand_file_name (newname, Qnil);
2124
2125 /* If the input file name has special constructs in it,
2126 call the corresponding file handler. */
2127 handler = Ffind_file_name_handler (file, Qcopy_file);
2128 /* Likewise for output file name. */
2129 if (NILP (handler))
2130 handler = Ffind_file_name_handler (newname, Qcopy_file);
2131 if (!NILP (handler))
2132 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2133 ok_if_already_exists, keep_date));
2134
2135 encoded_file = ENCODE_FILE (file);
2136 encoded_newname = ENCODE_FILE (newname);
2137
2138 if (NILP (ok_if_already_exists)
2139 || INTEGERP (ok_if_already_exists))
2140 barf_or_query_if_file_exists (encoded_newname, "copy to it",
2141 INTEGERP (ok_if_already_exists), &out_st, 0);
2142 else if (stat (XSTRING (encoded_newname)->data, &out_st) < 0)
2143 out_st.st_mode = 0;
2144
2145 ifd = open (XSTRING (encoded_file)->data, O_RDONLY);
2146 if (ifd < 0)
2147 report_file_error ("Opening input file", Fcons (file, Qnil));
2148
2149 record_unwind_protect (close_file_unwind, make_number (ifd));
2150
2151 /* We can only copy regular files and symbolic links. Other files are not
2152 copyable by us. */
2153 input_file_statable_p = (fstat (ifd, &st) >= 0);
2154
2155 #if !defined (MSDOS) || __DJGPP__ > 1
2156 if (out_st.st_mode != 0
2157 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2158 {
2159 errno = 0;
2160 report_file_error ("Input and output files are the same",
2161 Fcons (file, Fcons (newname, Qnil)));
2162 }
2163 #endif
2164
2165 #if defined (S_ISREG) && defined (S_ISLNK)
2166 if (input_file_statable_p)
2167 {
2168 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2169 {
2170 #if defined (EISDIR)
2171 /* Get a better looking error message. */
2172 errno = EISDIR;
2173 #endif /* EISDIR */
2174 report_file_error ("Non-regular file", Fcons (file, Qnil));
2175 }
2176 }
2177 #endif /* S_ISREG && S_ISLNK */
2178
2179 #ifdef VMS
2180 /* Create the copy file with the same record format as the input file */
2181 ofd = sys_creat (XSTRING (encoded_newname)->data, 0666, ifd);
2182 #else
2183 #ifdef MSDOS
2184 /* System's default file type was set to binary by _fmode in emacs.c. */
2185 ofd = creat (XSTRING (encoded_newname)->data, S_IREAD | S_IWRITE);
2186 #else /* not MSDOS */
2187 ofd = creat (XSTRING (encoded_newname)->data, 0666);
2188 #endif /* not MSDOS */
2189 #endif /* VMS */
2190 if (ofd < 0)
2191 report_file_error ("Opening output file", Fcons (newname, Qnil));
2192
2193 record_unwind_protect (close_file_unwind, make_number (ofd));
2194
2195 immediate_quit = 1;
2196 QUIT;
2197 while ((n = read (ifd, buf, sizeof buf)) > 0)
2198 if (write (ofd, buf, n) != n)
2199 report_file_error ("I/O error", Fcons (newname, Qnil));
2200 immediate_quit = 0;
2201
2202 /* Closing the output clobbers the file times on some systems. */
2203 if (close (ofd) < 0)
2204 report_file_error ("I/O error", Fcons (newname, Qnil));
2205
2206 if (input_file_statable_p)
2207 {
2208 if (!NILP (keep_date))
2209 {
2210 EMACS_TIME atime, mtime;
2211 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2212 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2213 if (set_file_times (XSTRING (encoded_newname)->data,
2214 atime, mtime))
2215 Fsignal (Qfile_date_error,
2216 Fcons (build_string ("Cannot set file date"),
2217 Fcons (newname, Qnil)));
2218 }
2219 #ifndef MSDOS
2220 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2221 #else /* MSDOS */
2222 #if defined (__DJGPP__) && __DJGPP__ > 1
2223 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2224 and if it can't, it tells so. Otherwise, under MSDOS we usually
2225 get only the READ bit, which will make the copied file read-only,
2226 so it's better not to chmod at all. */
2227 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2228 chmod (XSTRING (encoded_newname)->data, st.st_mode & 07777);
2229 #endif /* DJGPP version 2 or newer */
2230 #endif /* MSDOS */
2231 }
2232
2233 close (ifd);
2234
2235 /* Discard the unwind protects. */
2236 specpdl_ptr = specpdl + count;
2237
2238 UNGCPRO;
2239 return Qnil;
2240 }
2241 \f
2242 DEFUN ("make-directory-internal", Fmake_directory_internal,
2243 Smake_directory_internal, 1, 1, 0,
2244 "Create a new directory named DIRECTORY.")
2245 (directory)
2246 Lisp_Object directory;
2247 {
2248 unsigned char *dir;
2249 Lisp_Object handler;
2250 Lisp_Object encoded_dir;
2251
2252 CHECK_STRING (directory, 0);
2253 directory = Fexpand_file_name (directory, Qnil);
2254
2255 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2256 if (!NILP (handler))
2257 return call2 (handler, Qmake_directory_internal, directory);
2258
2259 encoded_dir = ENCODE_FILE (directory);
2260
2261 dir = XSTRING (encoded_dir)->data;
2262
2263 #ifdef WINDOWSNT
2264 if (mkdir (dir) != 0)
2265 #else
2266 if (mkdir (dir, 0777) != 0)
2267 #endif
2268 report_file_error ("Creating directory", Flist (1, &directory));
2269
2270 return Qnil;
2271 }
2272
2273 DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2274 "Delete the directory named DIRECTORY.")
2275 (directory)
2276 Lisp_Object directory;
2277 {
2278 unsigned char *dir;
2279 Lisp_Object handler;
2280 Lisp_Object encoded_dir;
2281
2282 CHECK_STRING (directory, 0);
2283 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2284
2285 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2286 if (!NILP (handler))
2287 return call2 (handler, Qdelete_directory, directory);
2288
2289 encoded_dir = ENCODE_FILE (directory);
2290
2291 dir = XSTRING (encoded_dir)->data;
2292
2293 if (rmdir (dir) != 0)
2294 report_file_error ("Removing directory", Flist (1, &directory));
2295
2296 return Qnil;
2297 }
2298
2299 DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2300 "Delete file named FILENAME.\n\
2301 If file has multiple names, it continues to exist with the other names.")
2302 (filename)
2303 Lisp_Object filename;
2304 {
2305 Lisp_Object handler;
2306 Lisp_Object encoded_file;
2307
2308 CHECK_STRING (filename, 0);
2309 filename = Fexpand_file_name (filename, Qnil);
2310
2311 handler = Ffind_file_name_handler (filename, Qdelete_file);
2312 if (!NILP (handler))
2313 return call2 (handler, Qdelete_file, filename);
2314
2315 encoded_file = ENCODE_FILE (filename);
2316
2317 if (0 > unlink (XSTRING (encoded_file)->data))
2318 report_file_error ("Removing old name", Flist (1, &filename));
2319 return Qnil;
2320 }
2321
2322 static Lisp_Object
2323 internal_delete_file_1 (ignore)
2324 Lisp_Object ignore;
2325 {
2326 return Qt;
2327 }
2328
2329 /* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2330
2331 int
2332 internal_delete_file (filename)
2333 Lisp_Object filename;
2334 {
2335 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2336 Qt, internal_delete_file_1));
2337 }
2338 \f
2339 DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2340 "fRename file: \nFRename %s to file: \np",
2341 "Rename FILE as NEWNAME. Both args strings.\n\
2342 If file has names other than FILE, it continues to have those names.\n\
2343 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2344 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2345 A number as third arg means request confirmation if NEWNAME already exists.\n\
2346 This is what happens in interactive use with M-x.")
2347 (file, newname, ok_if_already_exists)
2348 Lisp_Object file, newname, ok_if_already_exists;
2349 {
2350 #ifdef NO_ARG_ARRAY
2351 Lisp_Object args[2];
2352 #endif
2353 Lisp_Object handler;
2354 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2355 Lisp_Object encoded_file, encoded_newname;
2356
2357 encoded_file = encoded_newname = Qnil;
2358 GCPRO4 (file, newname, encoded_file, encoded_newname);
2359 CHECK_STRING (file, 0);
2360 CHECK_STRING (newname, 1);
2361 file = Fexpand_file_name (file, Qnil);
2362 newname = Fexpand_file_name (newname, Qnil);
2363
2364 /* If the file name has special constructs in it,
2365 call the corresponding file handler. */
2366 handler = Ffind_file_name_handler (file, Qrename_file);
2367 if (NILP (handler))
2368 handler = Ffind_file_name_handler (newname, Qrename_file);
2369 if (!NILP (handler))
2370 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2371 file, newname, ok_if_already_exists));
2372
2373 encoded_file = ENCODE_FILE (file);
2374 encoded_newname = ENCODE_FILE (newname);
2375
2376 if (NILP (ok_if_already_exists)
2377 || INTEGERP (ok_if_already_exists))
2378 barf_or_query_if_file_exists (encoded_newname, "rename to it",
2379 INTEGERP (ok_if_already_exists), 0, 0);
2380 #ifndef BSD4_1
2381 if (0 > rename (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2382 #else
2383 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data)
2384 || 0 > unlink (XSTRING (encoded_file)->data))
2385 #endif
2386 {
2387 if (errno == EXDEV)
2388 {
2389 Fcopy_file (file, newname,
2390 /* We have already prompted if it was an integer,
2391 so don't have copy-file prompt again. */
2392 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2393 Fdelete_file (file);
2394 }
2395 else
2396 #ifdef NO_ARG_ARRAY
2397 {
2398 args[0] = file;
2399 args[1] = newname;
2400 report_file_error ("Renaming", Flist (2, args));
2401 }
2402 #else
2403 report_file_error ("Renaming", Flist (2, &file));
2404 #endif
2405 }
2406 UNGCPRO;
2407 return Qnil;
2408 }
2409
2410 DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2411 "fAdd name to file: \nFName to add to %s: \np",
2412 "Give FILE additional name NEWNAME. Both args strings.\n\
2413 Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2414 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2415 A number as third arg means request confirmation if NEWNAME already exists.\n\
2416 This is what happens in interactive use with M-x.")
2417 (file, newname, ok_if_already_exists)
2418 Lisp_Object file, newname, ok_if_already_exists;
2419 {
2420 #ifdef NO_ARG_ARRAY
2421 Lisp_Object args[2];
2422 #endif
2423 Lisp_Object handler;
2424 Lisp_Object encoded_file, encoded_newname;
2425 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2426
2427 GCPRO4 (file, newname, encoded_file, encoded_newname);
2428 encoded_file = encoded_newname = Qnil;
2429 CHECK_STRING (file, 0);
2430 CHECK_STRING (newname, 1);
2431 file = Fexpand_file_name (file, Qnil);
2432 newname = Fexpand_file_name (newname, Qnil);
2433
2434 /* If the file name has special constructs in it,
2435 call the corresponding file handler. */
2436 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2437 if (!NILP (handler))
2438 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2439 newname, ok_if_already_exists));
2440
2441 /* If the new name has special constructs in it,
2442 call the corresponding file handler. */
2443 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2444 if (!NILP (handler))
2445 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2446 newname, ok_if_already_exists));
2447
2448 encoded_file = ENCODE_FILE (file);
2449 encoded_newname = ENCODE_FILE (newname);
2450
2451 if (NILP (ok_if_already_exists)
2452 || INTEGERP (ok_if_already_exists))
2453 barf_or_query_if_file_exists (encoded_newname, "make it a new name",
2454 INTEGERP (ok_if_already_exists), 0, 0);
2455
2456 unlink (XSTRING (newname)->data);
2457 if (0 > link (XSTRING (encoded_file)->data, XSTRING (encoded_newname)->data))
2458 {
2459 #ifdef NO_ARG_ARRAY
2460 args[0] = file;
2461 args[1] = newname;
2462 report_file_error ("Adding new name", Flist (2, args));
2463 #else
2464 report_file_error ("Adding new name", Flist (2, &file));
2465 #endif
2466 }
2467
2468 UNGCPRO;
2469 return Qnil;
2470 }
2471
2472 #ifdef S_IFLNK
2473 DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2474 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2475 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2476 Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2477 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2478 A number as third arg means request confirmation if LINKNAME already exists.\n\
2479 This happens for interactive use with M-x.")
2480 (filename, linkname, ok_if_already_exists)
2481 Lisp_Object filename, linkname, ok_if_already_exists;
2482 {
2483 #ifdef NO_ARG_ARRAY
2484 Lisp_Object args[2];
2485 #endif
2486 Lisp_Object handler;
2487 Lisp_Object encoded_filename, encoded_linkname;
2488 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2489
2490 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname);
2491 encoded_filename = encoded_linkname = Qnil;
2492 CHECK_STRING (filename, 0);
2493 CHECK_STRING (linkname, 1);
2494 /* If the link target has a ~, we must expand it to get
2495 a truly valid file name. Otherwise, do not expand;
2496 we want to permit links to relative file names. */
2497 if (XSTRING (filename)->data[0] == '~')
2498 filename = Fexpand_file_name (filename, Qnil);
2499 linkname = Fexpand_file_name (linkname, Qnil);
2500
2501 /* If the file name has special constructs in it,
2502 call the corresponding file handler. */
2503 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2504 if (!NILP (handler))
2505 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2506 linkname, ok_if_already_exists));
2507
2508 /* If the new link name has special constructs in it,
2509 call the corresponding file handler. */
2510 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2511 if (!NILP (handler))
2512 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2513 linkname, ok_if_already_exists));
2514
2515 encoded_filename = ENCODE_FILE (filename);
2516 encoded_linkname = ENCODE_FILE (linkname);
2517
2518 if (NILP (ok_if_already_exists)
2519 || INTEGERP (ok_if_already_exists))
2520 barf_or_query_if_file_exists (encoded_linkname, "make it a link",
2521 INTEGERP (ok_if_already_exists), 0, 0);
2522 if (0 > symlink (XSTRING (encoded_filename)->data,
2523 XSTRING (encoded_linkname)->data))
2524 {
2525 /* If we didn't complain already, silently delete existing file. */
2526 if (errno == EEXIST)
2527 {
2528 unlink (XSTRING (encoded_linkname)->data);
2529 if (0 <= symlink (XSTRING (encoded_filename)->data,
2530 XSTRING (encoded_linkname)->data))
2531 {
2532 UNGCPRO;
2533 return Qnil;
2534 }
2535 }
2536
2537 #ifdef NO_ARG_ARRAY
2538 args[0] = filename;
2539 args[1] = linkname;
2540 report_file_error ("Making symbolic link", Flist (2, args));
2541 #else
2542 report_file_error ("Making symbolic link", Flist (2, &filename));
2543 #endif
2544 }
2545 UNGCPRO;
2546 return Qnil;
2547 }
2548 #endif /* S_IFLNK */
2549
2550 #ifdef VMS
2551
2552 DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2553 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2554 "Define the job-wide logical name NAME to have the value STRING.\n\
2555 If STRING is nil or a null string, the logical name NAME is deleted.")
2556 (name, string)
2557 Lisp_Object name;
2558 Lisp_Object string;
2559 {
2560 CHECK_STRING (name, 0);
2561 if (NILP (string))
2562 delete_logical_name (XSTRING (name)->data);
2563 else
2564 {
2565 CHECK_STRING (string, 1);
2566
2567 if (XSTRING (string)->size == 0)
2568 delete_logical_name (XSTRING (name)->data);
2569 else
2570 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2571 }
2572
2573 return string;
2574 }
2575 #endif /* VMS */
2576
2577 #ifdef HPUX_NET
2578
2579 DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2580 "Open a network connection to PATH using LOGIN as the login string.")
2581 (path, login)
2582 Lisp_Object path, login;
2583 {
2584 int netresult;
2585
2586 CHECK_STRING (path, 0);
2587 CHECK_STRING (login, 0);
2588
2589 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2590
2591 if (netresult == -1)
2592 return Qnil;
2593 else
2594 return Qt;
2595 }
2596 #endif /* HPUX_NET */
2597 \f
2598 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2599 1, 1, 0,
2600 "Return t if file FILENAME specifies an absolute file name.\n\
2601 On Unix, this is a name starting with a `/' or a `~'.")
2602 (filename)
2603 Lisp_Object filename;
2604 {
2605 unsigned char *ptr;
2606
2607 CHECK_STRING (filename, 0);
2608 ptr = XSTRING (filename)->data;
2609 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2610 #ifdef VMS
2611 /* ??? This criterion is probably wrong for '<'. */
2612 || index (ptr, ':') || index (ptr, '<')
2613 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2614 && ptr[1] != '.')
2615 #endif /* VMS */
2616 #ifdef DOS_NT
2617 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2618 #endif
2619 )
2620 return Qt;
2621 else
2622 return Qnil;
2623 }
2624 \f
2625 /* Return nonzero if file FILENAME exists and can be executed. */
2626
2627 static int
2628 check_executable (filename)
2629 char *filename;
2630 {
2631 #ifdef DOS_NT
2632 int len = strlen (filename);
2633 char *suffix;
2634 struct stat st;
2635 if (stat (filename, &st) < 0)
2636 return 0;
2637 #if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2638 return ((st.st_mode & S_IEXEC) != 0);
2639 #else
2640 return (S_ISREG (st.st_mode)
2641 && len >= 5
2642 && (stricmp ((suffix = filename + len-4), ".com") == 0
2643 || stricmp (suffix, ".exe") == 0
2644 || stricmp (suffix, ".bat") == 0)
2645 || (st.st_mode & S_IFMT) == S_IFDIR);
2646 #endif /* not WINDOWSNT */
2647 #else /* not DOS_NT */
2648 #ifdef HAVE_EUIDACCESS
2649 return (euidaccess (filename, 1) >= 0);
2650 #else
2651 /* Access isn't quite right because it uses the real uid
2652 and we really want to test with the effective uid.
2653 But Unix doesn't give us a right way to do it. */
2654 return (access (filename, 1) >= 0);
2655 #endif
2656 #endif /* not DOS_NT */
2657 }
2658
2659 /* Return nonzero if file FILENAME exists and can be written. */
2660
2661 static int
2662 check_writable (filename)
2663 char *filename;
2664 {
2665 #ifdef MSDOS
2666 struct stat st;
2667 if (stat (filename, &st) < 0)
2668 return 0;
2669 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2670 #else /* not MSDOS */
2671 #ifdef HAVE_EUIDACCESS
2672 return (euidaccess (filename, 2) >= 0);
2673 #else
2674 /* Access isn't quite right because it uses the real uid
2675 and we really want to test with the effective uid.
2676 But Unix doesn't give us a right way to do it.
2677 Opening with O_WRONLY could work for an ordinary file,
2678 but would lose for directories. */
2679 return (access (filename, 2) >= 0);
2680 #endif
2681 #endif /* not MSDOS */
2682 }
2683
2684 DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2685 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2686 See also `file-readable-p' and `file-attributes'.")
2687 (filename)
2688 Lisp_Object filename;
2689 {
2690 Lisp_Object absname;
2691 Lisp_Object handler;
2692 struct stat statbuf;
2693
2694 CHECK_STRING (filename, 0);
2695 absname = Fexpand_file_name (filename, Qnil);
2696
2697 /* If the file name has special constructs in it,
2698 call the corresponding file handler. */
2699 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2700 if (!NILP (handler))
2701 return call2 (handler, Qfile_exists_p, absname);
2702
2703 absname = ENCODE_FILE (absname);
2704
2705 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2706 }
2707
2708 DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2709 "Return t if FILENAME can be executed by you.\n\
2710 For a directory, this means you can access files in that directory.")
2711 (filename)
2712 Lisp_Object filename;
2713
2714 {
2715 Lisp_Object absname;
2716 Lisp_Object handler;
2717
2718 CHECK_STRING (filename, 0);
2719 absname = Fexpand_file_name (filename, Qnil);
2720
2721 /* If the file name has special constructs in it,
2722 call the corresponding file handler. */
2723 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
2724 if (!NILP (handler))
2725 return call2 (handler, Qfile_executable_p, absname);
2726
2727 absname = ENCODE_FILE (absname);
2728
2729 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
2730 }
2731
2732 DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
2733 "Return t if file FILENAME exists and you can read it.\n\
2734 See also `file-exists-p' and `file-attributes'.")
2735 (filename)
2736 Lisp_Object filename;
2737 {
2738 Lisp_Object absname;
2739 Lisp_Object handler;
2740 int desc;
2741 int flags;
2742 struct stat statbuf;
2743
2744 CHECK_STRING (filename, 0);
2745 absname = Fexpand_file_name (filename, Qnil);
2746
2747 /* If the file name has special constructs in it,
2748 call the corresponding file handler. */
2749 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
2750 if (!NILP (handler))
2751 return call2 (handler, Qfile_readable_p, absname);
2752
2753 absname = ENCODE_FILE (absname);
2754
2755 #ifdef DOS_NT
2756 /* Under MS-DOS and Windows, open does not work for directories. */
2757 if (access (XSTRING (absname)->data, 0) == 0)
2758 return Qt;
2759 return Qnil;
2760 #else /* not DOS_NT */
2761 flags = O_RDONLY;
2762 #if defined (S_ISFIFO) && defined (O_NONBLOCK)
2763 /* Opening a fifo without O_NONBLOCK can wait.
2764 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2765 except in the case of a fifo, on a system which handles it. */
2766 desc = stat (XSTRING (absname)->data, &statbuf);
2767 if (desc < 0)
2768 return Qnil;
2769 if (S_ISFIFO (statbuf.st_mode))
2770 flags |= O_NONBLOCK;
2771 #endif
2772 desc = open (XSTRING (absname)->data, flags);
2773 if (desc < 0)
2774 return Qnil;
2775 close (desc);
2776 return Qt;
2777 #endif /* not DOS_NT */
2778 }
2779
2780 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2781 on the RT/PC. */
2782 DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2783 "Return t if file FILENAME can be written or created by you.")
2784 (filename)
2785 Lisp_Object filename;
2786 {
2787 Lisp_Object absname, dir, encoded;
2788 Lisp_Object handler;
2789 struct stat statbuf;
2790
2791 CHECK_STRING (filename, 0);
2792 absname = Fexpand_file_name (filename, Qnil);
2793
2794 /* If the file name has special constructs in it,
2795 call the corresponding file handler. */
2796 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
2797 if (!NILP (handler))
2798 return call2 (handler, Qfile_writable_p, absname);
2799
2800 encoded = ENCODE_FILE (absname);
2801 if (stat (XSTRING (encoded)->data, &statbuf) >= 0)
2802 return (check_writable (XSTRING (encoded)->data)
2803 ? Qt : Qnil);
2804
2805 dir = Ffile_name_directory (absname);
2806 #ifdef VMS
2807 if (!NILP (dir))
2808 dir = Fdirectory_file_name (dir);
2809 #endif /* VMS */
2810 #ifdef MSDOS
2811 if (!NILP (dir))
2812 dir = Fdirectory_file_name (dir);
2813 #endif /* MSDOS */
2814
2815 dir = ENCODE_FILE (dir);
2816 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
2817 ? Qt : Qnil);
2818 }
2819 \f
2820 DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
2821 "Access file FILENAME, and get an error if that does not work.\n\
2822 The second argument STRING is used in the error message.\n\
2823 If there is no error, we return nil.")
2824 (filename, string)
2825 Lisp_Object filename, string;
2826 {
2827 Lisp_Object handler, encoded_filename;
2828 int fd;
2829
2830 CHECK_STRING (filename, 0);
2831
2832 /* If the file name has special constructs in it,
2833 call the corresponding file handler. */
2834 handler = Ffind_file_name_handler (filename, Qaccess_file);
2835 if (!NILP (handler))
2836 return call3 (handler, Qaccess_file, filename, string);
2837
2838 encoded_filename = ENCODE_FILE (filename);
2839
2840 fd = open (XSTRING (encoded_filename)->data, O_RDONLY);
2841 if (fd < 0)
2842 report_file_error (XSTRING (string)->data, Fcons (filename, Qnil));
2843 close (fd);
2844
2845 return Qnil;
2846 }
2847 \f
2848 DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2849 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2850 The value is the name of the file to which it is linked.\n\
2851 Otherwise returns nil.")
2852 (filename)
2853 Lisp_Object filename;
2854 {
2855 #ifdef S_IFLNK
2856 char *buf;
2857 int bufsize;
2858 int valsize;
2859 Lisp_Object val;
2860 Lisp_Object handler;
2861
2862 CHECK_STRING (filename, 0);
2863 filename = Fexpand_file_name (filename, Qnil);
2864
2865 /* If the file name has special constructs in it,
2866 call the corresponding file handler. */
2867 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2868 if (!NILP (handler))
2869 return call2 (handler, Qfile_symlink_p, filename);
2870
2871 filename = ENCODE_FILE (filename);
2872
2873 bufsize = 100;
2874 while (1)
2875 {
2876 buf = (char *) xmalloc (bufsize);
2877 bzero (buf, bufsize);
2878 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
2879 if (valsize < bufsize) break;
2880 /* Buffer was not long enough */
2881 xfree (buf);
2882 bufsize *= 2;
2883 }
2884 if (valsize == -1)
2885 {
2886 xfree (buf);
2887 return Qnil;
2888 }
2889 val = make_string (buf, valsize);
2890 xfree (buf);
2891 val = DECODE_FILE (val);
2892 return val;
2893 #else /* not S_IFLNK */
2894 return Qnil;
2895 #endif /* not S_IFLNK */
2896 }
2897
2898 DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
2899 "Return t if FILENAME names an existing directory.")
2900 (filename)
2901 Lisp_Object filename;
2902 {
2903 register Lisp_Object absname;
2904 struct stat st;
2905 Lisp_Object handler;
2906
2907 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2908
2909 /* If the file name has special constructs in it,
2910 call the corresponding file handler. */
2911 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
2912 if (!NILP (handler))
2913 return call2 (handler, Qfile_directory_p, absname);
2914
2915 absname = ENCODE_FILE (absname);
2916
2917 if (stat (XSTRING (absname)->data, &st) < 0)
2918 return Qnil;
2919 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2920 }
2921
2922 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
2923 "Return t if file FILENAME is the name of a directory as a file,\n\
2924 and files in that directory can be opened by you. In order to use a\n\
2925 directory as a buffer's current directory, this predicate must return true.\n\
2926 A directory name spec may be given instead; then the value is t\n\
2927 if the directory so specified exists and really is a readable and\n\
2928 searchable directory.")
2929 (filename)
2930 Lisp_Object filename;
2931 {
2932 Lisp_Object handler;
2933 int tem;
2934 struct gcpro gcpro1;
2935
2936 /* If the file name has special constructs in it,
2937 call the corresponding file handler. */
2938 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2939 if (!NILP (handler))
2940 return call2 (handler, Qfile_accessible_directory_p, filename);
2941
2942 /* It's an unlikely combination, but yes we really do need to gcpro:
2943 Suppose that file-accessible-directory-p has no handler, but
2944 file-directory-p does have a handler; this handler causes a GC which
2945 relocates the string in `filename'; and finally file-directory-p
2946 returns non-nil. Then we would end up passing a garbaged string
2947 to file-executable-p. */
2948 GCPRO1 (filename);
2949 tem = (NILP (Ffile_directory_p (filename))
2950 || NILP (Ffile_executable_p (filename)));
2951 UNGCPRO;
2952 return tem ? Qnil : Qt;
2953 }
2954
2955 DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
2956 "Return t if file FILENAME is the name of a regular file.\n\
2957 This is the sort of file that holds an ordinary stream of data bytes.")
2958 (filename)
2959 Lisp_Object filename;
2960 {
2961 register Lisp_Object absname;
2962 struct stat st;
2963 Lisp_Object handler;
2964
2965 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2966
2967 /* If the file name has special constructs in it,
2968 call the corresponding file handler. */
2969 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
2970 if (!NILP (handler))
2971 return call2 (handler, Qfile_regular_p, absname);
2972
2973 absname = ENCODE_FILE (absname);
2974
2975 if (stat (XSTRING (absname)->data, &st) < 0)
2976 return Qnil;
2977 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2978 }
2979 \f
2980 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
2981 "Return mode bits of file named FILENAME, as an integer.")
2982 (filename)
2983 Lisp_Object filename;
2984 {
2985 Lisp_Object absname;
2986 struct stat st;
2987 Lisp_Object handler;
2988
2989 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2990
2991 /* If the file name has special constructs in it,
2992 call the corresponding file handler. */
2993 handler = Ffind_file_name_handler (absname, Qfile_modes);
2994 if (!NILP (handler))
2995 return call2 (handler, Qfile_modes, absname);
2996
2997 absname = ENCODE_FILE (absname);
2998
2999 if (stat (XSTRING (absname)->data, &st) < 0)
3000 return Qnil;
3001 #if defined (MSDOS) && __DJGPP__ < 2
3002 if (check_executable (XSTRING (absname)->data))
3003 st.st_mode |= S_IEXEC;
3004 #endif /* MSDOS && __DJGPP__ < 2 */
3005
3006 return make_number (st.st_mode & 07777);
3007 }
3008
3009 DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
3010 "Set mode bits of file named FILENAME to MODE (an integer).\n\
3011 Only the 12 low bits of MODE are used.")
3012 (filename, mode)
3013 Lisp_Object filename, mode;
3014 {
3015 Lisp_Object absname, encoded_absname;
3016 Lisp_Object handler;
3017
3018 absname = Fexpand_file_name (filename, current_buffer->directory);
3019 CHECK_NUMBER (mode, 1);
3020
3021 /* If the file name has special constructs in it,
3022 call the corresponding file handler. */
3023 handler = Ffind_file_name_handler (absname, Qset_file_modes);
3024 if (!NILP (handler))
3025 return call3 (handler, Qset_file_modes, absname, mode);
3026
3027 encoded_absname = ENCODE_FILE (absname);
3028
3029 if (chmod (XSTRING (encoded_absname)->data, XINT (mode)) < 0)
3030 report_file_error ("Doing chmod", Fcons (absname, Qnil));
3031
3032 return Qnil;
3033 }
3034
3035 DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
3036 "Set the file permission bits for newly created files.\n\
3037 The argument MODE should be an integer; only the low 9 bits are used.\n\
3038 This setting is inherited by subprocesses.")
3039 (mode)
3040 Lisp_Object mode;
3041 {
3042 CHECK_NUMBER (mode, 0);
3043
3044 umask ((~ XINT (mode)) & 0777);
3045
3046 return Qnil;
3047 }
3048
3049 DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
3050 "Return the default file protection for created files.\n\
3051 The value is an integer.")
3052 ()
3053 {
3054 int realmask;
3055 Lisp_Object value;
3056
3057 realmask = umask (0);
3058 umask (realmask);
3059
3060 XSETINT (value, (~ realmask) & 0777);
3061 return value;
3062 }
3063 \f
3064 #ifdef unix
3065
3066 DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
3067 "Tell Unix to finish all pending disk updates.")
3068 ()
3069 {
3070 sync ();
3071 return Qnil;
3072 }
3073
3074 #endif /* unix */
3075
3076 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
3077 "Return t if file FILE1 is newer than file FILE2.\n\
3078 If FILE1 does not exist, the answer is nil;\n\
3079 otherwise, if FILE2 does not exist, the answer is t.")
3080 (file1, file2)
3081 Lisp_Object file1, file2;
3082 {
3083 Lisp_Object absname1, absname2;
3084 struct stat st;
3085 int mtime1;
3086 Lisp_Object handler;
3087 struct gcpro gcpro1, gcpro2;
3088
3089 CHECK_STRING (file1, 0);
3090 CHECK_STRING (file2, 0);
3091
3092 absname1 = Qnil;
3093 GCPRO2 (absname1, file2);
3094 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
3095 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
3096 UNGCPRO;
3097
3098 /* If the file name has special constructs in it,
3099 call the corresponding file handler. */
3100 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
3101 if (NILP (handler))
3102 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
3103 if (!NILP (handler))
3104 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
3105
3106 GCPRO2 (absname1, absname2);
3107 absname1 = ENCODE_FILE (absname1);
3108 absname2 = ENCODE_FILE (absname2);
3109 UNGCPRO;
3110
3111 if (stat (XSTRING (absname1)->data, &st) < 0)
3112 return Qnil;
3113
3114 mtime1 = st.st_mtime;
3115
3116 if (stat (XSTRING (absname2)->data, &st) < 0)
3117 return Qt;
3118
3119 return (mtime1 > st.st_mtime) ? Qt : Qnil;
3120 }
3121 \f
3122 #ifdef DOS_NT
3123 Lisp_Object Qfind_buffer_file_type;
3124 #endif /* DOS_NT */
3125
3126 #ifndef READ_BUF_SIZE
3127 #define READ_BUF_SIZE (64 << 10)
3128 #endif
3129
3130 DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3131 1, 5, 0,
3132 "Insert contents of file FILENAME after point.\n\
3133 Returns list of absolute file name and number of bytes inserted.\n\
3134 If second argument VISIT is non-nil, the buffer's visited filename\n\
3135 and last save file modtime are set, and it is marked unmodified.\n\
3136 If visiting and the file does not exist, visiting is completed\n\
3137 before the error is signaled.\n\
3138 The optional third and fourth arguments BEG and END\n\
3139 specify what portion of the file to insert.\n\
3140 These arguments count bytes in the file, not characters in the buffer.\n\
3141 If VISIT is non-nil, BEG and END must be nil.\n\
3142 \n\
3143 If optional fifth argument REPLACE is non-nil,\n\
3144 it means replace the current buffer contents (in the accessible portion)\n\
3145 with the file contents. This is better than simply deleting and inserting\n\
3146 the whole thing because (1) it preserves some marker positions\n\
3147 and (2) it puts less data in the undo list.\n\
3148 When REPLACE is non-nil, the value is the number of characters actually read,\n\
3149 which is often less than the number of characters to be read.\n\
3150 This does code conversion according to the value of\n\
3151 `coding-system-for-read' or `file-coding-system-alist',\n\
3152 and sets the variable `last-coding-system-used' to the coding system\n\
3153 actually used.")
3154 (filename, visit, beg, end, replace)
3155 Lisp_Object filename, visit, beg, end, replace;
3156 {
3157 struct stat st;
3158 register int fd;
3159 int inserted = 0;
3160 register int how_much;
3161 register int unprocessed;
3162 int count = specpdl_ptr - specpdl;
3163 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3164 Lisp_Object handler, val, insval, orig_filename;
3165 Lisp_Object p;
3166 int total;
3167 int not_regular = 0;
3168 char read_buf[READ_BUF_SIZE];
3169 struct coding_system coding;
3170 unsigned char buffer[1 << 14];
3171 int replace_handled = 0;
3172 int set_coding_system = 0;
3173
3174 if (current_buffer->base_buffer && ! NILP (visit))
3175 error ("Cannot do file visiting in an indirect buffer");
3176
3177 if (!NILP (current_buffer->read_only))
3178 Fbarf_if_buffer_read_only ();
3179
3180 val = Qnil;
3181 p = Qnil;
3182 orig_filename = Qnil;
3183
3184 GCPRO4 (filename, val, p, orig_filename);
3185
3186 CHECK_STRING (filename, 0);
3187 filename = Fexpand_file_name (filename, Qnil);
3188
3189 /* If the file name has special constructs in it,
3190 call the corresponding file handler. */
3191 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3192 if (!NILP (handler))
3193 {
3194 val = call6 (handler, Qinsert_file_contents, filename,
3195 visit, beg, end, replace);
3196 goto handled;
3197 }
3198
3199 orig_filename = filename;
3200 filename = ENCODE_FILE (filename);
3201
3202 fd = -1;
3203
3204 #ifndef APOLLO
3205 if (stat (XSTRING (filename)->data, &st) < 0)
3206 #else
3207 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0
3208 || fstat (fd, &st) < 0)
3209 #endif /* not APOLLO */
3210 {
3211 if (fd >= 0) close (fd);
3212 badopen:
3213 if (NILP (visit))
3214 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3215 st.st_mtime = -1;
3216 how_much = 0;
3217 if (!NILP (Vcoding_system_for_read))
3218 current_buffer->buffer_file_coding_system = Vcoding_system_for_read;
3219 goto notfound;
3220 }
3221
3222 #ifdef S_IFREG
3223 /* This code will need to be changed in order to work on named
3224 pipes, and it's probably just not worth it. So we should at
3225 least signal an error. */
3226 if (!S_ISREG (st.st_mode))
3227 {
3228 not_regular = 1;
3229
3230 if (! NILP (visit))
3231 goto notfound;
3232
3233 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
3234 Fsignal (Qfile_error,
3235 Fcons (build_string ("not a regular file"),
3236 Fcons (orig_filename, Qnil)));
3237 }
3238 #endif
3239
3240 if (fd < 0)
3241 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0)
3242 goto badopen;
3243
3244 /* Replacement should preserve point as it preserves markers. */
3245 if (!NILP (replace))
3246 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3247
3248 record_unwind_protect (close_file_unwind, make_number (fd));
3249
3250 /* Supposedly happens on VMS. */
3251 if (! not_regular && st.st_size < 0)
3252 error ("File size is negative");
3253
3254 if (!NILP (beg) || !NILP (end))
3255 if (!NILP (visit))
3256 error ("Attempt to visit less than an entire file");
3257
3258 if (!NILP (beg))
3259 CHECK_NUMBER (beg, 0);
3260 else
3261 XSETFASTINT (beg, 0);
3262
3263 if (!NILP (end))
3264 CHECK_NUMBER (end, 0);
3265 else
3266 {
3267 if (! not_regular)
3268 {
3269 XSETINT (end, st.st_size);
3270 if (XINT (end) != st.st_size)
3271 error ("Maximum buffer size exceeded");
3272 }
3273 }
3274
3275 /* Decide the coding-system of the file. */
3276 {
3277 Lisp_Object val = Qnil;
3278
3279 if (!NILP (Vcoding_system_for_read))
3280 val = Vcoding_system_for_read;
3281 else
3282 {
3283 if (! NILP (Vset_auto_coding_function))
3284 {
3285 /* Find a coding system specified in the heading two lines
3286 or in the tailing several lines of the file. We assume
3287 that the 1K-byte and 3K-byte for heading and tailing
3288 respectively are sufficient fot this purpose. */
3289 int how_many, nread;
3290
3291 if (st.st_size <= (1024 * 4))
3292 nread = read (fd, read_buf, 1024 * 4);
3293 else
3294 {
3295 nread = read (fd, read_buf, 1024);
3296 if (nread >= 0)
3297 {
3298 if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
3299 report_file_error ("Setting file position",
3300 Fcons (orig_filename, Qnil));
3301 nread += read (fd, read_buf + nread, 1024 * 3);
3302 }
3303 }
3304
3305 if (nread < 0)
3306 error ("IO error reading %s: %s",
3307 XSTRING (orig_filename)->data, strerror (errno));
3308 else if (nread > 0)
3309 {
3310 Lisp_Object tem;
3311 /* Always make this a unibyte string
3312 because we have not yet decoded it. */
3313 tem = make_unibyte_string (read_buf, nread);
3314 val = call1 (Vset_auto_coding_function, tem);
3315 /* Rewind the file for the actual read done later. */
3316 if (lseek (fd, 0, 0) < 0)
3317 report_file_error ("Setting file position",
3318 Fcons (orig_filename, Qnil));
3319 }
3320 }
3321 if (NILP (val))
3322 {
3323 Lisp_Object args[6], coding_systems;
3324
3325 args[0] = Qinsert_file_contents, args[1] = orig_filename,
3326 args[2] = visit, args[3] = beg, args[4] = end, args[5] = replace;
3327 coding_systems = Ffind_operation_coding_system (6, args);
3328 if (CONSP (coding_systems)) val = XCONS (coding_systems)->car;
3329 }
3330 }
3331
3332 if (NILP (Vcoding_system_for_read)
3333 && NILP (current_buffer->enable_multibyte_characters))
3334 {
3335 /* We must suppress all text conversion except for end-of-line
3336 conversion. */
3337 struct coding_system coding_temp;
3338
3339 setup_coding_system (Fcheck_coding_system (val), &coding_temp);
3340 setup_coding_system (Qraw_text, &coding);
3341 coding.eol_type = coding_temp.eol_type;
3342 }
3343 else
3344 setup_coding_system (Fcheck_coding_system (val), &coding);
3345 }
3346
3347 /* If requested, replace the accessible part of the buffer
3348 with the file contents. Avoid replacing text at the
3349 beginning or end of the buffer that matches the file contents;
3350 that preserves markers pointing to the unchanged parts.
3351
3352 Here we implement this feature in an optimized way
3353 for the case where code conversion is NOT needed.
3354 The following if-statement handles the case of conversion
3355 in a less optimal way.
3356
3357 If the code conversion is "automatic" then we try using this
3358 method and hope for the best.
3359 But if we discover the need for conversion, we give up on this method
3360 and let the following if-statement handle the replace job. */
3361 if (!NILP (replace)
3362 && ! CODING_REQUIRE_DECODING (&coding))
3363 {
3364 /* same_at_start and same_at_end count bytes,
3365 because file access counts bytes
3366 and BEG and END count bytes. */
3367 int same_at_start = BEGV_BYTE;
3368 int same_at_end = ZV_BYTE;
3369 int overlap;
3370 /* There is still a possibility we will find the need to do code
3371 conversion. If that happens, we set this variable to 1 to
3372 give up on handling REPLACE in the optimized way. */
3373 int giveup_match_end = 0;
3374
3375 if (XINT (beg) != 0)
3376 {
3377 if (lseek (fd, XINT (beg), 0) < 0)
3378 report_file_error ("Setting file position",
3379 Fcons (orig_filename, Qnil));
3380 }
3381
3382 immediate_quit = 1;
3383 QUIT;
3384 /* Count how many chars at the start of the file
3385 match the text at the beginning of the buffer. */
3386 while (1)
3387 {
3388 int nread, bufpos;
3389
3390 nread = read (fd, buffer, sizeof buffer);
3391 if (nread < 0)
3392 error ("IO error reading %s: %s",
3393 XSTRING (orig_filename)->data, strerror (errno));
3394 else if (nread == 0)
3395 break;
3396
3397 if (coding.type == coding_type_undecided)
3398 detect_coding (&coding, buffer, nread);
3399 if (CODING_REQUIRE_DECODING (&coding))
3400 /* We found that the file should be decoded somehow.
3401 Let's give up here. */
3402 {
3403 giveup_match_end = 1;
3404 break;
3405 }
3406
3407 if (coding.eol_type == CODING_EOL_UNDECIDED)
3408 detect_eol (&coding, buffer, nread);
3409 if (coding.eol_type != CODING_EOL_UNDECIDED
3410 && coding.eol_type != CODING_EOL_LF)
3411 /* We found that the format of eol should be decoded.
3412 Let's give up here. */
3413 {
3414 giveup_match_end = 1;
3415 break;
3416 }
3417
3418 bufpos = 0;
3419 while (bufpos < nread && same_at_start < ZV_BYTE
3420 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3421 same_at_start++, bufpos++;
3422 /* If we found a discrepancy, stop the scan.
3423 Otherwise loop around and scan the next bufferful. */
3424 if (bufpos != nread)
3425 break;
3426 }
3427 immediate_quit = 0;
3428 /* If the file matches the buffer completely,
3429 there's no need to replace anything. */
3430 if (same_at_start - BEGV_BYTE == XINT (end))
3431 {
3432 close (fd);
3433 specpdl_ptr--;
3434 /* Truncate the buffer to the size of the file. */
3435 del_range_1 (same_at_start, same_at_end, 0);
3436 goto handled;
3437 }
3438 immediate_quit = 1;
3439 QUIT;
3440 /* Count how many chars at the end of the file
3441 match the text at the end of the buffer. But, if we have
3442 already found that decoding is necessary, don't waste time. */
3443 while (!giveup_match_end)
3444 {
3445 int total_read, nread, bufpos, curpos, trial;
3446
3447 /* At what file position are we now scanning? */
3448 curpos = XINT (end) - (ZV_BYTE - same_at_end);
3449 /* If the entire file matches the buffer tail, stop the scan. */
3450 if (curpos == 0)
3451 break;
3452 /* How much can we scan in the next step? */
3453 trial = min (curpos, sizeof buffer);
3454 if (lseek (fd, curpos - trial, 0) < 0)
3455 report_file_error ("Setting file position",
3456 Fcons (orig_filename, Qnil));
3457
3458 total_read = 0;
3459 while (total_read < trial)
3460 {
3461 nread = read (fd, buffer + total_read, trial - total_read);
3462 if (nread <= 0)
3463 error ("IO error reading %s: %s",
3464 XSTRING (orig_filename)->data, strerror (errno));
3465 total_read += nread;
3466 }
3467 /* Scan this bufferful from the end, comparing with
3468 the Emacs buffer. */
3469 bufpos = total_read;
3470 /* Compare with same_at_start to avoid counting some buffer text
3471 as matching both at the file's beginning and at the end. */
3472 while (bufpos > 0 && same_at_end > same_at_start
3473 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3474 same_at_end--, bufpos--;
3475
3476 /* If we found a discrepancy, stop the scan.
3477 Otherwise loop around and scan the preceding bufferful. */
3478 if (bufpos != 0)
3479 {
3480 /* If this discrepancy is because of code conversion,
3481 we cannot use this method; giveup and try the other. */
3482 if (same_at_end > same_at_start
3483 && FETCH_BYTE (same_at_end - 1) >= 0200
3484 && ! NILP (current_buffer->enable_multibyte_characters)
3485 && (CODING_MAY_REQUIRE_DECODING (&coding)))
3486 giveup_match_end = 1;
3487 break;
3488 }
3489 }
3490 immediate_quit = 0;
3491
3492 if (! giveup_match_end)
3493 {
3494 int temp;
3495
3496 /* We win! We can handle REPLACE the optimized way. */
3497
3498 /* Extends the end of non-matching text area to multibyte
3499 character boundary. */
3500 if (! NILP (current_buffer->enable_multibyte_characters))
3501 while (same_at_end < ZV_BYTE
3502 && ! CHAR_HEAD_P (FETCH_BYTE (same_at_end)))
3503 same_at_end++;
3504
3505 /* Don't try to reuse the same piece of text twice. */
3506 overlap = (same_at_start - BEGV_BYTE
3507 - (same_at_end + st.st_size - ZV));
3508 if (overlap > 0)
3509 same_at_end += overlap;
3510
3511 /* Arrange to read only the nonmatching middle part of the file. */
3512 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
3513 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
3514
3515 del_range_byte (same_at_start, same_at_end, 0);
3516 /* Insert from the file at the proper position. */
3517 temp = BYTE_TO_CHAR (same_at_start);
3518 SET_PT_BOTH (temp, same_at_start);
3519
3520 /* If display currently starts at beginning of line,
3521 keep it that way. */
3522 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3523 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3524
3525 replace_handled = 1;
3526 }
3527 }
3528
3529 /* If requested, replace the accessible part of the buffer
3530 with the file contents. Avoid replacing text at the
3531 beginning or end of the buffer that matches the file contents;
3532 that preserves markers pointing to the unchanged parts.
3533
3534 Here we implement this feature for the case where code conversion
3535 is needed, in a simple way that needs a lot of memory.
3536 The preceding if-statement handles the case of no conversion
3537 in a more optimized way. */
3538 if (!NILP (replace) && ! replace_handled)
3539 {
3540 int same_at_start = BEGV_BYTE;
3541 int same_at_end = ZV_BYTE;
3542 int overlap;
3543 int bufpos;
3544 /* Make sure that the gap is large enough. */
3545 int bufsize = 2 * st.st_size;
3546 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
3547 int temp;
3548
3549 /* First read the whole file, performing code conversion into
3550 CONVERSION_BUFFER. */
3551
3552 if (lseek (fd, XINT (beg), 0) < 0)
3553 {
3554 free (conversion_buffer);
3555 report_file_error ("Setting file position",
3556 Fcons (orig_filename, Qnil));
3557 }
3558
3559 total = st.st_size; /* Total bytes in the file. */
3560 how_much = 0; /* Bytes read from file so far. */
3561 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3562 unprocessed = 0; /* Bytes not processed in previous loop. */
3563
3564 while (how_much < total)
3565 {
3566 /* try is reserved in some compilers (Microsoft C) */
3567 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
3568 char *destination = read_buf + unprocessed;
3569 int this;
3570
3571 /* Allow quitting out of the actual I/O. */
3572 immediate_quit = 1;
3573 QUIT;
3574 this = read (fd, destination, trytry);
3575 immediate_quit = 0;
3576
3577 if (this < 0 || this + unprocessed == 0)
3578 {
3579 how_much = this;
3580 break;
3581 }
3582
3583 how_much += this;
3584
3585 if (CODING_MAY_REQUIRE_DECODING (&coding))
3586 {
3587 int require, result;
3588
3589 this += unprocessed;
3590
3591 /* If we are using more space than estimated,
3592 make CONVERSION_BUFFER bigger. */
3593 require = decoding_buffer_size (&coding, this);
3594 if (inserted + require + 2 * (total - how_much) > bufsize)
3595 {
3596 bufsize = inserted + require + 2 * (total - how_much);
3597 conversion_buffer = (unsigned char *) xrealloc (conversion_buffer, bufsize);
3598 }
3599
3600 /* Convert this batch with results in CONVERSION_BUFFER. */
3601 if (how_much >= total) /* This is the last block. */
3602 coding.mode |= CODING_MODE_LAST_BLOCK;
3603 result = decode_coding (&coding, read_buf,
3604 conversion_buffer + inserted,
3605 this, bufsize - inserted);
3606
3607 /* Save for next iteration whatever we didn't convert. */
3608 unprocessed = this - coding.consumed;
3609 bcopy (read_buf + coding.consumed, read_buf, unprocessed);
3610 this = coding.produced;
3611 }
3612
3613 inserted += this;
3614 }
3615
3616 /* At this point, INSERTED is how many characters (i.e. bytes)
3617 are present in CONVERSION_BUFFER.
3618 HOW_MUCH should equal TOTAL,
3619 or should be <= 0 if we couldn't read the file. */
3620
3621 if (how_much < 0)
3622 {
3623 free (conversion_buffer);
3624
3625 if (how_much == -1)
3626 error ("IO error reading %s: %s",
3627 XSTRING (orig_filename)->data, strerror (errno));
3628 else if (how_much == -2)
3629 error ("maximum buffer size exceeded");
3630 }
3631
3632 /* Compare the beginning of the converted file
3633 with the buffer text. */
3634
3635 bufpos = 0;
3636 while (bufpos < inserted && same_at_start < same_at_end
3637 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
3638 same_at_start++, bufpos++;
3639
3640 /* If the file matches the buffer completely,
3641 there's no need to replace anything. */
3642
3643 if (bufpos == inserted)
3644 {
3645 free (conversion_buffer);
3646 close (fd);
3647 specpdl_ptr--;
3648 /* Truncate the buffer to the size of the file. */
3649 del_range_1 (same_at_start, same_at_end, 0);
3650 goto handled;
3651 }
3652
3653 /* Scan this bufferful from the end, comparing with
3654 the Emacs buffer. */
3655 bufpos = inserted;
3656
3657 /* Compare with same_at_start to avoid counting some buffer text
3658 as matching both at the file's beginning and at the end. */
3659 while (bufpos > 0 && same_at_end > same_at_start
3660 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
3661 same_at_end--, bufpos--;
3662
3663 /* Don't try to reuse the same piece of text twice. */
3664 overlap = same_at_start - BEGV_BYTE - (same_at_end + inserted - ZV_BYTE);
3665 if (overlap > 0)
3666 same_at_end += overlap;
3667
3668 /* If display currently starts at beginning of line,
3669 keep it that way. */
3670 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3671 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3672
3673 /* Replace the chars that we need to replace,
3674 and update INSERTED to equal the number of bytes
3675 we are taking from the file. */
3676 inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
3677 del_range_byte (same_at_start, same_at_end, 0);
3678 SET_PT_BOTH (GPT, GPT_BYTE);
3679
3680 insert_1 (conversion_buffer + same_at_start - BEG_BYTE, inserted,
3681 0, 0, 0);
3682
3683 free (conversion_buffer);
3684 close (fd);
3685 specpdl_ptr--;
3686
3687 goto handled;
3688 }
3689
3690 if (! not_regular)
3691 {
3692 register Lisp_Object temp;
3693
3694 total = XINT (end) - XINT (beg);
3695
3696 /* Make sure point-max won't overflow after this insertion. */
3697 XSETINT (temp, total);
3698 if (total != XINT (temp))
3699 error ("Maximum buffer size exceeded");
3700 }
3701 else
3702 /* For a special file, all we can do is guess. */
3703 total = READ_BUF_SIZE;
3704
3705 if (NILP (visit) && total > 0)
3706 prepare_to_modify_buffer (PT, PT, NULL);
3707
3708 move_gap (PT);
3709 if (GAP_SIZE < total)
3710 make_gap (total - GAP_SIZE);
3711
3712 if (XINT (beg) != 0 || !NILP (replace))
3713 {
3714 if (lseek (fd, XINT (beg), 0) < 0)
3715 report_file_error ("Setting file position",
3716 Fcons (orig_filename, Qnil));
3717 }
3718
3719 /* In the following loop, HOW_MUCH contains the total bytes read so
3720 far for a regular file, and not changed for a special file. But,
3721 before exiting the loop, it is set to a negative value if I/O
3722 error occurs. */
3723 how_much = 0;
3724 /* Total bytes inserted. */
3725 inserted = 0;
3726 /* Here, we don't do code conversion in the loop. It is done by
3727 code_convert_region after all data are read into the buffer. */
3728 while (how_much < total)
3729 {
3730 /* try is reserved in some compilers (Microsoft C) */
3731 int trytry = min (total - how_much, READ_BUF_SIZE);
3732 int this;
3733
3734 /* For a special file, GAP_SIZE should be checked every time. */
3735 if (not_regular && GAP_SIZE < trytry)
3736 make_gap (total - GAP_SIZE);
3737
3738 /* Allow quitting out of the actual I/O. */
3739 immediate_quit = 1;
3740 QUIT;
3741 this = read (fd, BYTE_POS_ADDR (PT_BYTE + inserted - 1) + 1, trytry);
3742 immediate_quit = 0;
3743
3744 if (this <= 0)
3745 {
3746 how_much = this;
3747 break;
3748 }
3749
3750 GAP_SIZE -= this;
3751 GPT_BYTE += this;
3752 ZV_BYTE += this;
3753 Z_BYTE += this;
3754 GPT += this;
3755 ZV += this;
3756 Z += this;
3757
3758 /* For a regular file, where TOTAL is the real size,
3759 count HOW_MUCH to compare with it.
3760 For a special file, where TOTAL is just a buffer size,
3761 so don't bother counting in HOW_MUCH.
3762 (INSERTED is where we count the number of characters inserted.) */
3763 if (! not_regular)
3764 how_much += this;
3765 inserted += this;
3766 }
3767
3768 if (GAP_SIZE > 0)
3769 /* Put an anchor to ensure multi-byte form ends at gap. */
3770 *GPT_ADDR = 0;
3771
3772 close (fd);
3773
3774 /* Discard the unwind protect for closing the file. */
3775 specpdl_ptr--;
3776
3777 if (how_much < 0)
3778 error ("IO error reading %s: %s",
3779 XSTRING (orig_filename)->data, strerror (errno));
3780
3781 if (inserted > 0)
3782 {
3783 if (CODING_MAY_REQUIRE_DECODING (&coding))
3784 {
3785 /* Here, we don't have to consider byte combining (see the
3786 comment below) because code_convert_region takes care of
3787 it. */
3788 code_convert_region (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
3789 &coding, 0, 0);
3790 inserted = (NILP (current_buffer->enable_multibyte_characters)
3791 ? coding.produced : coding.produced_char);
3792 }
3793 else if (!NILP (current_buffer->enable_multibyte_characters))
3794 {
3795 int inserted_byte = inserted;
3796
3797 /* There's a possibility that we must combine bytes at the
3798 head (resp. the tail) of the just inserted text with the
3799 bytes before (resp. after) the gap to form a single
3800 character. */
3801 inserted = multibyte_chars_in_text (GPT_ADDR - inserted, inserted);
3802 adjust_after_insert (PT, PT_BYTE,
3803 PT + inserted_byte, PT_BYTE + inserted_byte,
3804 inserted);
3805 }
3806 else
3807 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
3808 inserted);
3809
3810 #ifdef DOS_NT
3811 /* Use the conversion type to determine buffer-file-type
3812 (find-buffer-file-type is now used to help determine the
3813 conversion). */
3814 if (coding.eol_type != CODING_EOL_UNDECIDED
3815 && coding.eol_type != CODING_EOL_LF)
3816 current_buffer->buffer_file_type = Qnil;
3817 else
3818 current_buffer->buffer_file_type = Qt;
3819 #endif
3820 }
3821
3822 set_coding_system = 1;
3823
3824 notfound:
3825 handled:
3826
3827 if (!NILP (visit))
3828 {
3829 if (!EQ (current_buffer->undo_list, Qt))
3830 current_buffer->undo_list = Qnil;
3831 #ifdef APOLLO
3832 stat (XSTRING (filename)->data, &st);
3833 #endif
3834
3835 if (NILP (handler))
3836 {
3837 current_buffer->modtime = st.st_mtime;
3838 current_buffer->filename = orig_filename;
3839 }
3840
3841 SAVE_MODIFF = MODIFF;
3842 current_buffer->auto_save_modified = MODIFF;
3843 XSETFASTINT (current_buffer->save_length, Z - BEG);
3844 #ifdef CLASH_DETECTION
3845 if (NILP (handler))
3846 {
3847 if (!NILP (current_buffer->file_truename))
3848 unlock_file (current_buffer->file_truename);
3849 unlock_file (filename);
3850 }
3851 #endif /* CLASH_DETECTION */
3852 if (not_regular)
3853 Fsignal (Qfile_error,
3854 Fcons (build_string ("not a regular file"),
3855 Fcons (orig_filename, Qnil)));
3856
3857 /* If visiting nonexistent file, return nil. */
3858 if (current_buffer->modtime == -1)
3859 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3860 }
3861
3862 /* Decode file format */
3863 if (inserted > 0)
3864 {
3865 insval = call3 (Qformat_decode,
3866 Qnil, make_number (inserted), visit);
3867 CHECK_NUMBER (insval, 0);
3868 inserted = XFASTINT (insval);
3869 }
3870
3871 /* Call after-change hooks for the inserted text, aside from the case
3872 of normal visiting (not with REPLACE), which is done in a new buffer
3873 "before" the buffer is changed. */
3874 if (inserted > 0 && total > 0
3875 && (NILP (visit) || !NILP (replace)))
3876 signal_after_change (PT, 0, inserted);
3877
3878 if (set_coding_system)
3879 Vlast_coding_system_used = coding.symbol;
3880
3881 if (inserted > 0)
3882 {
3883 p = Vafter_insert_file_functions;
3884 while (!NILP (p))
3885 {
3886 insval = call1 (Fcar (p), make_number (inserted));
3887 if (!NILP (insval))
3888 {
3889 CHECK_NUMBER (insval, 0);
3890 inserted = XFASTINT (insval);
3891 }
3892 QUIT;
3893 p = Fcdr (p);
3894 }
3895 }
3896
3897 /* ??? Retval needs to be dealt with in all cases consistently. */
3898 if (NILP (val))
3899 val = Fcons (orig_filename,
3900 Fcons (make_number (inserted),
3901 Qnil));
3902
3903 RETURN_UNGCPRO (unbind_to (count, val));
3904 }
3905 \f
3906 static Lisp_Object build_annotations P_ ((Lisp_Object, Lisp_Object,
3907 Lisp_Object));
3908
3909 /* If build_annotations switched buffers, switch back to BUF.
3910 Kill the temporary buffer that was selected in the meantime.
3911
3912 Since this kill only the last temporary buffer, some buffers remain
3913 not killed if build_annotations switched buffers more than once.
3914 -- K.Handa */
3915
3916 static Lisp_Object
3917 build_annotations_unwind (buf)
3918 Lisp_Object buf;
3919 {
3920 Lisp_Object tembuf;
3921
3922 if (XBUFFER (buf) == current_buffer)
3923 return Qnil;
3924 tembuf = Fcurrent_buffer ();
3925 Fset_buffer (buf);
3926 Fkill_buffer (tembuf);
3927 return Qnil;
3928 }
3929
3930 DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
3931 "r\nFWrite region to file: \ni\ni\ni\np",
3932 "Write current region into specified file.\n\
3933 When called from a program, takes three arguments:\n\
3934 START, END and FILENAME. START and END are buffer positions.\n\
3935 Optional fourth argument APPEND if non-nil means\n\
3936 append to existing file contents (if any).\n\
3937 Optional fifth argument VISIT if t means\n\
3938 set the last-save-file-modtime of buffer to this file's modtime\n\
3939 and mark buffer not modified.\n\
3940 If VISIT is a string, it is a second file name;\n\
3941 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3942 VISIT is also the file name to lock and unlock for clash detection.\n\
3943 If VISIT is neither t nor nil nor a string,\n\
3944 that means do not print the \"Wrote file\" message.\n\
3945 The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3946 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3947 The optional seventh arg CONFIRM, if non-nil, says ask for confirmation\n\
3948 before overwriting an existing file.\n\
3949 Kludgy feature: if START is a string, then that string is written\n\
3950 to the file, instead of any buffer contents, and END is ignored.")
3951 (start, end, filename, append, visit, lockname, confirm)
3952 Lisp_Object start, end, filename, append, visit, lockname, confirm;
3953 {
3954 register int desc;
3955 int failure;
3956 int save_errno;
3957 unsigned char *fn;
3958 struct stat st;
3959 int tem;
3960 int count = specpdl_ptr - specpdl;
3961 int count1;
3962 #ifdef VMS
3963 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
3964 #endif /* VMS */
3965 Lisp_Object handler;
3966 Lisp_Object visit_file;
3967 Lisp_Object annotations;
3968 Lisp_Object encoded_filename;
3969 int visiting, quietly;
3970 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3971 struct buffer *given_buffer;
3972 #ifdef DOS_NT
3973 int buffer_file_type = O_BINARY;
3974 #endif /* DOS_NT */
3975 struct coding_system coding;
3976
3977 if (current_buffer->base_buffer && ! NILP (visit))
3978 error ("Cannot do file visiting in an indirect buffer");
3979
3980 if (!NILP (start) && !STRINGP (start))
3981 validate_region (&start, &end);
3982
3983 GCPRO4 (start, filename, visit, lockname);
3984
3985 /* Decide the coding-system to encode the data with. */
3986 {
3987 Lisp_Object val;
3988
3989 if (auto_saving)
3990 val = Qnil;
3991 else if (!NILP (Vcoding_system_for_write))
3992 val = Vcoding_system_for_write;
3993 else if (NILP (current_buffer->enable_multibyte_characters))
3994 {
3995 /* If the variable `buffer-file-coding-system' is set locally,
3996 it means that the file was read with some kind of code
3997 conversion or the varialbe is explicitely set by users. We
3998 had better write it out with the same coding system even if
3999 `enable-multibyte-characters' is nil.
4000
4001 If it is not set locally, we anyway have to convert EOL
4002 format if the default value of `buffer-file-coding-system'
4003 tells that it is not Unix-like (LF only) format. */
4004 val = current_buffer->buffer_file_coding_system;
4005 if (NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4006 {
4007 struct coding_system coding_temp;
4008
4009 setup_coding_system (Fcheck_coding_system (val), &coding_temp);
4010 if (coding_temp.eol_type == CODING_EOL_CRLF
4011 || coding_temp.eol_type == CODING_EOL_CR)
4012 {
4013 setup_coding_system (Qraw_text, &coding);
4014 coding.eol_type = coding_temp.eol_type;
4015 goto done_setup_coding;
4016 }
4017 val = Qnil;
4018 }
4019 }
4020 else
4021 {
4022 Lisp_Object args[7], coding_systems;
4023
4024 args[0] = Qwrite_region; args[1] = start; args[2] = end;
4025 args[3] = filename; args[4] = append; args[5] = visit;
4026 args[6] = lockname;
4027 coding_systems = Ffind_operation_coding_system (7, args);
4028 val = (CONSP (coding_systems) && !NILP (XCONS (coding_systems)->cdr)
4029 ? XCONS (coding_systems)->cdr
4030 : current_buffer->buffer_file_coding_system);
4031 /* Confirm that VAL can surely encode the current region. */
4032 if (Ffboundp (Vselect_safe_coding_system_function))
4033 val = call3 (Vselect_safe_coding_system_function, start, end, val);
4034 }
4035 setup_coding_system (Fcheck_coding_system (val), &coding);
4036
4037 done_setup_coding:
4038 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
4039 coding.mode |= CODING_MODE_SELECTIVE_DISPLAY;
4040 }
4041
4042 Vlast_coding_system_used = coding.symbol;
4043
4044 filename = Fexpand_file_name (filename, Qnil);
4045
4046 if (! NILP (confirm))
4047 barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1);
4048
4049 if (STRINGP (visit))
4050 visit_file = Fexpand_file_name (visit, Qnil);
4051 else
4052 visit_file = filename;
4053 UNGCPRO;
4054
4055 visiting = (EQ (visit, Qt) || STRINGP (visit));
4056 quietly = !NILP (visit);
4057
4058 annotations = Qnil;
4059
4060 if (NILP (lockname))
4061 lockname = visit_file;
4062
4063 GCPRO5 (start, filename, annotations, visit_file, lockname);
4064
4065 /* If the file name has special constructs in it,
4066 call the corresponding file handler. */
4067 handler = Ffind_file_name_handler (filename, Qwrite_region);
4068 /* If FILENAME has no handler, see if VISIT has one. */
4069 if (NILP (handler) && STRINGP (visit))
4070 handler = Ffind_file_name_handler (visit, Qwrite_region);
4071
4072 if (!NILP (handler))
4073 {
4074 Lisp_Object val;
4075 val = call6 (handler, Qwrite_region, start, end,
4076 filename, append, visit);
4077
4078 if (visiting)
4079 {
4080 SAVE_MODIFF = MODIFF;
4081 XSETFASTINT (current_buffer->save_length, Z - BEG);
4082 current_buffer->filename = visit_file;
4083 }
4084 UNGCPRO;
4085 return val;
4086 }
4087
4088 /* Special kludge to simplify auto-saving. */
4089 if (NILP (start))
4090 {
4091 XSETFASTINT (start, BEG);
4092 XSETFASTINT (end, Z);
4093 }
4094
4095 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
4096 count1 = specpdl_ptr - specpdl;
4097
4098 given_buffer = current_buffer;
4099 annotations = build_annotations (start, end, coding.pre_write_conversion);
4100 if (current_buffer != given_buffer)
4101 {
4102 XSETFASTINT (start, BEGV);
4103 XSETFASTINT (end, ZV);
4104 }
4105
4106 #ifdef CLASH_DETECTION
4107 if (!auto_saving)
4108 {
4109 #if 0 /* This causes trouble for GNUS. */
4110 /* If we've locked this file for some other buffer,
4111 query before proceeding. */
4112 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
4113 call2 (intern ("ask-user-about-lock"), filename, Vuser_login_name);
4114 #endif
4115
4116 lock_file (lockname);
4117 }
4118 #endif /* CLASH_DETECTION */
4119
4120 encoded_filename = ENCODE_FILE (filename);
4121
4122 fn = XSTRING (encoded_filename)->data;
4123 desc = -1;
4124 if (!NILP (append))
4125 #ifdef DOS_NT
4126 desc = open (fn, O_WRONLY | buffer_file_type);
4127 #else /* not DOS_NT */
4128 desc = open (fn, O_WRONLY);
4129 #endif /* not DOS_NT */
4130
4131 if (desc < 0 && (NILP (append) || errno == ENOENT))
4132 #ifdef VMS
4133 if (auto_saving) /* Overwrite any previous version of autosave file */
4134 {
4135 vms_truncate (fn); /* if fn exists, truncate to zero length */
4136 desc = open (fn, O_RDWR);
4137 if (desc < 0)
4138 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
4139 ? XSTRING (current_buffer->filename)->data : 0,
4140 fn);
4141 }
4142 else /* Write to temporary name and rename if no errors */
4143 {
4144 Lisp_Object temp_name;
4145 temp_name = Ffile_name_directory (filename);
4146
4147 if (!NILP (temp_name))
4148 {
4149 temp_name = Fmake_temp_name (concat2 (temp_name,
4150 build_string ("$$SAVE$$")));
4151 fname = XSTRING (filename)->data;
4152 fn = XSTRING (temp_name)->data;
4153 desc = creat_copy_attrs (fname, fn);
4154 if (desc < 0)
4155 {
4156 /* If we can't open the temporary file, try creating a new
4157 version of the original file. VMS "creat" creates a
4158 new version rather than truncating an existing file. */
4159 fn = fname;
4160 fname = 0;
4161 desc = creat (fn, 0666);
4162 #if 0 /* This can clobber an existing file and fail to replace it,
4163 if the user runs out of space. */
4164 if (desc < 0)
4165 {
4166 /* We can't make a new version;
4167 try to truncate and rewrite existing version if any. */
4168 vms_truncate (fn);
4169 desc = open (fn, O_RDWR);
4170 }
4171 #endif
4172 }
4173 }
4174 else
4175 desc = creat (fn, 0666);
4176 }
4177 #else /* not VMS */
4178 #ifdef DOS_NT
4179 desc = open (fn,
4180 O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type,
4181 S_IREAD | S_IWRITE);
4182 #else /* not DOS_NT */
4183 desc = creat (fn, auto_saving ? auto_save_mode_bits : 0666);
4184 #endif /* not DOS_NT */
4185 #endif /* not VMS */
4186
4187 UNGCPRO;
4188
4189 if (desc < 0)
4190 {
4191 #ifdef CLASH_DETECTION
4192 save_errno = errno;
4193 if (!auto_saving) unlock_file (lockname);
4194 errno = save_errno;
4195 #endif /* CLASH_DETECTION */
4196 report_file_error ("Opening output file", Fcons (filename, Qnil));
4197 }
4198
4199 record_unwind_protect (close_file_unwind, make_number (desc));
4200
4201 if (!NILP (append))
4202 if (lseek (desc, 0, 2) < 0)
4203 {
4204 #ifdef CLASH_DETECTION
4205 if (!auto_saving) unlock_file (lockname);
4206 #endif /* CLASH_DETECTION */
4207 report_file_error ("Lseek error", Fcons (filename, Qnil));
4208 }
4209
4210 #ifdef VMS
4211 /*
4212 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4213 * if we do writes that don't end with a carriage return. Furthermore
4214 * it cannot handle writes of more then 16K. The modified
4215 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4216 * this EXCEPT for the last record (iff it doesn't end with a carriage
4217 * return). This implies that if your buffer doesn't end with a carriage
4218 * return, you get one free... tough. However it also means that if
4219 * we make two calls to sys_write (a la the following code) you can
4220 * get one at the gap as well. The easiest way to fix this (honest)
4221 * is to move the gap to the next newline (or the end of the buffer).
4222 * Thus this change.
4223 *
4224 * Yech!
4225 */
4226 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4227 move_gap (find_next_newline (GPT, 1));
4228 #else
4229 /* Whether VMS or not, we must move the gap to the next of newline
4230 when we must put designation sequences at beginning of line. */
4231 if (INTEGERP (start)
4232 && coding.type == coding_type_iso2022
4233 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4234 && GPT > BEG && GPT_ADDR[-1] != '\n')
4235 {
4236 int opoint = PT, opoint_byte = PT_BYTE;
4237 scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, 0);
4238 move_gap_both (PT, PT_BYTE);
4239 SET_PT_BOTH (opoint, opoint_byte);
4240 }
4241 #endif
4242
4243 failure = 0;
4244 immediate_quit = 1;
4245
4246 if (STRINGP (start))
4247 {
4248 failure = 0 > a_write (desc, XSTRING (start)->data,
4249 STRING_BYTES (XSTRING (start)), 0, &annotations,
4250 &coding);
4251 save_errno = errno;
4252 }
4253 else if (XINT (start) != XINT (end))
4254 {
4255 register int end1 = CHAR_TO_BYTE (XINT (end));
4256
4257 tem = CHAR_TO_BYTE (XINT (start));
4258
4259 if (XINT (start) < GPT)
4260 {
4261 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem),
4262 min (GPT_BYTE, end1) - tem, tem, &annotations,
4263 &coding);
4264 save_errno = errno;
4265 }
4266
4267 if (XINT (end) > GPT && !failure)
4268 {
4269 tem = max (tem, GPT_BYTE);
4270 failure = 0 > a_write (desc, BYTE_POS_ADDR (tem), end1 - tem,
4271 tem, &annotations, &coding);
4272 save_errno = errno;
4273 }
4274 }
4275 else
4276 {
4277 /* If file was empty, still need to write the annotations */
4278 coding.mode |= CODING_MODE_LAST_BLOCK;
4279 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding);
4280 save_errno = errno;
4281 }
4282
4283 if (CODING_REQUIRE_FLUSHING (&coding)
4284 && !(coding.mode & CODING_MODE_LAST_BLOCK)
4285 && ! failure)
4286 {
4287 /* We have to flush out a data. */
4288 coding.mode |= CODING_MODE_LAST_BLOCK;
4289 failure = 0 > e_write (desc, "", 0, &coding);
4290 save_errno = errno;
4291 }
4292
4293 immediate_quit = 0;
4294
4295 #ifdef HAVE_FSYNC
4296 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4297 Disk full in NFS may be reported here. */
4298 /* mib says that closing the file will try to write as fast as NFS can do
4299 it, and that means the fsync here is not crucial for autosave files. */
4300 if (!auto_saving && fsync (desc) < 0)
4301 {
4302 /* If fsync fails with EINTR, don't treat that as serious. */
4303 if (errno != EINTR)
4304 failure = 1, save_errno = errno;
4305 }
4306 #endif
4307
4308 /* Spurious "file has changed on disk" warnings have been
4309 observed on Suns as well.
4310 It seems that `close' can change the modtime, under nfs.
4311
4312 (This has supposedly been fixed in Sunos 4,
4313 but who knows about all the other machines with NFS?) */
4314 #if 0
4315
4316 /* On VMS and APOLLO, must do the stat after the close
4317 since closing changes the modtime. */
4318 #ifndef VMS
4319 #ifndef APOLLO
4320 /* Recall that #if defined does not work on VMS. */
4321 #define FOO
4322 fstat (desc, &st);
4323 #endif
4324 #endif
4325 #endif
4326
4327 /* NFS can report a write failure now. */
4328 if (close (desc) < 0)
4329 failure = 1, save_errno = errno;
4330
4331 #ifdef VMS
4332 /* If we wrote to a temporary name and had no errors, rename to real name. */
4333 if (fname)
4334 {
4335 if (!failure)
4336 failure = (rename (fn, fname) != 0), save_errno = errno;
4337 fn = fname;
4338 }
4339 #endif /* VMS */
4340
4341 #ifndef FOO
4342 stat (fn, &st);
4343 #endif
4344 /* Discard the unwind protect for close_file_unwind. */
4345 specpdl_ptr = specpdl + count1;
4346 /* Restore the original current buffer. */
4347 visit_file = unbind_to (count, visit_file);
4348
4349 #ifdef CLASH_DETECTION
4350 if (!auto_saving)
4351 unlock_file (lockname);
4352 #endif /* CLASH_DETECTION */
4353
4354 /* Do this before reporting IO error
4355 to avoid a "file has changed on disk" warning on
4356 next attempt to save. */
4357 if (visiting)
4358 current_buffer->modtime = st.st_mtime;
4359
4360 if (failure)
4361 error ("IO error writing %s: %s", XSTRING (filename)->data,
4362 strerror (save_errno));
4363
4364 if (visiting)
4365 {
4366 SAVE_MODIFF = MODIFF;
4367 XSETFASTINT (current_buffer->save_length, Z - BEG);
4368 current_buffer->filename = visit_file;
4369 update_mode_lines++;
4370 }
4371 else if (quietly)
4372 return Qnil;
4373
4374 if (!auto_saving)
4375 message_with_string ("Wrote %s", visit_file, 1);
4376
4377 return Qnil;
4378 }
4379 \f
4380 Lisp_Object merge ();
4381
4382 DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
4383 "Return t if (car A) is numerically less than (car B).")
4384 (a, b)
4385 Lisp_Object a, b;
4386 {
4387 return Flss (Fcar (a), Fcar (b));
4388 }
4389
4390 /* Build the complete list of annotations appropriate for writing out
4391 the text between START and END, by calling all the functions in
4392 write-region-annotate-functions and merging the lists they return.
4393 If one of these functions switches to a different buffer, we assume
4394 that buffer contains altered text. Therefore, the caller must
4395 make sure to restore the current buffer in all cases,
4396 as save-excursion would do. */
4397
4398 static Lisp_Object
4399 build_annotations (start, end, pre_write_conversion)
4400 Lisp_Object start, end, pre_write_conversion;
4401 {
4402 Lisp_Object annotations;
4403 Lisp_Object p, res;
4404 struct gcpro gcpro1, gcpro2;
4405 Lisp_Object original_buffer;
4406
4407 XSETBUFFER (original_buffer, current_buffer);
4408
4409 annotations = Qnil;
4410 p = Vwrite_region_annotate_functions;
4411 GCPRO2 (annotations, p);
4412 while (!NILP (p))
4413 {
4414 struct buffer *given_buffer = current_buffer;
4415 Vwrite_region_annotations_so_far = annotations;
4416 res = call2 (Fcar (p), start, end);
4417 /* If the function makes a different buffer current,
4418 assume that means this buffer contains altered text to be output.
4419 Reset START and END from the buffer bounds
4420 and discard all previous annotations because they should have
4421 been dealt with by this function. */
4422 if (current_buffer != given_buffer)
4423 {
4424 XSETFASTINT (start, BEGV);
4425 XSETFASTINT (end, ZV);
4426 annotations = Qnil;
4427 }
4428 Flength (res); /* Check basic validity of return value */
4429 annotations = merge (annotations, res, Qcar_less_than_car);
4430 p = Fcdr (p);
4431 }
4432
4433 /* Now do the same for annotation functions implied by the file-format */
4434 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
4435 p = Vauto_save_file_format;
4436 else
4437 p = current_buffer->file_format;
4438 while (!NILP (p))
4439 {
4440 struct buffer *given_buffer = current_buffer;
4441 Vwrite_region_annotations_so_far = annotations;
4442 res = call4 (Qformat_annotate_function, Fcar (p), start, end,
4443 original_buffer);
4444 if (current_buffer != given_buffer)
4445 {
4446 XSETFASTINT (start, BEGV);
4447 XSETFASTINT (end, ZV);
4448 annotations = Qnil;
4449 }
4450 Flength (res);
4451 annotations = merge (annotations, res, Qcar_less_than_car);
4452 p = Fcdr (p);
4453 }
4454
4455 /* At last, do the same for the function PRE_WRITE_CONVERSION
4456 implied by the current coding-system. */
4457 if (!NILP (pre_write_conversion))
4458 {
4459 struct buffer *given_buffer = current_buffer;
4460 Vwrite_region_annotations_so_far = annotations;
4461 res = call2 (pre_write_conversion, start, end);
4462 Flength (res);
4463 annotations = (current_buffer != given_buffer
4464 ? res
4465 : merge (annotations, res, Qcar_less_than_car));
4466 }
4467
4468 UNGCPRO;
4469 return annotations;
4470 }
4471 \f
4472 /* Write to descriptor DESC the NBYTES bytes starting at ADDR,
4473 assuming they start at byte position BYTEPOS in the buffer.
4474 Intersperse with them the annotations from *ANNOT
4475 which fall within the range of byte positions BYTEPOS to BYTEPOS + NBYTES,
4476 each at its appropriate position.
4477
4478 We modify *ANNOT by discarding elements as we use them up.
4479
4480 The return value is negative in case of system call failure. */
4481
4482 static int
4483 a_write (desc, addr, nbytes, bytepos, annot, coding)
4484 int desc;
4485 register char *addr;
4486 register int nbytes;
4487 int bytepos;
4488 Lisp_Object *annot;
4489 struct coding_system *coding;
4490 {
4491 Lisp_Object tem;
4492 int nextpos;
4493 int lastpos = bytepos + nbytes;
4494
4495 while (NILP (*annot) || CONSP (*annot))
4496 {
4497 tem = Fcar_safe (Fcar (*annot));
4498 nextpos = bytepos - 1;
4499 if (INTEGERP (tem))
4500 nextpos = CHAR_TO_BYTE (XFASTINT (tem));
4501
4502 /* If there are no more annotations in this range,
4503 output the rest of the range all at once. */
4504 if (! (nextpos >= bytepos && nextpos <= lastpos))
4505 return e_write (desc, addr, lastpos - bytepos, coding);
4506
4507 /* Output buffer text up to the next annotation's position. */
4508 if (nextpos > bytepos)
4509 {
4510 if (0 > e_write (desc, addr, nextpos - bytepos, coding))
4511 return -1;
4512 addr += nextpos - bytepos;
4513 bytepos = nextpos;
4514 }
4515 /* Output the annotation. */
4516 tem = Fcdr (Fcar (*annot));
4517 if (STRINGP (tem))
4518 {
4519 if (0 > e_write (desc, XSTRING (tem)->data, STRING_BYTES (XSTRING (tem)),
4520 coding))
4521 return -1;
4522 }
4523 *annot = Fcdr (*annot);
4524 }
4525 }
4526
4527 #ifndef WRITE_BUF_SIZE
4528 #define WRITE_BUF_SIZE (16 * 1024)
4529 #endif
4530
4531 /* Write NBYTES bytes starting at ADDR into descriptor DESC,
4532 encoding them with coding system CODING. */
4533
4534 static int
4535 e_write (desc, addr, nbytes, coding)
4536 int desc;
4537 register char *addr;
4538 register int nbytes;
4539 struct coding_system *coding;
4540 {
4541 char buf[WRITE_BUF_SIZE];
4542
4543 /* We used to have a code for handling selective display here. But,
4544 now it is handled within encode_coding. */
4545 while (1)
4546 {
4547 encode_coding (coding, addr, buf, nbytes, WRITE_BUF_SIZE);
4548 nbytes -= coding->consumed, addr += coding->consumed;
4549 if (coding->produced > 0)
4550 {
4551 coding->produced -= write (desc, buf, coding->produced);
4552 if (coding->produced) return -1;
4553 }
4554 if (nbytes <= 0)
4555 break;
4556 }
4557 return 0;
4558 }
4559 \f
4560 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
4561 Sverify_visited_file_modtime, 1, 1, 0,
4562 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4563 This means that the file has not been changed since it was visited or saved.")
4564 (buf)
4565 Lisp_Object buf;
4566 {
4567 struct buffer *b;
4568 struct stat st;
4569 Lisp_Object handler;
4570 Lisp_Object filename;
4571
4572 CHECK_BUFFER (buf, 0);
4573 b = XBUFFER (buf);
4574
4575 if (!STRINGP (b->filename)) return Qt;
4576 if (b->modtime == 0) return Qt;
4577
4578 /* If the file name has special constructs in it,
4579 call the corresponding file handler. */
4580 handler = Ffind_file_name_handler (b->filename,
4581 Qverify_visited_file_modtime);
4582 if (!NILP (handler))
4583 return call2 (handler, Qverify_visited_file_modtime, buf);
4584
4585 filename = ENCODE_FILE (b->filename);
4586
4587 if (stat (XSTRING (filename)->data, &st) < 0)
4588 {
4589 /* If the file doesn't exist now and didn't exist before,
4590 we say that it isn't modified, provided the error is a tame one. */
4591 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
4592 st.st_mtime = -1;
4593 else
4594 st.st_mtime = 0;
4595 }
4596 if (st.st_mtime == b->modtime
4597 /* If both are positive, accept them if they are off by one second. */
4598 || (st.st_mtime > 0 && b->modtime > 0
4599 && (st.st_mtime == b->modtime + 1
4600 || st.st_mtime == b->modtime - 1)))
4601 return Qt;
4602 return Qnil;
4603 }
4604
4605 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
4606 Sclear_visited_file_modtime, 0, 0, 0,
4607 "Clear out records of last mod time of visited file.\n\
4608 Next attempt to save will certainly not complain of a discrepancy.")
4609 ()
4610 {
4611 current_buffer->modtime = 0;
4612 return Qnil;
4613 }
4614
4615 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
4616 Svisited_file_modtime, 0, 0, 0,
4617 "Return the current buffer's recorded visited file modification time.\n\
4618 The value is a list of the form (HIGH . LOW), like the time values\n\
4619 that `file-attributes' returns.")
4620 ()
4621 {
4622 return long_to_cons ((unsigned long) current_buffer->modtime);
4623 }
4624
4625 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
4626 Sset_visited_file_modtime, 0, 1, 0,
4627 "Update buffer's recorded modification time from the visited file's time.\n\
4628 Useful if the buffer was not read from the file normally\n\
4629 or if the file itself has been changed for some known benign reason.\n\
4630 An argument specifies the modification time value to use\n\
4631 \(instead of that of the visited file), in the form of a list\n\
4632 \(HIGH . LOW) or (HIGH LOW).")
4633 (time_list)
4634 Lisp_Object time_list;
4635 {
4636 if (!NILP (time_list))
4637 current_buffer->modtime = cons_to_long (time_list);
4638 else
4639 {
4640 register Lisp_Object filename;
4641 struct stat st;
4642 Lisp_Object handler;
4643
4644 filename = Fexpand_file_name (current_buffer->filename, Qnil);
4645
4646 /* If the file name has special constructs in it,
4647 call the corresponding file handler. */
4648 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
4649 if (!NILP (handler))
4650 /* The handler can find the file name the same way we did. */
4651 return call2 (handler, Qset_visited_file_modtime, Qnil);
4652
4653 filename = ENCODE_FILE (filename);
4654
4655 if (stat (XSTRING (filename)->data, &st) >= 0)
4656 current_buffer->modtime = st.st_mtime;
4657 }
4658
4659 return Qnil;
4660 }
4661 \f
4662 Lisp_Object
4663 auto_save_error ()
4664 {
4665 ring_bell ();
4666 message_with_string ("Autosaving...error for %s", current_buffer->name, 1);
4667 Fsleep_for (make_number (1), Qnil);
4668 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
4669 Fsleep_for (make_number (1), Qnil);
4670 message_with_string ("Autosaving...error for %s", current_buffer->name, 0);
4671 Fsleep_for (make_number (1), Qnil);
4672 return Qnil;
4673 }
4674
4675 Lisp_Object
4676 auto_save_1 ()
4677 {
4678 unsigned char *fn;
4679 struct stat st;
4680
4681 /* Get visited file's mode to become the auto save file's mode. */
4682 if (stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
4683 /* But make sure we can overwrite it later! */
4684 auto_save_mode_bits = st.st_mode | 0600;
4685 else
4686 auto_save_mode_bits = 0666;
4687
4688 return
4689 Fwrite_region (Qnil, Qnil,
4690 current_buffer->auto_save_file_name,
4691 Qnil, Qlambda, Qnil, Qnil);
4692 }
4693
4694 static Lisp_Object
4695 do_auto_save_unwind (stream) /* used as unwind-protect function */
4696 Lisp_Object stream;
4697 {
4698 auto_saving = 0;
4699 if (!NILP (stream))
4700 fclose ((FILE *) (XFASTINT (XCONS (stream)->car) << 16
4701 | XFASTINT (XCONS (stream)->cdr)));
4702 return Qnil;
4703 }
4704
4705 static Lisp_Object
4706 do_auto_save_unwind_1 (value) /* used as unwind-protect function */
4707 Lisp_Object value;
4708 {
4709 minibuffer_auto_raise = XINT (value);
4710 return Qnil;
4711 }
4712
4713 DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
4714 "Auto-save all buffers that need it.\n\
4715 This is all buffers that have auto-saving enabled\n\
4716 and are changed since last auto-saved.\n\
4717 Auto-saving writes the buffer into a file\n\
4718 so that your editing is not lost if the system crashes.\n\
4719 This file is not the file you visited; that changes only when you save.\n\
4720 Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4721 A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4722 A non-nil CURRENT-ONLY argument means save only current buffer.")
4723 (no_message, current_only)
4724 Lisp_Object no_message, current_only;
4725 {
4726 struct buffer *old = current_buffer, *b;
4727 Lisp_Object tail, buf;
4728 int auto_saved = 0;
4729 char *omessage = echo_area_glyphs;
4730 int omessage_length = echo_area_glyphs_length;
4731 int oldmultibyte = message_enable_multibyte;
4732 int do_handled_files;
4733 Lisp_Object oquit;
4734 FILE *stream;
4735 Lisp_Object lispstream;
4736 int count = specpdl_ptr - specpdl;
4737 int *ptr;
4738 int orig_minibuffer_auto_raise = minibuffer_auto_raise;
4739
4740 /* Ordinarily don't quit within this function,
4741 but don't make it impossible to quit (in case we get hung in I/O). */
4742 oquit = Vquit_flag;
4743 Vquit_flag = Qnil;
4744
4745 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4746 point to non-strings reached from Vbuffer_alist. */
4747
4748 if (minibuf_level)
4749 no_message = Qt;
4750
4751 if (!NILP (Vrun_hooks))
4752 call1 (Vrun_hooks, intern ("auto-save-hook"));
4753
4754 if (STRINGP (Vauto_save_list_file_name))
4755 {
4756 Lisp_Object listfile;
4757 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
4758 stream = fopen (XSTRING (listfile)->data, "w");
4759 if (stream != NULL)
4760 {
4761 /* Arrange to close that file whether or not we get an error.
4762 Also reset auto_saving to 0. */
4763 lispstream = Fcons (Qnil, Qnil);
4764 XSETFASTINT (XCONS (lispstream)->car, (EMACS_UINT)stream >> 16);
4765 XSETFASTINT (XCONS (lispstream)->cdr, (EMACS_UINT)stream & 0xffff);
4766 }
4767 else
4768 lispstream = Qnil;
4769 }
4770 else
4771 {
4772 stream = NULL;
4773 lispstream = Qnil;
4774 }
4775
4776 record_unwind_protect (do_auto_save_unwind, lispstream);
4777 record_unwind_protect (do_auto_save_unwind_1,
4778 make_number (minibuffer_auto_raise));
4779 minibuffer_auto_raise = 0;
4780 auto_saving = 1;
4781
4782 /* First, save all files which don't have handlers. If Emacs is
4783 crashing, the handlers may tweak what is causing Emacs to crash
4784 in the first place, and it would be a shame if Emacs failed to
4785 autosave perfectly ordinary files because it couldn't handle some
4786 ange-ftp'd file. */
4787 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
4788 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
4789 {
4790 buf = XCONS (XCONS (tail)->car)->cdr;
4791 b = XBUFFER (buf);
4792
4793 /* Record all the buffers that have auto save mode
4794 in the special file that lists them. For each of these buffers,
4795 Record visited name (if any) and auto save name. */
4796 if (STRINGP (b->auto_save_file_name)
4797 && stream != NULL && do_handled_files == 0)
4798 {
4799 if (!NILP (b->filename))
4800 {
4801 fwrite (XSTRING (b->filename)->data, 1,
4802 STRING_BYTES (XSTRING (b->filename)), stream);
4803 }
4804 putc ('\n', stream);
4805 fwrite (XSTRING (b->auto_save_file_name)->data, 1,
4806 STRING_BYTES (XSTRING (b->auto_save_file_name)), stream);
4807 putc ('\n', stream);
4808 }
4809
4810 if (!NILP (current_only)
4811 && b != current_buffer)
4812 continue;
4813
4814 /* Don't auto-save indirect buffers.
4815 The base buffer takes care of it. */
4816 if (b->base_buffer)
4817 continue;
4818
4819 /* Check for auto save enabled
4820 and file changed since last auto save
4821 and file changed since last real save. */
4822 if (STRINGP (b->auto_save_file_name)
4823 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
4824 && b->auto_save_modified < BUF_MODIFF (b)
4825 /* -1 means we've turned off autosaving for a while--see below. */
4826 && XINT (b->save_length) >= 0
4827 && (do_handled_files
4828 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
4829 Qwrite_region))))
4830 {
4831 EMACS_TIME before_time, after_time;
4832
4833 EMACS_GET_TIME (before_time);
4834
4835 /* If we had a failure, don't try again for 20 minutes. */
4836 if (b->auto_save_failure_time >= 0
4837 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
4838 continue;
4839
4840 if ((XFASTINT (b->save_length) * 10
4841 > (BUF_Z (b) - BUF_BEG (b)) * 13)
4842 /* A short file is likely to change a large fraction;
4843 spare the user annoying messages. */
4844 && XFASTINT (b->save_length) > 5000
4845 /* These messages are frequent and annoying for `*mail*'. */
4846 && !EQ (b->filename, Qnil)
4847 && NILP (no_message))
4848 {
4849 /* It has shrunk too much; turn off auto-saving here. */
4850 minibuffer_auto_raise = orig_minibuffer_auto_raise;
4851 message_with_string ("Buffer %s has shrunk a lot; auto save turned off there",
4852 b->name, 1);
4853 minibuffer_auto_raise = 0;
4854 /* Turn off auto-saving until there's a real save,
4855 and prevent any more warnings. */
4856 XSETINT (b->save_length, -1);
4857 Fsleep_for (make_number (1), Qnil);
4858 continue;
4859 }
4860 set_buffer_internal (b);
4861 if (!auto_saved && NILP (no_message))
4862 message1 ("Auto-saving...");
4863 internal_condition_case (auto_save_1, Qt, auto_save_error);
4864 auto_saved++;
4865 b->auto_save_modified = BUF_MODIFF (b);
4866 XSETFASTINT (current_buffer->save_length, Z - BEG);
4867 set_buffer_internal (old);
4868
4869 EMACS_GET_TIME (after_time);
4870
4871 /* If auto-save took more than 60 seconds,
4872 assume it was an NFS failure that got a timeout. */
4873 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
4874 b->auto_save_failure_time = EMACS_SECS (after_time);
4875 }
4876 }
4877
4878 /* Prevent another auto save till enough input events come in. */
4879 record_auto_save ();
4880
4881 if (auto_saved && NILP (no_message))
4882 {
4883 if (omessage)
4884 {
4885 sit_for (1, 0, 0, 0, 0);
4886 message2 (omessage, omessage_length, oldmultibyte);
4887 }
4888 else
4889 message1 ("Auto-saving...done");
4890 }
4891
4892 Vquit_flag = oquit;
4893
4894 unbind_to (count, Qnil);
4895 return Qnil;
4896 }
4897
4898 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
4899 Sset_buffer_auto_saved, 0, 0, 0,
4900 "Mark current buffer as auto-saved with its current text.\n\
4901 No auto-save file will be written until the buffer changes again.")
4902 ()
4903 {
4904 current_buffer->auto_save_modified = MODIFF;
4905 XSETFASTINT (current_buffer->save_length, Z - BEG);
4906 current_buffer->auto_save_failure_time = -1;
4907 return Qnil;
4908 }
4909
4910 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
4911 Sclear_buffer_auto_save_failure, 0, 0, 0,
4912 "Clear any record of a recent auto-save failure in the current buffer.")
4913 ()
4914 {
4915 current_buffer->auto_save_failure_time = -1;
4916 return Qnil;
4917 }
4918
4919 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
4920 0, 0, 0,
4921 "Return t if buffer has been auto-saved since last read in or saved.")
4922 ()
4923 {
4924 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
4925 }
4926 \f
4927 /* Reading and completing file names */
4928 extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
4929
4930 /* In the string VAL, change each $ to $$ and return the result. */
4931
4932 static Lisp_Object
4933 double_dollars (val)
4934 Lisp_Object val;
4935 {
4936 register unsigned char *old, *new;
4937 register int n;
4938 int osize, count;
4939
4940 osize = STRING_BYTES (XSTRING (val));
4941
4942 /* Count the number of $ characters. */
4943 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
4944 if (*old++ == '$') count++;
4945 if (count > 0)
4946 {
4947 old = XSTRING (val)->data;
4948 val = make_uninit_multibyte_string (XSTRING (val)->size + count,
4949 osize + count);
4950 new = XSTRING (val)->data;
4951 for (n = osize; n > 0; n--)
4952 if (*old != '$')
4953 *new++ = *old++;
4954 else
4955 {
4956 *new++ = '$';
4957 *new++ = '$';
4958 old++;
4959 }
4960 }
4961 return val;
4962 }
4963
4964 DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
4965 3, 3, 0,
4966 "Internal subroutine for read-file-name. Do not call this.")
4967 (string, dir, action)
4968 Lisp_Object string, dir, action;
4969 /* action is nil for complete, t for return list of completions,
4970 lambda for verify final value */
4971 {
4972 Lisp_Object name, specdir, realdir, val, orig_string;
4973 int changed;
4974 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4975
4976 CHECK_STRING (string, 0);
4977
4978 realdir = dir;
4979 name = string;
4980 orig_string = Qnil;
4981 specdir = Qnil;
4982 changed = 0;
4983 /* No need to protect ACTION--we only compare it with t and nil. */
4984 GCPRO5 (string, realdir, name, specdir, orig_string);
4985
4986 if (XSTRING (string)->size == 0)
4987 {
4988 if (EQ (action, Qlambda))
4989 {
4990 UNGCPRO;
4991 return Qnil;
4992 }
4993 }
4994 else
4995 {
4996 orig_string = string;
4997 string = Fsubstitute_in_file_name (string);
4998 changed = NILP (Fstring_equal (string, orig_string));
4999 name = Ffile_name_nondirectory (string);
5000 val = Ffile_name_directory (string);
5001 if (! NILP (val))
5002 realdir = Fexpand_file_name (val, realdir);
5003 }
5004
5005 if (NILP (action))
5006 {
5007 specdir = Ffile_name_directory (string);
5008 val = Ffile_name_completion (name, realdir);
5009 UNGCPRO;
5010 if (!STRINGP (val))
5011 {
5012 if (changed)
5013 return double_dollars (string);
5014 return val;
5015 }
5016
5017 if (!NILP (specdir))
5018 val = concat2 (specdir, val);
5019 #ifndef VMS
5020 return double_dollars (val);
5021 #else /* not VMS */
5022 return val;
5023 #endif /* not VMS */
5024 }
5025 UNGCPRO;
5026
5027 if (EQ (action, Qt))
5028 return Ffile_name_all_completions (name, realdir);
5029 /* Only other case actually used is ACTION = lambda */
5030 #ifdef VMS
5031 /* Supposedly this helps commands such as `cd' that read directory names,
5032 but can someone explain how it helps them? -- RMS */
5033 if (XSTRING (name)->size == 0)
5034 return Qt;
5035 #endif /* VMS */
5036 return Ffile_exists_p (string);
5037 }
5038
5039 DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
5040 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
5041 Value is not expanded---you must call `expand-file-name' yourself.\n\
5042 Default name to DEFAULT-FILENAME if user enters a null string.\n\
5043 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
5044 except that if INITIAL is specified, that combined with DIR is used.)\n\
5045 Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
5046 Non-nil and non-t means also require confirmation after completion.\n\
5047 Fifth arg INITIAL specifies text to start with.\n\
5048 DIR defaults to current buffer's directory default.")
5049 (prompt, dir, default_filename, mustmatch, initial)
5050 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
5051 {
5052 Lisp_Object val, insdef, insdef1, tem;
5053 struct gcpro gcpro1, gcpro2;
5054 register char *homedir;
5055 int replace_in_history = 0;
5056 int add_to_history = 0;
5057 int count;
5058
5059 if (NILP (dir))
5060 dir = current_buffer->directory;
5061 if (NILP (default_filename))
5062 {
5063 if (! NILP (initial))
5064 default_filename = Fexpand_file_name (initial, dir);
5065 else
5066 default_filename = current_buffer->filename;
5067 }
5068
5069 /* If dir starts with user's homedir, change that to ~. */
5070 homedir = (char *) egetenv ("HOME");
5071 #ifdef DOS_NT
5072 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
5073 CORRECT_DIR_SEPS (homedir);
5074 #endif
5075 if (homedir != 0
5076 && STRINGP (dir)
5077 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
5078 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
5079 {
5080 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
5081 STRING_BYTES (XSTRING (dir)) - strlen (homedir) + 1);
5082 XSTRING (dir)->data[0] = '~';
5083 }
5084
5085 if (insert_default_directory && STRINGP (dir))
5086 {
5087 insdef = dir;
5088 if (!NILP (initial))
5089 {
5090 Lisp_Object args[2], pos;
5091
5092 args[0] = insdef;
5093 args[1] = initial;
5094 insdef = Fconcat (2, args);
5095 pos = make_number (XSTRING (double_dollars (dir))->size);
5096 insdef1 = Fcons (double_dollars (insdef), pos);
5097 }
5098 else
5099 insdef1 = double_dollars (insdef);
5100 }
5101 else if (STRINGP (initial))
5102 {
5103 insdef = initial;
5104 insdef1 = Fcons (double_dollars (insdef), make_number (0));
5105 }
5106 else
5107 insdef = Qnil, insdef1 = Qnil;
5108
5109 #ifdef VMS
5110 count = specpdl_ptr - specpdl;
5111 specbind (intern ("completion-ignore-case"), Qt);
5112 #endif
5113
5114 GCPRO2 (insdef, default_filename);
5115 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
5116 dir, mustmatch, insdef1,
5117 Qfile_name_history, default_filename, Qnil);
5118
5119 tem = Fsymbol_value (Qfile_name_history);
5120 if (CONSP (tem) && EQ (XCONS (tem)->car, val))
5121 replace_in_history = 1;
5122
5123 /* If Fcompleting_read returned the inserted default string itself
5124 (rather than a new string with the same contents),
5125 it has to mean that the user typed RET with the minibuffer empty.
5126 In that case, we really want to return ""
5127 so that commands such as set-visited-file-name can distinguish. */
5128 if (EQ (val, default_filename))
5129 {
5130 /* In this case, Fcompleting_read has not added an element
5131 to the history. Maybe we should. */
5132 if (! replace_in_history)
5133 add_to_history = 1;
5134
5135 val = build_string ("");
5136 }
5137
5138 #ifdef VMS
5139 unbind_to (count, Qnil);
5140 #endif
5141
5142 UNGCPRO;
5143 if (NILP (val))
5144 error ("No file name specified");
5145
5146 tem = Fstring_equal (val, insdef);
5147
5148 if (!NILP (tem) && !NILP (default_filename))
5149 val = default_filename;
5150 else if (XSTRING (val)->size == 0 && NILP (insdef))
5151 {
5152 if (!NILP (default_filename))
5153 val = default_filename;
5154 else
5155 error ("No default file name");
5156 }
5157 val = Fsubstitute_in_file_name (val);
5158
5159 if (replace_in_history)
5160 /* Replace what Fcompleting_read added to the history
5161 with what we will actually return. */
5162 XCONS (Fsymbol_value (Qfile_name_history))->car = val;
5163 else if (add_to_history)
5164 {
5165 /* Add the value to the history--but not if it matches
5166 the last value already there. */
5167 tem = Fsymbol_value (Qfile_name_history);
5168 if (! CONSP (tem) || NILP (Fequal (XCONS (tem)->car, val)))
5169 Fset (Qfile_name_history,
5170 Fcons (val, tem));
5171 }
5172 return val;
5173 }
5174 \f
5175 syms_of_fileio ()
5176 {
5177 Qexpand_file_name = intern ("expand-file-name");
5178 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
5179 Qdirectory_file_name = intern ("directory-file-name");
5180 Qfile_name_directory = intern ("file-name-directory");
5181 Qfile_name_nondirectory = intern ("file-name-nondirectory");
5182 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
5183 Qfile_name_as_directory = intern ("file-name-as-directory");
5184 Qcopy_file = intern ("copy-file");
5185 Qmake_directory_internal = intern ("make-directory-internal");
5186 Qdelete_directory = intern ("delete-directory");
5187 Qdelete_file = intern ("delete-file");
5188 Qrename_file = intern ("rename-file");
5189 Qadd_name_to_file = intern ("add-name-to-file");
5190 Qmake_symbolic_link = intern ("make-symbolic-link");
5191 Qfile_exists_p = intern ("file-exists-p");
5192 Qfile_executable_p = intern ("file-executable-p");
5193 Qfile_readable_p = intern ("file-readable-p");
5194 Qfile_writable_p = intern ("file-writable-p");
5195 Qfile_symlink_p = intern ("file-symlink-p");
5196 Qaccess_file = intern ("access-file");
5197 Qfile_directory_p = intern ("file-directory-p");
5198 Qfile_regular_p = intern ("file-regular-p");
5199 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
5200 Qfile_modes = intern ("file-modes");
5201 Qset_file_modes = intern ("set-file-modes");
5202 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
5203 Qinsert_file_contents = intern ("insert-file-contents");
5204 Qwrite_region = intern ("write-region");
5205 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
5206 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
5207
5208 staticpro (&Qexpand_file_name);
5209 staticpro (&Qsubstitute_in_file_name);
5210 staticpro (&Qdirectory_file_name);
5211 staticpro (&Qfile_name_directory);
5212 staticpro (&Qfile_name_nondirectory);
5213 staticpro (&Qunhandled_file_name_directory);
5214 staticpro (&Qfile_name_as_directory);
5215 staticpro (&Qcopy_file);
5216 staticpro (&Qmake_directory_internal);
5217 staticpro (&Qdelete_directory);
5218 staticpro (&Qdelete_file);
5219 staticpro (&Qrename_file);
5220 staticpro (&Qadd_name_to_file);
5221 staticpro (&Qmake_symbolic_link);
5222 staticpro (&Qfile_exists_p);
5223 staticpro (&Qfile_executable_p);
5224 staticpro (&Qfile_readable_p);
5225 staticpro (&Qfile_writable_p);
5226 staticpro (&Qaccess_file);
5227 staticpro (&Qfile_symlink_p);
5228 staticpro (&Qfile_directory_p);
5229 staticpro (&Qfile_regular_p);
5230 staticpro (&Qfile_accessible_directory_p);
5231 staticpro (&Qfile_modes);
5232 staticpro (&Qset_file_modes);
5233 staticpro (&Qfile_newer_than_file_p);
5234 staticpro (&Qinsert_file_contents);
5235 staticpro (&Qwrite_region);
5236 staticpro (&Qverify_visited_file_modtime);
5237 staticpro (&Qset_visited_file_modtime);
5238
5239 Qfile_name_history = intern ("file-name-history");
5240 Fset (Qfile_name_history, Qnil);
5241 staticpro (&Qfile_name_history);
5242
5243 Qfile_error = intern ("file-error");
5244 staticpro (&Qfile_error);
5245 Qfile_already_exists = intern ("file-already-exists");
5246 staticpro (&Qfile_already_exists);
5247 Qfile_date_error = intern ("file-date-error");
5248 staticpro (&Qfile_date_error);
5249
5250 #ifdef DOS_NT
5251 Qfind_buffer_file_type = intern ("find-buffer-file-type");
5252 staticpro (&Qfind_buffer_file_type);
5253 #endif /* DOS_NT */
5254
5255 DEFVAR_LISP ("file-name-coding-system", &Vfile_name_coding_system,
5256 "*Coding system for encoding file names.\n\
5257 If it is nil, default-file-name-coding-system (which see) is used.");
5258 Vfile_name_coding_system = Qnil;
5259
5260 DEFVAR_LISP ("default-file-name-coding-system",
5261 &Vdefault_file_name_coding_system,
5262 "Default coding system for encoding file names.\n\
5263 This variable is used only when file-name-coding-system is nil.\n\
5264 \n\
5265 This variable is set/changed by the command set-language-environment.\n\
5266 User should not set this variable manually,\n\
5267 instead use file-name-coding-system to get a constant encoding\n\
5268 of file names regardless of the current language environment.");
5269 Vdefault_file_name_coding_system = Qnil;
5270
5271 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
5272 "*Format in which to write auto-save files.\n\
5273 Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5274 If it is t, which is the default, auto-save files are written in the\n\
5275 same format as a regular save would use.");
5276 Vauto_save_file_format = Qt;
5277
5278 Qformat_decode = intern ("format-decode");
5279 staticpro (&Qformat_decode);
5280 Qformat_annotate_function = intern ("format-annotate-function");
5281 staticpro (&Qformat_annotate_function);
5282
5283 Qcar_less_than_car = intern ("car-less-than-car");
5284 staticpro (&Qcar_less_than_car);
5285
5286 Fput (Qfile_error, Qerror_conditions,
5287 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
5288 Fput (Qfile_error, Qerror_message,
5289 build_string ("File error"));
5290
5291 Fput (Qfile_already_exists, Qerror_conditions,
5292 Fcons (Qfile_already_exists,
5293 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5294 Fput (Qfile_already_exists, Qerror_message,
5295 build_string ("File already exists"));
5296
5297 Fput (Qfile_date_error, Qerror_conditions,
5298 Fcons (Qfile_date_error,
5299 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5300 Fput (Qfile_date_error, Qerror_message,
5301 build_string ("Cannot set file date"));
5302
5303 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
5304 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5305 insert_default_directory = 1;
5306
5307 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
5308 "*Non-nil means write new files with record format `stmlf'.\n\
5309 nil means use format `var'. This variable is meaningful only on VMS.");
5310 vms_stmlf_recfm = 0;
5311
5312 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
5313 "Directory separator character for built-in functions that return file names.\n\
5314 The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5315 This variable affects the built-in functions only on Windows,\n\
5316 on other platforms, it is initialized so that Lisp code can find out\n\
5317 what the normal separator is.");
5318 XSETFASTINT (Vdirectory_sep_char, '/');
5319
5320 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
5321 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5322 If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5323 HANDLER.\n\
5324 \n\
5325 The first argument given to HANDLER is the name of the I/O primitive\n\
5326 to be handled; the remaining arguments are the arguments that were\n\
5327 passed to that primitive. For example, if you do\n\
5328 (file-exists-p FILENAME)\n\
5329 and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5330 (funcall HANDLER 'file-exists-p FILENAME)\n\
5331 The function `find-file-name-handler' checks this list for a handler\n\
5332 for its argument.");
5333 Vfile_name_handler_alist = Qnil;
5334
5335 DEFVAR_LISP ("set-auto-coding-function",
5336 &Vset_auto_coding_function,
5337 "If non-nil, a function to call to decide a coding system of file.\n\
5338 One argument is passed to this function: the string of concatination\n\
5339 or the heading 1K-byte and the tailing 3K-byte of a file to be read.\n\
5340 This function should return a coding system to decode the file contents\n\
5341 specified in the heading lines with the format:\n\
5342 -*- ... coding: CODING-SYSTEM; ... -*-\n\
5343 or local variable spec of the tailing lines with `coding:' tag.");
5344 Vset_auto_coding_function = Qnil;
5345
5346 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
5347 "A list of functions to be called at the end of `insert-file-contents'.\n\
5348 Each is passed one argument, the number of bytes inserted. It should return\n\
5349 the new byte count, and leave point the same. If `insert-file-contents' is\n\
5350 intercepted by a handler from `file-name-handler-alist', that handler is\n\
5351 responsible for calling the after-insert-file-functions if appropriate.");
5352 Vafter_insert_file_functions = Qnil;
5353
5354 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
5355 "A list of functions to be called at the start of `write-region'.\n\
5356 Each is passed two arguments, START and END as for `write-region'.\n\
5357 These are usually two numbers but not always; see the documentation\n\
5358 for `write-region'. The function should return a list of pairs\n\
5359 of the form (POSITION . STRING), consisting of strings to be effectively\n\
5360 inserted at the specified positions of the file being written (1 means to\n\
5361 insert before the first byte written). The POSITIONs must be sorted into\n\
5362 increasing order. If there are several functions in the list, the several\n\
5363 lists are merged destructively.");
5364 Vwrite_region_annotate_functions = Qnil;
5365
5366 DEFVAR_LISP ("write-region-annotations-so-far",
5367 &Vwrite_region_annotations_so_far,
5368 "When an annotation function is called, this holds the previous annotations.\n\
5369 These are the annotations made by other annotation functions\n\
5370 that were already called. See also `write-region-annotate-functions'.");
5371 Vwrite_region_annotations_so_far = Qnil;
5372
5373 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
5374 "A list of file name handlers that temporarily should not be used.\n\
5375 This applies only to the operation `inhibit-file-name-operation'.");
5376 Vinhibit_file_name_handlers = Qnil;
5377
5378 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
5379 "The operation for which `inhibit-file-name-handlers' is applicable.");
5380 Vinhibit_file_name_operation = Qnil;
5381
5382 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
5383 "File name in which we write a list of all auto save file names.\n\
5384 This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5385 shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5386 a non-nil value.");
5387 Vauto_save_list_file_name = Qnil;
5388
5389 defsubr (&Sfind_file_name_handler);
5390 defsubr (&Sfile_name_directory);
5391 defsubr (&Sfile_name_nondirectory);
5392 defsubr (&Sunhandled_file_name_directory);
5393 defsubr (&Sfile_name_as_directory);
5394 defsubr (&Sdirectory_file_name);
5395 defsubr (&Smake_temp_name);
5396 defsubr (&Sexpand_file_name);
5397 defsubr (&Ssubstitute_in_file_name);
5398 defsubr (&Scopy_file);
5399 defsubr (&Smake_directory_internal);
5400 defsubr (&Sdelete_directory);
5401 defsubr (&Sdelete_file);
5402 defsubr (&Srename_file);
5403 defsubr (&Sadd_name_to_file);
5404 #ifdef S_IFLNK
5405 defsubr (&Smake_symbolic_link);
5406 #endif /* S_IFLNK */
5407 #ifdef VMS
5408 defsubr (&Sdefine_logical_name);
5409 #endif /* VMS */
5410 #ifdef HPUX_NET
5411 defsubr (&Ssysnetunam);
5412 #endif /* HPUX_NET */
5413 defsubr (&Sfile_name_absolute_p);
5414 defsubr (&Sfile_exists_p);
5415 defsubr (&Sfile_executable_p);
5416 defsubr (&Sfile_readable_p);
5417 defsubr (&Sfile_writable_p);
5418 defsubr (&Saccess_file);
5419 defsubr (&Sfile_symlink_p);
5420 defsubr (&Sfile_directory_p);
5421 defsubr (&Sfile_accessible_directory_p);
5422 defsubr (&Sfile_regular_p);
5423 defsubr (&Sfile_modes);
5424 defsubr (&Sset_file_modes);
5425 defsubr (&Sset_default_file_modes);
5426 defsubr (&Sdefault_file_modes);
5427 defsubr (&Sfile_newer_than_file_p);
5428 defsubr (&Sinsert_file_contents);
5429 defsubr (&Swrite_region);
5430 defsubr (&Scar_less_than_car);
5431 defsubr (&Sverify_visited_file_modtime);
5432 defsubr (&Sclear_visited_file_modtime);
5433 defsubr (&Svisited_file_modtime);
5434 defsubr (&Sset_visited_file_modtime);
5435 defsubr (&Sdo_auto_save);
5436 defsubr (&Sset_buffer_auto_saved);
5437 defsubr (&Sclear_buffer_auto_save_failure);
5438 defsubr (&Srecent_auto_save_p);
5439
5440 defsubr (&Sread_file_name_internal);
5441 defsubr (&Sread_file_name);
5442
5443 #ifdef unix
5444 defsubr (&Sunix_sync);
5445 #endif
5446 }