Fix previous change.
[bpt/emacs.git] / src / fileio.c
... / ...
CommitLineData
1/* File IO for GNU Emacs.
2 Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, 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
73extern int errno;
74#endif
75
76extern 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 */
155int 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 */
159int auto_save_mode_bits;
160
161/* Alist of elements (REGEXP . HANDLER) for file names
162 whose I/O is done with a special handler. */
163Lisp_Object Vfile_name_handler_alist;
164
165/* Format for auto-save files */
166Lisp_Object Vauto_save_file_format;
167
168/* Lisp functions for translating file formats */
169Lisp_Object Qformat_decode, Qformat_annotate_function;
170
171/* Functions to be called to process text properties in inserted file. */
172Lisp_Object Vafter_insert_file_functions;
173
174/* Functions to be called to create text property annotations for file. */
175Lisp_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. */
179Lisp_Object Vwrite_region_annotations_so_far;
180
181/* File name in which we write a list of all our auto save files. */
182Lisp_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. */
186int insert_default_directory;
187
188/* On VMS, nonzero means write new files with record format stmlf.
189 Zero means use var format. */
190int 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 \. */
194Lisp_Object Vdirectory_sep_char;
195
196extern Lisp_Object Vuser_login_name;
197
198extern 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
207static Lisp_Object Vinhibit_file_name_handlers;
208static Lisp_Object Vinhibit_file_name_operation;
209
210Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
211
212Lisp_Object Qfile_name_history;
213
214Lisp_Object Qcar_less_than_car;
215
216report_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
234close_file_unwind (fd)
235 Lisp_Object fd;
236{
237 close (XFASTINT (fd));
238}
239
240/* Restore point, having saved it as a marker. */
241
242restore_point_unwind (location)
243 Lisp_Object location;
244{
245 SET_PT (marker_position (location));
246 Fset_marker (location, Qnil, Qnil);
247}
248\f
249Lisp_Object Qexpand_file_name;
250Lisp_Object Qsubstitute_in_file_name;
251Lisp_Object Qdirectory_file_name;
252Lisp_Object Qfile_name_directory;
253Lisp_Object Qfile_name_nondirectory;
254Lisp_Object Qunhandled_file_name_directory;
255Lisp_Object Qfile_name_as_directory;
256Lisp_Object Qcopy_file;
257Lisp_Object Qmake_directory_internal;
258Lisp_Object Qdelete_directory;
259Lisp_Object Qdelete_file;
260Lisp_Object Qrename_file;
261Lisp_Object Qadd_name_to_file;
262Lisp_Object Qmake_symbolic_link;
263Lisp_Object Qfile_exists_p;
264Lisp_Object Qfile_executable_p;
265Lisp_Object Qfile_readable_p;
266Lisp_Object Qfile_writable_p;
267Lisp_Object Qfile_symlink_p;
268Lisp_Object Qaccess_file;
269Lisp_Object Qfile_directory_p;
270Lisp_Object Qfile_regular_p;
271Lisp_Object Qfile_accessible_directory_p;
272Lisp_Object Qfile_modes;
273Lisp_Object Qset_file_modes;
274Lisp_Object Qfile_newer_than_file_p;
275Lisp_Object Qinsert_file_contents;
276Lisp_Object Qwrite_region;
277Lisp_Object Qverify_visited_file_modtime;
278Lisp_Object Qset_visited_file_modtime;
279
280DEFUN ("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\
282Otherwise, return nil.\n\
283A file name is handled if one of the regular expressions in\n\
284`file-name-handler-alist' matches it.\n\n\
285If OPERATION equals `inhibit-file-name-operation', then we ignore\n\
286any handlers that are members of `inhibit-file-name-handlers',\n\
287but we still do run any other handlers. This lets handlers\n\
288use 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
327DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
328 1, 1, 0,
329 "Return the directory component in file name FILENAME.\n\
330Return nil if FILENAME does not include a directory.\n\
331Otherwise return a directory spec.\n\
332Given a Unix syntax file name, returns a string ending in slash;\n\
333on 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
389DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, Sfile_name_nondirectory,
390 1, 1, 0,
391 "Return file name FILENAME sans its directory.\n\
392For example, in a Unix-syntax file name,\n\
393this is everything after the last slash,\n\
394or 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
425DEFUN ("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\
427A `directly usable' directory name is one that may be used without the\n\
428intervention of any file handler.\n\
429If FILENAME is a directly usable file itself, return\n\
430(file-name-directory FILENAME).\n\
431The `call-process' and `start-process' functions use this function to\n\
432get 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
448char *
449file_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
527DEFUN ("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\
530This operation exists because a directory is also a file, but its name as\n\
531a directory is different from its name as a file.\n\
532The result can be used as the value of `default-directory'\n\
533or passed as second argument to `expand-file-name'.\n\
534For a Unix-syntax file name, just appends a slash.\n\
535On 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
566directory_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
717DEFUN ("directory-file-name", Fdirectory_file_name, Sdirectory_file_name,
718 1, 1, 0,
719 "Returns the file name of the directory named DIRECTORY.\n\
720This is the name of the file that holds the data for the directory DIRECTORY.\n\
721This operation exists because a directory is also a file, but its name as\n\
722a directory is different from its name as a file.\n\
723In Unix-syntax, this function just removes the final slash.\n\
724On VMS, given a VMS-syntax directory name such as \"[X.Y]\",\n\
725it 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
755DEFUN ("make-temp-name", Fmake_temp_name, Smake_temp_name, 1, 1, 0,
756 "Generate temporary file name (string) starting with PREFIX (a string).\n\
757The Emacs process number forms part of the result,\n\
758so 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
777DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
778 "Convert filename NAME to absolute, and canonicalize it.\n\
779Second 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\
781the current buffer's value of default-directory is used.\n\
782File name components that are `.' are removed, and \n\
783so are file name components followed by `..', along with the `..' itself;\n\
784note that these simplifications are done without checking the resulting\n\
785file names in the file system.\n\
786An initial `~/' expands to your home directory.\n\
787An initial `~USER/' expands to USER's home directory.\n\
788See 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 (length > 0 && 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 /* Keep initial / only if this is the whole name. */
1383 if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1384 ++o;
1385 p += 3;
1386 }
1387 else
1388 {
1389 *o++ = *p++;
1390 }
1391#endif /* not VMS */
1392 }
1393
1394#ifdef DOS_NT
1395 /* At last, set drive name. */
1396#ifdef WINDOWSNT
1397 /* Except for network file name. */
1398 if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
1399#endif /* WINDOWSNT */
1400 {
1401 if (!drive) abort ();
1402 target -= 2;
1403 target[0] = DRIVE_LETTER (drive);
1404 target[1] = ':';
1405 }
1406 CORRECT_DIR_SEPS (target);
1407#endif /* DOS_NT */
1408
1409 return make_string (target, o - target);
1410}
1411
1412#if 0
1413/* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1414DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1415 "Convert FILENAME to absolute, and canonicalize it.\n\
1416Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1417 (does not start with slash); if DEFAULT is nil or missing,\n\
1418the current buffer's value of default-directory is used.\n\
1419Filenames containing `.' or `..' as components are simplified;\n\
1420initial `~/' expands to your home directory.\n\
1421See also the function `substitute-in-file-name'.")
1422 (name, defalt)
1423 Lisp_Object name, defalt;
1424{
1425 unsigned char *nm;
1426
1427 register unsigned char *newdir, *p, *o;
1428 int tlen;
1429 unsigned char *target;
1430 struct passwd *pw;
1431 int lose;
1432#ifdef VMS
1433 unsigned char * colon = 0;
1434 unsigned char * close = 0;
1435 unsigned char * slash = 0;
1436 unsigned char * brack = 0;
1437 int lbrack = 0, rbrack = 0;
1438 int dots = 0;
1439#endif /* VMS */
1440
1441 CHECK_STRING (name, 0);
1442
1443#ifdef VMS
1444 /* Filenames on VMS are always upper case. */
1445 name = Fupcase (name);
1446#endif
1447
1448 nm = XSTRING (name)->data;
1449
1450 /* If nm is absolute, flush ...// and detect /./ and /../.
1451 If no /./ or /../ we can return right away. */
1452 if (
1453 nm[0] == '/'
1454#ifdef VMS
1455 || index (nm, ':')
1456#endif /* VMS */
1457 )
1458 {
1459 p = nm;
1460 lose = 0;
1461 while (*p)
1462 {
1463 if (p[0] == '/' && p[1] == '/'
1464#ifdef APOLLO
1465 /* // at start of filename is meaningful on Apollo system */
1466 && nm != p
1467#endif /* APOLLO */
1468 )
1469 nm = p + 1;
1470 if (p[0] == '/' && p[1] == '~')
1471 nm = p + 1, lose = 1;
1472 if (p[0] == '/' && p[1] == '.'
1473 && (p[2] == '/' || p[2] == 0
1474 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1475 lose = 1;
1476#ifdef VMS
1477 if (p[0] == '\\')
1478 lose = 1;
1479 if (p[0] == '/') {
1480 /* if dev:[dir]/, move nm to / */
1481 if (!slash && p > nm && (brack || colon)) {
1482 nm = (brack ? brack + 1 : colon + 1);
1483 lbrack = rbrack = 0;
1484 brack = 0;
1485 colon = 0;
1486 }
1487 slash = p;
1488 }
1489 if (p[0] == '-')
1490#ifndef VMS4_4
1491 /* VMS pre V4.4,convert '-'s in filenames. */
1492 if (lbrack == rbrack)
1493 {
1494 if (dots < 2) /* this is to allow negative version numbers */
1495 p[0] = '_';
1496 }
1497 else
1498#endif /* VMS4_4 */
1499 if (lbrack > rbrack &&
1500 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1501 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1502 lose = 1;
1503#ifndef VMS4_4
1504 else
1505 p[0] = '_';
1506#endif /* VMS4_4 */
1507 /* count open brackets, reset close bracket pointer */
1508 if (p[0] == '[' || p[0] == '<')
1509 lbrack++, brack = 0;
1510 /* count close brackets, set close bracket pointer */
1511 if (p[0] == ']' || p[0] == '>')
1512 rbrack++, brack = p;
1513 /* detect ][ or >< */
1514 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1515 lose = 1;
1516 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1517 nm = p + 1, lose = 1;
1518 if (p[0] == ':' && (colon || slash))
1519 /* if dev1:[dir]dev2:, move nm to dev2: */
1520 if (brack)
1521 {
1522 nm = brack + 1;
1523 brack = 0;
1524 }
1525 /* If /name/dev:, move nm to dev: */
1526 else if (slash)
1527 nm = slash + 1;
1528 /* If node::dev:, move colon following dev */
1529 else if (colon && colon[-1] == ':')
1530 colon = p;
1531 /* If dev1:dev2:, move nm to dev2: */
1532 else if (colon && colon[-1] != ':')
1533 {
1534 nm = colon + 1;
1535 colon = 0;
1536 }
1537 if (p[0] == ':' && !colon)
1538 {
1539 if (p[1] == ':')
1540 p++;
1541 colon = p;
1542 }
1543 if (lbrack == rbrack)
1544 if (p[0] == ';')
1545 dots = 2;
1546 else if (p[0] == '.')
1547 dots++;
1548#endif /* VMS */
1549 p++;
1550 }
1551 if (!lose)
1552 {
1553#ifdef VMS
1554 if (index (nm, '/'))
1555 return build_string (sys_translate_unix (nm));
1556#endif /* VMS */
1557 if (nm == XSTRING (name)->data)
1558 return name;
1559 return build_string (nm);
1560 }
1561 }
1562
1563 /* Now determine directory to start with and put it in NEWDIR */
1564
1565 newdir = 0;
1566
1567 if (nm[0] == '~') /* prefix ~ */
1568 if (nm[1] == '/'
1569#ifdef VMS
1570 || nm[1] == ':'
1571#endif /* VMS */
1572 || nm[1] == 0)/* ~/filename */
1573 {
1574 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1575 newdir = (unsigned char *) "";
1576 nm++;
1577#ifdef VMS
1578 nm++; /* Don't leave the slash in nm. */
1579#endif /* VMS */
1580 }
1581 else /* ~user/filename */
1582 {
1583 /* Get past ~ to user */
1584 unsigned char *user = nm + 1;
1585 /* Find end of name. */
1586 unsigned char *ptr = (unsigned char *) index (user, '/');
1587 int len = ptr ? ptr - user : strlen (user);
1588#ifdef VMS
1589 unsigned char *ptr1 = index (user, ':');
1590 if (ptr1 != 0 && ptr1 - user < len)
1591 len = ptr1 - user;
1592#endif /* VMS */
1593 /* Copy the user name into temp storage. */
1594 o = (unsigned char *) alloca (len + 1);
1595 bcopy ((char *) user, o, len);
1596 o[len] = 0;
1597
1598 /* Look up the user name. */
1599 pw = (struct passwd *) getpwnam (o + 1);
1600 if (!pw)
1601 error ("\"%s\" isn't a registered user", o + 1);
1602
1603 newdir = (unsigned char *) pw->pw_dir;
1604
1605 /* Discard the user name from NM. */
1606 nm += len;
1607 }
1608
1609 if (nm[0] != '/'
1610#ifdef VMS
1611 && !index (nm, ':')
1612#endif /* not VMS */
1613 && !newdir)
1614 {
1615 if (NILP (defalt))
1616 defalt = current_buffer->directory;
1617 CHECK_STRING (defalt, 1);
1618 newdir = XSTRING (defalt)->data;
1619 }
1620
1621 /* Now concatenate the directory and name to new space in the stack frame */
1622
1623 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1624 target = (unsigned char *) alloca (tlen);
1625 *target = 0;
1626
1627 if (newdir)
1628 {
1629#ifndef VMS
1630 if (nm[0] == 0 || nm[0] == '/')
1631 strcpy (target, newdir);
1632 else
1633#endif
1634 file_name_as_directory (target, newdir);
1635 }
1636
1637 strcat (target, nm);
1638#ifdef VMS
1639 if (index (target, '/'))
1640 strcpy (target, sys_translate_unix (target));
1641#endif /* VMS */
1642
1643 /* Now canonicalize by removing /. and /foo/.. if they appear */
1644
1645 p = target;
1646 o = target;
1647
1648 while (*p)
1649 {
1650#ifdef VMS
1651 if (*p != ']' && *p != '>' && *p != '-')
1652 {
1653 if (*p == '\\')
1654 p++;
1655 *o++ = *p++;
1656 }
1657 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1658 /* brackets are offset from each other by 2 */
1659 {
1660 p += 2;
1661 if (*p != '.' && *p != '-' && o[-1] != '.')
1662 /* convert [foo][bar] to [bar] */
1663 while (o[-1] != '[' && o[-1] != '<')
1664 o--;
1665 else if (*p == '-' && *o != '.')
1666 *--p = '.';
1667 }
1668 else if (p[0] == '-' && o[-1] == '.' &&
1669 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1670 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1671 {
1672 do
1673 o--;
1674 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1675 if (p[1] == '.') /* foo.-.bar ==> bar. */
1676 p += 2;
1677 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1678 p++, o--;
1679 /* else [foo.-] ==> [-] */
1680 }
1681 else
1682 {
1683#ifndef VMS4_4
1684 if (*p == '-' &&
1685 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1686 p[1] != ']' && p[1] != '>' && p[1] != '.')
1687 *p = '_';
1688#endif /* VMS4_4 */
1689 *o++ = *p++;
1690 }
1691#else /* not VMS */
1692 if (*p != '/')
1693 {
1694 *o++ = *p++;
1695 }
1696 else if (!strncmp (p, "//", 2)
1697#ifdef APOLLO
1698 /* // at start of filename is meaningful in Apollo system */
1699 && o != target
1700#endif /* APOLLO */
1701 )
1702 {
1703 o = target;
1704 p++;
1705 }
1706 else if (p[0] == '/' && p[1] == '.' &&
1707 (p[2] == '/' || p[2] == 0))
1708 p += 2;
1709 else if (!strncmp (p, "/..", 3)
1710 /* `/../' is the "superroot" on certain file systems. */
1711 && o != target
1712 && (p[3] == '/' || p[3] == 0))
1713 {
1714 while (o != target && *--o != '/')
1715 ;
1716#ifdef APOLLO
1717 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1718 ++o;
1719 else
1720#endif /* APOLLO */
1721 if (o == target && *o == '/')
1722 ++o;
1723 p += 3;
1724 }
1725 else
1726 {
1727 *o++ = *p++;
1728 }
1729#endif /* not VMS */
1730 }
1731
1732 return make_string (target, o - target);
1733}
1734#endif
1735\f
1736DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1737 Ssubstitute_in_file_name, 1, 1, 0,
1738 "Substitute environment variables referred to in FILENAME.\n\
1739`$FOO' where FOO is an environment variable name means to substitute\n\
1740the value of that variable. The variable name should be terminated\n\
1741with a character not a letter, digit or underscore; otherwise, enclose\n\
1742the entire variable name in braces.\n\
1743If `/~' appears, all of FILENAME through that `/' is discarded.\n\n\
1744On VMS, `$' substitution is not done; this function does little and only\n\
1745duplicates what `expand-file-name' does.")
1746 (filename)
1747 Lisp_Object filename;
1748{
1749 unsigned char *nm;
1750
1751 register unsigned char *s, *p, *o, *x, *endp;
1752 unsigned char *target;
1753 int total = 0;
1754 int substituted = 0;
1755 unsigned char *xnm;
1756 Lisp_Object handler;
1757
1758 CHECK_STRING (filename, 0);
1759
1760 /* If the file name has special constructs in it,
1761 call the corresponding file handler. */
1762 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1763 if (!NILP (handler))
1764 return call2 (handler, Qsubstitute_in_file_name, filename);
1765
1766 nm = XSTRING (filename)->data;
1767#ifdef DOS_NT
1768 nm = strcpy (alloca (strlen (nm) + 1), nm);
1769 CORRECT_DIR_SEPS (nm);
1770 substituted = (strcmp (nm, XSTRING (filename)->data) != 0);
1771#endif
1772 endp = nm + XSTRING (filename)->size;
1773
1774 /* If /~ or // appears, discard everything through first slash. */
1775
1776 for (p = nm; p != endp; p++)
1777 {
1778 if ((p[0] == '~'
1779#if defined (APOLLO) || defined (WINDOWSNT)
1780 /* // at start of file name is meaningful in Apollo and
1781 WindowsNT systems */
1782 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1783#else /* not (APOLLO || WINDOWSNT) */
1784 || IS_DIRECTORY_SEP (p[0])
1785#endif /* not (APOLLO || WINDOWSNT) */
1786 )
1787 && p != nm
1788 && (0
1789#ifdef VMS
1790 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
1791#endif /* VMS */
1792 || IS_DIRECTORY_SEP (p[-1])))
1793 {
1794 nm = p;
1795 substituted = 1;
1796 }
1797#ifdef DOS_NT
1798 /* see comment in expand-file-name about drive specifiers */
1799 else if (IS_DRIVE (p[0]) && p[1] == ':'
1800 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1801 {
1802 nm = p;
1803 substituted = 1;
1804 }
1805#endif /* DOS_NT */
1806 }
1807
1808#ifdef VMS
1809 return build_string (nm);
1810#else
1811
1812 /* See if any variables are substituted into the string
1813 and find the total length of their values in `total' */
1814
1815 for (p = nm; p != endp;)
1816 if (*p != '$')
1817 p++;
1818 else
1819 {
1820 p++;
1821 if (p == endp)
1822 goto badsubst;
1823 else if (*p == '$')
1824 {
1825 /* "$$" means a single "$" */
1826 p++;
1827 total -= 1;
1828 substituted = 1;
1829 continue;
1830 }
1831 else if (*p == '{')
1832 {
1833 o = ++p;
1834 while (p != endp && *p != '}') p++;
1835 if (*p != '}') goto missingclose;
1836 s = p;
1837 }
1838 else
1839 {
1840 o = p;
1841 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1842 s = p;
1843 }
1844
1845 /* Copy out the variable name */
1846 target = (unsigned char *) alloca (s - o + 1);
1847 strncpy (target, o, s - o);
1848 target[s - o] = 0;
1849#ifdef DOS_NT
1850 strupr (target); /* $home == $HOME etc. */
1851#endif /* DOS_NT */
1852
1853 /* Get variable value */
1854 o = (unsigned char *) egetenv (target);
1855 if (!o) goto badvar;
1856 total += strlen (o);
1857 substituted = 1;
1858 }
1859
1860 if (!substituted)
1861 return filename;
1862
1863 /* If substitution required, recopy the string and do it */
1864 /* Make space in stack frame for the new copy */
1865 xnm = (unsigned char *) alloca (XSTRING (filename)->size + total + 1);
1866 x = xnm;
1867
1868 /* Copy the rest of the name through, replacing $ constructs with values */
1869 for (p = nm; *p;)
1870 if (*p != '$')
1871 *x++ = *p++;
1872 else
1873 {
1874 p++;
1875 if (p == endp)
1876 goto badsubst;
1877 else if (*p == '$')
1878 {
1879 *x++ = *p++;
1880 continue;
1881 }
1882 else if (*p == '{')
1883 {
1884 o = ++p;
1885 while (p != endp && *p != '}') p++;
1886 if (*p != '}') goto missingclose;
1887 s = p++;
1888 }
1889 else
1890 {
1891 o = p;
1892 while (p != endp && (isalnum (*p) || *p == '_')) p++;
1893 s = p;
1894 }
1895
1896 /* Copy out the variable name */
1897 target = (unsigned char *) alloca (s - o + 1);
1898 strncpy (target, o, s - o);
1899 target[s - o] = 0;
1900#ifdef DOS_NT
1901 strupr (target); /* $home == $HOME etc. */
1902#endif /* DOS_NT */
1903
1904 /* Get variable value */
1905 o = (unsigned char *) egetenv (target);
1906 if (!o)
1907 goto badvar;
1908
1909 strcpy (x, o);
1910 x += strlen (o);
1911 }
1912
1913 *x = 0;
1914
1915 /* If /~ or // appears, discard everything through first slash. */
1916
1917 for (p = xnm; p != x; p++)
1918 if ((p[0] == '~'
1919#if defined (APOLLO) || defined (WINDOWSNT)
1920 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1921#else /* not (APOLLO || WINDOWSNT) */
1922 || IS_DIRECTORY_SEP (p[0])
1923#endif /* not (APOLLO || WINDOWSNT) */
1924 )
1925 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
1926 xnm = p;
1927#ifdef DOS_NT
1928 else if (IS_DRIVE (p[0]) && p[1] == ':'
1929 && p > nm && IS_DIRECTORY_SEP (p[-1]))
1930 xnm = p;
1931#endif
1932
1933 return make_string (xnm, x - xnm);
1934
1935 badsubst:
1936 error ("Bad format environment-variable substitution");
1937 missingclose:
1938 error ("Missing \"}\" in environment-variable substitution");
1939 badvar:
1940 error ("Substituting nonexistent environment variable \"%s\"", target);
1941
1942 /* NOTREACHED */
1943#endif /* not VMS */
1944}
1945\f
1946/* A slightly faster and more convenient way to get
1947 (directory-file-name (expand-file-name FOO)). */
1948
1949Lisp_Object
1950expand_and_dir_to_file (filename, defdir)
1951 Lisp_Object filename, defdir;
1952{
1953 register Lisp_Object absname;
1954
1955 absname = Fexpand_file_name (filename, defdir);
1956#ifdef VMS
1957 {
1958 register int c = XSTRING (absname)->data[XSTRING (absname)->size - 1];
1959 if (c == ':' || c == ']' || c == '>')
1960 absname = Fdirectory_file_name (absname);
1961 }
1962#else
1963 /* Remove final slash, if any (unless this is the root dir).
1964 stat behaves differently depending! */
1965 if (XSTRING (absname)->size > 1
1966 && IS_DIRECTORY_SEP (XSTRING (absname)->data[XSTRING (absname)->size - 1])
1967 && !IS_DEVICE_SEP (XSTRING (absname)->data[XSTRING (absname)->size-2]))
1968 /* We cannot take shortcuts; they might be wrong for magic file names. */
1969 absname = Fdirectory_file_name (absname);
1970#endif
1971 return absname;
1972}
1973\f
1974/* Signal an error if the file ABSNAME already exists.
1975 If INTERACTIVE is nonzero, ask the user whether to proceed,
1976 and bypass the error if the user says to go ahead.
1977 QUERYSTRING is a name for the action that is being considered
1978 to alter the file.
1979 *STATPTR is used to store the stat information if the file exists.
1980 If the file does not exist, STATPTR->st_mode is set to 0. */
1981
1982void
1983barf_or_query_if_file_exists (absname, querystring, interactive, statptr)
1984 Lisp_Object absname;
1985 unsigned char *querystring;
1986 int interactive;
1987 struct stat *statptr;
1988{
1989 register Lisp_Object tem;
1990 struct stat statbuf;
1991 struct gcpro gcpro1;
1992
1993 /* stat is a good way to tell whether the file exists,
1994 regardless of what access permissions it has. */
1995 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
1996 {
1997 if (! interactive)
1998 Fsignal (Qfile_already_exists,
1999 Fcons (build_string ("File already exists"),
2000 Fcons (absname, Qnil)));
2001 GCPRO1 (absname);
2002 tem = do_yes_or_no_p (format1 ("File %s already exists; %s anyway? ",
2003 XSTRING (absname)->data, querystring));
2004 UNGCPRO;
2005 if (NILP (tem))
2006 Fsignal (Qfile_already_exists,
2007 Fcons (build_string ("File already exists"),
2008 Fcons (absname, Qnil)));
2009 if (statptr)
2010 *statptr = statbuf;
2011 }
2012 else
2013 {
2014 if (statptr)
2015 statptr->st_mode = 0;
2016 }
2017 return;
2018}
2019
2020DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,
2021 "fCopy file: \nFCopy %s to file: \np\nP",
2022 "Copy FILE to NEWNAME. Both args must be strings.\n\
2023Signals a `file-already-exists' error if file NEWNAME already exists,\n\
2024unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\
2025A number as third arg means request confirmation if NEWNAME already exists.\n\
2026This is what happens in interactive use with M-x.\n\
2027Fourth arg KEEP-TIME non-nil means give the new file the same\n\
2028last-modified time as the old one. (This works on only some systems.)\n\
2029A prefix arg makes KEEP-TIME non-nil.")
2030 (file, newname, ok_if_already_exists, keep_date)
2031 Lisp_Object file, newname, ok_if_already_exists, keep_date;
2032{
2033 int ifd, ofd, n;
2034 char buf[16 * 1024];
2035 struct stat st, out_st;
2036 Lisp_Object handler;
2037 struct gcpro gcpro1, gcpro2;
2038 int count = specpdl_ptr - specpdl;
2039 int input_file_statable_p;
2040
2041 GCPRO2 (file, newname);
2042 CHECK_STRING (file, 0);
2043 CHECK_STRING (newname, 1);
2044 file = Fexpand_file_name (file, Qnil);
2045 newname = Fexpand_file_name (newname, Qnil);
2046
2047 /* If the input file name has special constructs in it,
2048 call the corresponding file handler. */
2049 handler = Ffind_file_name_handler (file, Qcopy_file);
2050 /* Likewise for output file name. */
2051 if (NILP (handler))
2052 handler = Ffind_file_name_handler (newname, Qcopy_file);
2053 if (!NILP (handler))
2054 RETURN_UNGCPRO (call5 (handler, Qcopy_file, file, newname,
2055 ok_if_already_exists, keep_date));
2056
2057 if (NILP (ok_if_already_exists)
2058 || INTEGERP (ok_if_already_exists))
2059 barf_or_query_if_file_exists (newname, "copy to it",
2060 INTEGERP (ok_if_already_exists), &out_st);
2061 else if (stat (XSTRING (newname)->data, &out_st) < 0)
2062 out_st.st_mode = 0;
2063
2064 ifd = open (XSTRING (file)->data, O_RDONLY);
2065 if (ifd < 0)
2066 report_file_error ("Opening input file", Fcons (file, Qnil));
2067
2068 record_unwind_protect (close_file_unwind, make_number (ifd));
2069
2070 /* We can only copy regular files and symbolic links. Other files are not
2071 copyable by us. */
2072 input_file_statable_p = (fstat (ifd, &st) >= 0);
2073
2074#if !defined (MSDOS) || __DJGPP__ > 1
2075 if (out_st.st_mode != 0
2076 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2077 {
2078 errno = 0;
2079 report_file_error ("Input and output files are the same",
2080 Fcons (file, Fcons (newname, Qnil)));
2081 }
2082#endif
2083
2084#if defined (S_ISREG) && defined (S_ISLNK)
2085 if (input_file_statable_p)
2086 {
2087 if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode)))
2088 {
2089#if defined (EISDIR)
2090 /* Get a better looking error message. */
2091 errno = EISDIR;
2092#endif /* EISDIR */
2093 report_file_error ("Non-regular file", Fcons (file, Qnil));
2094 }
2095 }
2096#endif /* S_ISREG && S_ISLNK */
2097
2098#ifdef VMS
2099 /* Create the copy file with the same record format as the input file */
2100 ofd = sys_creat (XSTRING (newname)->data, 0666, ifd);
2101#else
2102#ifdef MSDOS
2103 /* System's default file type was set to binary by _fmode in emacs.c. */
2104 ofd = creat (XSTRING (newname)->data, S_IREAD | S_IWRITE);
2105#else /* not MSDOS */
2106 ofd = creat (XSTRING (newname)->data, 0666);
2107#endif /* not MSDOS */
2108#endif /* VMS */
2109 if (ofd < 0)
2110 report_file_error ("Opening output file", Fcons (newname, Qnil));
2111
2112 record_unwind_protect (close_file_unwind, make_number (ofd));
2113
2114 immediate_quit = 1;
2115 QUIT;
2116 while ((n = read (ifd, buf, sizeof buf)) > 0)
2117 if (write (ofd, buf, n) != n)
2118 report_file_error ("I/O error", Fcons (newname, Qnil));
2119 immediate_quit = 0;
2120
2121 /* Closing the output clobbers the file times on some systems. */
2122 if (close (ofd) < 0)
2123 report_file_error ("I/O error", Fcons (newname, Qnil));
2124
2125 if (input_file_statable_p)
2126 {
2127 if (!NILP (keep_date))
2128 {
2129 EMACS_TIME atime, mtime;
2130 EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
2131 EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
2132 if (set_file_times (XSTRING (newname)->data, atime, mtime))
2133 Fsignal (Qfile_date_error,
2134 Fcons (build_string ("Cannot set file date"),
2135 Fcons (newname, Qnil)));
2136 }
2137#ifndef MSDOS
2138 chmod (XSTRING (newname)->data, st.st_mode & 07777);
2139#else /* MSDOS */
2140#if defined (__DJGPP__) && __DJGPP__ > 1
2141 /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
2142 and if it can't, it tells so. Otherwise, under MSDOS we usually
2143 get only the READ bit, which will make the copied file read-only,
2144 so it's better not to chmod at all. */
2145 if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
2146 chmod (XSTRING (newname)->data, st.st_mode & 07777);
2147#endif /* DJGPP version 2 or newer */
2148#endif /* MSDOS */
2149 }
2150
2151 close (ifd);
2152
2153 /* Discard the unwind protects. */
2154 specpdl_ptr = specpdl + count;
2155
2156 UNGCPRO;
2157 return Qnil;
2158}
2159\f
2160DEFUN ("make-directory-internal", Fmake_directory_internal,
2161 Smake_directory_internal, 1, 1, 0,
2162 "Create a new directory named DIRECTORY.")
2163 (directory)
2164 Lisp_Object directory;
2165{
2166 unsigned char *dir;
2167 Lisp_Object handler;
2168
2169 CHECK_STRING (directory, 0);
2170 directory = Fexpand_file_name (directory, Qnil);
2171
2172 handler = Ffind_file_name_handler (directory, Qmake_directory_internal);
2173 if (!NILP (handler))
2174 return call2 (handler, Qmake_directory_internal, directory);
2175
2176 dir = XSTRING (directory)->data;
2177
2178#ifdef WINDOWSNT
2179 if (mkdir (dir) != 0)
2180#else
2181 if (mkdir (dir, 0777) != 0)
2182#endif
2183 report_file_error ("Creating directory", Flist (1, &directory));
2184
2185 return Qnil;
2186}
2187
2188DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
2189 "Delete the directory named DIRECTORY.")
2190 (directory)
2191 Lisp_Object directory;
2192{
2193 unsigned char *dir;
2194 Lisp_Object handler;
2195
2196 CHECK_STRING (directory, 0);
2197 directory = Fdirectory_file_name (Fexpand_file_name (directory, Qnil));
2198 dir = XSTRING (directory)->data;
2199
2200 handler = Ffind_file_name_handler (directory, Qdelete_directory);
2201 if (!NILP (handler))
2202 return call2 (handler, Qdelete_directory, directory);
2203
2204 if (rmdir (dir) != 0)
2205 report_file_error ("Removing directory", Flist (1, &directory));
2206
2207 return Qnil;
2208}
2209
2210DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",
2211 "Delete file named FILENAME.\n\
2212If file has multiple names, it continues to exist with the other names.")
2213 (filename)
2214 Lisp_Object filename;
2215{
2216 Lisp_Object handler;
2217 CHECK_STRING (filename, 0);
2218 filename = Fexpand_file_name (filename, Qnil);
2219
2220 handler = Ffind_file_name_handler (filename, Qdelete_file);
2221 if (!NILP (handler))
2222 return call2 (handler, Qdelete_file, filename);
2223
2224 if (0 > unlink (XSTRING (filename)->data))
2225 report_file_error ("Removing old name", Flist (1, &filename));
2226 return Qnil;
2227}
2228
2229static Lisp_Object
2230internal_delete_file_1 (ignore)
2231 Lisp_Object ignore;
2232{
2233 return Qt;
2234}
2235
2236/* Delete file FILENAME, returning 1 if successful and 0 if failed. */
2237
2238int
2239internal_delete_file (filename)
2240 Lisp_Object filename;
2241{
2242 return NILP (internal_condition_case_1 (Fdelete_file, filename,
2243 Qt, internal_delete_file_1));
2244}
2245\f
2246DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
2247 "fRename file: \nFRename %s to file: \np",
2248 "Rename FILE as NEWNAME. Both args strings.\n\
2249If file has names other than FILE, it continues to have those names.\n\
2250Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2251unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2252A number as third arg means request confirmation if NEWNAME already exists.\n\
2253This is what happens in interactive use with M-x.")
2254 (file, newname, ok_if_already_exists)
2255 Lisp_Object file, newname, ok_if_already_exists;
2256{
2257#ifdef NO_ARG_ARRAY
2258 Lisp_Object args[2];
2259#endif
2260 Lisp_Object handler;
2261 struct gcpro gcpro1, gcpro2;
2262
2263 GCPRO2 (file, newname);
2264 CHECK_STRING (file, 0);
2265 CHECK_STRING (newname, 1);
2266 file = Fexpand_file_name (file, Qnil);
2267 newname = Fexpand_file_name (newname, Qnil);
2268
2269 /* If the file name has special constructs in it,
2270 call the corresponding file handler. */
2271 handler = Ffind_file_name_handler (file, Qrename_file);
2272 if (NILP (handler))
2273 handler = Ffind_file_name_handler (newname, Qrename_file);
2274 if (!NILP (handler))
2275 RETURN_UNGCPRO (call4 (handler, Qrename_file,
2276 file, newname, ok_if_already_exists));
2277
2278 if (NILP (ok_if_already_exists)
2279 || INTEGERP (ok_if_already_exists))
2280 barf_or_query_if_file_exists (newname, "rename to it",
2281 INTEGERP (ok_if_already_exists), 0);
2282#ifndef BSD4_1
2283 if (0 > rename (XSTRING (file)->data, XSTRING (newname)->data))
2284#else
2285 if (0 > link (XSTRING (file)->data, XSTRING (newname)->data)
2286 || 0 > unlink (XSTRING (file)->data))
2287#endif
2288 {
2289 if (errno == EXDEV)
2290 {
2291 Fcopy_file (file, newname,
2292 /* We have already prompted if it was an integer,
2293 so don't have copy-file prompt again. */
2294 NILP (ok_if_already_exists) ? Qnil : Qt, Qt);
2295 Fdelete_file (file);
2296 }
2297 else
2298#ifdef NO_ARG_ARRAY
2299 {
2300 args[0] = file;
2301 args[1] = newname;
2302 report_file_error ("Renaming", Flist (2, args));
2303 }
2304#else
2305 report_file_error ("Renaming", Flist (2, &file));
2306#endif
2307 }
2308 UNGCPRO;
2309 return Qnil;
2310}
2311
2312DEFUN ("add-name-to-file", Fadd_name_to_file, Sadd_name_to_file, 2, 3,
2313 "fAdd name to file: \nFName to add to %s: \np",
2314 "Give FILE additional name NEWNAME. Both args strings.\n\
2315Signals a `file-already-exists' error if a file NEWNAME already exists\n\
2316unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2317A number as third arg means request confirmation if NEWNAME already exists.\n\
2318This is what happens in interactive use with M-x.")
2319 (file, newname, ok_if_already_exists)
2320 Lisp_Object file, newname, ok_if_already_exists;
2321{
2322#ifdef NO_ARG_ARRAY
2323 Lisp_Object args[2];
2324#endif
2325 Lisp_Object handler;
2326 struct gcpro gcpro1, gcpro2;
2327
2328 GCPRO2 (file, newname);
2329 CHECK_STRING (file, 0);
2330 CHECK_STRING (newname, 1);
2331 file = Fexpand_file_name (file, Qnil);
2332 newname = Fexpand_file_name (newname, Qnil);
2333
2334 /* If the file name has special constructs in it,
2335 call the corresponding file handler. */
2336 handler = Ffind_file_name_handler (file, Qadd_name_to_file);
2337 if (!NILP (handler))
2338 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2339 newname, ok_if_already_exists));
2340
2341 /* If the new name has special constructs in it,
2342 call the corresponding file handler. */
2343 handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2344 if (!NILP (handler))
2345 RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, file,
2346 newname, ok_if_already_exists));
2347
2348 if (NILP (ok_if_already_exists)
2349 || INTEGERP (ok_if_already_exists))
2350 barf_or_query_if_file_exists (newname, "make it a new name",
2351 INTEGERP (ok_if_already_exists), 0);
2352#ifdef WINDOWSNT
2353 /* Windows does not support this operation. */
2354 report_file_error ("Adding new name", Flist (2, &file));
2355#else /* not WINDOWSNT */
2356
2357 unlink (XSTRING (newname)->data);
2358 if (0 > link (XSTRING (file)->data, XSTRING (newname)->data))
2359 {
2360#ifdef NO_ARG_ARRAY
2361 args[0] = file;
2362 args[1] = newname;
2363 report_file_error ("Adding new name", Flist (2, args));
2364#else
2365 report_file_error ("Adding new name", Flist (2, &file));
2366#endif
2367 }
2368#endif /* not WINDOWSNT */
2369
2370 UNGCPRO;
2371 return Qnil;
2372}
2373
2374#ifdef S_IFLNK
2375DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2376 "FMake symbolic link to file: \nFMake symbolic link to file %s: \np",
2377 "Make a symbolic link to FILENAME, named LINKNAME. Both args strings.\n\
2378Signals a `file-already-exists' error if a file LINKNAME already exists\n\
2379unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\
2380A number as third arg means request confirmation if LINKNAME already exists.\n\
2381This happens for interactive use with M-x.")
2382 (filename, linkname, ok_if_already_exists)
2383 Lisp_Object filename, linkname, ok_if_already_exists;
2384{
2385#ifdef NO_ARG_ARRAY
2386 Lisp_Object args[2];
2387#endif
2388 Lisp_Object handler;
2389 struct gcpro gcpro1, gcpro2;
2390
2391 GCPRO2 (filename, linkname);
2392 CHECK_STRING (filename, 0);
2393 CHECK_STRING (linkname, 1);
2394 /* If the link target has a ~, we must expand it to get
2395 a truly valid file name. Otherwise, do not expand;
2396 we want to permit links to relative file names. */
2397 if (XSTRING (filename)->data[0] == '~')
2398 filename = Fexpand_file_name (filename, Qnil);
2399 linkname = Fexpand_file_name (linkname, Qnil);
2400
2401 /* If the file name has special constructs in it,
2402 call the corresponding file handler. */
2403 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2404 if (!NILP (handler))
2405 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2406 linkname, ok_if_already_exists));
2407
2408 /* If the new link name has special constructs in it,
2409 call the corresponding file handler. */
2410 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2411 if (!NILP (handler))
2412 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2413 linkname, ok_if_already_exists));
2414
2415 if (NILP (ok_if_already_exists)
2416 || INTEGERP (ok_if_already_exists))
2417 barf_or_query_if_file_exists (linkname, "make it a link",
2418 INTEGERP (ok_if_already_exists), 0);
2419 if (0 > symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
2420 {
2421 /* If we didn't complain already, silently delete existing file. */
2422 if (errno == EEXIST)
2423 {
2424 unlink (XSTRING (linkname)->data);
2425 if (0 <= symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
2426 {
2427 UNGCPRO;
2428 return Qnil;
2429 }
2430 }
2431
2432#ifdef NO_ARG_ARRAY
2433 args[0] = filename;
2434 args[1] = linkname;
2435 report_file_error ("Making symbolic link", Flist (2, args));
2436#else
2437 report_file_error ("Making symbolic link", Flist (2, &filename));
2438#endif
2439 }
2440 UNGCPRO;
2441 return Qnil;
2442}
2443#endif /* S_IFLNK */
2444
2445#ifdef VMS
2446
2447DEFUN ("define-logical-name", Fdefine_logical_name, Sdefine_logical_name,
2448 2, 2, "sDefine logical name: \nsDefine logical name %s as: ",
2449 "Define the job-wide logical name NAME to have the value STRING.\n\
2450If STRING is nil or a null string, the logical name NAME is deleted.")
2451 (name, string)
2452 Lisp_Object name;
2453 Lisp_Object string;
2454{
2455 CHECK_STRING (name, 0);
2456 if (NILP (string))
2457 delete_logical_name (XSTRING (name)->data);
2458 else
2459 {
2460 CHECK_STRING (string, 1);
2461
2462 if (XSTRING (string)->size == 0)
2463 delete_logical_name (XSTRING (name)->data);
2464 else
2465 define_logical_name (XSTRING (name)->data, XSTRING (string)->data);
2466 }
2467
2468 return string;
2469}
2470#endif /* VMS */
2471
2472#ifdef HPUX_NET
2473
2474DEFUN ("sysnetunam", Fsysnetunam, Ssysnetunam, 2, 2, 0,
2475 "Open a network connection to PATH using LOGIN as the login string.")
2476 (path, login)
2477 Lisp_Object path, login;
2478{
2479 int netresult;
2480
2481 CHECK_STRING (path, 0);
2482 CHECK_STRING (login, 0);
2483
2484 netresult = netunam (XSTRING (path)->data, XSTRING (login)->data);
2485
2486 if (netresult == -1)
2487 return Qnil;
2488 else
2489 return Qt;
2490}
2491#endif /* HPUX_NET */
2492\f
2493DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, Sfile_name_absolute_p,
2494 1, 1, 0,
2495 "Return t if file FILENAME specifies an absolute file name.\n\
2496On Unix, this is a name starting with a `/' or a `~'.")
2497 (filename)
2498 Lisp_Object filename;
2499{
2500 unsigned char *ptr;
2501
2502 CHECK_STRING (filename, 0);
2503 ptr = XSTRING (filename)->data;
2504 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2505#ifdef VMS
2506/* ??? This criterion is probably wrong for '<'. */
2507 || index (ptr, ':') || index (ptr, '<')
2508 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2509 && ptr[1] != '.')
2510#endif /* VMS */
2511#ifdef DOS_NT
2512 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2513#endif
2514 )
2515 return Qt;
2516 else
2517 return Qnil;
2518}
2519\f
2520/* Return nonzero if file FILENAME exists and can be executed. */
2521
2522static int
2523check_executable (filename)
2524 char *filename;
2525{
2526#ifdef DOS_NT
2527 int len = strlen (filename);
2528 char *suffix;
2529 struct stat st;
2530 if (stat (filename, &st) < 0)
2531 return 0;
2532#if defined (WINDOWSNT) || (defined (MSDOS) && __DJGPP__ > 1)
2533 return ((st.st_mode & S_IEXEC) != 0);
2534#else
2535 return (S_ISREG (st.st_mode)
2536 && len >= 5
2537 && (stricmp ((suffix = filename + len-4), ".com") == 0
2538 || stricmp (suffix, ".exe") == 0
2539 || stricmp (suffix, ".bat") == 0)
2540 || (st.st_mode & S_IFMT) == S_IFDIR);
2541#endif /* not WINDOWSNT */
2542#else /* not DOS_NT */
2543#ifdef HAVE_EUIDACCESS
2544 return (euidaccess (filename, 1) >= 0);
2545#else
2546 /* Access isn't quite right because it uses the real uid
2547 and we really want to test with the effective uid.
2548 But Unix doesn't give us a right way to do it. */
2549 return (access (filename, 1) >= 0);
2550#endif
2551#endif /* not DOS_NT */
2552}
2553
2554/* Return nonzero if file FILENAME exists and can be written. */
2555
2556static int
2557check_writable (filename)
2558 char *filename;
2559{
2560#ifdef MSDOS
2561 struct stat st;
2562 if (stat (filename, &st) < 0)
2563 return 0;
2564 return (st.st_mode & S_IWRITE || (st.st_mode & S_IFMT) == S_IFDIR);
2565#else /* not MSDOS */
2566#ifdef HAVE_EUIDACCESS
2567 return (euidaccess (filename, 2) >= 0);
2568#else
2569 /* Access isn't quite right because it uses the real uid
2570 and we really want to test with the effective uid.
2571 But Unix doesn't give us a right way to do it.
2572 Opening with O_WRONLY could work for an ordinary file,
2573 but would lose for directories. */
2574 return (access (filename, 2) >= 0);
2575#endif
2576#endif /* not MSDOS */
2577}
2578
2579DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0,
2580 "Return t if file FILENAME exists. (This does not mean you can read it.)\n\
2581See also `file-readable-p' and `file-attributes'.")
2582 (filename)
2583 Lisp_Object filename;
2584{
2585 Lisp_Object absname;
2586 Lisp_Object handler;
2587 struct stat statbuf;
2588
2589 CHECK_STRING (filename, 0);
2590 absname = Fexpand_file_name (filename, Qnil);
2591
2592 /* If the file name has special constructs in it,
2593 call the corresponding file handler. */
2594 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2595 if (!NILP (handler))
2596 return call2 (handler, Qfile_exists_p, absname);
2597
2598 return (stat (XSTRING (absname)->data, &statbuf) >= 0) ? Qt : Qnil;
2599}
2600
2601DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0,
2602 "Return t if FILENAME can be executed by you.\n\
2603For a directory, this means you can access files in that directory.")
2604 (filename)
2605 Lisp_Object filename;
2606
2607{
2608 Lisp_Object absname;
2609 Lisp_Object handler;
2610
2611 CHECK_STRING (filename, 0);
2612 absname = Fexpand_file_name (filename, Qnil);
2613
2614 /* If the file name has special constructs in it,
2615 call the corresponding file handler. */
2616 handler = Ffind_file_name_handler (absname, Qfile_executable_p);
2617 if (!NILP (handler))
2618 return call2 (handler, Qfile_executable_p, absname);
2619
2620 return (check_executable (XSTRING (absname)->data) ? Qt : Qnil);
2621}
2622
2623DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0,
2624 "Return t if file FILENAME exists and you can read it.\n\
2625See also `file-exists-p' and `file-attributes'.")
2626 (filename)
2627 Lisp_Object filename;
2628{
2629 Lisp_Object absname;
2630 Lisp_Object handler;
2631 int desc;
2632 int flags;
2633 struct stat statbuf;
2634
2635 CHECK_STRING (filename, 0);
2636 absname = Fexpand_file_name (filename, Qnil);
2637
2638 /* If the file name has special constructs in it,
2639 call the corresponding file handler. */
2640 handler = Ffind_file_name_handler (absname, Qfile_readable_p);
2641 if (!NILP (handler))
2642 return call2 (handler, Qfile_readable_p, absname);
2643
2644#ifdef DOS_NT
2645 /* Under MS-DOS and Windows, open does not work for directories. */
2646 if (access (XSTRING (absname)->data, 0) == 0)
2647 return Qt;
2648 return Qnil;
2649#else /* not DOS_NT */
2650 flags = O_RDONLY;
2651#if defined (S_ISFIFO) && defined (O_NONBLOCK)
2652 /* Opening a fifo without O_NONBLOCK can wait.
2653 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2654 except in the case of a fifo, on a system which handles it. */
2655 desc = stat (XSTRING (absname)->data, &statbuf);
2656 if (desc < 0)
2657 return Qnil;
2658 if (S_ISFIFO (statbuf.st_mode))
2659 flags |= O_NONBLOCK;
2660#endif
2661 desc = open (XSTRING (absname)->data, flags);
2662 if (desc < 0)
2663 return Qnil;
2664 close (desc);
2665 return Qt;
2666#endif /* not DOS_NT */
2667}
2668
2669/* Having this before file-symlink-p mysteriously caused it to be forgotten
2670 on the RT/PC. */
2671DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2672 "Return t if file FILENAME can be written or created by you.")
2673 (filename)
2674 Lisp_Object filename;
2675{
2676 Lisp_Object absname, dir;
2677 Lisp_Object handler;
2678 struct stat statbuf;
2679
2680 CHECK_STRING (filename, 0);
2681 absname = Fexpand_file_name (filename, Qnil);
2682
2683 /* If the file name has special constructs in it,
2684 call the corresponding file handler. */
2685 handler = Ffind_file_name_handler (absname, Qfile_writable_p);
2686 if (!NILP (handler))
2687 return call2 (handler, Qfile_writable_p, absname);
2688
2689 if (stat (XSTRING (absname)->data, &statbuf) >= 0)
2690 return (check_writable (XSTRING (absname)->data)
2691 ? Qt : Qnil);
2692 dir = Ffile_name_directory (absname);
2693#ifdef VMS
2694 if (!NILP (dir))
2695 dir = Fdirectory_file_name (dir);
2696#endif /* VMS */
2697#ifdef MSDOS
2698 if (!NILP (dir))
2699 dir = Fdirectory_file_name (dir);
2700#endif /* MSDOS */
2701 return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "")
2702 ? Qt : Qnil);
2703}
2704\f
2705DEFUN ("access-file", Faccess_file, Saccess_file, 2, 2, 0,
2706 "Access file FILENAME, and get an error if that does not work.\n\
2707The second argument STRING is used in the error message.\n\
2708If there is no error, we return nil.")
2709 (filename, string)
2710 Lisp_Object filename, string;
2711{
2712 Lisp_Object handler;
2713 int fd;
2714
2715 CHECK_STRING (filename, 0);
2716
2717 /* If the file name has special constructs in it,
2718 call the corresponding file handler. */
2719 handler = Ffind_file_name_handler (filename, Qaccess_file);
2720 if (!NILP (handler))
2721 return call3 (handler, Qaccess_file, filename, string);
2722
2723 fd = open (XSTRING (filename)->data, O_RDONLY);
2724 if (fd < 0)
2725 report_file_error (XSTRING (string)->data, Fcons (filename, Qnil));
2726 close (fd);
2727
2728 return Qnil;
2729}
2730\f
2731DEFUN ("file-symlink-p", Ffile_symlink_p, Sfile_symlink_p, 1, 1, 0,
2732 "Return non-nil if file FILENAME is the name of a symbolic link.\n\
2733The value is the name of the file to which it is linked.\n\
2734Otherwise returns nil.")
2735 (filename)
2736 Lisp_Object filename;
2737{
2738#ifdef S_IFLNK
2739 char *buf;
2740 int bufsize;
2741 int valsize;
2742 Lisp_Object val;
2743 Lisp_Object handler;
2744
2745 CHECK_STRING (filename, 0);
2746 filename = Fexpand_file_name (filename, Qnil);
2747
2748 /* If the file name has special constructs in it,
2749 call the corresponding file handler. */
2750 handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2751 if (!NILP (handler))
2752 return call2 (handler, Qfile_symlink_p, filename);
2753
2754 bufsize = 100;
2755 while (1)
2756 {
2757 buf = (char *) xmalloc (bufsize);
2758 bzero (buf, bufsize);
2759 valsize = readlink (XSTRING (filename)->data, buf, bufsize);
2760 if (valsize < bufsize) break;
2761 /* Buffer was not long enough */
2762 xfree (buf);
2763 bufsize *= 2;
2764 }
2765 if (valsize == -1)
2766 {
2767 xfree (buf);
2768 return Qnil;
2769 }
2770 val = make_string (buf, valsize);
2771 xfree (buf);
2772 return val;
2773#else /* not S_IFLNK */
2774 return Qnil;
2775#endif /* not S_IFLNK */
2776}
2777
2778DEFUN ("file-directory-p", Ffile_directory_p, Sfile_directory_p, 1, 1, 0,
2779 "Return t if file FILENAME is the name of a directory as a file.\n\
2780A directory name spec may be given instead; then the value is t\n\
2781if the directory so specified exists and really is a directory.")
2782 (filename)
2783 Lisp_Object filename;
2784{
2785 register Lisp_Object absname;
2786 struct stat st;
2787 Lisp_Object handler;
2788
2789 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2790
2791 /* If the file name has special constructs in it,
2792 call the corresponding file handler. */
2793 handler = Ffind_file_name_handler (absname, Qfile_directory_p);
2794 if (!NILP (handler))
2795 return call2 (handler, Qfile_directory_p, absname);
2796
2797 if (stat (XSTRING (absname)->data, &st) < 0)
2798 return Qnil;
2799 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2800}
2801
2802DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
2803 "Return t if file FILENAME is the name of a directory as a file,\n\
2804and files in that directory can be opened by you. In order to use a\n\
2805directory as a buffer's current directory, this predicate must return true.\n\
2806A directory name spec may be given instead; then the value is t\n\
2807if the directory so specified exists and really is a readable and\n\
2808searchable directory.")
2809 (filename)
2810 Lisp_Object filename;
2811{
2812 Lisp_Object handler;
2813 int tem;
2814 struct gcpro gcpro1;
2815
2816 /* If the file name has special constructs in it,
2817 call the corresponding file handler. */
2818 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2819 if (!NILP (handler))
2820 return call2 (handler, Qfile_accessible_directory_p, filename);
2821
2822 /* It's an unlikely combination, but yes we really do need to gcpro:
2823 Suppose that file-accessible-directory-p has no handler, but
2824 file-directory-p does have a handler; this handler causes a GC which
2825 relocates the string in `filename'; and finally file-directory-p
2826 returns non-nil. Then we would end up passing a garbaged string
2827 to file-executable-p. */
2828 GCPRO1 (filename);
2829 tem = (NILP (Ffile_directory_p (filename))
2830 || NILP (Ffile_executable_p (filename)));
2831 UNGCPRO;
2832 return tem ? Qnil : Qt;
2833}
2834
2835DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
2836 "Return t if file FILENAME is the name of a regular file.\n\
2837This is the sort of file that holds an ordinary stream of data bytes.")
2838 (filename)
2839 Lisp_Object filename;
2840{
2841 register Lisp_Object absname;
2842 struct stat st;
2843 Lisp_Object handler;
2844
2845 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2846
2847 /* If the file name has special constructs in it,
2848 call the corresponding file handler. */
2849 handler = Ffind_file_name_handler (absname, Qfile_regular_p);
2850 if (!NILP (handler))
2851 return call2 (handler, Qfile_regular_p, absname);
2852
2853 if (stat (XSTRING (absname)->data, &st) < 0)
2854 return Qnil;
2855 return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2856}
2857\f
2858DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
2859 "Return mode bits of file named FILENAME, as an integer.")
2860 (filename)
2861 Lisp_Object filename;
2862{
2863 Lisp_Object absname;
2864 struct stat st;
2865 Lisp_Object handler;
2866
2867 absname = expand_and_dir_to_file (filename, current_buffer->directory);
2868
2869 /* If the file name has special constructs in it,
2870 call the corresponding file handler. */
2871 handler = Ffind_file_name_handler (absname, Qfile_modes);
2872 if (!NILP (handler))
2873 return call2 (handler, Qfile_modes, absname);
2874
2875 if (stat (XSTRING (absname)->data, &st) < 0)
2876 return Qnil;
2877#if defined (MSDOS) && __DJGPP__ < 2
2878 if (check_executable (XSTRING (absname)->data))
2879 st.st_mode |= S_IEXEC;
2880#endif /* MSDOS && __DJGPP__ < 2 */
2881
2882 return make_number (st.st_mode & 07777);
2883}
2884
2885DEFUN ("set-file-modes", Fset_file_modes, Sset_file_modes, 2, 2, 0,
2886 "Set mode bits of file named FILENAME to MODE (an integer).\n\
2887Only the 12 low bits of MODE are used.")
2888 (filename, mode)
2889 Lisp_Object filename, mode;
2890{
2891 Lisp_Object absname;
2892 Lisp_Object handler;
2893
2894 absname = Fexpand_file_name (filename, current_buffer->directory);
2895 CHECK_NUMBER (mode, 1);
2896
2897 /* If the file name has special constructs in it,
2898 call the corresponding file handler. */
2899 handler = Ffind_file_name_handler (absname, Qset_file_modes);
2900 if (!NILP (handler))
2901 return call3 (handler, Qset_file_modes, absname, mode);
2902
2903 if (chmod (XSTRING (absname)->data, XINT (mode)) < 0)
2904 report_file_error ("Doing chmod", Fcons (absname, Qnil));
2905
2906 return Qnil;
2907}
2908
2909DEFUN ("set-default-file-modes", Fset_default_file_modes, Sset_default_file_modes, 1, 1, 0,
2910 "Set the file permission bits for newly created files.\n\
2911The argument MODE should be an integer; only the low 9 bits are used.\n\
2912This setting is inherited by subprocesses.")
2913 (mode)
2914 Lisp_Object mode;
2915{
2916 CHECK_NUMBER (mode, 0);
2917
2918 umask ((~ XINT (mode)) & 0777);
2919
2920 return Qnil;
2921}
2922
2923DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
2924 "Return the default file protection for created files.\n\
2925The value is an integer.")
2926 ()
2927{
2928 int realmask;
2929 Lisp_Object value;
2930
2931 realmask = umask (0);
2932 umask (realmask);
2933
2934 XSETINT (value, (~ realmask) & 0777);
2935 return value;
2936}
2937\f
2938#ifdef unix
2939
2940DEFUN ("unix-sync", Funix_sync, Sunix_sync, 0, 0, "",
2941 "Tell Unix to finish all pending disk updates.")
2942 ()
2943{
2944 sync ();
2945 return Qnil;
2946}
2947
2948#endif /* unix */
2949
2950DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, Sfile_newer_than_file_p, 2, 2, 0,
2951 "Return t if file FILE1 is newer than file FILE2.\n\
2952If FILE1 does not exist, the answer is nil;\n\
2953otherwise, if FILE2 does not exist, the answer is t.")
2954 (file1, file2)
2955 Lisp_Object file1, file2;
2956{
2957 Lisp_Object absname1, absname2;
2958 struct stat st;
2959 int mtime1;
2960 Lisp_Object handler;
2961 struct gcpro gcpro1, gcpro2;
2962
2963 CHECK_STRING (file1, 0);
2964 CHECK_STRING (file2, 0);
2965
2966 absname1 = Qnil;
2967 GCPRO2 (absname1, file2);
2968 absname1 = expand_and_dir_to_file (file1, current_buffer->directory);
2969 absname2 = expand_and_dir_to_file (file2, current_buffer->directory);
2970 UNGCPRO;
2971
2972 /* If the file name has special constructs in it,
2973 call the corresponding file handler. */
2974 handler = Ffind_file_name_handler (absname1, Qfile_newer_than_file_p);
2975 if (NILP (handler))
2976 handler = Ffind_file_name_handler (absname2, Qfile_newer_than_file_p);
2977 if (!NILP (handler))
2978 return call3 (handler, Qfile_newer_than_file_p, absname1, absname2);
2979
2980 if (stat (XSTRING (absname1)->data, &st) < 0)
2981 return Qnil;
2982
2983 mtime1 = st.st_mtime;
2984
2985 if (stat (XSTRING (absname2)->data, &st) < 0)
2986 return Qt;
2987
2988 return (mtime1 > st.st_mtime) ? Qt : Qnil;
2989}
2990\f
2991#ifdef DOS_NT
2992Lisp_Object Qfind_buffer_file_type;
2993#endif /* DOS_NT */
2994
2995#ifndef READ_BUF_SIZE
2996#define READ_BUF_SIZE (64 << 10)
2997#endif
2998
2999DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
3000 1, 5, 0,
3001 "Insert contents of file FILENAME after point.\n\
3002Returns list of absolute file name and length of data inserted.\n\
3003If second argument VISIT is non-nil, the buffer's visited filename\n\
3004and last save file modtime are set, and it is marked unmodified.\n\
3005If visiting and the file does not exist, visiting is completed\n\
3006before the error is signaled.\n\
3007The optional third and fourth arguments BEG and END\n\
3008specify what portion of the file to insert.\n\
3009If VISIT is non-nil, BEG and END must be nil.\n\
3010\n\
3011If optional fifth argument REPLACE is non-nil,\n\
3012it means replace the current buffer contents (in the accessible portion)\n\
3013with the file contents. This is better than simply deleting and inserting\n\
3014the whole thing because (1) it preserves some marker positions\n\
3015and (2) it puts less data in the undo list.\n\
3016When REPLACE is non-nil, the value is the number of characters actually read,\n\
3017which is often less than the number of characters to be read.\n\
3018This does code conversion according to the value of\n\
3019 `coding-system-for-read' or `coding-system-alist', and sets the variable\n\
3020 `last-coding-system-used' to the coding system actually used.")
3021 (filename, visit, beg, end, replace)
3022 Lisp_Object filename, visit, beg, end, replace;
3023{
3024 struct stat st;
3025 register int fd;
3026 register int inserted = 0;
3027 register int how_much;
3028 register int unprocessed;
3029 int count = specpdl_ptr - specpdl;
3030 struct gcpro gcpro1, gcpro2, gcpro3;
3031 Lisp_Object handler, val, insval;
3032 Lisp_Object p;
3033 int total;
3034 int not_regular = 0;
3035 char read_buf[READ_BUF_SIZE];
3036 struct coding_system coding;
3037 unsigned char buffer[1 << 14];
3038 int replace_handled = 0;
3039
3040 if (current_buffer->base_buffer && ! NILP (visit))
3041 error ("Cannot do file visiting in an indirect buffer");
3042
3043 if (!NILP (current_buffer->read_only))
3044 Fbarf_if_buffer_read_only ();
3045
3046 val = Qnil;
3047 p = Qnil;
3048
3049 GCPRO3 (filename, val, p);
3050
3051 CHECK_STRING (filename, 0);
3052 filename = Fexpand_file_name (filename, Qnil);
3053
3054 /* If the file name has special constructs in it,
3055 call the corresponding file handler. */
3056 handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
3057 if (!NILP (handler))
3058 {
3059 val = call6 (handler, Qinsert_file_contents, filename,
3060 visit, beg, end, replace);
3061 goto handled;
3062 }
3063
3064 /* Decide the coding-system of the file. */
3065 {
3066 Lisp_Object val = Vcoding_system_for_read;
3067 if (NILP (current_buffer->enable_multibyte_characters))
3068 val = Qnil;
3069 else if (NILP (val))
3070 {
3071 Lisp_Object args[6], coding_systems;
3072
3073 args[0] = Qinsert_file_contents, args[1] = filename, args[2] = visit,
3074 args[3] = beg, args[4] = end, args[5] = replace;
3075 coding_systems = Ffind_coding_system (6, args);
3076 val = CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil;
3077 }
3078 setup_coding_system (Fcheck_coding_system (val), &coding);
3079 }
3080
3081 fd = -1;
3082
3083#ifndef APOLLO
3084 if (stat (XSTRING (filename)->data, &st) < 0)
3085#else
3086 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0
3087 || fstat (fd, &st) < 0)
3088#endif /* not APOLLO */
3089 {
3090 if (fd >= 0) close (fd);
3091 badopen:
3092 if (NILP (visit))
3093 report_file_error ("Opening input file", Fcons (filename, Qnil));
3094 st.st_mtime = -1;
3095 how_much = 0;
3096 goto notfound;
3097 }
3098
3099#ifdef S_IFREG
3100 /* This code will need to be changed in order to work on named
3101 pipes, and it's probably just not worth it. So we should at
3102 least signal an error. */
3103 if (!S_ISREG (st.st_mode))
3104 {
3105 not_regular = 1;
3106
3107 if (! NILP (visit))
3108 goto notfound;
3109
3110 if (! NILP (replace) || ! NILP (beg) || ! NILP (end))
3111 Fsignal (Qfile_error,
3112 Fcons (build_string ("not a regular file"),
3113 Fcons (filename, Qnil)));
3114 }
3115#endif
3116
3117 if (fd < 0)
3118 if ((fd = open (XSTRING (filename)->data, O_RDONLY)) < 0)
3119 goto badopen;
3120
3121 /* Replacement should preserve point as it preserves markers. */
3122 if (!NILP (replace))
3123 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3124
3125 record_unwind_protect (close_file_unwind, make_number (fd));
3126
3127 /* Supposedly happens on VMS. */
3128 if (! not_regular && st.st_size < 0)
3129 error ("File size is negative");
3130
3131 if (!NILP (beg) || !NILP (end))
3132 if (!NILP (visit))
3133 error ("Attempt to visit less than an entire file");
3134
3135 if (!NILP (beg))
3136 CHECK_NUMBER (beg, 0);
3137 else
3138 XSETFASTINT (beg, 0);
3139
3140 if (!NILP (end))
3141 CHECK_NUMBER (end, 0);
3142 else
3143 {
3144 if (! not_regular)
3145 {
3146 XSETINT (end, st.st_size);
3147 if (XINT (end) != st.st_size)
3148 error ("Maximum buffer size exceeded");
3149 }
3150 }
3151
3152 /* If requested, replace the accessible part of the buffer
3153 with the file contents. Avoid replacing text at the
3154 beginning or end of the buffer that matches the file contents;
3155 that preserves markers pointing to the unchanged parts.
3156
3157 Here we implement this feature in an optimized way
3158 for the case where code conversion is NOT needed.
3159 The following if-statement handles the case of conversion
3160 in a less optimal way.
3161
3162 If the code conversion is "automatic" then we try using this
3163 method and hope for the best.
3164 But if we discover the need for conversion, we give up on this method
3165 and let the following if-statement handle the replace job. */
3166 if (!NILP (replace)
3167 && (! CODING_REQUIRE_CONVERSION (&coding)
3168 || (coding.type == coding_type_automatic
3169 && ! CODING_REQUIRE_EOL_CONVERSION (&coding))
3170 || (coding.eol_type == CODING_EOL_AUTOMATIC
3171 && ! CODING_REQUIRE_TEXT_CONVERSION (&coding))))
3172 {
3173 int same_at_start = BEGV;
3174 int same_at_end = ZV;
3175 int overlap;
3176 /* There is still a possibility we will find the need to do code
3177 conversion. If that happens, we set this variable to 1 to
3178 give up on handling REPLACE in the optimized way. */
3179 int giveup_match_end = 0;
3180
3181 if (XINT (beg) != 0)
3182 {
3183 if (lseek (fd, XINT (beg), 0) < 0)
3184 report_file_error ("Setting file position",
3185 Fcons (filename, Qnil));
3186 }
3187
3188 immediate_quit = 1;
3189 QUIT;
3190 /* Count how many chars at the start of the file
3191 match the text at the beginning of the buffer. */
3192 while (1)
3193 {
3194 int nread, bufpos;
3195
3196 nread = read (fd, buffer, sizeof buffer);
3197 if (nread < 0)
3198 error ("IO error reading %s: %s",
3199 XSTRING (filename)->data, strerror (errno));
3200 else if (nread == 0)
3201 break;
3202
3203 if (coding.type == coding_type_automatic)
3204 detect_coding (&coding, buffer, nread);
3205 if (CODING_REQUIRE_TEXT_CONVERSION (&coding))
3206 /* We found that the file should be decoded somehow.
3207 Let's give up here. */
3208 {
3209 giveup_match_end = 1;
3210 break;
3211 }
3212
3213 if (coding.eol_type == CODING_EOL_AUTOMATIC)
3214 detect_eol (&coding, buffer, nread);
3215 if (CODING_REQUIRE_EOL_CONVERSION (&coding))
3216 /* We found that the format of eol should be decoded.
3217 Let's give up here. */
3218 {
3219 giveup_match_end = 1;
3220 break;
3221 }
3222
3223 bufpos = 0;
3224 while (bufpos < nread && same_at_start < ZV
3225 && FETCH_BYTE (same_at_start) == buffer[bufpos])
3226 same_at_start++, bufpos++;
3227 /* If we found a discrepancy, stop the scan.
3228 Otherwise loop around and scan the next bufferful. */
3229 if (bufpos != nread)
3230 break;
3231 }
3232 immediate_quit = 0;
3233 /* If the file matches the buffer completely,
3234 there's no need to replace anything. */
3235 if (same_at_start - BEGV == XINT (end))
3236 {
3237 close (fd);
3238 specpdl_ptr--;
3239 /* Truncate the buffer to the size of the file. */
3240 del_range_1 (same_at_start, same_at_end, 0);
3241 goto handled;
3242 }
3243 immediate_quit = 1;
3244 QUIT;
3245 /* Count how many chars at the end of the file
3246 match the text at the end of the buffer. But, if we have
3247 already found that decoding is necessary, don't waste time. */
3248 while (!giveup_match_end)
3249 {
3250 int total_read, nread, bufpos, curpos, trial;
3251
3252 /* At what file position are we now scanning? */
3253 curpos = XINT (end) - (ZV - same_at_end);
3254 /* If the entire file matches the buffer tail, stop the scan. */
3255 if (curpos == 0)
3256 break;
3257 /* How much can we scan in the next step? */
3258 trial = min (curpos, sizeof buffer);
3259 if (lseek (fd, curpos - trial, 0) < 0)
3260 report_file_error ("Setting file position",
3261 Fcons (filename, Qnil));
3262
3263 total_read = 0;
3264 while (total_read < trial)
3265 {
3266 nread = read (fd, buffer + total_read, trial - total_read);
3267 if (nread <= 0)
3268 error ("IO error reading %s: %s",
3269 XSTRING (filename)->data, strerror (errno));
3270 total_read += nread;
3271 }
3272 /* Scan this bufferful from the end, comparing with
3273 the Emacs buffer. */
3274 bufpos = total_read;
3275 /* Compare with same_at_start to avoid counting some buffer text
3276 as matching both at the file's beginning and at the end. */
3277 while (bufpos > 0 && same_at_end > same_at_start
3278 && FETCH_BYTE (same_at_end - 1) == buffer[bufpos - 1])
3279 same_at_end--, bufpos--;
3280
3281 /* If we found a discrepancy, stop the scan.
3282 Otherwise loop around and scan the preceding bufferful. */
3283 if (bufpos != 0)
3284 {
3285 /* If this discrepancy is because of code conversion,
3286 we cannot use this method; giveup and try the other. */
3287 if (same_at_end > same_at_start
3288 && FETCH_BYTE (same_at_end - 1) >= 0200
3289 && ! NILP (current_buffer->enable_multibyte_characters))
3290 giveup_match_end = 1;
3291 break;
3292 }
3293 }
3294 immediate_quit = 0;
3295
3296 if (! giveup_match_end)
3297 {
3298 /* We win! We can handle REPLACE the optimized way. */
3299
3300 /* Don't try to reuse the same piece of text twice. */
3301 overlap = same_at_start - BEGV - (same_at_end + st.st_size - ZV);
3302 if (overlap > 0)
3303 same_at_end += overlap;
3304
3305 /* Arrange to read only the nonmatching middle part of the file. */
3306 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV));
3307 XSETFASTINT (end, XINT (end) - (ZV - same_at_end));
3308
3309 del_range_1 (same_at_start, same_at_end, 0);
3310 /* Insert from the file at the proper position. */
3311 SET_PT (same_at_start);
3312
3313 /* If display currently starts at beginning of line,
3314 keep it that way. */
3315 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3316 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3317
3318 replace_handled = 1;
3319 }
3320 }
3321
3322 /* If requested, replace the accessible part of the buffer
3323 with the file contents. Avoid replacing text at the
3324 beginning or end of the buffer that matches the file contents;
3325 that preserves markers pointing to the unchanged parts.
3326
3327 Here we implement this feature for the case where code conversion
3328 is needed, in a simple way that needs a lot of memory.
3329 The preceding if-statement handles the case of no conversion
3330 in a more optimized way. */
3331 if (!NILP (replace) && ! replace_handled)
3332 {
3333 int same_at_start = BEGV;
3334 int same_at_end = ZV;
3335 int overlap;
3336 int bufpos;
3337 /* Make sure that the gap is large enough. */
3338 int bufsize = 2 * st.st_size;
3339 unsigned char *conversion_buffer = (unsigned char *) xmalloc (bufsize);
3340
3341 /* First read the whole file, performing code conversion into
3342 CONVERSION_BUFFER. */
3343
3344 if (lseek (fd, XINT (beg), 0) < 0)
3345 {
3346 free (conversion_buffer);
3347 report_file_error ("Setting file position",
3348 Fcons (filename, Qnil));
3349 }
3350
3351 total = st.st_size; /* Total bytes in the file. */
3352 how_much = 0; /* Bytes read from file so far. */
3353 inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
3354 unprocessed = 0; /* Bytes not processed in previous loop. */
3355
3356 while (how_much < total)
3357 {
3358 /* try is reserved in some compilers (Microsoft C) */
3359 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
3360 char *destination = read_buf + unprocessed;
3361 int this;
3362
3363 /* Allow quitting out of the actual I/O. */
3364 immediate_quit = 1;
3365 QUIT;
3366 this = read (fd, destination, trytry);
3367 immediate_quit = 0;
3368
3369 if (this < 0 || this + unprocessed == 0)
3370 {
3371 how_much = this;
3372 break;
3373 }
3374
3375 how_much += this;
3376
3377 if (CODING_REQUIRE_CONVERSION (&coding))
3378 {
3379 int require, produced, consumed;
3380
3381 this += unprocessed;
3382
3383 /* If we are using more space than estimated,
3384 make CONVERSION_BUFFER bigger. */
3385 require = decoding_buffer_size (&coding, this);
3386 if (inserted + require + 2 * (total - how_much) > bufsize)
3387 {
3388 bufsize = inserted + require + 2 * (total - how_much);
3389 conversion_buffer = (unsigned char *) realloc (conversion_buffer, bufsize);
3390 }
3391
3392 /* Convert this batch with results in CONVERSION_BUFFER. */
3393 if (how_much >= total) /* This is the last block. */
3394 coding.last_block = 1;
3395 produced = decode_coding (&coding, read_buf,
3396 conversion_buffer + inserted,
3397 this, bufsize - inserted,
3398 &consumed);
3399
3400 /* Save for next iteration whatever we didn't convert. */
3401 unprocessed = this - consumed;
3402 bcopy (read_buf + consumed, read_buf, unprocessed);
3403 this = produced;
3404 }
3405
3406 inserted += this;
3407 }
3408
3409 /* At this point, INSERTED is how many characters
3410 are present in CONVERSION_BUFFER.
3411 HOW_MUCH should equal TOTAL,
3412 or should be <= 0 if we couldn't read the file. */
3413
3414 if (how_much < 0)
3415 {
3416 free (conversion_buffer);
3417
3418 if (how_much == -1)
3419 error ("IO error reading %s: %s",
3420 XSTRING (filename)->data, strerror (errno));
3421 else if (how_much == -2)
3422 error ("maximum buffer size exceeded");
3423 }
3424
3425 /* Compare the beginning of the converted file
3426 with the buffer text. */
3427
3428 bufpos = 0;
3429 while (bufpos < inserted && same_at_start < same_at_end
3430 && FETCH_BYTE (same_at_start) == conversion_buffer[bufpos])
3431 same_at_start++, bufpos++;
3432
3433 /* If the file matches the buffer completely,
3434 there's no need to replace anything. */
3435
3436 if (bufpos == inserted)
3437 {
3438 free (conversion_buffer);
3439 close (fd);
3440 specpdl_ptr--;
3441 /* Truncate the buffer to the size of the file. */
3442 del_range_1 (same_at_start, same_at_end, 0);
3443 goto handled;
3444 }
3445
3446 /* Scan this bufferful from the end, comparing with
3447 the Emacs buffer. */
3448 bufpos = inserted;
3449
3450 /* Compare with same_at_start to avoid counting some buffer text
3451 as matching both at the file's beginning and at the end. */
3452 while (bufpos > 0 && same_at_end > same_at_start
3453 && FETCH_BYTE (same_at_end - 1) == conversion_buffer[bufpos - 1])
3454 same_at_end--, bufpos--;
3455
3456 /* Don't try to reuse the same piece of text twice. */
3457 overlap = same_at_start - BEGV - (same_at_end + inserted - ZV);
3458 if (overlap > 0)
3459 same_at_end += overlap;
3460
3461 /* If display currently starts at beginning of line,
3462 keep it that way. */
3463 if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
3464 XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
3465
3466 /* Replace the chars that we need to replace,
3467 and update INSERTED to equal the number of bytes
3468 we are taking from the file. */
3469 inserted -= (Z - same_at_end) + (same_at_start - BEG);
3470 move_gap (same_at_start);
3471 del_range_1 (same_at_start, same_at_end, 0);
3472 SET_PT (same_at_start);
3473 insert_1 (conversion_buffer + same_at_start - BEG, inserted, 0, 0);
3474
3475 free (conversion_buffer);
3476 close (fd);
3477 specpdl_ptr--;
3478
3479 goto handled;
3480 }
3481
3482 if (! not_regular)
3483 {
3484 register Lisp_Object temp;
3485
3486 total = XINT (end) - XINT (beg);
3487
3488 /* Make sure point-max won't overflow after this insertion. */
3489 XSETINT (temp, total);
3490 if (total != XINT (temp))
3491 error ("Maximum buffer size exceeded");
3492 }
3493 else
3494 /* For a special file, all we can do is guess. */
3495 total = READ_BUF_SIZE;
3496
3497 if (NILP (visit) && total > 0)
3498 prepare_to_modify_buffer (PT, PT);
3499
3500 move_gap (PT);
3501 if (GAP_SIZE < total)
3502 make_gap (total - GAP_SIZE);
3503
3504 if (XINT (beg) != 0 || !NILP (replace))
3505 {
3506 if (lseek (fd, XINT (beg), 0) < 0)
3507 report_file_error ("Setting file position", Fcons (filename, Qnil));
3508 }
3509
3510 /* In the following loop, HOW_MUCH contains the total bytes read so
3511 far. Before exiting the loop, it is set to -1 if I/O error
3512 occurs, set to -2 if the maximum buffer size is exceeded. */
3513 how_much = 0;
3514 /* Total bytes inserted. */
3515 inserted = 0;
3516 /* Bytes not processed in the previous loop because short gap size. */
3517 unprocessed = 0;
3518 while (how_much < total)
3519 {
3520 /* try is reserved in some compilers (Microsoft C) */
3521 int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
3522 char *destination = (CODING_REQUIRE_CONVERSION (&coding)
3523 ? read_buf + unprocessed
3524 : (char *) (POS_ADDR (PT + inserted - 1) + 1));
3525 int this;
3526
3527 /* Allow quitting out of the actual I/O. */
3528 immediate_quit = 1;
3529 QUIT;
3530 this = read (fd, destination, trytry);
3531 immediate_quit = 0;
3532
3533 if (this < 0 || this + unprocessed == 0)
3534 {
3535 how_much = this;
3536 break;
3537 }
3538
3539 /* For a regular file, where TOTAL is the real size,
3540 count HOW_MUCH to compare with it.
3541 For a special file, where TOTAL is just a buffer size,
3542 so don't bother counting in HOW_MUCH.
3543 (INSERTED is where we count the number of characters inserted.) */
3544 if (! not_regular)
3545 how_much += this;
3546
3547 if (CODING_REQUIRE_CONVERSION (&coding))
3548 {
3549 int require, produced, consumed;
3550
3551 this += unprocessed;
3552 /* Make sure that the gap is large enough. */
3553 require = decoding_buffer_size (&coding, this);
3554 if (GAP_SIZE < require)
3555 make_gap (require - GAP_SIZE);
3556
3557 if (! not_regular)
3558 {
3559 if (how_much >= total) /* This is the last block. */
3560 coding.last_block = 1;
3561 }
3562 else
3563 {
3564 /* If we encounter EOF, say it is the last block. (The
3565 data this will apply to is the UNPROCESSED characters
3566 carried over from the last batch.) */
3567 if (this == 0)
3568 coding.last_block = 1;
3569 }
3570
3571 produced = decode_coding (&coding, read_buf,
3572 POS_ADDR (PT + inserted - 1) + 1,
3573 this, GAP_SIZE, &consumed);
3574 if (produced > 0)
3575 {
3576 Lisp_Object temp;
3577
3578 XSET (temp, Lisp_Int, Z + produced);
3579 if (Z + produced != XINT (temp))
3580 {
3581 how_much = -2;
3582 break;
3583 }
3584 }
3585 unprocessed = this - consumed;
3586 bcopy (read_buf + consumed, read_buf, unprocessed);
3587 this = produced;
3588 }
3589
3590 GPT += this;
3591 GAP_SIZE -= this;
3592 ZV += this;
3593 Z += this;
3594 if (GAP_SIZE > 0)
3595 /* Put an anchor to ensure multi-byte form ends at gap. */
3596 *GPT_ADDR = 0;
3597 inserted += this;
3598 }
3599
3600 /* We don't have to consider file type of MSDOS because all files
3601 are read as binary and end-of-line format has already been
3602 decoded appropriately. */
3603#if 0
3604#ifdef DOS_NT
3605 /* Demacs 1.1.1 91/10/16 HIRANO Satoshi, MW July 1993 */
3606 /* Determine file type from name and remove LFs from CR-LFs if the file
3607 is deemed to be a text file. */
3608 {
3609 current_buffer->buffer_file_type
3610 = call1 (Qfind_buffer_file_type, filename);
3611 if (NILP (current_buffer->buffer_file_type))
3612 {
3613 int reduced_size
3614 = inserted - crlf_to_lf (inserted, POS_ADDR (PT - 1) + 1);
3615 ZV -= reduced_size;
3616 Z -= reduced_size;
3617 GPT -= reduced_size;
3618 GAP_SIZE += reduced_size;
3619 inserted -= reduced_size;
3620 }
3621 }
3622#endif /* DOS_NT */
3623#endif /* 0 */
3624
3625 if (inserted > 0)
3626 {
3627 record_insert (PT, inserted);
3628
3629 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
3630 offset_intervals (current_buffer, PT, inserted);
3631 MODIFF++;
3632 }
3633
3634 close (fd);
3635
3636 /* Discard the unwind protect for closing the file. */
3637 specpdl_ptr--;
3638
3639 if (how_much == -1)
3640 error ("IO error reading %s: %s",
3641 XSTRING (filename)->data, strerror (errno));
3642 else if (how_much == -2)
3643 error ("maximum buffer size exceeded");
3644
3645 notfound:
3646 handled:
3647
3648 if (!NILP (visit))
3649 {
3650 if (!EQ (current_buffer->undo_list, Qt))
3651 current_buffer->undo_list = Qnil;
3652#ifdef APOLLO
3653 stat (XSTRING (filename)->data, &st);
3654#endif
3655
3656 if (NILP (handler))
3657 {
3658 current_buffer->modtime = st.st_mtime;
3659 current_buffer->filename = filename;
3660 }
3661
3662 SAVE_MODIFF = MODIFF;
3663 current_buffer->auto_save_modified = MODIFF;
3664 XSETFASTINT (current_buffer->save_length, Z - BEG);
3665#ifdef CLASH_DETECTION
3666 if (NILP (handler))
3667 {
3668 if (!NILP (current_buffer->file_truename))
3669 unlock_file (current_buffer->file_truename);
3670 unlock_file (filename);
3671 }
3672#endif /* CLASH_DETECTION */
3673 if (not_regular)
3674 Fsignal (Qfile_error,
3675 Fcons (build_string ("not a regular file"),
3676 Fcons (filename, Qnil)));
3677
3678 /* If visiting nonexistent file, return nil. */
3679 if (current_buffer->modtime == -1)
3680 report_file_error ("Opening input file", Fcons (filename, Qnil));
3681 }
3682
3683 /* Decode file format */
3684 if (inserted > 0)
3685 {
3686 insval = call3 (Qformat_decode,
3687 Qnil, make_number (inserted), visit);
3688 CHECK_NUMBER (insval, 0);
3689 inserted = XFASTINT (insval);
3690 }
3691
3692 /* Call after-change hooks for the inserted text, aside from the case
3693 of normal visiting (not with REPLACE), which is done in a new buffer
3694 "before" the buffer is changed. */
3695 if (inserted > 0 && total > 0
3696 && (NILP (visit) || !NILP (replace)))
3697 signal_after_change (PT, 0, inserted);
3698
3699 if (inserted > 0)
3700 {
3701 p = Vafter_insert_file_functions;
3702 if (!NILP (coding.post_read_conversion))
3703 p = Fcons (coding.post_read_conversion, p);
3704
3705 while (!NILP (p))
3706 {
3707 insval = call1 (Fcar (p), make_number (inserted));
3708 if (!NILP (insval))
3709 {
3710 CHECK_NUMBER (insval, 0);
3711 inserted = XFASTINT (insval);
3712 }
3713 QUIT;
3714 p = Fcdr (p);
3715 }
3716 }
3717
3718 if (NILP (val))
3719 val = Fcons (filename,
3720 Fcons (make_number (inserted),
3721 Qnil));
3722
3723 RETURN_UNGCPRO (unbind_to (count, val));
3724}
3725\f
3726static Lisp_Object build_annotations ();
3727
3728/* If build_annotations switched buffers, switch back to BUF.
3729 Kill the temporary buffer that was selected in the meantime.
3730
3731 Since this kill only the last temporary buffer, some buffers remain
3732 not killed if build_annotations switched buffers more than once.
3733 -- K.Handa */
3734
3735static Lisp_Object
3736build_annotations_unwind (buf)
3737 Lisp_Object buf;
3738{
3739 Lisp_Object tembuf;
3740
3741 if (XBUFFER (buf) == current_buffer)
3742 return Qnil;
3743 tembuf = Fcurrent_buffer ();
3744 Fset_buffer (buf);
3745 Fkill_buffer (tembuf);
3746 return Qnil;
3747}
3748
3749DEFUN ("write-region", Fwrite_region, Swrite_region, 3, 7,
3750 "r\nFWrite region to file: \ni\ni\ni\nZCoding system: ",
3751 "Write current region into specified file.\n\
3752When called from a program, takes three arguments:\n\
3753START, END and FILENAME. START and END are buffer positions.\n\
3754Optional fourth argument APPEND if non-nil means\n\
3755 append to existing file contents (if any).\n\
3756Optional fifth argument VISIT if t means\n\
3757 set the last-save-file-modtime of buffer to this file's modtime\n\
3758 and mark buffer not modified.\n\
3759If VISIT is a string, it is a second file name;\n\
3760 the output goes to FILENAME, but the buffer is marked as visiting VISIT.\n\
3761 VISIT is also the file name to lock and unlock for clash detection.\n\
3762If VISIT is neither t nor nil nor a string,\n\
3763 that means do not print the \"Wrote file\" message.\n\
3764The optional sixth arg LOCKNAME, if non-nil, specifies the name to\n\
3765 use for locking and unlocking, overriding FILENAME and VISIT.\n\
3766The optional seventh arg CODING-SYSTEM, if non-nil, specifies the coding\n\
3767 system to be used for encoding characters. For interactive use,\n\
3768 you can specify it by giving a prefix argument. If no coding system\n\
3769 is specified, the current region is encoded according to the value of\n\
3770 `coding-system-for-write' or `coding-system-alist'. The variable\n\
3771 `last-coding-system-used' is set the coding system actually used.\n\
3772Kludgy feature: if START is a string, then that string is written\n\
3773to the file, instead of any buffer contents, and END is ignored.")
3774 (start, end, filename, append, visit, lockname, coding_system_symbol)
3775 Lisp_Object start, end, filename, append, visit, lockname;
3776 Lisp_Object coding_system_symbol;
3777{
3778 register int desc;
3779 int failure;
3780 int save_errno;
3781 unsigned char *fn;
3782 struct stat st;
3783 int tem;
3784 int count = specpdl_ptr - specpdl;
3785 int count1;
3786#ifdef VMS
3787 unsigned char *fname = 0; /* If non-0, original filename (must rename) */
3788#endif /* VMS */
3789 Lisp_Object handler;
3790 Lisp_Object visit_file;
3791 Lisp_Object annotations;
3792 int visiting, quietly;
3793 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3794 struct buffer *given_buffer;
3795#ifdef DOS_NT
3796 int buffer_file_type
3797 = NILP (current_buffer->buffer_file_type) ? O_TEXT : O_BINARY;
3798#endif /* DOS_NT */
3799 struct coding_system coding;
3800
3801 if (current_buffer->base_buffer && ! NILP (visit))
3802 error ("Cannot do file visiting in an indirect buffer");
3803
3804 if (!NILP (start) && !STRINGP (start))
3805 validate_region (&start, &end);
3806
3807 GCPRO5 (start, filename, visit, lockname, coding_system_symbol);
3808
3809 /* Decide the coding-system to be encoded to. */
3810 {
3811 Lisp_Object val;
3812
3813 if (auto_saving || NILP (current_buffer->enable_multibyte_characters))
3814 val = Qnil;
3815 else if (!NILP (coding_system_symbol))
3816 val = coding_system_symbol;
3817 else if (!NILP (Vcoding_system_for_write))
3818 val = Vcoding_system_for_write;
3819 else if (!NILP (Flocal_variable_if_set_p (Qbuffer_file_coding_system,
3820 Qnil)))
3821 val = Fsymbol_value (Qbuffer_file_coding_system);
3822 else
3823 {
3824 Lisp_Object args[7], coding_systems;
3825
3826 args[0] = Qwrite_region, args[1] = start, args[2] = end,
3827 args[3] = filename, args[4] = append, args[5] = visit,
3828 args[6] = lockname;
3829 coding_systems = Ffind_coding_system (7, args);
3830 val = (CONSP (coding_systems)
3831 ? XCONS (coding_systems)->cdr
3832 : Fsymbol_value (Qbuffer_file_coding_system));
3833 }
3834 setup_coding_system (Fcheck_coding_system (val), &coding);
3835 if (!STRINGP (start) && !NILP (current_buffer->selective_display))
3836 coding.selective = 1;
3837#ifdef DOS_NT
3838 if (!NILP (current_buffer->buffer_file_type))
3839 coding.eol_type = CODING_EOL_LF;
3840#endif /* DOS_NT */
3841 }
3842
3843 filename = Fexpand_file_name (filename, Qnil);
3844 if (STRINGP (visit))
3845 visit_file = Fexpand_file_name (visit, Qnil);
3846 else
3847 visit_file = filename;
3848 UNGCPRO;
3849
3850 visiting = (EQ (visit, Qt) || STRINGP (visit));
3851 quietly = !NILP (visit);
3852
3853 annotations = Qnil;
3854
3855 if (NILP (lockname))
3856 lockname = visit_file;
3857
3858 GCPRO5 (start, filename, annotations, visit_file, lockname);
3859
3860 /* If the file name has special constructs in it,
3861 call the corresponding file handler. */
3862 handler = Ffind_file_name_handler (filename, Qwrite_region);
3863 /* If FILENAME has no handler, see if VISIT has one. */
3864 if (NILP (handler) && STRINGP (visit))
3865 handler = Ffind_file_name_handler (visit, Qwrite_region);
3866
3867 if (!NILP (handler))
3868 {
3869 Lisp_Object val;
3870 val = call6 (handler, Qwrite_region, start, end,
3871 filename, append, visit);
3872
3873 if (visiting)
3874 {
3875 SAVE_MODIFF = MODIFF;
3876 XSETFASTINT (current_buffer->save_length, Z - BEG);
3877 current_buffer->filename = visit_file;
3878 }
3879 UNGCPRO;
3880 return val;
3881 }
3882
3883 /* Special kludge to simplify auto-saving. */
3884 if (NILP (start))
3885 {
3886 XSETFASTINT (start, BEG);
3887 XSETFASTINT (end, Z);
3888 }
3889
3890 record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
3891 count1 = specpdl_ptr - specpdl;
3892
3893 given_buffer = current_buffer;
3894 annotations = build_annotations (start, end, coding.pre_write_conversion);
3895 if (current_buffer != given_buffer)
3896 {
3897 start = BEGV;
3898 end = ZV;
3899 }
3900
3901#ifdef CLASH_DETECTION
3902 if (!auto_saving)
3903 {
3904 /* If we've locked this file for some other buffer,
3905 query before proceeding. */
3906 if (!visiting && EQ (Ffile_locked_p (lockname), Qt))
3907 call2 (intern ("ask-user-about-lock"), fn, Vuser_login_name);
3908
3909 lock_file (lockname);
3910 }
3911#endif /* CLASH_DETECTION */
3912
3913 fn = XSTRING (filename)->data;
3914 desc = -1;
3915 if (!NILP (append))
3916#ifdef DOS_NT
3917 desc = open (fn, O_WRONLY | buffer_file_type);
3918#else /* not DOS_NT */
3919 desc = open (fn, O_WRONLY);
3920#endif /* not DOS_NT */
3921
3922 if (desc < 0 && (NILP (append) || errno == ENOENT) )
3923#ifdef VMS
3924 if (auto_saving) /* Overwrite any previous version of autosave file */
3925 {
3926 vms_truncate (fn); /* if fn exists, truncate to zero length */
3927 desc = open (fn, O_RDWR);
3928 if (desc < 0)
3929 desc = creat_copy_attrs (STRINGP (current_buffer->filename)
3930 ? XSTRING (current_buffer->filename)->data : 0,
3931 fn);
3932 }
3933 else /* Write to temporary name and rename if no errors */
3934 {
3935 Lisp_Object temp_name;
3936 temp_name = Ffile_name_directory (filename);
3937
3938 if (!NILP (temp_name))
3939 {
3940 temp_name = Fmake_temp_name (concat2 (temp_name,
3941 build_string ("$$SAVE$$")));
3942 fname = XSTRING (filename)->data;
3943 fn = XSTRING (temp_name)->data;
3944 desc = creat_copy_attrs (fname, fn);
3945 if (desc < 0)
3946 {
3947 /* If we can't open the temporary file, try creating a new
3948 version of the original file. VMS "creat" creates a
3949 new version rather than truncating an existing file. */
3950 fn = fname;
3951 fname = 0;
3952 desc = creat (fn, 0666);
3953#if 0 /* This can clobber an existing file and fail to replace it,
3954 if the user runs out of space. */
3955 if (desc < 0)
3956 {
3957 /* We can't make a new version;
3958 try to truncate and rewrite existing version if any. */
3959 vms_truncate (fn);
3960 desc = open (fn, O_RDWR);
3961 }
3962#endif
3963 }
3964 }
3965 else
3966 desc = creat (fn, 0666);
3967 }
3968#else /* not VMS */
3969#ifdef DOS_NT
3970 desc = open (fn,
3971 O_WRONLY | O_TRUNC | O_CREAT | buffer_file_type,
3972 S_IREAD | S_IWRITE);
3973#else /* not DOS_NT */
3974 desc = creat (fn, auto_saving ? auto_save_mode_bits : 0666);
3975#endif /* not DOS_NT */
3976#endif /* not VMS */
3977
3978 UNGCPRO;
3979
3980 if (desc < 0)
3981 {
3982#ifdef CLASH_DETECTION
3983 save_errno = errno;
3984 if (!auto_saving) unlock_file (lockname);
3985 errno = save_errno;
3986#endif /* CLASH_DETECTION */
3987 report_file_error ("Opening output file", Fcons (filename, Qnil));
3988 }
3989
3990 record_unwind_protect (close_file_unwind, make_number (desc));
3991
3992 if (!NILP (append))
3993 if (lseek (desc, 0, 2) < 0)
3994 {
3995#ifdef CLASH_DETECTION
3996 if (!auto_saving) unlock_file (lockname);
3997#endif /* CLASH_DETECTION */
3998 report_file_error ("Lseek error", Fcons (filename, Qnil));
3999 }
4000
4001#ifdef VMS
4002/*
4003 * Kludge Warning: The VMS C RTL likes to insert carriage returns
4004 * if we do writes that don't end with a carriage return. Furthermore
4005 * it cannot handle writes of more then 16K. The modified
4006 * version of "sys_write" in SYSDEP.C (see comment there) copes with
4007 * this EXCEPT for the last record (iff it doesn't end with a carriage
4008 * return). This implies that if your buffer doesn't end with a carriage
4009 * return, you get one free... tough. However it also means that if
4010 * we make two calls to sys_write (a la the following code) you can
4011 * get one at the gap as well. The easiest way to fix this (honest)
4012 * is to move the gap to the next newline (or the end of the buffer).
4013 * Thus this change.
4014 *
4015 * Yech!
4016 */
4017 if (GPT > BEG && GPT_ADDR[-1] != '\n')
4018 move_gap (find_next_newline (GPT, 1));
4019#else
4020 /* Whether VMS or not, we must move the gap to the next of newline
4021 when we must put designation sequences at beginning of line. */
4022 if (INTEGERP (start)
4023 && coding.type == coding_type_iso2022
4024 && coding.flags & CODING_FLAG_ISO_DESIGNATE_AT_BOL
4025 && GPT > BEG && GPT_ADDR[-1] != '\n')
4026 move_gap (find_next_newline (GPT, 1));
4027#endif
4028
4029 failure = 0;
4030 immediate_quit = 1;
4031
4032 if (STRINGP (start))
4033 {
4034 failure = 0 > a_write (desc, XSTRING (start)->data,
4035 XSTRING (start)->size, 0, &annotations, &coding);
4036 save_errno = errno;
4037 }
4038 else if (XINT (start) != XINT (end))
4039 {
4040 int nwritten = 0;
4041 if (XINT (start) < GPT)
4042 {
4043 register int end1 = XINT (end);
4044 tem = XINT (start);
4045 failure = 0 > a_write (desc, POS_ADDR (tem),
4046 min (GPT, end1) - tem, tem, &annotations,
4047 &coding);
4048 nwritten += min (GPT, end1) - tem;
4049 save_errno = errno;
4050 }
4051
4052 if (XINT (end) > GPT && !failure)
4053 {
4054 tem = XINT (start);
4055 tem = max (tem, GPT);
4056 failure = 0 > a_write (desc, POS_ADDR (tem), XINT (end) - tem,
4057 tem, &annotations, &coding);
4058 nwritten += XINT (end) - tem;
4059 save_errno = errno;
4060 }
4061 }
4062 else
4063 {
4064 /* If file was empty, still need to write the annotations */
4065 coding.last_block = 1;
4066 failure = 0 > a_write (desc, "", 0, XINT (start), &annotations, &coding);
4067 save_errno = errno;
4068 }
4069
4070 if (coding.require_flushing)
4071 {
4072 /* We have to flush out a data. */
4073 coding.last_block = 1;
4074 failure = 0 > e_write (desc, "", 0, &coding);
4075 save_errno = errno;
4076 }
4077
4078 immediate_quit = 0;
4079
4080#ifdef HAVE_FSYNC
4081 /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
4082 Disk full in NFS may be reported here. */
4083 /* mib says that closing the file will try to write as fast as NFS can do
4084 it, and that means the fsync here is not crucial for autosave files. */
4085 if (!auto_saving && fsync (desc) < 0)
4086 {
4087 /* If fsync fails with EINTR, don't treat that as serious. */
4088 if (errno != EINTR)
4089 failure = 1, save_errno = errno;
4090 }
4091#endif
4092
4093 /* Spurious "file has changed on disk" warnings have been
4094 observed on Suns as well.
4095 It seems that `close' can change the modtime, under nfs.
4096
4097 (This has supposedly been fixed in Sunos 4,
4098 but who knows about all the other machines with NFS?) */
4099#if 0
4100
4101 /* On VMS and APOLLO, must do the stat after the close
4102 since closing changes the modtime. */
4103#ifndef VMS
4104#ifndef APOLLO
4105 /* Recall that #if defined does not work on VMS. */
4106#define FOO
4107 fstat (desc, &st);
4108#endif
4109#endif
4110#endif
4111
4112 /* NFS can report a write failure now. */
4113 if (close (desc) < 0)
4114 failure = 1, save_errno = errno;
4115
4116#ifdef VMS
4117 /* If we wrote to a temporary name and had no errors, rename to real name. */
4118 if (fname)
4119 {
4120 if (!failure)
4121 failure = (rename (fn, fname) != 0), save_errno = errno;
4122 fn = fname;
4123 }
4124#endif /* VMS */
4125
4126#ifndef FOO
4127 stat (fn, &st);
4128#endif
4129 /* Discard the unwind protect for close_file_unwind. */
4130 specpdl_ptr = specpdl + count1;
4131 /* Restore the original current buffer. */
4132 visit_file = unbind_to (count, visit_file);
4133
4134#ifdef CLASH_DETECTION
4135 if (!auto_saving)
4136 unlock_file (lockname);
4137#endif /* CLASH_DETECTION */
4138
4139 /* Do this before reporting IO error
4140 to avoid a "file has changed on disk" warning on
4141 next attempt to save. */
4142 if (visiting)
4143 current_buffer->modtime = st.st_mtime;
4144
4145 if (failure)
4146 error ("IO error writing %s: %s", fn, strerror (save_errno));
4147
4148 if (visiting)
4149 {
4150 SAVE_MODIFF = MODIFF;
4151 XSETFASTINT (current_buffer->save_length, Z - BEG);
4152 current_buffer->filename = visit_file;
4153 update_mode_lines++;
4154 }
4155 else if (quietly)
4156 return Qnil;
4157
4158 if (!auto_saving)
4159 message ("Wrote %s", XSTRING (visit_file)->data);
4160
4161 return Qnil;
4162}
4163
4164Lisp_Object merge ();
4165
4166DEFUN ("car-less-than-car", Fcar_less_than_car, Scar_less_than_car, 2, 2, 0,
4167 "Return t if (car A) is numerically less than (car B).")
4168 (a, b)
4169 Lisp_Object a, b;
4170{
4171 return Flss (Fcar (a), Fcar (b));
4172}
4173
4174/* Build the complete list of annotations appropriate for writing out
4175 the text between START and END, by calling all the functions in
4176 write-region-annotate-functions and merging the lists they return.
4177 If one of these functions switches to a different buffer, we assume
4178 that buffer contains altered text. Therefore, the caller must
4179 make sure to restore the current buffer in all cases,
4180 as save-excursion would do. */
4181
4182static Lisp_Object
4183build_annotations (start, end, pre_write_conversion)
4184 Lisp_Object start, end, pre_write_conversion;
4185{
4186 Lisp_Object annotations;
4187 Lisp_Object p, res;
4188 struct gcpro gcpro1, gcpro2;
4189 Lisp_Object original_buffer;
4190
4191 XSETBUFFER (original_buffer, current_buffer);
4192
4193 annotations = Qnil;
4194 p = Vwrite_region_annotate_functions;
4195 GCPRO2 (annotations, p);
4196 while (!NILP (p))
4197 {
4198 struct buffer *given_buffer = current_buffer;
4199 Vwrite_region_annotations_so_far = annotations;
4200 res = call2 (Fcar (p), start, end);
4201 /* If the function makes a different buffer current,
4202 assume that means this buffer contains altered text to be output.
4203 Reset START and END from the buffer bounds
4204 and discard all previous annotations because they should have
4205 been dealt with by this function. */
4206 if (current_buffer != given_buffer)
4207 {
4208 start = BEGV;
4209 end = ZV;
4210 annotations = Qnil;
4211 }
4212 Flength (res); /* Check basic validity of return value */
4213 annotations = merge (annotations, res, Qcar_less_than_car);
4214 p = Fcdr (p);
4215 }
4216
4217 /* Now do the same for annotation functions implied by the file-format */
4218 if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
4219 p = Vauto_save_file_format;
4220 else
4221 p = current_buffer->file_format;
4222 while (!NILP (p))
4223 {
4224 struct buffer *given_buffer = current_buffer;
4225 Vwrite_region_annotations_so_far = annotations;
4226 res = call4 (Qformat_annotate_function, Fcar (p), start, end,
4227 original_buffer);
4228 if (current_buffer != given_buffer)
4229 {
4230 start = BEGV;
4231 end = ZV;
4232 annotations = Qnil;
4233 }
4234 Flength (res);
4235 annotations = merge (annotations, res, Qcar_less_than_car);
4236 p = Fcdr (p);
4237 }
4238
4239 /* At last, do the same for the function PRE_WRITE_CONVERSION
4240 implied by the current coding-system. */
4241 if (!NILP (pre_write_conversion))
4242 {
4243 struct buffer *given_buffer = current_buffer;
4244 Vwrite_region_annotations_so_far = annotations;
4245 res = call2 (pre_write_conversion, start, end);
4246 Flength (res);
4247 annotations = (current_buffer != given_buffer
4248 ? res
4249 : merge (annotations, res, Qcar_less_than_car));
4250 }
4251
4252 UNGCPRO;
4253 return annotations;
4254}
4255
4256/* Write to descriptor DESC the LEN characters starting at ADDR,
4257 assuming they start at position POS in the buffer.
4258 Intersperse with them the annotations from *ANNOT
4259 (those which fall within the range of positions POS to POS + LEN),
4260 each at its appropriate position.
4261
4262 Modify *ANNOT by discarding elements as we output them.
4263 The return value is negative in case of system call failure. */
4264
4265int
4266a_write (desc, addr, len, pos, annot, coding)
4267 int desc;
4268 register char *addr;
4269 register int len;
4270 int pos;
4271 Lisp_Object *annot;
4272 struct coding_system *coding;
4273{
4274 Lisp_Object tem;
4275 int nextpos;
4276 int lastpos = pos + len;
4277
4278 while (NILP (*annot) || CONSP (*annot))
4279 {
4280 tem = Fcar_safe (Fcar (*annot));
4281 if (INTEGERP (tem) && XINT (tem) >= pos && XFASTINT (tem) <= lastpos)
4282 nextpos = XFASTINT (tem);
4283 else
4284 return e_write (desc, addr, lastpos - pos, coding);
4285 if (nextpos > pos)
4286 {
4287 if (0 > e_write (desc, addr, nextpos - pos, coding))
4288 return -1;
4289 addr += nextpos - pos;
4290 pos = nextpos;
4291 }
4292 tem = Fcdr (Fcar (*annot));
4293 if (STRINGP (tem))
4294 {
4295 if (0 > e_write (desc, XSTRING (tem)->data, XSTRING (tem)->size,
4296 coding))
4297 return -1;
4298 }
4299 *annot = Fcdr (*annot);
4300 }
4301}
4302
4303#ifndef WRITE_BUF_SIZE
4304#define WRITE_BUF_SIZE (16 * 1024)
4305#endif
4306
4307int
4308e_write (desc, addr, len, coding)
4309 int desc;
4310 register char *addr;
4311 register int len;
4312 struct coding_system *coding;
4313{
4314 char buf[WRITE_BUF_SIZE];
4315 int produced, consumed;
4316
4317 /* We used to have a code for handling selective display here. But,
4318 now it is handled within encode_coding. */
4319 while (1)
4320 {
4321 produced = encode_coding (coding, addr, buf, len, WRITE_BUF_SIZE,
4322 &consumed);
4323 len -= consumed, addr += consumed;
4324 if (produced > 0)
4325 {
4326 produced -= write (desc, buf, produced);
4327 if (produced) return -1;
4328 }
4329 if (len <= 0)
4330 break;
4331 }
4332 return 0;
4333}
4334
4335DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
4336 Sverify_visited_file_modtime, 1, 1, 0,
4337 "Return t if last mod time of BUF's visited file matches what BUF records.\n\
4338This means that the file has not been changed since it was visited or saved.")
4339 (buf)
4340 Lisp_Object buf;
4341{
4342 struct buffer *b;
4343 struct stat st;
4344 Lisp_Object handler;
4345
4346 CHECK_BUFFER (buf, 0);
4347 b = XBUFFER (buf);
4348
4349 if (!STRINGP (b->filename)) return Qt;
4350 if (b->modtime == 0) return Qt;
4351
4352 /* If the file name has special constructs in it,
4353 call the corresponding file handler. */
4354 handler = Ffind_file_name_handler (b->filename,
4355 Qverify_visited_file_modtime);
4356 if (!NILP (handler))
4357 return call2 (handler, Qverify_visited_file_modtime, buf);
4358
4359 if (stat (XSTRING (b->filename)->data, &st) < 0)
4360 {
4361 /* If the file doesn't exist now and didn't exist before,
4362 we say that it isn't modified, provided the error is a tame one. */
4363 if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
4364 st.st_mtime = -1;
4365 else
4366 st.st_mtime = 0;
4367 }
4368 if (st.st_mtime == b->modtime
4369 /* If both are positive, accept them if they are off by one second. */
4370 || (st.st_mtime > 0 && b->modtime > 0
4371 && (st.st_mtime == b->modtime + 1
4372 || st.st_mtime == b->modtime - 1)))
4373 return Qt;
4374 return Qnil;
4375}
4376
4377DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
4378 Sclear_visited_file_modtime, 0, 0, 0,
4379 "Clear out records of last mod time of visited file.\n\
4380Next attempt to save will certainly not complain of a discrepancy.")
4381 ()
4382{
4383 current_buffer->modtime = 0;
4384 return Qnil;
4385}
4386
4387DEFUN ("visited-file-modtime", Fvisited_file_modtime,
4388 Svisited_file_modtime, 0, 0, 0,
4389 "Return the current buffer's recorded visited file modification time.\n\
4390The value is a list of the form (HIGH . LOW), like the time values\n\
4391that `file-attributes' returns.")
4392 ()
4393{
4394 return long_to_cons ((unsigned long) current_buffer->modtime);
4395}
4396
4397DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
4398 Sset_visited_file_modtime, 0, 1, 0,
4399 "Update buffer's recorded modification time from the visited file's time.\n\
4400Useful if the buffer was not read from the file normally\n\
4401or if the file itself has been changed for some known benign reason.\n\
4402An argument specifies the modification time value to use\n\
4403\(instead of that of the visited file), in the form of a list\n\
4404\(HIGH . LOW) or (HIGH LOW).")
4405 (time_list)
4406 Lisp_Object time_list;
4407{
4408 if (!NILP (time_list))
4409 current_buffer->modtime = cons_to_long (time_list);
4410 else
4411 {
4412 register Lisp_Object filename;
4413 struct stat st;
4414 Lisp_Object handler;
4415
4416 filename = Fexpand_file_name (current_buffer->filename, Qnil);
4417
4418 /* If the file name has special constructs in it,
4419 call the corresponding file handler. */
4420 handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
4421 if (!NILP (handler))
4422 /* The handler can find the file name the same way we did. */
4423 return call2 (handler, Qset_visited_file_modtime, Qnil);
4424 else if (stat (XSTRING (filename)->data, &st) >= 0)
4425 current_buffer->modtime = st.st_mtime;
4426 }
4427
4428 return Qnil;
4429}
4430\f
4431Lisp_Object
4432auto_save_error ()
4433{
4434 ring_bell ();
4435 message ("Autosaving...error for %s", XSTRING (current_buffer->name)->data);
4436 Fsleep_for (make_number (1), Qnil);
4437 message ("Autosaving...error!for %s", XSTRING (current_buffer->name)->data);
4438 Fsleep_for (make_number (1), Qnil);
4439 message ("Autosaving...error for %s", XSTRING (current_buffer->name)->data);
4440 Fsleep_for (make_number (1), Qnil);
4441 return Qnil;
4442}
4443
4444Lisp_Object
4445auto_save_1 ()
4446{
4447 unsigned char *fn;
4448 struct stat st;
4449
4450 /* Get visited file's mode to become the auto save file's mode. */
4451 if (stat (XSTRING (current_buffer->filename)->data, &st) >= 0)
4452 /* But make sure we can overwrite it later! */
4453 auto_save_mode_bits = st.st_mode | 0600;
4454 else
4455 auto_save_mode_bits = 0666;
4456
4457 return
4458 Fwrite_region (Qnil, Qnil,
4459 current_buffer->auto_save_file_name,
4460 Qnil, Qlambda, Qnil, Qnil);
4461}
4462
4463static Lisp_Object
4464do_auto_save_unwind (desc) /* used as unwind-protect function */
4465 Lisp_Object desc;
4466{
4467 auto_saving = 0;
4468 if (XINT (desc) >= 0)
4469 close (XINT (desc));
4470 return Qnil;
4471}
4472
4473DEFUN ("do-auto-save", Fdo_auto_save, Sdo_auto_save, 0, 2, "",
4474 "Auto-save all buffers that need it.\n\
4475This is all buffers that have auto-saving enabled\n\
4476and are changed since last auto-saved.\n\
4477Auto-saving writes the buffer into a file\n\
4478so that your editing is not lost if the system crashes.\n\
4479This file is not the file you visited; that changes only when you save.\n\
4480Normally we run the normal hook `auto-save-hook' before saving.\n\n\
4481A non-nil NO-MESSAGE argument means do not print any message if successful.\n\
4482A non-nil CURRENT-ONLY argument means save only current buffer.")
4483 (no_message, current_only)
4484 Lisp_Object no_message, current_only;
4485{
4486 struct buffer *old = current_buffer, *b;
4487 Lisp_Object tail, buf;
4488 int auto_saved = 0;
4489 char *omessage = echo_area_glyphs;
4490 int omessage_length = echo_area_glyphs_length;
4491 int do_handled_files;
4492 Lisp_Object oquit;
4493 int listdesc;
4494 int count = specpdl_ptr - specpdl;
4495 int *ptr;
4496
4497 /* Ordinarily don't quit within this function,
4498 but don't make it impossible to quit (in case we get hung in I/O). */
4499 oquit = Vquit_flag;
4500 Vquit_flag = Qnil;
4501
4502 /* No GCPRO needed, because (when it matters) all Lisp_Object variables
4503 point to non-strings reached from Vbuffer_alist. */
4504
4505 if (minibuf_level)
4506 no_message = Qt;
4507
4508 if (!NILP (Vrun_hooks))
4509 call1 (Vrun_hooks, intern ("auto-save-hook"));
4510
4511 if (STRINGP (Vauto_save_list_file_name))
4512 {
4513 Lisp_Object listfile;
4514 listfile = Fexpand_file_name (Vauto_save_list_file_name, Qnil);
4515#ifdef DOS_NT
4516 listdesc = open (XSTRING (listfile)->data,
4517 O_WRONLY | O_TRUNC | O_CREAT | O_TEXT,
4518 S_IREAD | S_IWRITE);
4519#else /* not DOS_NT */
4520 listdesc = creat (XSTRING (listfile)->data, 0666);
4521#endif /* not DOS_NT */
4522 }
4523 else
4524 listdesc = -1;
4525
4526 /* Arrange to close that file whether or not we get an error.
4527 Also reset auto_saving to 0. */
4528 record_unwind_protect (do_auto_save_unwind, make_number (listdesc));
4529
4530 auto_saving = 1;
4531
4532 /* First, save all files which don't have handlers. If Emacs is
4533 crashing, the handlers may tweak what is causing Emacs to crash
4534 in the first place, and it would be a shame if Emacs failed to
4535 autosave perfectly ordinary files because it couldn't handle some
4536 ange-ftp'd file. */
4537 for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
4538 for (tail = Vbuffer_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
4539 {
4540 buf = XCONS (XCONS (tail)->car)->cdr;
4541 b = XBUFFER (buf);
4542
4543 /* Record all the buffers that have auto save mode
4544 in the special file that lists them. For each of these buffers,
4545 Record visited name (if any) and auto save name. */
4546 if (STRINGP (b->auto_save_file_name)
4547 && listdesc >= 0 && do_handled_files == 0)
4548 {
4549 if (!NILP (b->filename))
4550 {
4551 write (listdesc, XSTRING (b->filename)->data,
4552 XSTRING (b->filename)->size);
4553 }
4554 write (listdesc, "\n", 1);
4555 write (listdesc, XSTRING (b->auto_save_file_name)->data,
4556 XSTRING (b->auto_save_file_name)->size);
4557 write (listdesc, "\n", 1);
4558 }
4559
4560 if (!NILP (current_only)
4561 && b != current_buffer)
4562 continue;
4563
4564 /* Don't auto-save indirect buffers.
4565 The base buffer takes care of it. */
4566 if (b->base_buffer)
4567 continue;
4568
4569 /* Check for auto save enabled
4570 and file changed since last auto save
4571 and file changed since last real save. */
4572 if (STRINGP (b->auto_save_file_name)
4573 && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
4574 && b->auto_save_modified < BUF_MODIFF (b)
4575 /* -1 means we've turned off autosaving for a while--see below. */
4576 && XINT (b->save_length) >= 0
4577 && (do_handled_files
4578 || NILP (Ffind_file_name_handler (b->auto_save_file_name,
4579 Qwrite_region))))
4580 {
4581 EMACS_TIME before_time, after_time;
4582
4583 EMACS_GET_TIME (before_time);
4584
4585 /* If we had a failure, don't try again for 20 minutes. */
4586 if (b->auto_save_failure_time >= 0
4587 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
4588 continue;
4589
4590 if ((XFASTINT (b->save_length) * 10
4591 > (BUF_Z (b) - BUF_BEG (b)) * 13)
4592 /* A short file is likely to change a large fraction;
4593 spare the user annoying messages. */
4594 && XFASTINT (b->save_length) > 5000
4595 /* These messages are frequent and annoying for `*mail*'. */
4596 && !EQ (b->filename, Qnil)
4597 && NILP (no_message))
4598 {
4599 /* It has shrunk too much; turn off auto-saving here. */
4600 message ("Buffer %s has shrunk a lot; auto save turned off there",
4601 XSTRING (b->name)->data);
4602 /* Turn off auto-saving until there's a real save,
4603 and prevent any more warnings. */
4604 XSETINT (b->save_length, -1);
4605 Fsleep_for (make_number (1), Qnil);
4606 continue;
4607 }
4608 set_buffer_internal (b);
4609 if (!auto_saved && NILP (no_message))
4610 message1 ("Auto-saving...");
4611 internal_condition_case (auto_save_1, Qt, auto_save_error);
4612 auto_saved++;
4613 b->auto_save_modified = BUF_MODIFF (b);
4614 XSETFASTINT (current_buffer->save_length, Z - BEG);
4615 set_buffer_internal (old);
4616
4617 EMACS_GET_TIME (after_time);
4618
4619 /* If auto-save took more than 60 seconds,
4620 assume it was an NFS failure that got a timeout. */
4621 if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
4622 b->auto_save_failure_time = EMACS_SECS (after_time);
4623 }
4624 }
4625
4626 /* Prevent another auto save till enough input events come in. */
4627 record_auto_save ();
4628
4629 if (auto_saved && NILP (no_message))
4630 {
4631 if (omessage)
4632 {
4633 sit_for (1, 0, 0, 0);
4634 message2 (omessage, omessage_length);
4635 }
4636 else
4637 message1 ("Auto-saving...done");
4638 }
4639
4640 Vquit_flag = oquit;
4641
4642 unbind_to (count, Qnil);
4643 return Qnil;
4644}
4645
4646DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved,
4647 Sset_buffer_auto_saved, 0, 0, 0,
4648 "Mark current buffer as auto-saved with its current text.\n\
4649No auto-save file will be written until the buffer changes again.")
4650 ()
4651{
4652 current_buffer->auto_save_modified = MODIFF;
4653 XSETFASTINT (current_buffer->save_length, Z - BEG);
4654 current_buffer->auto_save_failure_time = -1;
4655 return Qnil;
4656}
4657
4658DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
4659 Sclear_buffer_auto_save_failure, 0, 0, 0,
4660 "Clear any record of a recent auto-save failure in the current buffer.")
4661 ()
4662{
4663 current_buffer->auto_save_failure_time = -1;
4664 return Qnil;
4665}
4666
4667DEFUN ("recent-auto-save-p", Frecent_auto_save_p, Srecent_auto_save_p,
4668 0, 0, 0,
4669 "Return t if buffer has been auto-saved since last read in or saved.")
4670 ()
4671{
4672 return (SAVE_MODIFF < current_buffer->auto_save_modified) ? Qt : Qnil;
4673}
4674\f
4675/* Reading and completing file names */
4676extern Lisp_Object Ffile_name_completion (), Ffile_name_all_completions ();
4677
4678/* In the string VAL, change each $ to $$ and return the result. */
4679
4680static Lisp_Object
4681double_dollars (val)
4682 Lisp_Object val;
4683{
4684 register unsigned char *old, *new;
4685 register int n;
4686 int osize, count;
4687
4688 osize = XSTRING (val)->size;
4689 /* Quote "$" as "$$" to get it past substitute-in-file-name */
4690 for (n = osize, count = 0, old = XSTRING (val)->data; n > 0; n--)
4691 if (*old++ == '$') count++;
4692 if (count > 0)
4693 {
4694 old = XSTRING (val)->data;
4695 val = Fmake_string (make_number (osize + count), make_number (0));
4696 new = XSTRING (val)->data;
4697 for (n = osize; n > 0; n--)
4698 if (*old != '$')
4699 *new++ = *old++;
4700 else
4701 {
4702 *new++ = '$';
4703 *new++ = '$';
4704 old++;
4705 }
4706 }
4707 return val;
4708}
4709
4710DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
4711 3, 3, 0,
4712 "Internal subroutine for read-file-name. Do not call this.")
4713 (string, dir, action)
4714 Lisp_Object string, dir, action;
4715 /* action is nil for complete, t for return list of completions,
4716 lambda for verify final value */
4717{
4718 Lisp_Object name, specdir, realdir, val, orig_string;
4719 int changed;
4720 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4721
4722 CHECK_STRING (string, 0);
4723
4724 realdir = dir;
4725 name = string;
4726 orig_string = Qnil;
4727 specdir = Qnil;
4728 changed = 0;
4729 /* No need to protect ACTION--we only compare it with t and nil. */
4730 GCPRO5 (string, realdir, name, specdir, orig_string);
4731
4732 if (XSTRING (string)->size == 0)
4733 {
4734 if (EQ (action, Qlambda))
4735 {
4736 UNGCPRO;
4737 return Qnil;
4738 }
4739 }
4740 else
4741 {
4742 orig_string = string;
4743 string = Fsubstitute_in_file_name (string);
4744 changed = NILP (Fstring_equal (string, orig_string));
4745 name = Ffile_name_nondirectory (string);
4746 val = Ffile_name_directory (string);
4747 if (! NILP (val))
4748 realdir = Fexpand_file_name (val, realdir);
4749 }
4750
4751 if (NILP (action))
4752 {
4753 specdir = Ffile_name_directory (string);
4754 val = Ffile_name_completion (name, realdir);
4755 UNGCPRO;
4756 if (!STRINGP (val))
4757 {
4758 if (changed)
4759 return double_dollars (string);
4760 return val;
4761 }
4762
4763 if (!NILP (specdir))
4764 val = concat2 (specdir, val);
4765#ifndef VMS
4766 return double_dollars (val);
4767#else /* not VMS */
4768 return val;
4769#endif /* not VMS */
4770 }
4771 UNGCPRO;
4772
4773 if (EQ (action, Qt))
4774 return Ffile_name_all_completions (name, realdir);
4775 /* Only other case actually used is ACTION = lambda */
4776#ifdef VMS
4777 /* Supposedly this helps commands such as `cd' that read directory names,
4778 but can someone explain how it helps them? -- RMS */
4779 if (XSTRING (name)->size == 0)
4780 return Qt;
4781#endif /* VMS */
4782 return Ffile_exists_p (string);
4783}
4784
4785DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
4786 "Read file name, prompting with PROMPT and completing in directory DIR.\n\
4787Value is not expanded---you must call `expand-file-name' yourself.\n\
4788Default name to DEFAULT-FILENAME if user enters a null string.\n\
4789 (If DEFAULT-FILENAME is omitted, the visited file name is used,\n\
4790 except that if INITIAL is specified, that combined with DIR is used.)\n\
4791Fourth arg MUSTMATCH non-nil means require existing file's name.\n\
4792 Non-nil and non-t means also require confirmation after completion.\n\
4793Fifth arg INITIAL specifies text to start with.\n\
4794DIR defaults to current buffer's directory default.")
4795 (prompt, dir, default_filename, mustmatch, initial)
4796 Lisp_Object prompt, dir, default_filename, mustmatch, initial;
4797{
4798 Lisp_Object val, insdef, insdef1, tem;
4799 struct gcpro gcpro1, gcpro2;
4800 register char *homedir;
4801 int count;
4802
4803 if (NILP (dir))
4804 dir = current_buffer->directory;
4805 if (NILP (default_filename))
4806 {
4807 if (! NILP (initial))
4808 default_filename = Fexpand_file_name (initial, dir);
4809 else
4810 default_filename = current_buffer->filename;
4811 }
4812
4813 /* If dir starts with user's homedir, change that to ~. */
4814 homedir = (char *) egetenv ("HOME");
4815#ifdef DOS_NT
4816 homedir = strcpy (alloca (strlen (homedir) + 1), homedir);
4817 CORRECT_DIR_SEPS (homedir);
4818#endif
4819 if (homedir != 0
4820 && STRINGP (dir)
4821 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
4822 && IS_DIRECTORY_SEP (XSTRING (dir)->data[strlen (homedir)]))
4823 {
4824 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
4825 XSTRING (dir)->size - strlen (homedir) + 1);
4826 XSTRING (dir)->data[0] = '~';
4827 }
4828
4829 if (insert_default_directory && STRINGP (dir))
4830 {
4831 insdef = dir;
4832 if (!NILP (initial))
4833 {
4834 Lisp_Object args[2], pos;
4835
4836 args[0] = insdef;
4837 args[1] = initial;
4838 insdef = Fconcat (2, args);
4839 pos = make_number (XSTRING (double_dollars (dir))->size);
4840 insdef1 = Fcons (double_dollars (insdef), pos);
4841 }
4842 else
4843 insdef1 = double_dollars (insdef);
4844 }
4845 else if (STRINGP (initial))
4846 {
4847 insdef = initial;
4848 insdef1 = Fcons (double_dollars (insdef), 0);
4849 }
4850 else
4851 insdef = Qnil, insdef1 = Qnil;
4852
4853#ifdef VMS
4854 count = specpdl_ptr - specpdl;
4855 specbind (intern ("completion-ignore-case"), Qt);
4856#endif
4857
4858 GCPRO2 (insdef, default_filename);
4859 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4860 dir, mustmatch, insdef1,
4861 Qfile_name_history, default_filename);
4862
4863#ifdef VMS
4864 unbind_to (count, Qnil);
4865#endif
4866
4867 UNGCPRO;
4868 if (NILP (val))
4869 error ("No file name specified");
4870 tem = Fstring_equal (val, insdef);
4871 if (!NILP (tem) && !NILP (default_filename))
4872 return default_filename;
4873 if (XSTRING (val)->size == 0 && NILP (insdef))
4874 {
4875 if (!NILP (default_filename))
4876 return default_filename;
4877 else
4878 error ("No default file name");
4879 }
4880 return Fsubstitute_in_file_name (val);
4881}
4882
4883#if 0 /* Old version */
4884DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0,
4885 /* Don't confuse make-docfile by having two doc strings for this function.
4886 make-docfile does not pay attention to #if, for good reason! */
4887 0)
4888 (prompt, dir, defalt, mustmatch, initial)
4889 Lisp_Object prompt, dir, defalt, mustmatch, initial;
4890{
4891 Lisp_Object val, insdef, tem;
4892 struct gcpro gcpro1, gcpro2;
4893 register char *homedir;
4894 int count;
4895
4896 if (NILP (dir))
4897 dir = current_buffer->directory;
4898 if (NILP (defalt))
4899 defalt = current_buffer->filename;
4900
4901 /* If dir starts with user's homedir, change that to ~. */
4902 homedir = (char *) egetenv ("HOME");
4903 if (homedir != 0
4904 && STRINGP (dir)
4905 && !strncmp (homedir, XSTRING (dir)->data, strlen (homedir))
4906 && XSTRING (dir)->data[strlen (homedir)] == '/')
4907 {
4908 dir = make_string (XSTRING (dir)->data + strlen (homedir) - 1,
4909 XSTRING (dir)->size - strlen (homedir) + 1);
4910 XSTRING (dir)->data[0] = '~';
4911 }
4912
4913 if (!NILP (initial))
4914 insdef = initial;
4915 else if (insert_default_directory)
4916 insdef = dir;
4917 else
4918 insdef = build_string ("");
4919
4920#ifdef VMS
4921 count = specpdl_ptr - specpdl;
4922 specbind (intern ("completion-ignore-case"), Qt);
4923#endif
4924
4925 GCPRO2 (insdef, defalt);
4926 val = Fcompleting_read (prompt, intern ("read-file-name-internal"),
4927 dir, mustmatch,
4928 insert_default_directory ? insdef : Qnil,
4929 Qfile_name_history, Qnil);
4930
4931#ifdef VMS
4932 unbind_to (count, Qnil);
4933#endif
4934
4935 UNGCPRO;
4936 if (NILP (val))
4937 error ("No file name specified");
4938 tem = Fstring_equal (val, insdef);
4939 if (!NILP (tem) && !NILP (defalt))
4940 return defalt;
4941 return Fsubstitute_in_file_name (val);
4942}
4943#endif /* Old version */
4944\f
4945syms_of_fileio ()
4946{
4947 Qexpand_file_name = intern ("expand-file-name");
4948 Qsubstitute_in_file_name = intern ("substitute-in-file-name");
4949 Qdirectory_file_name = intern ("directory-file-name");
4950 Qfile_name_directory = intern ("file-name-directory");
4951 Qfile_name_nondirectory = intern ("file-name-nondirectory");
4952 Qunhandled_file_name_directory = intern ("unhandled-file-name-directory");
4953 Qfile_name_as_directory = intern ("file-name-as-directory");
4954 Qcopy_file = intern ("copy-file");
4955 Qmake_directory_internal = intern ("make-directory-internal");
4956 Qdelete_directory = intern ("delete-directory");
4957 Qdelete_file = intern ("delete-file");
4958 Qrename_file = intern ("rename-file");
4959 Qadd_name_to_file = intern ("add-name-to-file");
4960 Qmake_symbolic_link = intern ("make-symbolic-link");
4961 Qfile_exists_p = intern ("file-exists-p");
4962 Qfile_executable_p = intern ("file-executable-p");
4963 Qfile_readable_p = intern ("file-readable-p");
4964 Qfile_writable_p = intern ("file-writable-p");
4965 Qfile_symlink_p = intern ("file-symlink-p");
4966 Qaccess_file = intern ("access-file");
4967 Qfile_directory_p = intern ("file-directory-p");
4968 Qfile_regular_p = intern ("file-regular-p");
4969 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
4970 Qfile_modes = intern ("file-modes");
4971 Qset_file_modes = intern ("set-file-modes");
4972 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
4973 Qinsert_file_contents = intern ("insert-file-contents");
4974 Qwrite_region = intern ("write-region");
4975 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
4976 Qset_visited_file_modtime = intern ("set-visited-file-modtime");
4977
4978 staticpro (&Qexpand_file_name);
4979 staticpro (&Qsubstitute_in_file_name);
4980 staticpro (&Qdirectory_file_name);
4981 staticpro (&Qfile_name_directory);
4982 staticpro (&Qfile_name_nondirectory);
4983 staticpro (&Qunhandled_file_name_directory);
4984 staticpro (&Qfile_name_as_directory);
4985 staticpro (&Qcopy_file);
4986 staticpro (&Qmake_directory_internal);
4987 staticpro (&Qdelete_directory);
4988 staticpro (&Qdelete_file);
4989 staticpro (&Qrename_file);
4990 staticpro (&Qadd_name_to_file);
4991 staticpro (&Qmake_symbolic_link);
4992 staticpro (&Qfile_exists_p);
4993 staticpro (&Qfile_executable_p);
4994 staticpro (&Qfile_readable_p);
4995 staticpro (&Qfile_writable_p);
4996 staticpro (&Qaccess_file);
4997 staticpro (&Qfile_symlink_p);
4998 staticpro (&Qfile_directory_p);
4999 staticpro (&Qfile_regular_p);
5000 staticpro (&Qfile_accessible_directory_p);
5001 staticpro (&Qfile_modes);
5002 staticpro (&Qset_file_modes);
5003 staticpro (&Qfile_newer_than_file_p);
5004 staticpro (&Qinsert_file_contents);
5005 staticpro (&Qwrite_region);
5006 staticpro (&Qverify_visited_file_modtime);
5007 staticpro (&Qset_visited_file_modtime);
5008
5009 Qfile_name_history = intern ("file-name-history");
5010 Fset (Qfile_name_history, Qnil);
5011 staticpro (&Qfile_name_history);
5012
5013 Qfile_error = intern ("file-error");
5014 staticpro (&Qfile_error);
5015 Qfile_already_exists = intern ("file-already-exists");
5016 staticpro (&Qfile_already_exists);
5017 Qfile_date_error = intern ("file-date-error");
5018 staticpro (&Qfile_date_error);
5019
5020#ifdef DOS_NT
5021 Qfind_buffer_file_type = intern ("find-buffer-file-type");
5022 staticpro (&Qfind_buffer_file_type);
5023#endif /* DOS_NT */
5024
5025 DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format,
5026 "*Format in which to write auto-save files.\n\
5027Should be a list of symbols naming formats that are defined in `format-alist'.\n\
5028If it is t, which is the default, auto-save files are written in the\n\
5029same format as a regular save would use.");
5030 Vauto_save_file_format = Qt;
5031
5032 Qformat_decode = intern ("format-decode");
5033 staticpro (&Qformat_decode);
5034 Qformat_annotate_function = intern ("format-annotate-function");
5035 staticpro (&Qformat_annotate_function);
5036
5037 Qcar_less_than_car = intern ("car-less-than-car");
5038 staticpro (&Qcar_less_than_car);
5039
5040 Fput (Qfile_error, Qerror_conditions,
5041 Fcons (Qfile_error, Fcons (Qerror, Qnil)));
5042 Fput (Qfile_error, Qerror_message,
5043 build_string ("File error"));
5044
5045 Fput (Qfile_already_exists, Qerror_conditions,
5046 Fcons (Qfile_already_exists,
5047 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5048 Fput (Qfile_already_exists, Qerror_message,
5049 build_string ("File already exists"));
5050
5051 Fput (Qfile_date_error, Qerror_conditions,
5052 Fcons (Qfile_date_error,
5053 Fcons (Qfile_error, Fcons (Qerror, Qnil))));
5054 Fput (Qfile_date_error, Qerror_message,
5055 build_string ("Cannot set file date"));
5056
5057 DEFVAR_BOOL ("insert-default-directory", &insert_default_directory,
5058 "*Non-nil means when reading a filename start with default dir in minibuffer.");
5059 insert_default_directory = 1;
5060
5061 DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm,
5062 "*Non-nil means write new files with record format `stmlf'.\n\
5063nil means use format `var'. This variable is meaningful only on VMS.");
5064 vms_stmlf_recfm = 0;
5065
5066 DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char,
5067 "Directory separator character for built-in functions that return file names.\n\
5068The value should be either ?/ or ?\\ (any other value is treated as ?\\).\n\
5069This variable affects the built-in functions only on Windows,\n\
5070on other platforms, it is initialized so that Lisp code can find out\n\
5071what the normal separator is.");
5072 Vdirectory_sep_char = '/';
5073
5074 DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist,
5075 "*Alist of elements (REGEXP . HANDLER) for file names handled specially.\n\
5076If a file name matches REGEXP, then all I/O on that file is done by calling\n\
5077HANDLER.\n\
5078\n\
5079The first argument given to HANDLER is the name of the I/O primitive\n\
5080to be handled; the remaining arguments are the arguments that were\n\
5081passed to that primitive. For example, if you do\n\
5082 (file-exists-p FILENAME)\n\
5083and FILENAME is handled by HANDLER, then HANDLER is called like this:\n\
5084 (funcall HANDLER 'file-exists-p FILENAME)\n\
5085The function `find-file-name-handler' checks this list for a handler\n\
5086for its argument.");
5087 Vfile_name_handler_alist = Qnil;
5088
5089 DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions,
5090 "A list of functions to be called at the end of `insert-file-contents'.\n\
5091Each is passed one argument, the number of bytes inserted. It should return\n\
5092the new byte count, and leave point the same. If `insert-file-contents' is\n\
5093intercepted by a handler from `file-name-handler-alist', that handler is\n\
5094responsible for calling the after-insert-file-functions if appropriate.");
5095 Vafter_insert_file_functions = Qnil;
5096
5097 DEFVAR_LISP ("write-region-annotate-functions", &Vwrite_region_annotate_functions,
5098 "A list of functions to be called at the start of `write-region'.\n\
5099Each is passed two arguments, START and END as for `write-region'.\n\
5100These are usually two numbers but not always; see the documentation\n\
5101for `write-region'. The function should return a list of pairs\n\
5102of the form (POSITION . STRING), consisting of strings to be effectively\n\
5103inserted at the specified positions of the file being written (1 means to\n\
5104insert before the first byte written). The POSITIONs must be sorted into\n\
5105increasing order. If there are several functions in the list, the several\n\
5106lists are merged destructively.");
5107 Vwrite_region_annotate_functions = Qnil;
5108
5109 DEFVAR_LISP ("write-region-annotations-so-far",
5110 &Vwrite_region_annotations_so_far,
5111 "When an annotation function is called, this holds the previous annotations.\n\
5112These are the annotations made by other annotation functions\n\
5113that were already called. See also `write-region-annotate-functions'.");
5114 Vwrite_region_annotations_so_far = Qnil;
5115
5116 DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers,
5117 "A list of file name handlers that temporarily should not be used.\n\
5118This applies only to the operation `inhibit-file-name-operation'.");
5119 Vinhibit_file_name_handlers = Qnil;
5120
5121 DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation,
5122 "The operation for which `inhibit-file-name-handlers' is applicable.");
5123 Vinhibit_file_name_operation = Qnil;
5124
5125 DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
5126 "File name in which we write a list of all auto save file names.\n\
5127This variable is initialized automatically from `auto-save-list-file-prefix'\n\
5128shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
5129a non-nil value.");
5130 Vauto_save_list_file_name = Qnil;
5131
5132 defsubr (&Sfind_file_name_handler);
5133 defsubr (&Sfile_name_directory);
5134 defsubr (&Sfile_name_nondirectory);
5135 defsubr (&Sunhandled_file_name_directory);
5136 defsubr (&Sfile_name_as_directory);
5137 defsubr (&Sdirectory_file_name);
5138 defsubr (&Smake_temp_name);
5139 defsubr (&Sexpand_file_name);
5140 defsubr (&Ssubstitute_in_file_name);
5141 defsubr (&Scopy_file);
5142 defsubr (&Smake_directory_internal);
5143 defsubr (&Sdelete_directory);
5144 defsubr (&Sdelete_file);
5145 defsubr (&Srename_file);
5146 defsubr (&Sadd_name_to_file);
5147#ifdef S_IFLNK
5148 defsubr (&Smake_symbolic_link);
5149#endif /* S_IFLNK */
5150#ifdef VMS
5151 defsubr (&Sdefine_logical_name);
5152#endif /* VMS */
5153#ifdef HPUX_NET
5154 defsubr (&Ssysnetunam);
5155#endif /* HPUX_NET */
5156 defsubr (&Sfile_name_absolute_p);
5157 defsubr (&Sfile_exists_p);
5158 defsubr (&Sfile_executable_p);
5159 defsubr (&Sfile_readable_p);
5160 defsubr (&Sfile_writable_p);
5161 defsubr (&Saccess_file);
5162 defsubr (&Sfile_symlink_p);
5163 defsubr (&Sfile_directory_p);
5164 defsubr (&Sfile_accessible_directory_p);
5165 defsubr (&Sfile_regular_p);
5166 defsubr (&Sfile_modes);
5167 defsubr (&Sset_file_modes);
5168 defsubr (&Sset_default_file_modes);
5169 defsubr (&Sdefault_file_modes);
5170 defsubr (&Sfile_newer_than_file_p);
5171 defsubr (&Sinsert_file_contents);
5172 defsubr (&Swrite_region);
5173 defsubr (&Scar_less_than_car);
5174 defsubr (&Sverify_visited_file_modtime);
5175 defsubr (&Sclear_visited_file_modtime);
5176 defsubr (&Svisited_file_modtime);
5177 defsubr (&Sset_visited_file_modtime);
5178 defsubr (&Sdo_auto_save);
5179 defsubr (&Sset_buffer_auto_saved);
5180 defsubr (&Sclear_buffer_auto_save_failure);
5181 defsubr (&Srecent_auto_save_p);
5182
5183 defsubr (&Sread_file_name_internal);
5184 defsubr (&Sread_file_name);
5185
5186#ifdef unix
5187 defsubr (&Sunix_sync);
5188#endif
5189}