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