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