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