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