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