XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / src / fileio.c
1 /* File IO for XEmacs.
2    Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc.
3    Copyright (C) 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; 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 /* Synched up with: Mule 2.0, FSF 19.30. */
23 /* More syncing: FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
24
25 #include <config.h>
26 #include "lisp.h"
27 #include <limits.h>
28
29 #include "buffer.h"
30 #include "events.h"
31 #include "frame.h"
32 #include "insdel.h"
33 #include "lstream.h"
34 #include "redisplay.h"
35 #include "sysdep.h"
36 #include "window.h"             /* minibuf_level */
37 #ifdef FILE_CODING
38 #include "file-coding.h"
39 #endif
40
41 #ifdef HAVE_LIBGEN_H            /* Must come before sysfile.h */
42 #include <libgen.h>
43 #endif
44 #include "sysfile.h"
45 #include "sysproc.h"
46 #include "syspwd.h"
47 #include "systime.h"
48 #include "sysdir.h"
49
50 #ifdef HPUX
51 #include <netio.h>
52 #ifdef HPUX_PRE_8_0
53 #include <errnet.h>
54 #endif /* HPUX_PRE_8_0 */
55 #endif /* HPUX */
56
57 #ifdef WINDOWSNT
58 #define NOMINMAX 1
59 #include <direct.h>
60 #include <fcntl.h>
61 #include <stdlib.h>
62 #endif /* not WINDOWSNT */
63
64 #ifdef WINDOWSNT
65 #define CORRECT_DIR_SEPS(s) \
66   do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
67     else unixtodos_filename (s); \
68   } while (0)
69 #define IS_DRIVE(x) isalpha (x)
70 /* Need to lower-case the drive letter, or else expanded
71    filenames will sometimes compare inequal, because
72    `expand-file-name' doesn't always down-case the drive letter.  */
73 #define DRIVE_LETTER(x) tolower (x)
74 #endif /* WINDOWSNT */
75
76 int lisp_to_time (Lisp_Object, time_t *);
77 Lisp_Object time_to_lisp (time_t);
78
79 /* Nonzero during writing of auto-save files */
80 static int auto_saving;
81
82 /* Set by auto_save_1 to mode of original file so Fwrite_region_internal
83    will create a new file with the same mode as the original */
84 static int auto_save_mode_bits;
85
86 /* Alist of elements (REGEXP . HANDLER) for file names
87    whose I/O is done with a special handler.  */
88 Lisp_Object Vfile_name_handler_alist;
89
90 /* Format for auto-save files */
91 Lisp_Object Vauto_save_file_format;
92
93 /* Lisp functions for translating file formats */
94 Lisp_Object Qformat_decode, Qformat_annotate_function;
95
96 /* Functions to be called to process text properties in inserted file.  */
97 Lisp_Object Vafter_insert_file_functions;
98
99 /* Functions to be called to create text property annotations for file.  */
100 Lisp_Object Vwrite_region_annotate_functions;
101
102 /* During build_annotations, each time an annotation function is called,
103    this holds the annotations made by the previous functions.  */
104 Lisp_Object Vwrite_region_annotations_so_far;
105
106 /* File name in which we write a list of all our auto save files.  */
107 Lisp_Object Vauto_save_list_file_name;
108
109 int disable_auto_save_when_buffer_shrinks;
110
111 Lisp_Object Vdirectory_sep_char;
112
113 /* These variables describe handlers that have "already" had a chance
114    to handle the current operation.
115
116    Vinhibit_file_name_handlers is a list of file name handlers.
117    Vinhibit_file_name_operation is the operation being handled.
118    If we try to handle that operation, we ignore those handlers.  */
119
120 static Lisp_Object Vinhibit_file_name_handlers;
121 static Lisp_Object Vinhibit_file_name_operation;
122
123 Lisp_Object Qfile_error, Qfile_already_exists;
124
125 Lisp_Object Qauto_save_hook;
126 Lisp_Object Qauto_save_error;
127 Lisp_Object Qauto_saving;
128
129 Lisp_Object Qcar_less_than_car;
130
131 Lisp_Object Qcompute_buffer_file_truename;
132
133 EXFUN (Frunning_temacs_p, 0);
134
135 /* signal a file error when errno contains a meaningful value. */
136
137 DOESNT_RETURN
138 report_file_error (CONST char *string, Lisp_Object data)
139 {
140   /* #### dmoore - This uses current_buffer, better make sure no one
141      has GC'd the current buffer.  File handlers are giving me a headache
142      maybe I'll just always protect current_buffer around all of those
143      calls. */
144
145   signal_error (Qfile_error,
146                 Fcons (build_translated_string (string),
147                        Fcons (lisp_strerror (errno), data)));
148 }
149
150 void
151 maybe_report_file_error (CONST char *string, Lisp_Object data,
152                          Lisp_Object class, Error_behavior errb)
153 {
154   /* Optimization: */
155   if (ERRB_EQ (errb, ERROR_ME_NOT))
156     return;
157
158   maybe_signal_error (Qfile_error,
159                       Fcons (build_translated_string (string),
160                              Fcons (lisp_strerror (errno), data)),
161                       class, errb);
162 }
163
164 /* signal a file error when errno does not contain a meaningful value. */
165
166 DOESNT_RETURN
167 signal_file_error (CONST char *string, Lisp_Object data)
168 {
169   signal_error (Qfile_error,
170                 list2 (build_translated_string (string), data));
171 }
172
173 void
174 maybe_signal_file_error (CONST char *string, Lisp_Object data,
175                          Lisp_Object class, Error_behavior errb)
176 {
177   /* Optimization: */
178   if (ERRB_EQ (errb, ERROR_ME_NOT))
179     return;
180   maybe_signal_error (Qfile_error,
181                       list2 (build_translated_string (string), data),
182                       class, errb);
183 }
184
185 DOESNT_RETURN
186 signal_double_file_error (CONST char *string1, CONST char *string2,
187                           Lisp_Object data)
188 {
189   signal_error (Qfile_error,
190                 list3 (build_translated_string (string1),
191                        build_translated_string (string2),
192                        data));
193 }
194
195 void
196 maybe_signal_double_file_error (CONST char *string1, CONST char *string2,
197                                 Lisp_Object data, Lisp_Object class,
198                                 Error_behavior errb)
199 {
200   /* Optimization: */
201   if (ERRB_EQ (errb, ERROR_ME_NOT))
202     return;
203   maybe_signal_error (Qfile_error,
204                       list3 (build_translated_string (string1),
205                              build_translated_string (string2),
206                              data),
207                       class, errb);
208 }
209
210 DOESNT_RETURN
211 signal_double_file_error_2 (CONST char *string1, CONST char *string2,
212                             Lisp_Object data1, Lisp_Object data2)
213 {
214   signal_error (Qfile_error,
215                 list4 (build_translated_string (string1),
216                        build_translated_string (string2),
217                        data1, data2));
218 }
219
220 void
221 maybe_signal_double_file_error_2 (CONST char *string1, CONST char *string2,
222                                   Lisp_Object data1, Lisp_Object data2,
223                                   Lisp_Object class, Error_behavior errb)
224 {
225   /* Optimization: */
226   if (ERRB_EQ (errb, ERROR_ME_NOT))
227     return;
228   maybe_signal_error (Qfile_error,
229                       list4 (build_translated_string (string1),
230                              build_translated_string (string2),
231                              data1, data2),
232                       class, errb);
233 }
234
235 \f
236 /* Just like strerror(3), except return a lisp string instead of char *.
237    The string needs to be converted since it may be localized.
238    Perhaps this should use strerror-coding-system instead? */
239 Lisp_Object
240 lisp_strerror (int errnum)
241 {
242   return build_ext_string (strerror (errnum), Qnative);
243 }
244
245 static Lisp_Object
246 close_file_unwind (Lisp_Object fd)
247 {
248   if (CONSP (fd))
249     {
250       if (INTP (XCAR (fd)))
251         close (XINT (XCAR (fd)));
252
253       free_cons (XCONS (fd));
254     }
255   else
256     close (XINT (fd));
257
258   return Qnil;
259 }
260
261 static Lisp_Object
262 delete_stream_unwind (Lisp_Object stream)
263 {
264   Lstream_delete (XLSTREAM (stream));
265   return Qnil;
266 }
267
268 /* Restore point, having saved it as a marker.  */
269
270 static Lisp_Object
271 restore_point_unwind (Lisp_Object point_marker)
272 {
273   BUF_SET_PT (current_buffer, marker_position (point_marker));
274   return Fset_marker (point_marker, Qnil, Qnil);
275 }
276
277 /* Versions of read() and write() that allow quitting out of the actual
278    I/O.  We don't use immediate_quit (i.e. direct longjmp() out of the
279    signal handler) because that's way too losing.
280
281    (#### Actually, longjmp()ing out of the signal handler may not be
282    as losing as I thought.  See sys_do_signal() in sysdep.c.) */
283
284 ssize_t
285 read_allowing_quit (int fildes, void *buf, size_t size)
286 {
287   QUIT;
288   return sys_read_1 (fildes, buf, size, 1);
289 }
290
291 ssize_t
292 write_allowing_quit (int fildes, CONST void *buf, size_t size)
293 {
294   QUIT;
295   return sys_write_1 (fildes, buf, size, 1);
296 }
297
298 \f
299 Lisp_Object Qexpand_file_name;
300 Lisp_Object Qfile_truename;
301 Lisp_Object Qsubstitute_in_file_name;
302 Lisp_Object Qdirectory_file_name;
303 Lisp_Object Qfile_name_directory;
304 Lisp_Object Qfile_name_nondirectory;
305 Lisp_Object Qunhandled_file_name_directory;
306 Lisp_Object Qfile_name_as_directory;
307 Lisp_Object Qcopy_file;
308 Lisp_Object Qmake_directory_internal;
309 Lisp_Object Qdelete_directory;
310 Lisp_Object Qdelete_file;
311 Lisp_Object Qrename_file;
312 Lisp_Object Qadd_name_to_file;
313 Lisp_Object Qmake_symbolic_link;
314 Lisp_Object Qfile_exists_p;
315 Lisp_Object Qfile_executable_p;
316 Lisp_Object Qfile_readable_p;
317 Lisp_Object Qfile_symlink_p;
318 Lisp_Object Qfile_writable_p;
319 Lisp_Object Qfile_directory_p;
320 Lisp_Object Qfile_regular_p;
321 Lisp_Object Qfile_accessible_directory_p;
322 Lisp_Object Qfile_modes;
323 Lisp_Object Qset_file_modes;
324 Lisp_Object Qfile_newer_than_file_p;
325 Lisp_Object Qinsert_file_contents;
326 Lisp_Object Qwrite_region;
327 Lisp_Object Qverify_visited_file_modtime;
328 Lisp_Object Qset_visited_file_modtime;
329
330 /* If FILENAME is handled specially on account of its syntax,
331    return its handler function.  Otherwise, return nil.  */
332
333 DEFUN ("find-file-name-handler", Ffind_file_name_handler, 1, 2, 0, /*
334 Return FILENAME's handler function for OPERATION, if it has one.
335 Otherwise, return nil.
336 A file name is handled if one of the regular expressions in
337 `file-name-handler-alist' matches it.
338
339 If OPERATION equals `inhibit-file-name-operation', then we ignore
340 any handlers that are members of `inhibit-file-name-handlers',
341 but we still do run any other handlers.  This lets handlers
342 use the standard functions without calling themselves recursively.
343 */
344        (filename, operation))
345 {
346   /* This function does not GC */
347   /* This function can be called during GC */
348   /* This function must not munge the match data.  */
349   Lisp_Object chain, inhibited_handlers;
350
351   CHECK_STRING (filename);
352
353   if (EQ (operation, Vinhibit_file_name_operation))
354     inhibited_handlers = Vinhibit_file_name_handlers;
355   else
356     inhibited_handlers = Qnil;
357
358   EXTERNAL_LIST_LOOP (chain, Vfile_name_handler_alist)
359     {
360       Lisp_Object elt = XCAR (chain);
361       if (CONSP (elt))
362         {
363           Lisp_Object string = XCAR (elt);
364           if (STRINGP (string)
365               && (fast_lisp_string_match (string, filename) >= 0))
366             {
367               Lisp_Object handler = XCDR (elt);
368               if (NILP (Fmemq (handler, inhibited_handlers)))
369                 return handler;
370             }
371         }
372       QUIT;
373     }
374   return Qnil;
375 }
376
377 static Lisp_Object
378 call2_check_string (Lisp_Object fn, Lisp_Object arg0, Lisp_Object arg1)
379 {
380   /* This function can call lisp */
381   Lisp_Object result = call2 (fn, arg0, arg1);
382   CHECK_STRING (result);
383   return result;
384 }
385
386 static Lisp_Object
387 call2_check_string_or_nil (Lisp_Object fn, Lisp_Object arg0, Lisp_Object arg1)
388 {
389   /* This function can call lisp */
390   Lisp_Object result = call2 (fn, arg0, arg1);
391   if (!NILP (result))
392     CHECK_STRING (result);
393   return result;
394 }
395
396 static Lisp_Object
397 call3_check_string (Lisp_Object fn, Lisp_Object arg0,
398                     Lisp_Object arg1, Lisp_Object arg2)
399 {
400   /* This function can call lisp */
401   Lisp_Object result = call3 (fn, arg0, arg1, arg2);
402   CHECK_STRING (result);
403   return result;
404 }
405
406 \f
407 DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /*
408 Return the directory component in file name NAME.
409 Return nil if NAME does not include a directory.
410 Otherwise return a directory spec.
411 Given a Unix syntax file name, returns a string ending in slash.
412 */
413        (file))
414 {
415   /* This function can GC.  GC checked 1997.04.06. */
416   Bufbyte *beg;
417   Bufbyte *p;
418   Lisp_Object handler;
419
420   CHECK_STRING (file);
421
422   /* If the file name has special constructs in it,
423      call the corresponding file handler.  */
424   handler = Ffind_file_name_handler (file, Qfile_name_directory);
425   if (!NILP (handler))
426     return call2_check_string_or_nil (handler, Qfile_name_directory, file);
427
428 #ifdef FILE_SYSTEM_CASE
429   file = FILE_SYSTEM_CASE (file);
430 #endif
431   beg = XSTRING_DATA (file);
432   p = beg + XSTRING_LENGTH (file);
433
434   while (p != beg && !IS_ANY_SEP (p[-1])
435 #ifdef WINDOWSNT
436          /* only recognize drive specifier at beginning */
437          && !(p[-1] == ':' && p == beg + 2)
438 #endif
439     ) p--;
440
441   if (p == beg)
442     return Qnil;
443 #ifdef WINDOWSNT
444   /* Expansion of "c:" to drive and default directory.  */
445   /* (NT does the right thing.)  */
446   if (p == beg + 2 && beg[1] == ':')
447     {
448       /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir.  */
449       Bufbyte *res = alloca (MAXPATHLEN + 1);
450       if (getdefdir (toupper (*beg) - 'A' + 1, res))
451         {
452           char *c=((char *) res) + strlen ((char *) res);
453           if (!IS_DIRECTORY_SEP (*c))
454             {
455               *c++ = DIRECTORY_SEP;
456               *c = '\0';
457             }
458           beg = res;
459           p = beg + strlen ((char *) beg);
460         }
461     }
462 #endif /* WINDOWSNT */
463   return make_string (beg, p - beg);
464 }
465
466 DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /*
467 Return file name NAME sans its directory.
468 For example, in a Unix-syntax file name,
469 this is everything after the last slash,
470 or the entire name if it contains no slash.
471 */
472        (file))
473 {
474   /* This function can GC.  GC checked 1997.04.06. */
475   Bufbyte *beg, *p, *end;
476   Lisp_Object handler;
477
478   CHECK_STRING (file);
479
480   /* If the file name has special constructs in it,
481      call the corresponding file handler.  */
482   handler = Ffind_file_name_handler (file, Qfile_name_nondirectory);
483   if (!NILP (handler))
484     return call2_check_string (handler, Qfile_name_nondirectory, file);
485
486   beg = XSTRING_DATA (file);
487   end = p = beg + XSTRING_LENGTH (file);
488
489   while (p != beg && !IS_ANY_SEP (p[-1])
490 #ifdef WINDOWSNT
491          /* only recognize drive specifier at beginning */
492          && !(p[-1] == ':' && p == beg + 2)
493 #endif
494     ) p--;
495
496   return make_string (p, end - p);
497 }
498
499 DEFUN ("unhandled-file-name-directory", Funhandled_file_name_directory, 1, 1, 0, /*
500 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 */
508   (filename))
509 {
510   /* This function can GC.  GC checked 1997.04.06. */
511   Lisp_Object handler;
512
513   /* If the file name has special constructs in it,
514      call the corresponding file handler.  */
515   handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
516   if (!NILP (handler))
517     return call2 (handler, Qunhandled_file_name_directory,
518                   filename);
519
520   return Ffile_name_directory (filename);
521 }
522
523 \f
524 static char *
525 file_name_as_directory (char *out, char *in)
526 {
527   int size = strlen (in);
528
529   if (size == 0)
530     {
531       out[0] = '.';
532       out[1] = DIRECTORY_SEP;
533       out[2] = '\0';
534     }
535   else
536     {
537       strcpy (out, in);
538       /* Append a slash if necessary */
539       if (!IS_ANY_SEP (out[size-1]))
540         {
541           out[size] = DIRECTORY_SEP;
542           out[size + 1] = '\0';
543         }
544     }
545   return out;
546 }
547
548 DEFUN ("file-name-as-directory", Ffile_name_as_directory, 1, 1, 0, /*
549 Return a string representing file FILENAME interpreted as a directory.
550 This operation exists because a directory is also a file, but its name as
551 a directory is different from its name as a file.
552 The result can be used as the value of `default-directory'
553 or passed as second argument to `expand-file-name'.
554 For a Unix-syntax file name, just appends a slash,
555 except for (file-name-as-directory \"\") => \"./\".
556 */
557        (file))
558 {
559   /* This function can GC.  GC checked 1997.04.06. */
560   char *buf;
561   Lisp_Object handler;
562
563   CHECK_STRING (file);
564
565   /* If the file name has special constructs in it,
566      call the corresponding file handler.  */
567   handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
568   if (!NILP (handler))
569     return call2_check_string (handler, Qfile_name_as_directory, file);
570
571   buf = (char *) alloca (XSTRING_LENGTH (file) + 10);
572   return build_string (file_name_as_directory
573                        (buf, (char *) XSTRING_DATA (file)));
574 }
575 \f
576 /*
577  * Convert from directory name to filename.
578  * On UNIX, it's simple: just make sure there isn't a terminating /
579  *
580  * Value is nonzero if the string output is different from the input.
581  */
582
583 static int
584 directory_file_name (CONST char *src, char *dst)
585 {
586   long slen = strlen (src);
587   /* Process as Unix format: just remove any final slash.
588      But leave "/" unchanged; do not change it to "".  */
589   strcpy (dst, src);
590   if (slen > 1
591       && IS_DIRECTORY_SEP (dst[slen - 1])
592 #ifdef WINDOWSNT
593       && !IS_ANY_SEP (dst[slen - 2])
594 #endif /* WINDOWSNT */
595       )
596     dst[slen - 1] = 0;
597   return 1;
598 }
599
600 DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /*
601 Return the file name of the directory named DIR.
602 This is the name of the file that holds the data for the directory DIR.
603 This operation exists because a directory is also a file, but its name as
604 a directory is different from its name as a file.
605 In Unix-syntax, this function just removes the final slash.
606 */
607        (directory))
608 {
609   /* This function can GC.  GC checked 1997.04.06. */
610   char *buf;
611   Lisp_Object handler;
612
613   CHECK_STRING (directory);
614
615 #if 0 /* #### WTF? */
616   if (NILP (directory))
617     return Qnil;
618 #endif
619
620   /* If the file name has special constructs in it,
621      call the corresponding file handler.  */
622   handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
623   if (!NILP (handler))
624     return call2_check_string (handler, Qdirectory_file_name, directory);
625   buf = (char *) alloca (XSTRING_LENGTH (directory) + 20);
626   directory_file_name ((char *) XSTRING_DATA (directory), buf);
627   return build_string (buf);
628 }
629 \f
630 /* Fmake_temp_name used to be a simple wrapper around mktemp(), but it
631    proved too broken for our purposes (it supported only 26 or 62
632    unique names under some implementations).  For example, this
633    arbitrary limit broke generation of Gnus Incoming* files.
634
635    This implementation is better than what one usually finds in libc.
636    --hniksic */
637
638 DEFUN ("make-temp-name", Fmake_temp_name, 1, 1, 0, /*
639 Generate temporary file name starting with PREFIX.
640 The Emacs process number forms part of the result, so there is no
641 danger of generating a name being used by another process.
642
643 In addition, this function makes an attempt to choose a name that
644 does not specify an existing file.  To make this work, PREFIX should
645 be an absolute file name.
646 */
647        (prefix))
648 {
649   static char tbl[64] = {
650     'A','B','C','D','E','F','G','H',
651     'I','J','K','L','M','N','O','P',
652     'Q','R','S','T','U','V','W','X',
653     'Y','Z','a','b','c','d','e','f',
654     'g','h','i','j','k','l','m','n',
655     'o','p','q','r','s','t','u','v',
656     'w','x','y','z','0','1','2','3',
657     '4','5','6','7','8','9','-','_' };
658   static unsigned count, count_initialized_p;
659
660   Lisp_Object val;
661   Bytecount len;
662   Bufbyte *p, *data;
663   unsigned pid;
664
665   CHECK_STRING (prefix);
666
667   /* I was tempted to apply Fexpand_file_name on PREFIX here, but it's
668      a bad idea because:
669
670      1) It might change the prefix, so the resulting string might not
671      begin with PREFIX.  This violates the principle of least
672      surprise.
673
674      2) It breaks under many unforeseeable circumstances, such as with
675      the code that uses (make-temp-name "") instead of
676      (make-temp-name "./").
677
678      3) It might yield unexpected (to stat(2)) results in the presence
679      of EFS and file name handlers.  */
680
681   len = XSTRING_LENGTH (prefix);
682   val = make_uninit_string (len + 6);
683   data = XSTRING_DATA (val);
684   memcpy (data, XSTRING_DATA (prefix), len);
685   p = data + len;
686
687   /* VAL is created by adding 6 characters to PREFIX.  The first three
688      are the PID of this process, in base 64, and the second three are
689      incremented if the file already exists.  This ensures 262144
690      unique file names per PID per PREFIX.  */
691
692   pid = (unsigned)getpid ();
693   *p++ = tbl[pid & 63], pid >>= 6;
694   *p++ = tbl[pid & 63], pid >>= 6;
695   *p++ = tbl[pid & 63], pid >>= 6;
696
697   /* Here we try to minimize useless stat'ing when this function is
698      invoked many times successively with the same PREFIX.  We achieve
699      this by initializing count to a random value, and incrementing it
700      afterwards.  */
701   if (!count_initialized_p)
702     {
703       count = (unsigned)time (NULL);
704       /* Dumping temacs with a non-zero count_initialized_p wouldn't
705          make much sense.  */
706       if (NILP (Frunning_temacs_p ()))
707         count_initialized_p = 1;
708     }
709
710   while (1)
711     {
712       struct stat ignored;
713       unsigned num = count;
714
715       p[0] = tbl[num & 63], num >>= 6;
716       p[1] = tbl[num & 63], num >>= 6;
717       p[2] = tbl[num & 63], num >>= 6;
718
719       /* Poor man's congruential RN generator.  Replace with ++count
720          for debugging.  */
721       count += 25229;
722       count %= 225307;
723
724       QUIT;
725
726       if (stat ((CONST char *) data, &ignored) < 0)
727         {
728           /* We want to return only if errno is ENOENT.  */
729           if (errno == ENOENT)
730             return val;
731
732           /* The error here is dubious, but there is little else we
733              can do.  The alternatives are to return nil, which is
734              as bad as (and in many cases worse than) throwing the
735              error, or to ignore the error, which will likely result
736              in inflooping.  */
737           report_file_error ("Cannot create temporary name for prefix",
738                              list1 (prefix));
739           return Qnil; /* not reached */
740         }
741     }
742 }
743
744 \f
745 DEFUN ("expand-file-name", Fexpand_file_name, 1, 2, 0, /*
746 Convert filename NAME to absolute, and canonicalize it.
747 Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
748  (does not start with slash); if DEFAULT-DIRECTORY is nil or missing,
749 the current buffer's value of default-directory is used.
750 File name components that are `.' are removed, and
751 so are file name components followed by `..', along with the `..' itself;
752 note that these simplifications are done without checking the resulting
753 file names in the file system.
754 An initial `~/' expands to your home directory.
755 An initial `~USER/' expands to USER's home directory.
756 See also the function `substitute-in-file-name'.
757 */
758        (name, default_directory))
759 {
760   /* This function can GC */
761   Bufbyte *nm;
762
763   Bufbyte *newdir, *p, *o;
764   int tlen;
765   Bufbyte *target;
766 #ifdef WINDOWSNT
767   int drive = 0;
768   int collapse_newdir = 1;
769 #else
770   struct passwd *pw;
771 #endif /* WINDOWSNT */
772   int length;
773   Lisp_Object handler;
774 #ifdef __CYGWIN32__
775   char *user;
776 #endif
777
778   CHECK_STRING (name);
779
780   /* If the file name has special constructs in it,
781      call the corresponding file handler.  */
782   handler = Ffind_file_name_handler (name, Qexpand_file_name);
783   if (!NILP (handler))
784     return call3_check_string (handler, Qexpand_file_name, name,
785                                default_directory);
786
787   /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted.  */
788   if (NILP (default_directory))
789     default_directory = current_buffer->directory;
790   if (! STRINGP (default_directory))
791     default_directory = build_string ("/");
792
793   if (!NILP (default_directory))
794     {
795       handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
796       if (!NILP (handler))
797         return call3 (handler, Qexpand_file_name, name, default_directory);
798     }
799
800   o = XSTRING_DATA (default_directory);
801
802   /* Make sure DEFAULT_DIRECTORY is properly expanded.
803      It would be better to do this down below where we actually use
804      default_directory.  Unfortunately, calling Fexpand_file_name recursively
805      could invoke GC, and the strings might be relocated.  This would
806      be annoying because we have pointers into strings lying around
807      that would need adjusting, and people would add new pointers to
808      the code and forget to adjust them, resulting in intermittent bugs.
809      Putting this call here avoids all that crud.
810
811      The EQ test avoids infinite recursion.  */
812   if (! NILP (default_directory) && !EQ (default_directory, name)
813       /* Save time in some common cases - as long as default_directory
814          is not relative, it can be canonicalized with name below (if it
815          is needed at all) without requiring it to be expanded now.  */
816 #ifdef WINDOWSNT
817       /* Detect MSDOS file names with drive specifiers.  */
818       && ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
819       /* Detect Windows file names in UNC format.  */
820       && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
821
822 #else /* not WINDOWSNT */
823
824       /* Detect Unix absolute file names (/... alone is not absolute on
825          DOS or Windows).  */
826       && ! (IS_DIRECTORY_SEP (o[0]))
827 #endif /* not WINDOWSNT */
828       )
829     {
830       struct gcpro gcpro1;
831
832       GCPRO1 (name);
833       default_directory = Fexpand_file_name (default_directory, Qnil);
834       UNGCPRO;
835     }
836
837 #ifdef FILE_SYSTEM_CASE
838   name = FILE_SYSTEM_CASE (name);
839 #endif
840
841  /* #### dmoore - this is ugly, clean this up.  Looks like nm pointing
842     into name should be safe during all of this, though. */
843   nm = XSTRING_DATA (name);
844
845 #ifdef WINDOWSNT
846   /* We will force directory separators to be either all \ or /, so make
847      a local copy to modify, even if there ends up being no change. */
848   nm = strcpy (alloca (strlen (nm) + 1), nm);
849
850   /* Find and remove drive specifier if present; this makes nm absolute
851      even if the rest of the name appears to be relative. */
852   {
853     Bufbyte *colon = strrchr (nm, ':');
854
855     if (colon)
856       /* Only recognize colon as part of drive specifier if there is a
857          single alphabetic character preceding the colon (and if the
858          character before the drive letter, if present, is a directory
859          separator); this is to support the remote system syntax used by
860          ange-ftp, and the "po:username" syntax for POP mailboxes. */
861     look_again:
862       if (nm == colon)
863         nm++;
864       else if (IS_DRIVE (colon[-1])
865                && (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2])))
866         {
867           drive = colon[-1];
868           nm = colon + 1;
869         }
870       else
871         {
872           while (--colon >= nm)
873             if (colon[0] == ':')
874               goto look_again;
875         }
876   }
877
878   /* If we see "c://somedir", we want to strip the first slash after the
879      colon when stripping the drive letter.  Otherwise, this expands to
880      "//somedir".  */
881   if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
882     nm++;
883 #endif /* WINDOWSNT */
884
885   /* If nm is absolute, look for /./ or /../ sequences; if none are
886      found, we can probably return right away.  We will avoid allocating
887      a new string if name is already fully expanded.  */
888   if (
889       IS_DIRECTORY_SEP (nm[0])
890 #ifdef WINDOWSNT
891       && (drive || IS_DIRECTORY_SEP (nm[1]))
892 #endif
893       )
894     {
895       /* If it turns out that the filename we want to return is just a
896          suffix of FILENAME, we don't need to go through and edit
897          things; we just need to construct a new string using data
898          starting at the middle of FILENAME.  If we set lose to a
899          non-zero value, that means we've discovered that we can't do
900          that cool trick.  */
901       int lose = 0;
902
903       p = nm;
904       while (*p)
905         {
906           /* Since we know the name is absolute, we can assume that each
907              element starts with a "/".  */
908
909           /* "." and ".." are hairy.  */
910           if (IS_DIRECTORY_SEP (p[0])
911               && p[1] == '.'
912               && (IS_DIRECTORY_SEP (p[2])
913                   || p[2] == 0
914                   || (p[2] == '.' && (IS_DIRECTORY_SEP (p[3])
915                                       || p[3] == 0))))
916             lose = 1;
917           p++;
918         }
919       if (!lose)
920         {
921 #ifdef WINDOWSNT
922           /* Make sure directories are all separated with / or \ as
923              desired, but avoid allocation of a new string when not
924              required. */
925           CORRECT_DIR_SEPS (nm);
926           if (IS_DIRECTORY_SEP (nm[1]))
927             {
928               if (strcmp (nm, XSTRING_DATA (name)) != 0)
929                 name = build_string (nm);
930             }
931           /* drive must be set, so this is okay */
932           else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0)
933             {
934               name = make_string (nm - 2, p - nm + 2);
935               XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
936               XSTRING_DATA (name)[1] = ':';
937             }
938           return name;
939 #else /* not WINDOWSNT */
940           if (nm == XSTRING_DATA (name))
941             return name;
942           return build_string ((char *) nm);
943 #endif /* not WINDOWSNT */
944         }
945     }
946
947   /* At this point, nm might or might not be an absolute file name.  We
948      need to expand ~ or ~user if present, otherwise prefix nm with
949      default_directory if nm is not absolute, and finally collapse /./
950      and /foo/../ sequences.
951
952      We set newdir to be the appropriate prefix if one is needed:
953        - the relevant user directory if nm starts with ~ or ~user
954        - the specified drive's working dir (DOS/NT only) if nm does not
955          start with /
956        - the value of default_directory.
957
958      Note that these prefixes are not guaranteed to be absolute (except
959      for the working dir of a drive).  Therefore, to ensure we always
960      return an absolute name, if the final prefix is not absolute we
961      append it to the current working directory.  */
962
963   newdir = 0;
964
965   if (nm[0] == '~')             /* prefix ~ */
966     {
967       if (IS_DIRECTORY_SEP (nm[1])
968           || nm[1] == 0)        /* ~ by itself */
969         {
970           Extbyte *newdir_external = get_home_directory ();
971
972           if (newdir_external == NULL)
973             newdir = (Bufbyte *) "";
974           else
975             TO_INTERNAL_FORMAT (C_STRING, newdir_external,
976                                 C_STRING_ALLOCA, (* ((char **) &newdir)),
977                                 Qfile_name);
978
979           nm++;
980 #ifdef WINDOWSNT
981           collapse_newdir = 0;
982 #endif
983         }
984       else                      /* ~user/filename */
985         {
986           for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)); p++)
987             DO_NOTHING;
988           o = (Bufbyte *) alloca (p - nm + 1);
989           memcpy (o, (char *) nm, p - nm);
990           o [p - nm] = 0;
991
992           /* #### marcpa's syncing note: FSF uses getpwnam even on NT,
993              which does not work.  The following works only if ~USER
994              names the user who runs this instance of XEmacs.  While
995              NT is single-user (for the moment) you still can have
996              multiple user profiles users defined, each with its HOME.
997              Therefore, the following should be reworked to handle
998              this case.  */
999 #ifdef  WINDOWSNT
1000           /* Now if the file given is "~foo/file" and HOME="c:/", then
1001              we want the file to be named "c:/file" ("~foo" becomes
1002              "c:/").  The variable o has "~foo", so we can use the
1003              length of that string to offset nm.  August Hill, 31 Aug
1004              1998.  */
1005           newdir = (Bufbyte *) get_home_directory();
1006           dostounix_filename (newdir);
1007           nm += strlen(o) + 1;
1008 #else  /* not WINDOWSNT */
1009 #ifdef __CYGWIN32__
1010           if ((user = user_login_name (NULL)) != NULL)
1011             {
1012               /* Does the user login name match the ~name? */
1013               if (strcmp (user, (char *) o + 1) == 0)
1014                 {
1015                   newdir = (Bufbyte *) get_home_directory();
1016                   nm = p;
1017                 }
1018             }
1019           if (! newdir)
1020             {
1021 #endif /* __CYGWIN32__ */
1022           /* Jamie reports that getpwnam() can get wedged by SIGIO/SIGALARM
1023              occurring in it. (It can call select()). */
1024           slow_down_interrupts ();
1025           pw = (struct passwd *) getpwnam ((char *) o + 1);
1026           speed_up_interrupts ();
1027           if (pw)
1028             {
1029               newdir = (Bufbyte *) pw -> pw_dir;
1030               nm = p;
1031             }
1032 #ifdef __CYGWIN32__
1033             }
1034 #endif
1035 #endif /* not WINDOWSNT */
1036
1037           /* If we don't find a user of that name, leave the name
1038              unchanged; don't move nm forward to p.  */
1039         }
1040     }
1041
1042 #ifdef WINDOWSNT
1043   /* On DOS and Windows, nm is absolute if a drive name was specified;
1044      use the drive's current directory as the prefix if needed.  */
1045   if (!newdir && drive)
1046     {
1047       /* Get default directory if needed to make nm absolute. */
1048       if (!IS_DIRECTORY_SEP (nm[0]))
1049         {
1050           newdir = alloca (MAXPATHLEN + 1);
1051           if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1052             newdir = NULL;
1053         }
1054       if (!newdir)
1055         {
1056           /* Either nm starts with /, or drive isn't mounted. */
1057           newdir = alloca (4);
1058           newdir[0] = DRIVE_LETTER (drive);
1059           newdir[1] = ':';
1060           newdir[2] = '/';
1061           newdir[3] = 0;
1062         }
1063     }
1064 #endif /* WINDOWSNT */
1065
1066   /* Finally, if no prefix has been specified and nm is not absolute,
1067      then it must be expanded relative to default_directory. */
1068
1069   if (1
1070 #ifndef WINDOWSNT
1071       /* /... alone is not absolute on DOS and Windows. */
1072       && !IS_DIRECTORY_SEP (nm[0])
1073 #else
1074       && !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
1075 #endif
1076       && !newdir)
1077     {
1078       newdir = XSTRING_DATA (default_directory);
1079     }
1080
1081 #ifdef WINDOWSNT
1082   if (newdir)
1083     {
1084       /* First ensure newdir is an absolute name. */
1085       if (
1086           /* Detect MSDOS file names with drive specifiers.  */
1087           ! (IS_DRIVE (newdir[0])
1088              && IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
1089           /* Detect Windows file names in UNC format.  */
1090           && ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1091           /* Detect drive spec by itself */
1092           && ! (IS_DEVICE_SEP (newdir[1]) && newdir[2] == 0)
1093           )
1094         {
1095           /* Effectively, let newdir be (expand-file-name newdir cwd).
1096              Because of the admonition against calling expand-file-name
1097              when we have pointers into lisp strings, we accomplish this
1098              indirectly by prepending newdir to nm if necessary, and using
1099              cwd (or the wd of newdir's drive) as the new newdir. */
1100
1101           if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1102             {
1103               drive = newdir[0];
1104               newdir += 2;
1105             }
1106           if (!IS_DIRECTORY_SEP (nm[0]))
1107             {
1108               char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
1109               file_name_as_directory (tmp, newdir);
1110               strcat (tmp, nm);
1111               nm = tmp;
1112             }
1113           newdir = alloca (MAXPATHLEN + 1);
1114           if (drive)
1115             {
1116               if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
1117                 newdir = "/";
1118             }
1119           else
1120             getwd (newdir);
1121         }
1122
1123       /* Strip off drive name from prefix, if present. */
1124       if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
1125         {
1126           drive = newdir[0];
1127           newdir += 2;
1128         }
1129
1130       /* Keep only a prefix from newdir if nm starts with slash
1131          (/ /server/share for UNC, nothing otherwise).  */
1132       if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
1133         {
1134           if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
1135             {
1136               newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
1137               p = newdir + 2;
1138               while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1139               p++;
1140               while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1141               *p = 0;
1142             }
1143           else
1144             newdir = "";
1145         }
1146     }
1147 #endif /* WINDOWSNT */
1148
1149   if (newdir)
1150     {
1151       /* Get rid of any slash at the end of newdir, unless newdir is
1152          just // (an incomplete UNC name).  */
1153       length = strlen ((char *) newdir);
1154       if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1155 #ifdef WINDOWSNT
1156           && !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
1157 #endif
1158           )
1159         {
1160           Bufbyte *temp = (Bufbyte *) alloca (length);
1161           memcpy (temp, newdir, length - 1);
1162           temp[length - 1] = 0;
1163           newdir = temp;
1164         }
1165       tlen = length + 1;
1166     }
1167   else
1168     tlen = 0;
1169
1170   /* Now concatenate the directory and name to new space in the stack frame */
1171   tlen += strlen ((char *) nm) + 1;
1172 #ifdef WINDOWSNT
1173   /* Add reserved space for drive name.  (The Microsoft x86 compiler
1174      produces incorrect code if the following two lines are combined.)  */
1175   target = (Bufbyte *) alloca (tlen + 2);
1176   target += 2;
1177 #else  /* not WINDOWSNT */
1178   target = (Bufbyte *) alloca (tlen);
1179 #endif /* not WINDOWSNT */
1180   *target = 0;
1181
1182   if (newdir)
1183     {
1184       if (nm[0] == 0 || IS_DIRECTORY_SEP (nm[0]))
1185         strcpy ((char *) target, (char *) newdir);
1186       else
1187         file_name_as_directory ((char *) target, (char *) newdir);
1188     }
1189
1190   strcat ((char *) target, (char *) nm);
1191
1192   /* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
1193
1194   /* Now canonicalize by removing /. and /foo/.. if they appear.  */
1195
1196   p = target;
1197   o = target;
1198
1199   while (*p)
1200     {
1201       if (!IS_DIRECTORY_SEP (*p))
1202         {
1203           *o++ = *p++;
1204         }
1205       else if (IS_DIRECTORY_SEP (p[0])
1206                && p[1] == '.'
1207                && (IS_DIRECTORY_SEP (p[2])
1208                    || p[2] == 0))
1209         {
1210           /* If "/." is the entire filename, keep the "/".  Otherwise,
1211              just delete the whole "/.".  */
1212           if (o == target && p[2] == '\0')
1213             *o++ = *p;
1214           p += 2;
1215         }
1216       else if (IS_DIRECTORY_SEP (p[0]) && p[1] == '.' && p[2] == '.'
1217                /* `/../' is the "superroot" on certain file systems.  */
1218                && o != target
1219                && (IS_DIRECTORY_SEP (p[3]) || p[3] == 0))
1220         {
1221           while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
1222             ;
1223           /* Keep initial / only if this is the whole name.  */
1224           if (o == target && IS_ANY_SEP (*o) && p[3] == 0)
1225             ++o;
1226           p += 3;
1227         }
1228 #ifdef WINDOWSNT
1229       /* if drive is set, we're not dealing with an UNC, so
1230          multiple dir-seps are redundant (and reportedly cause trouble
1231          under win95) */
1232       else if (drive && IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
1233           ++p;
1234 #endif
1235       else
1236         {
1237           *o++ = *p++;
1238         }
1239     }
1240
1241 #ifdef WINDOWSNT
1242   /* At last, set drive name, except for network file name.  */
1243   if (drive)
1244     {
1245       target -= 2;
1246       target[0] = DRIVE_LETTER (drive);
1247       target[1] = ':';
1248     }
1249   else
1250     {
1251       assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]));
1252     }
1253   CORRECT_DIR_SEPS (target);
1254 #endif /* WINDOWSNT */
1255
1256   return make_string (target, o - target);
1257 }
1258
1259 #if 0 /* FSFmacs */
1260 /* another older version of expand-file-name; */
1261 #endif
1262
1263 DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /*
1264 Return the canonical name of the given FILE.
1265 Second arg DEFAULT is directory to start with if FILE is relative
1266  (does not start with slash); if DEFAULT is nil or missing,
1267  the current buffer's value of default-directory is used.
1268 No component of the resulting pathname will be a symbolic link, as
1269  in the realpath() function.
1270 */
1271        (filename, default_))
1272 {
1273   /* This function can GC.  GC checked 1997.04.06. */
1274   Lisp_Object expanded_name;
1275   Lisp_Object handler;
1276   struct gcpro gcpro1;
1277
1278   CHECK_STRING (filename);
1279
1280   expanded_name = Fexpand_file_name (filename, default_);
1281
1282   if (!STRINGP (expanded_name))
1283     return Qnil;
1284
1285   GCPRO1 (expanded_name);
1286   handler = Ffind_file_name_handler (expanded_name, Qfile_truename);
1287   UNGCPRO;
1288
1289   if (!NILP (handler))
1290     return call2_check_string (handler, Qfile_truename, expanded_name);
1291
1292   {
1293     char resolved_path[MAXPATHLEN];
1294     Extbyte *path;
1295     Extbyte *p;
1296     Extcount elen;
1297
1298     TO_EXTERNAL_FORMAT (LISP_STRING, expanded_name,
1299                         ALLOCA, (path, elen),
1300                         Qfile_name);
1301     p = path;
1302     if (elen > MAXPATHLEN)
1303       goto toolong;
1304     
1305     /* Try doing it all at once. */
1306     /* !! Does realpath() Mule-encapsulate?
1307        Answer: Nope! So we do it above */
1308     if (!xrealpath ((char *) path, resolved_path))
1309       {
1310         /* Didn't resolve it -- have to do it one component at a time. */
1311         /* "realpath" is a typically useless, stupid un*x piece of crap.
1312            It claims to return a useful value in the "error" case, but since
1313            there is no indication provided of how far along the pathname
1314            the function went before erring, there is no way to use the
1315            partial result returned.  What a piece of junk. */
1316         for (;;)
1317           {
1318             p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
1319             if (p)
1320               *p = 0;
1321
1322             /* memset (resolved_path, 0, sizeof (resolved_path)); */
1323             if (xrealpath ((char *) path, resolved_path))
1324               {
1325                 if (p)
1326                   *p = '/';
1327                 else
1328                   break;
1329
1330               }
1331             else if (errno == ENOENT || errno == EACCES)
1332               {
1333                 /* Failed on this component.  Just tack on the rest of
1334                    the string and we are done. */
1335                 int rlen = strlen (resolved_path);
1336
1337                 /* "On failure, it returns NULL, sets errno to indicate
1338                    the error, and places in resolved_path the absolute pathname
1339                    of the path component which could not be resolved." */
1340                 if (p)
1341                   {
1342                     int plen = elen - (p - path);
1343
1344                     if (rlen > 1 && resolved_path[rlen - 1] == '/')
1345                       rlen = rlen - 1;
1346
1347                     if (plen + rlen + 1 > countof (resolved_path))
1348                       goto toolong;
1349
1350                     resolved_path[rlen] = '/';
1351                     memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1);
1352                   }
1353                 break;
1354               }
1355             else
1356               goto lose;
1357           }
1358       }
1359
1360     {
1361       int rlen = strlen (resolved_path);
1362       if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/'
1363           && !(rlen > 0 && resolved_path[rlen - 1] == '/'))
1364         {
1365           if (rlen + 1 > countof (resolved_path))
1366             goto toolong;
1367           resolved_path[rlen] = '/';
1368           resolved_path[rlen + 1] = 0;
1369           rlen = rlen + 1;
1370         }
1371       return make_ext_string ((Bufbyte *) resolved_path, rlen, Qbinary);
1372     }
1373
1374   toolong:
1375     errno = ENAMETOOLONG;
1376     goto lose;
1377   lose:
1378     report_file_error ("Finding truename", list1 (expanded_name));
1379   }
1380   return Qnil;  /* suppress compiler warning */
1381 }
1382
1383 \f
1384 DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1, 1, 0, /*
1385 Substitute environment variables referred to in FILENAME.
1386 `$FOO' where FOO is an environment variable name means to substitute
1387 the value of that variable.  The variable name should be terminated
1388 with a character not a letter, digit or underscore; otherwise, enclose
1389 the entire variable name in braces.
1390 If `/~' appears, all of FILENAME through that `/' is discarded.
1391
1392 */
1393        (string))
1394 {
1395   /* This function can GC.  GC checked 1997.04.06. */
1396   Bufbyte *nm;
1397
1398   Bufbyte *s, *p, *o, *x, *endp;
1399   Bufbyte *target = 0;
1400   int total = 0;
1401   int substituted = 0;
1402   Bufbyte *xnm;
1403   Lisp_Object handler;
1404
1405   CHECK_STRING (string);
1406
1407   /* If the file name has special constructs in it,
1408      call the corresponding file handler.  */
1409   handler = Ffind_file_name_handler (string, Qsubstitute_in_file_name);
1410   if (!NILP (handler))
1411     return call2_check_string_or_nil (handler, Qsubstitute_in_file_name,
1412                                       string);
1413
1414   nm = XSTRING_DATA (string);
1415   endp = nm + XSTRING_LENGTH (string);
1416
1417   /* If /~ or // appears, discard everything through first slash. */
1418
1419   for (p = nm; p != endp; p++)
1420     {
1421       if ((p[0] == '~'
1422 #if defined (WINDOWSNT) || defined (__CYGWIN32__)
1423            /* // at start of file name is meaningful in WindowsNT systems */
1424            || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
1425 #else /* not (WINDOWSNT || __CYGWIN32__) */
1426            || IS_DIRECTORY_SEP (p[0])
1427 #endif /* not (WINDOWSNT || __CYGWIN32__) */
1428            )
1429           && p != nm
1430           && (IS_DIRECTORY_SEP (p[-1])))
1431         {
1432           nm = p;
1433           substituted = 1;
1434         }
1435 #ifdef WINDOWSNT
1436       /* see comment in expand-file-name about drive specifiers */
1437       else if (IS_DRIVE (p[0]) && p[1] == ':'
1438                && p > nm && IS_DIRECTORY_SEP (p[-1]))
1439         {
1440           nm = p;
1441           substituted = 1;
1442         }
1443 #endif /* WINDOWSNT */
1444     }
1445
1446   /* See if any variables are substituted into the string
1447      and find the total length of their values in `total' */
1448
1449   for (p = nm; p != endp;)
1450     if (*p != '$')
1451       p++;
1452     else
1453       {
1454         p++;
1455         if (p == endp)
1456           goto badsubst;
1457         else if (*p == '$')
1458           {
1459             /* "$$" means a single "$" */
1460             p++;
1461             total -= 1;
1462             substituted = 1;
1463             continue;
1464           }
1465         else if (*p == '{')
1466           {
1467             o = ++p;
1468             while (p != endp && *p != '}') p++;
1469             if (*p != '}') goto missingclose;
1470             s = p;
1471           }
1472         else
1473           {
1474             o = p;
1475             while (p != endp && (isalnum (*p) || *p == '_')) p++;
1476             s = p;
1477           }
1478
1479         /* Copy out the variable name */
1480         target = (Bufbyte *) alloca (s - o + 1);
1481         strncpy ((char *) target, (char *) o, s - o);
1482         target[s - o] = 0;
1483 #ifdef WINDOWSNT
1484         strupr (target); /* $home == $HOME etc.  */
1485 #endif /* WINDOWSNT */
1486
1487         /* Get variable value */
1488         o = (Bufbyte *) egetenv ((char *) target);
1489         if (!o) goto badvar;
1490         total += strlen ((char *) o);
1491         substituted = 1;
1492       }
1493
1494   if (!substituted)
1495     return string;
1496
1497   /* If substitution required, recopy the string and do it */
1498   /* Make space in stack frame for the new copy */
1499   xnm = (Bufbyte *) alloca (XSTRING_LENGTH (string) + total + 1);
1500   x = xnm;
1501
1502   /* Copy the rest of the name through, replacing $ constructs with values */
1503   for (p = nm; *p;)
1504     if (*p != '$')
1505       *x++ = *p++;
1506     else
1507       {
1508         p++;
1509         if (p == endp)
1510           goto badsubst;
1511         else if (*p == '$')
1512           {
1513             *x++ = *p++;
1514             continue;
1515           }
1516         else if (*p == '{')
1517           {
1518             o = ++p;
1519             while (p != endp && *p != '}') p++;
1520             if (*p != '}') goto missingclose;
1521             s = p++;
1522           }
1523         else
1524           {
1525             o = p;
1526             while (p != endp && (isalnum (*p) || *p == '_')) p++;
1527             s = p;
1528           }
1529
1530         /* Copy out the variable name */
1531         target = (Bufbyte *) alloca (s - o + 1);
1532         strncpy ((char *) target, (char *) o, s - o);
1533         target[s - o] = 0;
1534 #ifdef WINDOWSNT
1535         strupr (target); /* $home == $HOME etc.  */
1536 #endif /* WINDOWSNT */
1537
1538         /* Get variable value */
1539         o = (Bufbyte *) egetenv ((char *) target);
1540         if (!o)
1541           goto badvar;
1542
1543         strcpy ((char *) x, (char *) o);
1544         x += strlen ((char *) o);
1545       }
1546
1547   *x = 0;
1548
1549   /* If /~ or // appears, discard everything through first slash. */
1550
1551   for (p = xnm; p != x; p++)
1552     if ((p[0] == '~'
1553 #if defined (WINDOWSNT)
1554          || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
1555 #else /* not WINDOWSNT */
1556          || IS_DIRECTORY_SEP (p[0])
1557 #endif /* not WINDOWSNT */
1558          )
1559         /* don't do p[-1] if that would go off the beginning --jwz */
1560         && p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
1561       xnm = p;
1562 #ifdef WINDOWSNT
1563     else if (IS_DRIVE (p[0]) && p[1] == ':'
1564              && p > nm && IS_DIRECTORY_SEP (p[-1]))
1565         xnm = p;
1566 #endif
1567
1568   return make_string (xnm, x - xnm);
1569
1570  badsubst:
1571   error ("Bad format environment-variable substitution");
1572  missingclose:
1573   error ("Missing \"}\" in environment-variable substitution");
1574  badvar:
1575   error ("Substituting nonexistent environment variable \"%s\"",
1576          target);
1577
1578   /* NOTREACHED */
1579   return Qnil;  /* suppress compiler warning */
1580 }
1581 \f
1582 /* A slightly faster and more convenient way to get
1583    (directory-file-name (expand-file-name FOO)).  */
1584
1585 Lisp_Object
1586 expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
1587 {
1588   /* This function can call lisp */
1589   Lisp_Object abspath;
1590   struct gcpro gcpro1;
1591
1592   abspath = Fexpand_file_name (filename, defdir);
1593   GCPRO1 (abspath);
1594   /* Remove final slash, if any (unless path is root).
1595      stat behaves differently depending!  */
1596   if (XSTRING_LENGTH (abspath) > 1
1597       && IS_DIRECTORY_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 1))
1598       && !IS_DEVICE_SEP (XSTRING_BYTE (abspath, XSTRING_LENGTH (abspath) - 2)))
1599     /* We cannot take shortcuts; they might be wrong for magic file names.  */
1600     abspath = Fdirectory_file_name (abspath);
1601   UNGCPRO;
1602   return abspath;
1603 }
1604 \f
1605 /* Signal an error if the file ABSNAME already exists.
1606    If INTERACTIVE is nonzero, ask the user whether to proceed,
1607    and bypass the error if the user says to go ahead.
1608    QUERYSTRING is a name for the action that is being considered
1609    to alter the file.
1610    *STATPTR is used to store the stat information if the file exists.
1611    If the file does not exist, STATPTR->st_mode is set to 0.  */
1612
1613 static void
1614 barf_or_query_if_file_exists (Lisp_Object absname, CONST char *querystring,
1615                               int interactive, struct stat *statptr)
1616 {
1617   /* This function can GC.  GC checked 1997.04.06. */
1618   struct stat statbuf;
1619
1620   /* stat is a good way to tell whether the file exists,
1621      regardless of what access permissions it has.  */
1622   if (stat ((char *) XSTRING_DATA (absname), &statbuf) >= 0)
1623     {
1624       Lisp_Object tem;
1625
1626       if (interactive)
1627         {
1628           Lisp_Object prompt;
1629           struct gcpro gcpro1;
1630
1631           prompt = emacs_doprnt_string_c
1632             ((CONST Bufbyte *) GETTEXT ("File %s already exists; %s anyway? "),
1633              Qnil, -1, XSTRING_DATA (absname),
1634              GETTEXT (querystring));
1635
1636           GCPRO1 (prompt);
1637           tem = call1 (Qyes_or_no_p, prompt);
1638           UNGCPRO;
1639         }
1640       else
1641         tem = Qnil;
1642
1643       if (NILP (tem))
1644         Fsignal (Qfile_already_exists,
1645                  list2 (build_translated_string ("File already exists"),
1646                         absname));
1647       if (statptr)
1648         *statptr = statbuf;
1649     }
1650   else
1651     {
1652       if (statptr)
1653         statptr->st_mode = 0;
1654     }
1655   return;
1656 }
1657
1658 DEFUN ("copy-file", Fcopy_file, 2, 4,
1659        "fCopy file: \nFCopy %s to file: \np\nP", /*
1660 Copy FILE to NEWNAME.  Both args must be strings.
1661 Signals a `file-already-exists' error if file NEWNAME already exists,
1662 unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
1663 A number as third arg means request confirmation if NEWNAME already exists.
1664 This is what happens in interactive use with M-x.
1665 Fourth arg KEEP-TIME non-nil means give the new file the same
1666 last-modified time as the old one.  (This works on only some systems.)
1667 A prefix arg makes KEEP-TIME non-nil.
1668 */
1669        (filename, newname, ok_if_already_exists, keep_time))
1670 {
1671   /* This function can GC.  GC checked 1997.04.06. */
1672   int ifd, ofd, n;
1673   char buf[16 * 1024];
1674   struct stat st, out_st;
1675   Lisp_Object handler;
1676   int speccount = specpdl_depth ();
1677   struct gcpro gcpro1, gcpro2;
1678   /* Lisp_Object args[6]; */
1679   int input_file_statable_p;
1680
1681   GCPRO2 (filename, newname);
1682   CHECK_STRING (filename);
1683   CHECK_STRING (newname);
1684   filename = Fexpand_file_name (filename, Qnil);
1685   newname = Fexpand_file_name (newname, Qnil);
1686
1687   /* If the input file name has special constructs in it,
1688      call the corresponding file handler.  */
1689   handler = Ffind_file_name_handler (filename, Qcopy_file);
1690   /* Likewise for output file name.  */
1691   if (NILP (handler))
1692     handler = Ffind_file_name_handler (newname, Qcopy_file);
1693   if (!NILP (handler))
1694   {
1695     UNGCPRO;
1696     return call5 (handler, Qcopy_file, filename, newname,
1697                   ok_if_already_exists, keep_time);
1698   }
1699
1700   /* When second argument is a directory, copy the file into it.
1701      (copy-file "foo" "bar/") == (copy-file "foo" "bar/foo")
1702    */
1703   if (!NILP (Ffile_directory_p (newname)))
1704     {
1705       Lisp_Object args[3];
1706       struct gcpro ngcpro1;
1707       int i = 1;
1708
1709       args[0] = newname;
1710       args[1] = Qnil; args[2] = Qnil;
1711       NGCPRO1 (*args);
1712       ngcpro1.nvars = 3;
1713       if (XSTRING_BYTE (newname, XSTRING_LENGTH (newname) - 1) != '/')
1714         args[i++] = build_string ("/");
1715       args[i++] = Ffile_name_nondirectory (filename);
1716       newname = Fconcat (i, args);
1717       NUNGCPRO;
1718     }
1719
1720   if (NILP (ok_if_already_exists)
1721       || INTP (ok_if_already_exists))
1722     barf_or_query_if_file_exists (newname, "copy to it",
1723                                   INTP (ok_if_already_exists), &out_st);
1724   else if (stat ((CONST char *) XSTRING_DATA (newname), &out_st) < 0)
1725     out_st.st_mode = 0;
1726
1727   ifd = interruptible_open ((char *) XSTRING_DATA (filename), O_RDONLY | OPEN_BINARY, 0);
1728   if (ifd < 0)
1729     report_file_error ("Opening input file", list1 (filename));
1730
1731   record_unwind_protect (close_file_unwind, make_int (ifd));
1732
1733   /* We can only copy regular files and symbolic links.  Other files are not
1734      copyable by us. */
1735   input_file_statable_p = (fstat (ifd, &st) >= 0);
1736
1737 #ifndef WINDOWSNT
1738   if (out_st.st_mode != 0
1739       && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
1740     {
1741       errno = 0;
1742       report_file_error ("Input and output files are the same",
1743                          list2 (filename, newname));
1744     }
1745 #endif
1746
1747 #if defined (S_ISREG) && defined (S_ISLNK)
1748   if (input_file_statable_p)
1749     {
1750       if (!(S_ISREG (st.st_mode))
1751           /* XEmacs: have to allow S_ISCHR in order to copy /dev/null */
1752 #ifdef S_ISCHR
1753           && !(S_ISCHR (st.st_mode))
1754 #endif
1755           && !(S_ISLNK (st.st_mode)))
1756         {
1757 #if defined (EISDIR)
1758           /* Get a better looking error message. */
1759           errno = EISDIR;
1760 #endif /* EISDIR */
1761         report_file_error ("Non-regular file", list1 (filename));
1762         }
1763     }
1764 #endif /* S_ISREG && S_ISLNK */
1765
1766   ofd = open( (char *) XSTRING_DATA (newname),
1767               O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, CREAT_MODE);
1768   if (ofd < 0)
1769     report_file_error ("Opening output file", list1 (newname));
1770
1771   {
1772     Lisp_Object ofd_locative = noseeum_cons (make_int (ofd), Qnil);
1773
1774     record_unwind_protect (close_file_unwind, ofd_locative);
1775
1776     while ((n = read_allowing_quit (ifd, buf, sizeof (buf))) > 0)
1777     {
1778       if (write_allowing_quit (ofd, buf, n) != n)
1779         report_file_error ("I/O error", list1 (newname));
1780     }
1781
1782     /* Closing the output clobbers the file times on some systems.  */
1783     if (close (ofd) < 0)
1784       report_file_error ("I/O error", list1 (newname));
1785
1786     if (input_file_statable_p)
1787     {
1788       if (!NILP (keep_time))
1789       {
1790         EMACS_TIME atime, mtime;
1791         EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
1792         EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
1793         if (set_file_times ((char *) XSTRING_DATA (newname), atime,
1794                             mtime))
1795           report_file_error ("I/O error", list1 (newname));
1796       }
1797       chmod ((CONST char *) XSTRING_DATA (newname),
1798              st.st_mode & 07777);
1799     }
1800
1801     /* We'll close it by hand */
1802     XCAR (ofd_locative) = Qnil;
1803
1804     /* Close ifd */
1805     unbind_to (speccount, Qnil);
1806   }
1807
1808   UNGCPRO;
1809   return Qnil;
1810 }
1811 \f
1812 DEFUN ("make-directory-internal", Fmake_directory_internal, 1, 1, 0, /*
1813 Create a directory.  One argument, a file name string.
1814 */
1815        (dirname_))
1816 {
1817   /* This function can GC.  GC checked 1997.04.06. */
1818   char dir [MAXPATHLEN];
1819   Lisp_Object handler;
1820   struct gcpro gcpro1;
1821
1822   CHECK_STRING (dirname_);
1823   dirname_ = Fexpand_file_name (dirname_, Qnil);
1824
1825   GCPRO1 (dirname_);
1826   handler = Ffind_file_name_handler (dirname_, Qmake_directory_internal);
1827   UNGCPRO;
1828   if (!NILP (handler))
1829     return (call2 (handler, Qmake_directory_internal, dirname_));
1830
1831   if (XSTRING_LENGTH (dirname_) > (Bytecount) (sizeof (dir) - 1))
1832     {
1833       return Fsignal (Qfile_error,
1834                       list3 (build_translated_string ("Creating directory"),
1835                              build_translated_string ("pathame too long"),
1836                              dirname_));
1837     }
1838   strncpy (dir, (char *) XSTRING_DATA (dirname_),
1839            XSTRING_LENGTH (dirname_) + 1);
1840
1841   if (dir [XSTRING_LENGTH (dirname_) - 1] == '/')
1842     dir [XSTRING_LENGTH (dirname_) - 1] = 0;
1843
1844   if (mkdir (dir, 0777) != 0)
1845     report_file_error ("Creating directory", list1 (dirname_));
1846
1847   return Qnil;
1848 }
1849
1850 DEFUN ("delete-directory", Fdelete_directory, 1, 1, "FDelete directory: ", /*
1851 Delete a directory.  One argument, a file name or directory name string.
1852 */
1853        (dirname_))
1854 {
1855   /* This function can GC.  GC checked 1997.04.06. */
1856   Lisp_Object handler;
1857   struct gcpro gcpro1;
1858
1859   CHECK_STRING (dirname_);
1860
1861   GCPRO1 (dirname_);
1862   dirname_ = Fexpand_file_name (dirname_, Qnil);
1863   dirname_ = Fdirectory_file_name (dirname_);
1864
1865   handler = Ffind_file_name_handler (dirname_, Qdelete_directory);
1866   UNGCPRO;
1867   if (!NILP (handler))
1868     return (call2 (handler, Qdelete_directory, dirname_));
1869
1870   if (rmdir ((char *) XSTRING_DATA (dirname_)) != 0)
1871     report_file_error ("Removing directory", list1 (dirname_));
1872
1873   return Qnil;
1874 }
1875
1876 DEFUN ("delete-file", Fdelete_file, 1, 1, "fDelete file: ", /*
1877 Delete specified file.  One argument, a file name string.
1878 If file has multiple names, it continues to exist with the other names.
1879 */
1880        (filename))
1881 {
1882   /* This function can GC.  GC checked 1997.04.06. */
1883   Lisp_Object handler;
1884   struct gcpro gcpro1;
1885
1886   CHECK_STRING (filename);
1887   filename = Fexpand_file_name (filename, Qnil);
1888
1889   GCPRO1 (filename);
1890   handler = Ffind_file_name_handler (filename, Qdelete_file);
1891   UNGCPRO;
1892   if (!NILP (handler))
1893     return call2 (handler, Qdelete_file, filename);
1894
1895   if (0 > unlink ((char *) XSTRING_DATA (filename)))
1896     report_file_error ("Removing old name", list1 (filename));
1897   return Qnil;
1898 }
1899
1900 static Lisp_Object
1901 internal_delete_file_1 (Lisp_Object ignore, Lisp_Object ignore2)
1902 {
1903   return Qt;
1904 }
1905
1906 /* Delete file FILENAME, returning 1 if successful and 0 if failed.  */
1907
1908 int
1909 internal_delete_file (Lisp_Object filename)
1910 {
1911   /* This function can GC.  GC checked 1997.04.06. */
1912   return NILP (condition_case_1 (Qt, Fdelete_file, filename,
1913                                  internal_delete_file_1, Qnil));
1914 }
1915 \f
1916 DEFUN ("rename-file", Frename_file, 2, 3,
1917        "fRename file: \nFRename %s to file: \np", /*
1918 Rename FILE as NEWNAME.  Both args strings.
1919 If file has names other than FILE, it continues to have those names.
1920 Signals a `file-already-exists' error if a file NEWNAME already exists
1921 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
1922 A number as third arg means request confirmation if NEWNAME already exists.
1923 This is what happens in interactive use with M-x.
1924 */
1925        (filename, newname, ok_if_already_exists))
1926 {
1927   /* This function can GC.  GC checked 1997.04.06. */
1928   Lisp_Object handler;
1929   struct gcpro gcpro1, gcpro2;
1930
1931   GCPRO2 (filename, newname);
1932   CHECK_STRING (filename);
1933   CHECK_STRING (newname);
1934   filename = Fexpand_file_name (filename, Qnil);
1935   newname = Fexpand_file_name (newname, Qnil);
1936
1937   /* If the file name has special constructs in it,
1938      call the corresponding file handler.  */
1939   handler = Ffind_file_name_handler (filename, Qrename_file);
1940   if (NILP (handler))
1941     handler = Ffind_file_name_handler (newname, Qrename_file);
1942   if (!NILP (handler))
1943   {
1944     UNGCPRO;
1945     return call4 (handler, Qrename_file,
1946                   filename, newname, ok_if_already_exists);
1947   }
1948
1949   /* When second argument is a directory, rename the file into it.
1950      (rename-file "foo" "bar/") == (rename-file "foo" "bar/foo")
1951    */
1952   if (!NILP (Ffile_directory_p (newname)))
1953     {
1954       Lisp_Object args[3];
1955       struct gcpro ngcpro1;
1956       int i = 1;
1957
1958       args[0] = newname;
1959       args[1] = Qnil; args[2] = Qnil;
1960       NGCPRO1 (*args);
1961       ngcpro1.nvars = 3;
1962       if (XSTRING_BYTE (newname, XSTRING_LENGTH (newname) - 1) != '/')
1963         args[i++] = build_string ("/");
1964       args[i++] = Ffile_name_nondirectory (filename);
1965       newname = Fconcat (i, args);
1966       NUNGCPRO;
1967     }
1968
1969   if (NILP (ok_if_already_exists)
1970       || INTP (ok_if_already_exists))
1971     barf_or_query_if_file_exists (newname, "rename to it",
1972                                   INTP (ok_if_already_exists), 0);
1973
1974 /* Syncing with FSF 19.34.6 note: FSF does not have conditional code for
1975    WINDOWSNT here; I've removed it.  --marcpa */
1976
1977     /* FSFmacs only calls rename() here under BSD 4.1, and calls
1978        link() and unlink() otherwise, but that's bogus.  Sometimes
1979        rename() succeeds where link()/unlink() fail, and we have
1980        configure check for rename() and emulate using link()/unlink()
1981        if necessary. */
1982   if (0 > rename ((char *) XSTRING_DATA (filename),
1983                   (char *) XSTRING_DATA (newname)))
1984     {
1985       if (errno == EXDEV)
1986         {
1987           Fcopy_file (filename, newname,
1988                       /* We have already prompted if it was an integer,
1989                          so don't have copy-file prompt again.  */
1990                       (NILP (ok_if_already_exists) ? Qnil : Qt),
1991                       Qt);
1992           Fdelete_file (filename);
1993         }
1994       else
1995         {
1996           report_file_error ("Renaming", list2 (filename, newname));
1997         }
1998     }
1999   UNGCPRO;
2000   return Qnil;
2001 }
2002
2003 DEFUN ("add-name-to-file", Fadd_name_to_file, 2, 3,
2004        "fAdd name to file: \nFName to add to %s: \np", /*
2005 Give FILE additional name NEWNAME.  Both args strings.
2006 Signals a `file-already-exists' error if a file NEWNAME already exists
2007 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2008 A number as third arg means request confirmation if NEWNAME already exists.
2009 This is what happens in interactive use with M-x.
2010 */
2011        (filename, newname, ok_if_already_exists))
2012 {
2013   /* This function can GC.  GC checked 1997.04.06. */
2014   Lisp_Object handler;
2015   struct gcpro gcpro1, gcpro2;
2016
2017   GCPRO2 (filename, newname);
2018   CHECK_STRING (filename);
2019   CHECK_STRING (newname);
2020   filename = Fexpand_file_name (filename, Qnil);
2021   newname = Fexpand_file_name (newname, Qnil);
2022
2023   /* If the file name has special constructs in it,
2024      call the corresponding file handler.  */
2025   handler = Ffind_file_name_handler (filename, Qadd_name_to_file);
2026   if (!NILP (handler))
2027     RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, filename,
2028                            newname, ok_if_already_exists));
2029
2030   /* If the new name has special constructs in it,
2031      call the corresponding file handler.  */
2032   handler = Ffind_file_name_handler (newname, Qadd_name_to_file);
2033   if (!NILP (handler))
2034     RETURN_UNGCPRO (call4 (handler, Qadd_name_to_file, filename,
2035                            newname, ok_if_already_exists));
2036
2037   if (NILP (ok_if_already_exists)
2038       || INTP (ok_if_already_exists))
2039     barf_or_query_if_file_exists (newname, "make it a new name",
2040                                   INTP (ok_if_already_exists), 0);
2041 /* Syncing with FSF 19.34.6 note: FSF does not report a file error
2042    on NT here. --marcpa */
2043 /* But FSF #defines link as sys_link which is supplied in nt.c. We can't do
2044    that because sysfile.h defines sys_link depending on ENCAPSULATE_LINK.
2045    Reverted to previous behavior pending a working fix. (jhar) */
2046 #if defined(WINDOWSNT)
2047   /* Windows does not support this operation.  */
2048   report_file_error ("Adding new name", Flist (2, &filename));
2049 #else /* not defined(WINDOWSNT) */
2050
2051   unlink ((char *) XSTRING_DATA (newname));
2052   if (0 > link ((char *) XSTRING_DATA (filename),
2053                 (char *) XSTRING_DATA (newname)))
2054     {
2055       report_file_error ("Adding new name",
2056                          list2 (filename, newname));
2057     }
2058 #endif /* defined(WINDOWSNT) */
2059
2060   UNGCPRO;
2061   return Qnil;
2062 }
2063
2064 #ifdef S_IFLNK
2065 DEFUN ("make-symbolic-link", Fmake_symbolic_link, 2, 3,
2066        "FMake symbolic link to file: \nFMake symbolic link to file %s: \np", /*
2067 Make a symbolic link to FILENAME, named LINKNAME.  Both args strings.
2068 Signals a `file-already-exists' error if a file LINKNAME already exists
2069 unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2070 A number as third arg means request confirmation if LINKNAME already exists.
2071 This happens for interactive use with M-x.
2072 */
2073        (filename, linkname, ok_if_already_exists))
2074 {
2075   /* This function can GC.  GC checked 1997.06.04. */
2076   Lisp_Object handler;
2077   struct gcpro gcpro1, gcpro2;
2078
2079   GCPRO2 (filename, linkname);
2080   CHECK_STRING (filename);
2081   CHECK_STRING (linkname);
2082   /* If the link target has a ~, we must expand it to get
2083      a truly valid file name.  Otherwise, do not expand;
2084      we want to permit links to relative file names.  */
2085   if (XSTRING_BYTE (filename, 0) == '~')
2086     filename = Fexpand_file_name (filename, Qnil);
2087   linkname = Fexpand_file_name (linkname, Qnil);
2088
2089   /* If the file name has special constructs in it,
2090      call the corresponding file handler.  */
2091   handler = Ffind_file_name_handler (filename, Qmake_symbolic_link);
2092   if (!NILP (handler))
2093     RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, linkname,
2094                            ok_if_already_exists));
2095
2096   /* If the new link name has special constructs in it,
2097      call the corresponding file handler.  */
2098   handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2099   if (!NILP (handler))
2100     RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename,
2101                            linkname, ok_if_already_exists));
2102
2103   if (NILP (ok_if_already_exists)
2104       || INTP (ok_if_already_exists))
2105     barf_or_query_if_file_exists (linkname, "make it a link",
2106                                   INTP (ok_if_already_exists), 0);
2107
2108   unlink ((char *) XSTRING_DATA (linkname));
2109   if (0 > symlink ((char *) XSTRING_DATA (filename),
2110                    (char *) XSTRING_DATA (linkname)))
2111     {
2112       report_file_error ("Making symbolic link",
2113                          list2 (filename, linkname));
2114     }
2115   UNGCPRO;
2116   return Qnil;
2117 }
2118 #endif /* S_IFLNK */
2119
2120 #ifdef HPUX_NET
2121
2122 DEFUN ("sysnetunam", Fsysnetunam, 2, 2, 0, /*
2123 Open a network connection to PATH using LOGIN as the login string.
2124 */
2125        (path, login))
2126 {
2127   int netresult;
2128   const char *path_ext;
2129   const char *login_ext;
2130
2131   CHECK_STRING (path);
2132   CHECK_STRING (login);
2133
2134   /* netunam, being a strange-o system call only used once, is not
2135      encapsulated. */
2136
2137   TO_EXTERNAL_FORMAT (LISP_STRING, path,  C_STRING_ALLOCA, path_ext,  Qfile_name);
2138   TO_EXTERNAL_FORMAT (LISP_STRING, login, C_STRING_ALLOCA, login_ext, Qnative);
2139
2140   netresult = netunam (path_ext, login_ext);
2141
2142   return netresult == -1 ? Qnil : Qt;
2143 }
2144 #endif /* HPUX_NET */
2145 \f
2146 DEFUN ("file-name-absolute-p", Ffile_name_absolute_p, 1, 1, 0, /*
2147 Return t if file FILENAME specifies an absolute path name.
2148 On Unix, this is a name starting with a `/' or a `~'.
2149 */
2150        (filename))
2151 {
2152   /* This function does not GC */
2153   Bufbyte *ptr;
2154
2155   CHECK_STRING (filename);
2156   ptr = XSTRING_DATA (filename);
2157   return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2158 #ifdef WINDOWSNT
2159           || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2160 #endif
2161           ) ? Qt : Qnil;
2162 }
2163 \f
2164 /* Return nonzero if file FILENAME exists and can be executed.  */
2165
2166 static int
2167 check_executable (char *filename)
2168 {
2169 #ifdef WINDOWSNT
2170   struct stat st;
2171   if (stat (filename, &st) < 0)
2172     return 0;
2173   return ((st.st_mode & S_IEXEC) != 0);
2174 #else /* not WINDOWSNT */
2175 #ifdef HAVE_EACCESS
2176   return eaccess (filename, 1) >= 0;
2177 #else
2178   /* Access isn't quite right because it uses the real uid
2179      and we really want to test with the effective uid.
2180      But Unix doesn't give us a right way to do it.  */
2181   return access (filename, 1) >= 0;
2182 #endif /* HAVE_EACCESS */
2183 #endif /* not WINDOWSNT */
2184 }
2185
2186 /* Return nonzero if file FILENAME exists and can be written.  */
2187
2188 static int
2189 check_writable (CONST char *filename)
2190 {
2191 #ifdef HAVE_EACCESS
2192   return (eaccess (filename, 2) >= 0);
2193 #else
2194   /* Access isn't quite right because it uses the real uid
2195      and we really want to test with the effective uid.
2196      But Unix doesn't give us a right way to do it.
2197      Opening with O_WRONLY could work for an ordinary file,
2198      but would lose for directories.  */
2199   return (access (filename, 2) >= 0);
2200 #endif
2201 }
2202
2203 DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /*
2204 Return t if file FILENAME exists.  (This does not mean you can read it.)
2205 See also `file-readable-p' and `file-attributes'.
2206 */
2207        (filename))
2208 {
2209   /* This function can call lisp */
2210   Lisp_Object abspath;
2211   Lisp_Object handler;
2212   struct stat statbuf;
2213   struct gcpro gcpro1;
2214
2215   CHECK_STRING (filename);
2216   abspath = Fexpand_file_name (filename, Qnil);
2217
2218   /* If the file name has special constructs in it,
2219      call the corresponding file handler.  */
2220   GCPRO1 (abspath);
2221   handler = Ffind_file_name_handler (abspath, Qfile_exists_p);
2222   UNGCPRO;
2223   if (!NILP (handler))
2224     return call2 (handler, Qfile_exists_p, abspath);
2225
2226   return stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0 ? Qt : Qnil;
2227 }
2228
2229 DEFUN ("file-executable-p", Ffile_executable_p, 1, 1, 0, /*
2230 Return t if FILENAME can be executed by you.
2231 For a directory, this means you can access files in that directory.
2232 */
2233        (filename))
2234
2235 {
2236   /* This function can GC.  GC checked 1997.04.10. */
2237   Lisp_Object abspath;
2238   Lisp_Object handler;
2239   struct gcpro gcpro1;
2240
2241   CHECK_STRING (filename);
2242   abspath = Fexpand_file_name (filename, Qnil);
2243
2244   /* If the file name has special constructs in it,
2245      call the corresponding file handler.  */
2246   GCPRO1 (abspath);
2247   handler = Ffind_file_name_handler (abspath, Qfile_executable_p);
2248   UNGCPRO;
2249   if (!NILP (handler))
2250     return call2 (handler, Qfile_executable_p, abspath);
2251
2252   return check_executable ((char *) XSTRING_DATA (abspath)) ? Qt : Qnil;
2253 }
2254
2255 DEFUN ("file-readable-p", Ffile_readable_p, 1, 1, 0, /*
2256 Return t if file FILENAME exists and you can read it.
2257 See also `file-exists-p' and `file-attributes'.
2258 */
2259        (filename))
2260 {
2261   /* This function can GC */
2262   Lisp_Object abspath = Qnil;
2263   Lisp_Object handler;
2264   struct gcpro gcpro1;
2265   GCPRO1 (abspath);
2266
2267   CHECK_STRING (filename);
2268   abspath = Fexpand_file_name (filename, Qnil);
2269
2270   /* If the file name has special constructs in it,
2271      call the corresponding file handler.  */
2272   handler = Ffind_file_name_handler (abspath, Qfile_readable_p);
2273   if (!NILP (handler))
2274     RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
2275
2276 #if defined(WINDOWSNT) || defined(__CYGWIN32__)
2277   /* Under MS-DOS and Windows, open does not work for directories.  */
2278   UNGCPRO;
2279   if (access (XSTRING_DATA (abspath), 0) == 0)
2280     return Qt;
2281   else
2282     return Qnil;
2283 #else /* not WINDOWSNT */
2284   {
2285     int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0);
2286     UNGCPRO;
2287     if (desc < 0)
2288       return Qnil;
2289     close (desc);
2290     return Qt;
2291   }
2292 #endif /* not WINDOWSNT */
2293 }
2294
2295 /* Having this before file-symlink-p mysteriously caused it to be forgotten
2296    on the RT/PC.  */
2297 DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /*
2298 Return t if file FILENAME can be written or created by you.
2299 */
2300        (filename))
2301 {
2302   /* This function can GC.  GC checked 1997.04.10. */
2303   Lisp_Object abspath, dir;
2304   Lisp_Object handler;
2305   struct stat statbuf;
2306   struct gcpro gcpro1;
2307
2308   CHECK_STRING (filename);
2309   abspath = Fexpand_file_name (filename, Qnil);
2310
2311   /* If the file name has special constructs in it,
2312      call the corresponding file handler.  */
2313   GCPRO1 (abspath);
2314   handler = Ffind_file_name_handler (abspath, Qfile_writable_p);
2315   UNGCPRO;
2316   if (!NILP (handler))
2317     return call2 (handler, Qfile_writable_p, abspath);
2318
2319   if (stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0)
2320     return (check_writable ((char *) XSTRING_DATA (abspath))
2321             ? Qt : Qnil);
2322
2323
2324   GCPRO1 (abspath);
2325   dir = Ffile_name_directory (abspath);
2326   UNGCPRO;
2327   return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir)
2328                           : "")
2329           ? Qt : Qnil);
2330 }
2331
2332 DEFUN ("file-symlink-p", Ffile_symlink_p, 1, 1, 0, /*
2333 Return non-nil if file FILENAME is the name of a symbolic link.
2334 The value is the name of the file to which it is linked.
2335 Otherwise returns nil.
2336 */
2337        (filename))
2338 {
2339   /* This function can GC.  GC checked 1997.04.10. */
2340 #ifdef S_IFLNK
2341   char *buf;
2342   int bufsize;
2343   int valsize;
2344   Lisp_Object val;
2345   Lisp_Object handler;
2346   struct gcpro gcpro1;
2347
2348   CHECK_STRING (filename);
2349   filename = Fexpand_file_name (filename, Qnil);
2350
2351   /* If the file name has special constructs in it,
2352      call the corresponding file handler.  */
2353   GCPRO1 (filename);
2354   handler = Ffind_file_name_handler (filename, Qfile_symlink_p);
2355   UNGCPRO;
2356   if (!NILP (handler))
2357     return call2 (handler, Qfile_symlink_p, filename);
2358
2359   bufsize = 100;
2360   while (1)
2361     {
2362       buf = xnew_array_and_zero (char, bufsize);
2363       valsize = readlink ((char *) XSTRING_DATA (filename),
2364                           buf, bufsize);
2365       if (valsize < bufsize) break;
2366       /* Buffer was not long enough */
2367       xfree (buf);
2368       bufsize *= 2;
2369     }
2370   if (valsize == -1)
2371     {
2372       xfree (buf);
2373       return Qnil;
2374     }
2375   val = make_string ((Bufbyte *) buf, valsize);
2376   xfree (buf);
2377   return val;
2378 #else /* not S_IFLNK */
2379   return Qnil;
2380 #endif /* not S_IFLNK */
2381 }
2382
2383 DEFUN ("file-directory-p", Ffile_directory_p, 1, 1, 0, /*
2384 Return t if file FILENAME is the name of a directory as a file.
2385 A directory name spec may be given instead; then the value is t
2386 if the directory so specified exists and really is a directory.
2387 */
2388        (filename))
2389 {
2390   /* This function can GC.  GC checked 1997.04.10. */
2391   Lisp_Object abspath;
2392   struct stat st;
2393   Lisp_Object handler;
2394   struct gcpro gcpro1;
2395
2396   GCPRO1 (current_buffer->directory);
2397   abspath = expand_and_dir_to_file (filename,
2398                                     current_buffer->directory);
2399   UNGCPRO;
2400
2401   /* If the file name has special constructs in it,
2402      call the corresponding file handler.  */
2403   GCPRO1 (abspath);
2404   handler = Ffind_file_name_handler (abspath, Qfile_directory_p);
2405   UNGCPRO;
2406   if (!NILP (handler))
2407     return call2 (handler, Qfile_directory_p, abspath);
2408
2409   if (stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2410     return Qnil;
2411   return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
2412 }
2413
2414 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 1, 1, 0, /*
2415 Return t if file FILENAME is the name of a directory as a file,
2416 and files in that directory can be opened by you.  In order to use a
2417 directory as a buffer's current directory, this predicate must return true.
2418 A directory name spec may be given instead; then the value is t
2419 if the directory so specified exists and really is a readable and
2420 searchable directory.
2421 */
2422        (filename))
2423 {
2424   /* This function can GC.  GC checked 1997.04.10. */
2425   Lisp_Object handler;
2426
2427   /* If the file name has special constructs in it,
2428      call the corresponding file handler.  */
2429   handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p);
2430   if (!NILP (handler))
2431     return call2 (handler, Qfile_accessible_directory_p,
2432                   filename);
2433
2434 #if !defined(WINDOWSNT)
2435   if (NILP (Ffile_directory_p (filename)))
2436       return (Qnil);
2437   else
2438     return Ffile_executable_p (filename);
2439 #else
2440   {
2441     int tem;
2442     struct gcpro gcpro1;
2443     /* It's an unlikely combination, but yes we really do need to gcpro:
2444        Suppose that file-accessible-directory-p has no handler, but
2445        file-directory-p does have a handler; this handler causes a GC which
2446        relocates the string in `filename'; and finally file-directory-p
2447        returns non-nil.  Then we would end up passing a garbaged string
2448        to file-executable-p.  */
2449     GCPRO1 (filename);
2450     tem = (NILP (Ffile_directory_p (filename))
2451            || NILP (Ffile_executable_p (filename)));
2452     UNGCPRO;
2453     return tem ? Qnil : Qt;
2454   }
2455 #endif /* !defined(WINDOWSNT) */
2456 }
2457
2458 DEFUN ("file-regular-p", Ffile_regular_p, 1, 1, 0, /*
2459 Return t if file FILENAME is the name of a regular file.
2460 This is the sort of file that holds an ordinary stream of data bytes.
2461 */
2462        (filename))
2463 {
2464   /* This function can GC.  GC checked 1997.04.10. */
2465   Lisp_Object abspath;
2466   struct stat st;
2467   Lisp_Object handler;
2468   struct gcpro gcpro1;
2469
2470   GCPRO1 (current_buffer->directory);
2471   abspath = expand_and_dir_to_file (filename, current_buffer->directory);
2472   UNGCPRO;
2473
2474   /* If the file name has special constructs in it,
2475      call the corresponding file handler.  */
2476   GCPRO1 (abspath);
2477   handler = Ffind_file_name_handler (abspath, Qfile_regular_p);
2478   UNGCPRO;
2479   if (!NILP (handler))
2480     return call2 (handler, Qfile_regular_p, abspath);
2481
2482   if (stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2483     return Qnil;
2484   return (st.st_mode & S_IFMT) == S_IFREG ? Qt : Qnil;
2485 }
2486 \f
2487 DEFUN ("file-modes", Ffile_modes, 1, 1, 0, /*
2488 Return mode bits of FILE, as an integer.
2489 */
2490        (filename))
2491 {
2492   /* This function can GC.  GC checked 1997.04.10. */
2493   Lisp_Object abspath;
2494   struct stat st;
2495   Lisp_Object handler;
2496   struct gcpro gcpro1;
2497
2498   GCPRO1 (current_buffer->directory);
2499   abspath = expand_and_dir_to_file (filename,
2500                                     current_buffer->directory);
2501   UNGCPRO;
2502
2503   /* If the file name has special constructs in it,
2504      call the corresponding file handler.  */
2505   GCPRO1 (abspath);
2506   handler = Ffind_file_name_handler (abspath, Qfile_modes);
2507   UNGCPRO;
2508   if (!NILP (handler))
2509     return call2 (handler, Qfile_modes, abspath);
2510
2511   if (stat ((char *) XSTRING_DATA (abspath), &st) < 0)
2512     return Qnil;
2513   /* Syncing with FSF 19.34.6 note: not in FSF, #if 0'ed out here. */
2514 #if 0
2515 #ifdef DOS_NT
2516   if (check_executable (XSTRING_DATA (abspath)))
2517     st.st_mode |= S_IEXEC;
2518 #endif /* DOS_NT */
2519 #endif /* 0 */
2520
2521   return make_int (st.st_mode & 07777);
2522 }
2523
2524 DEFUN ("set-file-modes", Fset_file_modes, 2, 2, 0, /*
2525 Set mode bits of FILE to MODE (an integer).
2526 Only the 12 low bits of MODE are used.
2527 */
2528        (filename, mode))
2529 {
2530   /* This function can GC.  GC checked 1997.04.10. */
2531   Lisp_Object abspath;
2532   Lisp_Object handler;
2533   struct gcpro gcpro1;
2534
2535   GCPRO1 (current_buffer->directory);
2536   abspath = Fexpand_file_name (filename, current_buffer->directory);
2537   UNGCPRO;
2538
2539   CHECK_INT (mode);
2540
2541   /* If the file name has special constructs in it,
2542      call the corresponding file handler.  */
2543   GCPRO1 (abspath);
2544   handler = Ffind_file_name_handler (abspath, Qset_file_modes);
2545   UNGCPRO;
2546   if (!NILP (handler))
2547     return call3 (handler, Qset_file_modes, abspath, mode);
2548
2549   if (chmod ((char *) XSTRING_DATA (abspath), XINT (mode)) < 0)
2550     report_file_error ("Doing chmod", list1 (abspath));
2551
2552   return Qnil;
2553 }
2554
2555 DEFUN ("set-default-file-modes", Fset_default_file_modes, 1, 1, 0, /*
2556 Set the file permission bits for newly created files.
2557 MASK should be an integer; if a permission's bit in MASK is 1,
2558 subsequently created files will not have that permission enabled.
2559 Only the low 9 bits are used.
2560 This setting is inherited by subprocesses.
2561 */
2562        (mode))
2563 {
2564   CHECK_INT (mode);
2565
2566   umask ((~ XINT (mode)) & 0777);
2567
2568   return Qnil;
2569 }
2570
2571 DEFUN ("default-file-modes", Fdefault_file_modes, 0, 0, 0, /*
2572 Return the default file protection for created files.
2573 The umask value determines which permissions are enabled in newly
2574 created files.  If a permission's bit in the umask is 1, subsequently
2575 created files will not have that permission enabled.
2576 */
2577        ())
2578 {
2579   int mode;
2580
2581   mode = umask (0);
2582   umask (mode);
2583
2584   return make_int ((~ mode) & 0777);
2585 }
2586 \f
2587 DEFUN ("unix-sync", Funix_sync, 0, 0, "", /*
2588 Tell Unix to finish all pending disk updates.
2589 */
2590        ())
2591 {
2592 #ifndef WINDOWSNT
2593   sync ();
2594 #endif
2595   return Qnil;
2596 }
2597
2598 \f
2599 DEFUN ("file-newer-than-file-p", Ffile_newer_than_file_p, 2, 2, 0, /*
2600 Return t if file FILE1 is newer than file FILE2.
2601 If FILE1 does not exist, the answer is nil;
2602 otherwise, if FILE2 does not exist, the answer is t.
2603 */
2604        (file1, file2))
2605 {
2606   /* This function can GC.  GC checked 1997.04.10. */
2607   Lisp_Object abspath1, abspath2;
2608   struct stat st;
2609   int mtime1;
2610   Lisp_Object handler;
2611   struct gcpro gcpro1, gcpro2, gcpro3;
2612
2613   CHECK_STRING (file1);
2614   CHECK_STRING (file2);
2615
2616   abspath1 = Qnil;
2617   abspath2 = Qnil;
2618
2619   GCPRO3 (abspath1, abspath2, current_buffer->directory);
2620   abspath1 = expand_and_dir_to_file (file1, current_buffer->directory);
2621   abspath2 = expand_and_dir_to_file (file2, current_buffer->directory);
2622
2623   /* If the file name has special constructs in it,
2624      call the corresponding file handler.  */
2625   handler = Ffind_file_name_handler (abspath1, Qfile_newer_than_file_p);
2626   if (NILP (handler))
2627     handler = Ffind_file_name_handler (abspath2, Qfile_newer_than_file_p);
2628   UNGCPRO;
2629   if (!NILP (handler))
2630     return call3 (handler, Qfile_newer_than_file_p, abspath1,
2631                   abspath2);
2632
2633   if (stat ((char *) XSTRING_DATA (abspath1), &st) < 0)
2634     return Qnil;
2635
2636   mtime1 = st.st_mtime;
2637
2638   if (stat ((char *) XSTRING_DATA (abspath2), &st) < 0)
2639     return Qt;
2640
2641   return (mtime1 > st.st_mtime) ? Qt : Qnil;
2642 }
2643
2644 \f
2645 /* Stack sizes > 2**16 is a good way to elicit compiler bugs */
2646 /* #define READ_BUF_SIZE (2 << 16) */
2647 #define READ_BUF_SIZE (1 << 15)
2648
2649 DEFUN ("insert-file-contents-internal", Finsert_file_contents_internal,
2650        1, 7, 0, /*
2651 Insert contents of file FILENAME after point; no coding-system frobbing.
2652 This function is identical to `insert-file-contents' except for the
2653 handling of the CODESYS and USED-CODESYS arguments under
2654 XEmacs/Mule. (When Mule support is not present, both functions are
2655 identical and ignore the CODESYS and USED-CODESYS arguments.)
2656
2657 If support for Mule exists in this Emacs, the file is decoded according
2658 to CODESYS; if omitted, no conversion happens.  If USED-CODESYS is non-nil,
2659 it should be a symbol, and the actual coding system that was used for the
2660 decoding is stored into it.  It will in general be different from CODESYS
2661 if CODESYS specifies automatic encoding detection or end-of-line detection.
2662
2663 Currently BEG and END refer to byte positions (as opposed to character
2664 positions), even in Mule. (Fixing this is very difficult.)
2665 */
2666        (filename, visit, beg, end, replace, codesys, used_codesys))
2667 {
2668   /* This function can call lisp */
2669   /* #### dmoore - this function hasn't been checked for gc recently */
2670   struct stat st;
2671   int fd;
2672   int saverrno = 0;
2673   Charcount inserted = 0;
2674   int speccount;
2675   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
2676   Lisp_Object handler = Qnil, val;
2677   int total;
2678   Bufbyte read_buf[READ_BUF_SIZE];
2679   int mc_count;
2680   struct buffer *buf = current_buffer;
2681   Lisp_Object curbuf;
2682   int not_regular = 0;
2683
2684   if (buf->base_buffer && ! NILP (visit))
2685     error ("Cannot do file visiting in an indirect buffer");
2686
2687   /* No need to call Fbarf_if_buffer_read_only() here.
2688      That's called in begin_multiple_change() or wherever. */
2689
2690   val = Qnil;
2691
2692   /* #### dmoore - should probably check in various places to see if
2693      curbuf was killed and if so signal an error? */
2694
2695   XSETBUFFER (curbuf, buf);
2696
2697   GCPRO5 (filename, val, visit, handler, curbuf);
2698
2699   mc_count = (NILP (replace)) ?
2700     begin_multiple_change (buf, BUF_PT  (buf), BUF_PT (buf)) :
2701     begin_multiple_change (buf, BUF_BEG (buf), BUF_Z  (buf));
2702
2703   speccount = specpdl_depth (); /* begin_multiple_change also adds
2704                                    an unwind_protect */
2705
2706   filename = Fexpand_file_name (filename, Qnil);
2707
2708   /* If the file name has special constructs in it,
2709      call the corresponding file handler.  */
2710   handler = Ffind_file_name_handler (filename, Qinsert_file_contents);
2711   if (!NILP (handler))
2712     {
2713       val = call6 (handler, Qinsert_file_contents, filename,
2714                    visit, beg, end, replace);
2715       goto handled;
2716     }
2717
2718 #ifdef FILE_CODING
2719   if (!NILP (used_codesys))
2720     CHECK_SYMBOL (used_codesys);
2721 #endif
2722
2723   if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) )
2724     error ("Attempt to visit less than an entire file");
2725
2726   fd = -1;
2727
2728   if (stat ((char *) XSTRING_DATA (filename), &st) < 0)
2729     {
2730       if (fd >= 0) close (fd);
2731     badopen:
2732       if (NILP (visit))
2733         report_file_error ("Opening input file", list1 (filename));
2734       st.st_mtime = -1;
2735       goto notfound;
2736     }
2737
2738 #ifdef S_IFREG
2739   /* Signal an error if we are accessing a non-regular file, with
2740      REPLACE, BEG or END being non-nil.  */
2741   if (!S_ISREG (st.st_mode))
2742     {
2743       not_regular = 1;
2744
2745       if (!NILP (visit))
2746         goto notfound;
2747
2748       if (!NILP (replace) || !NILP (beg) || !NILP (end))
2749         {
2750           end_multiple_change (buf, mc_count);
2751
2752           return Fsignal (Qfile_error,
2753                           list2 (build_translated_string("not a regular file"),
2754                                  filename));
2755         }
2756     }
2757 #endif /* S_IFREG */
2758
2759   if (!NILP (beg))
2760     CHECK_INT (beg);
2761   else
2762     beg = Qzero;
2763
2764   if (!NILP (end))
2765     CHECK_INT (end);
2766
2767   if (fd < 0)
2768     {
2769       if ((fd = interruptible_open ((char *) XSTRING_DATA (filename),
2770                                     O_RDONLY | OPEN_BINARY, 0)) < 0)
2771         goto badopen;
2772     }
2773
2774   /* Replacement should preserve point as it preserves markers.  */
2775   if (!NILP (replace))
2776     record_unwind_protect (restore_point_unwind, Fpoint_marker (Qnil, Qnil));
2777
2778   record_unwind_protect (close_file_unwind, make_int (fd));
2779
2780   /* Supposedly happens on VMS.  */
2781   if (st.st_size < 0)
2782     error ("File size is negative");
2783
2784   if (NILP (end))
2785     {
2786       if (!not_regular)
2787         {
2788           end = make_int (st.st_size);
2789           if (XINT (end) != st.st_size)
2790             error ("Maximum buffer size exceeded");
2791         }
2792     }
2793
2794   /* If requested, replace the accessible part of the buffer
2795      with the file contents.  Avoid replacing text at the
2796      beginning or end of the buffer that matches the file contents;
2797      that preserves markers pointing to the unchanged parts.  */
2798 #if !defined (FILE_CODING)
2799   /* The replace-mode code currently only works when the assumption
2800      'one byte == one char' holds true.  This fails Mule because
2801      files may contain multibyte characters.  It holds under Windows NT
2802      provided we convert CRLF into LF. */
2803 # define FSFMACS_SPEEDY_INSERT
2804 #endif /* !defined (FILE_CODING) */
2805
2806 #ifndef FSFMACS_SPEEDY_INSERT
2807   if (!NILP (replace))
2808     {
2809       buffer_delete_range (buf, BUF_BEG (buf), BUF_Z (buf),
2810                            !NILP (visit) ? INSDEL_NO_LOCKING : 0);
2811     }
2812 #else /* FSFMACS_SPEEDY_INSERT */
2813   if (!NILP (replace))
2814     {
2815       char buffer[1 << 14];
2816       Bufpos same_at_start = BUF_BEGV (buf);
2817       Bufpos same_at_end = BUF_ZV (buf);
2818       int overlap;
2819
2820       /* Count how many chars at the start of the file
2821          match the text at the beginning of the buffer.  */
2822       while (1)
2823         {
2824           int nread;
2825           Bufpos bufpos;
2826           nread = read_allowing_quit (fd, buffer, sizeof buffer);
2827           if (nread < 0)
2828             error ("IO error reading %s: %s",
2829                    XSTRING_DATA (filename), strerror (errno));
2830           else if (nread == 0)
2831             break;
2832           bufpos = 0;
2833           while (bufpos < nread && same_at_start < BUF_ZV (buf)
2834                  && BUF_FETCH_CHAR (buf, same_at_start) == buffer[bufpos])
2835             same_at_start++, bufpos++;
2836           /* If we found a discrepancy, stop the scan.
2837              Otherwise loop around and scan the next bufferful.  */
2838           if (bufpos != nread)
2839             break;
2840         }
2841       /* If the file matches the buffer completely,
2842          there's no need to replace anything.  */
2843       if (same_at_start - BUF_BEGV (buf) == st.st_size)
2844         {
2845           close (fd);
2846           unbind_to (speccount, Qnil);
2847           /* Truncate the buffer to the size of the file.  */
2848           buffer_delete_range (buf, same_at_start, same_at_end,
2849                                !NILP (visit) ? INSDEL_NO_LOCKING : 0);
2850           goto handled;
2851         }
2852       /* Count how many chars at the end of the file
2853          match the text at the end of the buffer.  */
2854       while (1)
2855         {
2856           int total_read, nread;
2857           Bufpos bufpos, curpos, trial;
2858
2859           /* At what file position are we now scanning?  */
2860           curpos = st.st_size - (BUF_ZV (buf) - same_at_end);
2861           /* If the entire file matches the buffer tail, stop the scan.  */
2862           if (curpos == 0)
2863             break;
2864           /* How much can we scan in the next step?  */
2865           trial = min (curpos, (Bufpos) sizeof (buffer));
2866           if (lseek (fd, curpos - trial, 0) < 0)
2867             report_file_error ("Setting file position", list1 (filename));
2868
2869           total_read = 0;
2870           while (total_read < trial)
2871             {
2872               nread = read_allowing_quit (fd, buffer + total_read,
2873                                           trial - total_read);
2874               if (nread <= 0)
2875                 report_file_error ("IO error reading file", list1 (filename));
2876               total_read += nread;
2877             }
2878           /* Scan this bufferful from the end, comparing with
2879              the Emacs buffer.  */
2880           bufpos = total_read;
2881           /* Compare with same_at_start to avoid counting some buffer text
2882              as matching both at the file's beginning and at the end.  */
2883           while (bufpos > 0 && same_at_end > same_at_start
2884                  && BUF_FETCH_CHAR (buf, same_at_end - 1) ==
2885                  buffer[bufpos - 1])
2886             same_at_end--, bufpos--;
2887           /* If we found a discrepancy, stop the scan.
2888              Otherwise loop around and scan the preceding bufferful.  */
2889           if (bufpos != 0)
2890             break;
2891           /* If display current starts at beginning of line,
2892              keep it that way.  */
2893           if (XBUFFER (XWINDOW (Fselected_window (Qnil))->buffer) == buf)
2894             XWINDOW (Fselected_window (Qnil))->start_at_line_beg =
2895               !NILP (Fbolp (make_buffer (buf)));
2896         }
2897
2898       /* Don't try to reuse the same piece of text twice.  */
2899       overlap = same_at_start - BUF_BEGV (buf) -
2900         (same_at_end + st.st_size - BUF_ZV (buf));
2901       if (overlap > 0)
2902         same_at_end += overlap;
2903
2904       /* Arrange to read only the nonmatching middle part of the file.  */
2905       beg = make_int (same_at_start - BUF_BEGV (buf));
2906       end = make_int (st.st_size - (BUF_ZV (buf) - same_at_end));
2907
2908       buffer_delete_range (buf, same_at_start, same_at_end,
2909                            !NILP (visit) ? INSDEL_NO_LOCKING : 0);
2910       /* Insert from the file at the proper position.  */
2911       BUF_SET_PT (buf, same_at_start);
2912     }
2913 #endif /* FSFMACS_SPEEDY_INSERT */
2914
2915   if (!not_regular)
2916     {
2917       total = XINT (end) - XINT (beg);
2918
2919       /* Make sure point-max won't overflow after this insertion.  */
2920       if (total != XINT (make_int (total)))
2921         error ("Maximum buffer size exceeded");
2922     }
2923   else
2924     /* For a special file, all we can do is guess.  The value of -1
2925        will make the stream functions read as much as possible.  */
2926     total = -1;
2927
2928   if (XINT (beg) != 0
2929 #ifdef FSFMACS_SPEEDY_INSERT
2930       /* why was this here? asked jwz.  The reason is that the replace-mode
2931          connivings above will normally put the file pointer other than
2932          where it should be. */
2933       || !NILP (replace)
2934 #endif /* !FSFMACS_SPEEDY_INSERT */
2935       )
2936     {
2937       if (lseek (fd, XINT (beg), 0) < 0)
2938         report_file_error ("Setting file position", list1 (filename));
2939     }
2940
2941   {
2942     Bufpos cur_point = BUF_PT (buf);
2943     struct gcpro ngcpro1;
2944     Lisp_Object stream = make_filedesc_input_stream (fd, 0, total,
2945                                                      LSTR_ALLOW_QUIT);
2946
2947     NGCPRO1 (stream);
2948     Lstream_set_buffering (XLSTREAM (stream), LSTREAM_BLOCKN_BUFFERED, 65536);
2949 #ifdef FILE_CODING
2950     stream = make_decoding_input_stream
2951       (XLSTREAM (stream), Fget_coding_system (codesys));
2952     Lstream_set_character_mode (XLSTREAM (stream));
2953     Lstream_set_buffering (XLSTREAM (stream), LSTREAM_BLOCKN_BUFFERED, 65536);
2954 #endif /* FILE_CODING */
2955
2956     record_unwind_protect (delete_stream_unwind, stream);
2957
2958     /* No need to limit the amount of stuff we attempt to read. (It would
2959        be incorrect, anyway, when Mule is enabled.) Instead, the limiting
2960        occurs inside of the filedesc stream. */
2961     while (1)
2962       {
2963         ssize_t this_len;
2964         Charcount cc_inserted;
2965
2966         QUIT;
2967         this_len = Lstream_read (XLSTREAM (stream), read_buf,
2968                                  sizeof (read_buf));
2969
2970         if (this_len <= 0)
2971           {
2972             if (this_len < 0)
2973               saverrno = errno;
2974             break;
2975           }
2976
2977         cc_inserted = buffer_insert_raw_string_1 (buf, cur_point, read_buf,
2978                                                   this_len,
2979                                                   !NILP (visit)
2980                                                   ? INSDEL_NO_LOCKING : 0);
2981         inserted  += cc_inserted;
2982         cur_point += cc_inserted;
2983       }
2984 #ifdef FILE_CODING
2985     if (!NILP (used_codesys))
2986       {
2987         Fset (used_codesys,
2988               XCODING_SYSTEM_NAME (decoding_stream_coding_system (XLSTREAM (stream))));
2989       }
2990 #endif /* FILE_CODING */
2991     NUNGCPRO;
2992   }
2993
2994   /* Close the file/stream */
2995   unbind_to (speccount, Qnil);
2996
2997   if (saverrno != 0)
2998     {
2999       error ("IO error reading %s: %s",
3000              XSTRING_DATA (filename), strerror (saverrno));
3001     }
3002
3003  notfound:
3004  handled:
3005
3006   end_multiple_change (buf, mc_count);
3007
3008   if (!NILP (visit))
3009     {
3010       if (!EQ (buf->undo_list, Qt))
3011         buf->undo_list = Qnil;
3012       if (NILP (handler))
3013         {
3014           buf->modtime = st.st_mtime;
3015           buf->filename = filename;
3016           /* XEmacs addition: */
3017           /* This function used to be in C, ostensibly so that
3018              it could be called here.  But that's just silly.
3019              There's no reason C code can't call out to Lisp
3020              code, and it's a lot cleaner this way. */
3021           if (!NILP (Ffboundp (Qcompute_buffer_file_truename)))
3022             call1 (Qcompute_buffer_file_truename, make_buffer (buf));
3023         }
3024       BUF_SAVE_MODIFF (buf) = BUF_MODIFF (buf);
3025       buf->auto_save_modified = BUF_MODIFF (buf);
3026       buf->saved_size = make_int (BUF_SIZE (buf));
3027 #ifdef CLASH_DETECTION
3028       if (NILP (handler))
3029         {
3030           if (!NILP (buf->file_truename))
3031             unlock_file (buf->file_truename);
3032           unlock_file (filename);
3033         }
3034 #endif /* CLASH_DETECTION */
3035       if (not_regular)
3036         RETURN_UNGCPRO (Fsignal (Qfile_error,
3037                                  list2 (build_string ("not a regular file"),
3038                                  filename)));
3039
3040       /* If visiting nonexistent file, return nil.  */
3041       if (buf->modtime == -1)
3042         report_file_error ("Opening input file",
3043                            list1 (filename));
3044     }
3045
3046   /* Decode file format */
3047   if (inserted > 0)
3048     {
3049       Lisp_Object insval = call3 (Qformat_decode,
3050                                   Qnil, make_int (inserted), visit);
3051       CHECK_INT (insval);
3052       inserted = XINT (insval);
3053     }
3054
3055   if (inserted > 0)
3056     {
3057       Lisp_Object p;
3058       struct gcpro ngcpro1;
3059
3060       NGCPRO1 (p);
3061       EXTERNAL_LIST_LOOP (p, Vafter_insert_file_functions)
3062         {
3063           Lisp_Object insval =
3064             call1 (XCAR (p), make_int (inserted));
3065           if (!NILP (insval))
3066             {
3067               CHECK_NATNUM (insval);
3068               inserted = XINT (insval);
3069             }
3070           QUIT;
3071         }
3072       NUNGCPRO;
3073     }
3074
3075   UNGCPRO;
3076
3077   if (!NILP (val))
3078     return (val);
3079   else
3080     return (list2 (filename, make_int (inserted)));
3081 }
3082
3083 \f
3084 static int a_write (Lisp_Object outstream, Lisp_Object instream, int pos,
3085                     Lisp_Object *annot);
3086 static Lisp_Object build_annotations (Lisp_Object start, Lisp_Object end);
3087
3088 /* If build_annotations switched buffers, switch back to BUF.
3089    Kill the temporary buffer that was selected in the meantime.  */
3090
3091 static Lisp_Object
3092 build_annotations_unwind (Lisp_Object buf)
3093 {
3094   Lisp_Object tembuf;
3095
3096   if (XBUFFER (buf) == current_buffer)
3097     return Qnil;
3098   tembuf = Fcurrent_buffer ();
3099   Fset_buffer (buf);
3100   Fkill_buffer (tembuf);
3101   return Qnil;
3102 }
3103
3104 DEFUN ("write-region-internal", Fwrite_region_internal, 3, 7,
3105        "r\nFWrite region to file: ", /*
3106 Write current region into specified file; no coding-system frobbing.
3107 This function is identical to `write-region' except for the handling
3108 of the CODESYS argument under XEmacs/Mule. (When Mule support is not
3109 present, both functions are identical and ignore the CODESYS argument.)
3110 If support for Mule exists in this Emacs, the file is encoded according
3111 to the value of CODESYS.  If this is nil, no code conversion occurs.
3112 */
3113        (start, end, filename, append, visit, lockname, codesys))
3114 {
3115   /* This function can call lisp */
3116   int desc;
3117   int failure;
3118   int save_errno = 0;
3119   struct stat st;
3120   Lisp_Object fn;
3121   int speccount = specpdl_depth ();
3122   int visiting_other = STRINGP (visit);
3123   int visiting = (EQ (visit, Qt) || visiting_other);
3124   int quietly = (!visiting && !NILP (visit));
3125   Lisp_Object visit_file = Qnil;
3126   Lisp_Object annotations = Qnil;
3127   struct buffer *given_buffer;
3128   Bufpos start1, end1;
3129
3130   /* #### dmoore - if Fexpand_file_name or handlers kill the buffer,
3131      we should signal an error rather than blissfully continuing
3132      along.  ARGH, this function is going to lose lose lose.  We need
3133      to protect the current_buffer from being destroyed, but the
3134      multiple return points make this a pain in the butt. */
3135
3136 #ifdef FILE_CODING
3137   codesys = Fget_coding_system (codesys);
3138 #endif /* FILE_CODING */
3139
3140   if (current_buffer->base_buffer && ! NILP (visit))
3141     error ("Cannot do file visiting in an indirect buffer");
3142
3143   if (!NILP (start) && !STRINGP (start))
3144     get_buffer_range_char (current_buffer, start, end, &start1, &end1, 0);
3145
3146   {
3147     Lisp_Object handler;
3148     struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3149
3150     GCPRO5 (start, filename, visit, visit_file, lockname);
3151
3152     if (visiting_other)
3153       visit_file = Fexpand_file_name (visit, Qnil);
3154     else
3155       visit_file = filename;
3156     filename = Fexpand_file_name (filename, Qnil);
3157
3158     UNGCPRO;
3159
3160     if (NILP (lockname))
3161       lockname = visit_file;
3162
3163     /* If the file name has special constructs in it,
3164        call the corresponding file handler.  */
3165     handler = Ffind_file_name_handler (filename, Qwrite_region);
3166     /* If FILENAME has no handler, see if VISIT has one.  */
3167     if (NILP (handler) && STRINGP (visit))
3168       handler = Ffind_file_name_handler (visit, Qwrite_region);
3169
3170     if (!NILP (handler))
3171       {
3172         Lisp_Object val = call8 (handler, Qwrite_region, start, end,
3173                                  filename, append, visit, lockname, codesys);
3174         if (visiting)
3175           {
3176             BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer);
3177             current_buffer->saved_size = make_int (BUF_SIZE (current_buffer));
3178             current_buffer->filename = visit_file;
3179             MARK_MODELINE_CHANGED;
3180           }
3181         return val;
3182       }
3183   }
3184
3185 #ifdef CLASH_DETECTION
3186   if (!auto_saving)
3187     {
3188       Lisp_Object curbuf;
3189       struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3190
3191       XSETBUFFER (curbuf, current_buffer);
3192       GCPRO5 (start, filename, visit_file, lockname, curbuf);
3193       lock_file (lockname);
3194       UNGCPRO;
3195     }
3196 #endif /* CLASH_DETECTION */
3197
3198   /* Special kludge to simplify auto-saving.  */
3199   if (NILP (start))
3200     {
3201       start1 = BUF_BEG (current_buffer);
3202       end1 = BUF_Z (current_buffer);
3203     }
3204
3205   record_unwind_protect (build_annotations_unwind, Fcurrent_buffer ());
3206
3207   given_buffer = current_buffer;
3208   annotations = build_annotations (start, end);
3209   if (current_buffer != given_buffer)
3210     {
3211       start1 = BUF_BEGV (current_buffer);
3212       end1 = BUF_ZV (current_buffer);
3213     }
3214
3215   fn = filename;
3216   desc = -1;
3217   if (!NILP (append))
3218     {
3219       desc = open ((char *) XSTRING_DATA (fn), O_WRONLY | OPEN_BINARY, 0);
3220     }
3221   if (desc < 0)
3222     {
3223       desc = open ((char *) XSTRING_DATA (fn),
3224                    (O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY),
3225                    ((auto_saving) ? auto_save_mode_bits : CREAT_MODE));
3226     }
3227
3228   if (desc < 0)
3229     {
3230 #ifdef CLASH_DETECTION
3231       save_errno = errno;
3232       if (!auto_saving) unlock_file (lockname);
3233       errno = save_errno;
3234 #endif /* CLASH_DETECTION */
3235       report_file_error ("Opening output file", list1 (filename));
3236     }
3237
3238   {
3239     Lisp_Object desc_locative = Fcons (make_int (desc), Qnil);
3240     Lisp_Object instream = Qnil, outstream = Qnil;
3241     struct gcpro gcpro1, gcpro2;
3242     /* need to gcpro; QUIT could happen out of call to write() */
3243     GCPRO2 (instream, outstream);
3244
3245     record_unwind_protect (close_file_unwind, desc_locative);
3246
3247     if (!NILP (append))
3248       {
3249         if (lseek (desc, 0, 2) < 0)
3250           {
3251 #ifdef CLASH_DETECTION
3252             if (!auto_saving) unlock_file (lockname);
3253 #endif /* CLASH_DETECTION */
3254             report_file_error ("Lseek error",
3255                                list1 (filename));
3256           }
3257       }
3258
3259     failure = 0;
3260
3261     /* Note: I tried increasing the buffering size, along with
3262        various other tricks, but nothing seemed to make much of
3263        a difference in the time it took to save a large file.
3264        (Actually that's not true.  With a local disk, changing
3265        the buffer size doesn't seem to make much difference.
3266        With an NFS-mounted disk, it could make a lot of difference
3267        because you're affecting the number of network requests
3268        that need to be made, and there could be a large latency
3269        for each request.  So I've increased the buffer size
3270        to 64K.) */
3271     outstream = make_filedesc_output_stream (desc, 0, -1, 0);
3272     Lstream_set_buffering (XLSTREAM (outstream),
3273                            LSTREAM_BLOCKN_BUFFERED, 65536);
3274 #ifdef FILE_CODING
3275     outstream =
3276       make_encoding_output_stream (XLSTREAM (outstream), codesys);
3277     Lstream_set_buffering (XLSTREAM (outstream),
3278                            LSTREAM_BLOCKN_BUFFERED, 65536);
3279 #endif /* FILE_CODING */
3280     if (STRINGP (start))
3281       {
3282         instream = make_lisp_string_input_stream (start, 0, -1);
3283         start1 = 0;
3284       }
3285     else
3286       instream = make_lisp_buffer_input_stream (current_buffer, start1, end1,
3287                                                 LSTR_SELECTIVE |
3288                                                 LSTR_IGNORE_ACCESSIBLE);
3289     failure = (0 > (a_write (outstream, instream, start1,
3290                              &annotations)));
3291     save_errno = errno;
3292     /* Note that this doesn't close the desc since we created the
3293        stream without the LSTR_CLOSING flag, but it does
3294        flush out any buffered data. */
3295     if (Lstream_close (XLSTREAM (outstream)) < 0)
3296       {
3297         failure = 1;
3298         save_errno = errno;
3299       }
3300     Lstream_close (XLSTREAM (instream));
3301     UNGCPRO;
3302
3303 #ifdef HAVE_FSYNC
3304     /* Note fsync appears to change the modtime on BSD4.2 (both vax and sun).
3305        Disk full in NFS may be reported here.  */
3306     /* mib says that closing the file will try to write as fast as NFS can do
3307        it, and that means the fsync here is not crucial for autosave files.  */
3308     if (!auto_saving && fsync (desc) < 0
3309         /* If fsync fails with EINTR, don't treat that as serious.  */
3310         && errno != EINTR)
3311       {
3312         failure = 1;
3313         save_errno = errno;
3314       }
3315 #endif /* HAVE_FSYNC */
3316
3317     /* Spurious "file has changed on disk" warnings used to be seen on
3318        systems where close() can change the modtime.  This is known to
3319        happen on various NFS file systems, on Windows, and on Linux.
3320        Rather than handling this on a per-system basis, we
3321        unconditionally do the stat() after the close(). */
3322
3323     /* NFS can report a write failure now.  */
3324     if (close (desc) < 0)
3325       {
3326         failure = 1;
3327         save_errno = errno;
3328       }
3329
3330     /* Discard the close unwind-protect.  Execute the one for
3331        build_annotations (switches back to the original current buffer
3332        as necessary). */
3333     XCAR (desc_locative) = Qnil;
3334     unbind_to (speccount, Qnil);
3335   }
3336
3337   stat ((char *) XSTRING_DATA (fn), &st);
3338
3339 #ifdef CLASH_DETECTION
3340   if (!auto_saving)
3341     unlock_file (lockname);
3342 #endif /* CLASH_DETECTION */
3343
3344   /* Do this before reporting IO error
3345      to avoid a "file has changed on disk" warning on
3346      next attempt to save.  */
3347   if (visiting)
3348     current_buffer->modtime = st.st_mtime;
3349
3350   if (failure)
3351     error ("IO error writing %s: %s",
3352            XSTRING_DATA (fn),
3353            strerror (save_errno));
3354
3355   if (visiting)
3356     {
3357       BUF_SAVE_MODIFF (current_buffer) = BUF_MODIFF (current_buffer);
3358       current_buffer->saved_size = make_int (BUF_SIZE (current_buffer));
3359       current_buffer->filename = visit_file;
3360       MARK_MODELINE_CHANGED;
3361     }
3362   else if (quietly)
3363     {
3364       return Qnil;
3365     }
3366
3367   if (!auto_saving)
3368     {
3369       if (visiting_other)
3370         message ("Wrote %s", XSTRING_DATA (visit_file));
3371       else
3372         {
3373           struct gcpro gcpro1;
3374           Lisp_Object fsp;
3375           GCPRO1 (fn);
3376
3377           fsp = Ffile_symlink_p (fn);
3378           if (NILP (fsp))
3379             message ("Wrote %s", XSTRING_DATA (fn));
3380           else
3381             message ("Wrote %s (symlink to %s)",
3382                      XSTRING_DATA (fn), XSTRING_DATA (fsp));
3383           UNGCPRO;
3384         }
3385     }
3386   return Qnil;
3387 }
3388
3389 /* #### This is such a load of shit!!!!  There is no way we should define
3390    something so stupid as a subr, just sort the fucking list more
3391    intelligently. */
3392 DEFUN ("car-less-than-car", Fcar_less_than_car, 2, 2, 0, /*
3393 Return t if (car A) is numerically less than (car B).
3394 */
3395        (a, b))
3396 {
3397   Lisp_Object objs[2];
3398   objs[0] = Fcar (a);
3399   objs[1] = Fcar (b);
3400   return Flss (2, objs);
3401 }
3402
3403 /* Heh heh heh, let's define this too, just to aggravate the person who
3404    wrote the above comment. */
3405 DEFUN ("cdr-less-than-cdr", Fcdr_less_than_cdr, 2, 2, 0, /*
3406 Return t if (cdr A) is numerically less than (cdr B).
3407 */
3408        (a, b))
3409 {
3410   Lisp_Object objs[2];
3411   objs[0] = Fcdr (a);
3412   objs[1] = Fcdr (b);
3413   return Flss (2, objs);
3414 }
3415
3416 /* Build the complete list of annotations appropriate for writing out
3417    the text between START and END, by calling all the functions in
3418    write-region-annotate-functions and merging the lists they return.
3419    If one of these functions switches to a different buffer, we assume
3420    that buffer contains altered text.  Therefore, the caller must
3421    make sure to restore the current buffer in all cases,
3422    as save-excursion would do.  */
3423
3424 static Lisp_Object
3425 build_annotations (Lisp_Object start, Lisp_Object end)
3426 {
3427   /* This function can GC */
3428   Lisp_Object annotations;
3429   Lisp_Object p, res;
3430   struct gcpro gcpro1, gcpro2;
3431   Lisp_Object original_buffer;
3432
3433   XSETBUFFER (original_buffer, current_buffer);
3434
3435   annotations = Qnil;
3436   p = Vwrite_region_annotate_functions;
3437   GCPRO2 (annotations, p);
3438   while (!NILP (p))
3439     {
3440       struct buffer *given_buffer = current_buffer;
3441       Vwrite_region_annotations_so_far = annotations;
3442       res = call2 (Fcar (p), start, end);
3443       /* If the function makes a different buffer current,
3444          assume that means this buffer contains altered text to be output.
3445          Reset START and END from the buffer bounds
3446          and discard all previous annotations because they should have
3447          been dealt with by this function.  */
3448       if (current_buffer != given_buffer)
3449         {
3450           start = make_int (BUF_BEGV (current_buffer));
3451           end = make_int (BUF_ZV (current_buffer));
3452           annotations = Qnil;
3453         }
3454       Flength (res);     /* Check basic validity of return value */
3455       annotations = merge (annotations, res, Qcar_less_than_car);
3456       p = Fcdr (p);
3457     }
3458
3459   /* Now do the same for annotation functions implied by the file-format */
3460   if (auto_saving && (!EQ (Vauto_save_file_format, Qt)))
3461     p = Vauto_save_file_format;
3462   else
3463     p = current_buffer->file_format;
3464   while (!NILP (p))
3465     {
3466       struct buffer *given_buffer = current_buffer;
3467       Vwrite_region_annotations_so_far = annotations;
3468       res = call4 (Qformat_annotate_function, Fcar (p), start, end,
3469                    original_buffer);
3470       if (current_buffer != given_buffer)
3471         {
3472           start = make_int (BUF_BEGV (current_buffer));
3473           end = make_int (BUF_ZV (current_buffer));
3474           annotations = Qnil;
3475         }
3476       Flength (res);
3477       annotations = merge (annotations, res, Qcar_less_than_car);
3478       p = Fcdr (p);
3479     }
3480   UNGCPRO;
3481   return annotations;
3482 }
3483
3484 /* Write to stream OUTSTREAM the characters from INSTREAM (it is read until
3485    EOF is encountered), assuming they start at position POS in the buffer
3486    of string that STREAM refers to.  Intersperse with them the annotations
3487    from *ANNOT that fall into the range of positions we are reading from,
3488    each at its appropriate position.
3489
3490    Modify *ANNOT by discarding elements as we output them.
3491    The return value is negative in case of system call failure.  */
3492
3493 /* 4K should probably be fine.  We just need to reduce the number of
3494    function calls to reasonable level.  The Lstream stuff itself will
3495    batch to 64K to reduce the number of system calls. */
3496
3497 #define A_WRITE_BATCH_SIZE 4096
3498
3499 static int
3500 a_write (Lisp_Object outstream, Lisp_Object instream, int pos,
3501          Lisp_Object *annot)
3502 {
3503   Lisp_Object tem;
3504   int nextpos;
3505   unsigned char largebuf[A_WRITE_BATCH_SIZE];
3506   Lstream *instr = XLSTREAM (instream);
3507   Lstream *outstr = XLSTREAM (outstream);
3508
3509   while (LISTP (*annot))
3510     {
3511       tem = Fcar_safe (Fcar (*annot));
3512       if (INTP (tem))
3513         nextpos = XINT (tem);
3514       else
3515         nextpos = INT_MAX;
3516 #ifdef MULE
3517       /* If there are annotations left and we have Mule, then we
3518          have to do the I/O one emchar at a time so we can
3519          determine when to insert the annotation. */
3520       if (!NILP (*annot))
3521         {
3522           Emchar ch;
3523           while (pos != nextpos && (ch = Lstream_get_emchar (instr)) != EOF)
3524             {
3525               if (Lstream_put_emchar (outstr, ch) < 0)
3526                 return -1;
3527               pos++;
3528             }
3529         }
3530       else
3531 #endif /* MULE */
3532         {
3533           while (pos != nextpos)
3534             {
3535               /* Otherwise there is no point to that.  Just go in batches. */
3536               int chunk = min (nextpos - pos, A_WRITE_BATCH_SIZE);
3537
3538               chunk = Lstream_read (instr, largebuf, chunk);
3539               if (chunk < 0)
3540                 return -1;
3541               if (chunk == 0) /* EOF */
3542                 break;
3543               if (Lstream_write (outstr, largebuf, chunk) < chunk)
3544                 return -1;
3545               pos += chunk;
3546             }
3547         }
3548       if (pos == nextpos)
3549         {
3550           tem = Fcdr (Fcar (*annot));
3551           if (STRINGP (tem))
3552             {
3553               if (Lstream_write (outstr, XSTRING_DATA (tem),
3554                                  XSTRING_LENGTH (tem)) < 0)
3555                 return -1;
3556             }
3557           *annot = Fcdr (*annot);
3558         }
3559       else
3560         return 0;
3561     }
3562   return -1;
3563 }
3564
3565
3566 \f
3567 #if 0
3568 #include <des_crypt.h>
3569
3570 #define CRYPT_BLOCK_SIZE 8      /* bytes */
3571 #define CRYPT_KEY_SIZE 8        /* bytes */
3572
3573 DEFUN ("encrypt-string", Fencrypt_string, 2, 2, 0, /*
3574 Encrypt STRING using KEY.
3575 */
3576        (string, key))
3577 {
3578   char *encrypted_string, *raw_key;
3579   int rounded_size, extra, key_size;
3580
3581   /* !!#### May produce bogus data under Mule. */
3582   CHECK_STRING (string);
3583   CHECK_STRING (key);
3584
3585   extra = XSTRING_LENGTH (string) % CRYPT_BLOCK_SIZE;
3586   rounded_size = XSTRING_LENGTH (string) + extra;
3587   encrypted_string = alloca (rounded_size + 1);
3588   memcpy (encrypted_string, XSTRING_DATA (string), XSTRING_LENGTH (string));
3589   memset (encrypted_string + rounded_size - extra, 0, extra + 1);
3590
3591   key_size = min (CRYPT_KEY_SIZE, XSTRING_LENGTH (key))
3592
3593   raw_key = alloca (CRYPT_KEY_SIZE + 1);
3594   memcpy (raw_key, XSTRING_DATA (key), key_size);
3595   memset (raw_key + key_size, 0, (CRYPT_KEY_SIZE + 1) - key_size);
3596
3597   ecb_crypt (raw_key, encrypted_string, rounded_size,
3598              DES_ENCRYPT | DES_SW);
3599   return make_string (encrypted_string, rounded_size);
3600 }
3601
3602 DEFUN ("decrypt-string", Fdecrypt_string, 2, 2, 0, /*
3603 Decrypt STRING using KEY.
3604 */
3605        (string, key))
3606 {
3607   char *decrypted_string, *raw_key;
3608   int string_size, key_size;
3609
3610   CHECK_STRING (string);
3611   CHECK_STRING (key);
3612
3613   string_size = XSTRING_LENGTH (string) + 1;
3614   decrypted_string = alloca (string_size);
3615   memcpy (decrypted_string, XSTRING_DATA (string), string_size);
3616   decrypted_string[string_size - 1] = '\0';
3617
3618   key_size = min (CRYPT_KEY_SIZE, XSTRING_LENGTH (key))
3619
3620   raw_key = alloca (CRYPT_KEY_SIZE + 1);
3621   memcpy (raw_key, XSTRING_DATA (key), key_size);
3622   memset (raw_key + key_size, 0, (CRYPT_KEY_SIZE + 1) - key_size);
3623
3624
3625   ecb_crypt (raw_key, decrypted_string, string_size, D | DES_SW);
3626   return make_string (decrypted_string, string_size - 1);
3627 }
3628 #endif /* 0 */
3629
3630 \f
3631 DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 1, 1, 0, /*
3632 Return t if last mod time of BUF's visited file matches what BUF records.
3633 This means that the file has not been changed since it was visited or saved.
3634 */
3635        (buf))
3636 {
3637   /* This function can call lisp */
3638   struct buffer *b;
3639   struct stat st;
3640   Lisp_Object handler;
3641
3642   CHECK_BUFFER (buf);
3643   b = XBUFFER (buf);
3644
3645   if (!STRINGP (b->filename)) return Qt;
3646   if (b->modtime == 0) return Qt;
3647
3648   /* If the file name has special constructs in it,
3649      call the corresponding file handler.  */
3650   handler = Ffind_file_name_handler (b->filename,
3651                                      Qverify_visited_file_modtime);
3652   if (!NILP (handler))
3653     return call2 (handler, Qverify_visited_file_modtime, buf);
3654
3655   if (stat ((char *) XSTRING_DATA (b->filename), &st) < 0)
3656     {
3657       /* If the file doesn't exist now and didn't exist before,
3658          we say that it isn't modified, provided the error is a tame one.  */
3659       if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
3660         st.st_mtime = -1;
3661       else
3662         st.st_mtime = 0;
3663     }
3664   if (st.st_mtime == b->modtime
3665       /* If both are positive, accept them if they are off by one second.  */
3666       || (st.st_mtime > 0 && b->modtime > 0
3667           && (st.st_mtime == b->modtime + 1
3668               || st.st_mtime == b->modtime - 1)))
3669     return Qt;
3670   return Qnil;
3671 }
3672
3673 DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime, 0, 0, 0, /*
3674 Clear out records of last mod time of visited file.
3675 Next attempt to save will certainly not complain of a discrepancy.
3676 */
3677        ())
3678 {
3679   current_buffer->modtime = 0;
3680   return Qnil;
3681 }
3682
3683 DEFUN ("visited-file-modtime", Fvisited_file_modtime, 0, 0, 0, /*
3684 Return the current buffer's recorded visited file modification time.
3685 The value is a list of the form (HIGH . LOW), like the time values
3686 that `file-attributes' returns.
3687 */
3688        ())
3689 {
3690   return time_to_lisp ((time_t) current_buffer->modtime);
3691 }
3692
3693 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime, 0, 1, 0, /*
3694 Update buffer's recorded modification time from the visited file's time.
3695 Useful if the buffer was not read from the file normally
3696 or if the file itself has been changed for some known benign reason.
3697 An argument specifies the modification time value to use
3698 \(instead of that of the visited file), in the form of a list
3699 \(HIGH . LOW) or (HIGH LOW).
3700 */
3701        (time_list))
3702 {
3703   /* This function can call lisp */
3704   if (!NILP (time_list))
3705     {
3706       time_t the_time;
3707       lisp_to_time (time_list, &the_time);
3708       current_buffer->modtime = (int) the_time;
3709     }
3710   else
3711     {
3712       Lisp_Object filename;
3713       struct stat st;
3714       Lisp_Object handler;
3715       struct gcpro gcpro1, gcpro2, gcpro3;
3716
3717       GCPRO3 (filename, time_list, current_buffer->filename);
3718       filename = Fexpand_file_name (current_buffer->filename, Qnil);
3719
3720       /* If the file name has special constructs in it,
3721          call the corresponding file handler.  */
3722       handler = Ffind_file_name_handler (filename, Qset_visited_file_modtime);
3723       UNGCPRO;
3724       if (!NILP (handler))
3725         /* The handler can find the file name the same way we did.  */
3726         return call2 (handler, Qset_visited_file_modtime, Qnil);
3727       else if (stat ((char *) XSTRING_DATA (filename), &st) >= 0)
3728         current_buffer->modtime = st.st_mtime;
3729     }
3730
3731   return Qnil;
3732 }
3733 \f
3734 static Lisp_Object
3735 auto_save_error (Lisp_Object condition_object, Lisp_Object ignored)
3736 {
3737   /* This function can call lisp */
3738   if (gc_in_progress)
3739     return Qnil;
3740   /* Don't try printing an error message after everything is gone! */
3741   if (preparing_for_armageddon)
3742     return Qnil;
3743   clear_echo_area (selected_frame (), Qauto_saving, 1);
3744   Fding (Qt, Qauto_save_error, Qnil);
3745   message ("Auto-saving...error for %s", XSTRING_DATA (current_buffer->name));
3746   Fsleep_for (make_int (1));
3747   message ("Auto-saving...error!for %s", XSTRING_DATA (current_buffer->name));
3748   Fsleep_for (make_int (1));
3749   message ("Auto-saving...error for %s", XSTRING_DATA (current_buffer->name));
3750   Fsleep_for (make_int (1));
3751   return Qnil;
3752 }
3753
3754 static Lisp_Object
3755 auto_save_1 (Lisp_Object ignored)
3756 {
3757   /* This function can call lisp */
3758   /* #### I think caller is protecting current_buffer? */
3759   struct stat st;
3760   Lisp_Object fn = current_buffer->filename;
3761   Lisp_Object a  = current_buffer->auto_save_file_name;
3762
3763   if (!STRINGP (a))
3764     return (Qnil);
3765
3766   /* Get visited file's mode to become the auto save file's mode.  */
3767   if (STRINGP (fn) &&
3768       stat ((char *) XSTRING_DATA (fn), &st) >= 0)
3769     /* But make sure we can overwrite it later!  */
3770     auto_save_mode_bits = st.st_mode | 0600;
3771   else
3772     /* default mode for auto-save files of buffers with no file is
3773        readable by owner only.  This may annoy some small number of
3774        people, but the alternative removes all privacy from email. */
3775     auto_save_mode_bits = 0600;
3776
3777   return
3778     /* !!#### need to deal with this 'escape-quoted everywhere */
3779     Fwrite_region_internal (Qnil, Qnil, a, Qnil, Qlambda, Qnil,
3780 #ifdef MULE
3781                             Qescape_quoted
3782 #else
3783                             Qnil
3784 #endif
3785                             );
3786 }
3787
3788 static Lisp_Object
3789 auto_save_expand_name_error (Lisp_Object condition_object, Lisp_Object ignored)
3790 {
3791   /* #### this function should spew an error message about not being
3792      able to open the .saves file. */
3793   return Qnil;
3794 }
3795
3796 static Lisp_Object
3797 auto_save_expand_name (Lisp_Object name)
3798 {
3799   struct gcpro gcpro1;
3800
3801   /* note that caller did NOT gc protect name, so we do it. */
3802   /* #### dmoore - this might not be necessary, if condition_case_1
3803      protects it.  but I don't think it does. */
3804   GCPRO1 (name);
3805   RETURN_UNGCPRO (Fexpand_file_name (name, Qnil));
3806 }
3807
3808
3809 static Lisp_Object
3810 do_auto_save_unwind (Lisp_Object fd)
3811 {
3812   close (XINT (fd));
3813   return (fd);
3814 }
3815
3816 static Lisp_Object
3817 do_auto_save_unwind_2 (Lisp_Object old_auto_saving)
3818 {
3819   auto_saving = XINT (old_auto_saving);
3820   return Qnil;
3821 }
3822
3823 /* Fdo_auto_save() checks whether a GC is in progress when it is called,
3824    and if so, tries to avoid touching lisp objects.
3825
3826    The only time that Fdo_auto_save() is called while GC is in progress
3827    is if we're going down, as a result of an abort() or a kill signal.
3828    It's fairly important that we generate autosave files in that case!
3829  */
3830
3831 DEFUN ("do-auto-save", Fdo_auto_save, 0, 2, "", /*
3832 Auto-save all buffers that need it.
3833 This is all buffers that have auto-saving enabled
3834 and are changed since last auto-saved.
3835 Auto-saving writes the buffer into a file
3836 so that your editing is not lost if the system crashes.
3837 This file is not the file you visited; that changes only when you save.
3838 Normally we run the normal hook `auto-save-hook' before saving.
3839
3840 Non-nil first argument means do not print any message if successful.
3841 Non-nil second argument means save only current buffer.
3842 */
3843        (no_message, current_only))
3844 {
3845   /* This function can call lisp */
3846   struct buffer *b;
3847   Lisp_Object tail, buf;
3848   int auto_saved = 0;
3849   int do_handled_files;
3850   Lisp_Object oquit = Qnil;
3851   Lisp_Object listfile = Qnil;
3852   Lisp_Object old;
3853   int listdesc = -1;
3854   int speccount = specpdl_depth ();
3855   struct gcpro gcpro1, gcpro2, gcpro3;
3856
3857   XSETBUFFER (old, current_buffer);
3858   GCPRO3 (oquit, listfile, old);
3859   check_quit (); /* make Vquit_flag accurate */
3860   /* Ordinarily don't quit within this function,
3861      but don't make it impossible to quit (in case we get hung in I/O).  */
3862   oquit = Vquit_flag;
3863   Vquit_flag = Qnil;
3864
3865   /* No further GCPRO needed, because (when it matters) all Lisp_Object
3866      variables point to non-strings reached from Vbuffer_alist.  */
3867
3868   if (minibuf_level != 0 || preparing_for_armageddon)
3869     no_message = Qt;
3870
3871   run_hook (Qauto_save_hook);
3872
3873   if (STRINGP (Vauto_save_list_file_name))
3874     listfile = condition_case_1 (Qt,
3875                                  auto_save_expand_name,
3876                                  Vauto_save_list_file_name,
3877                                  auto_save_expand_name_error, Qnil);
3878
3879   /* Make sure auto_saving is reset. */
3880   record_unwind_protect (do_auto_save_unwind_2, make_int (auto_saving));
3881
3882   auto_saving = 1;
3883
3884   /* First, save all files which don't have handlers.  If Emacs is
3885      crashing, the handlers may tweak what is causing Emacs to crash
3886      in the first place, and it would be a shame if Emacs failed to
3887      autosave perfectly ordinary files because it couldn't handle some
3888      ange-ftp'd file.  */
3889   for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
3890     {
3891       for (tail = Vbuffer_alist;
3892            CONSP (tail);
3893            tail = XCDR (tail))
3894         {
3895           buf = XCDR (XCAR (tail));
3896           b = XBUFFER (buf);
3897
3898           if (!NILP (current_only)
3899               && b != current_buffer)
3900             continue;
3901
3902           /* Don't auto-save indirect buffers.
3903              The base buffer takes care of it.  */
3904           if (b->base_buffer)
3905             continue;
3906
3907           /* Check for auto save enabled
3908              and file changed since last auto save
3909              and file changed since last real save.  */
3910           if (STRINGP (b->auto_save_file_name)
3911               && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
3912               && b->auto_save_modified < BUF_MODIFF (b)
3913               /* -1 means we've turned off autosaving for a while--see below.  */
3914               && XINT (b->saved_size) >= 0
3915               && (do_handled_files
3916                   || NILP (Ffind_file_name_handler (b->auto_save_file_name,
3917                                                     Qwrite_region))))
3918             {
3919               EMACS_TIME before_time, after_time;
3920
3921               EMACS_GET_TIME (before_time);
3922               /* If we had a failure, don't try again for 20 minutes.  */
3923               if (!preparing_for_armageddon
3924                   && b->auto_save_failure_time >= 0
3925                   && (EMACS_SECS (before_time) - b->auto_save_failure_time <
3926                       1200))
3927                 continue;
3928
3929               if (!preparing_for_armageddon &&
3930                   (XINT (b->saved_size) * 10
3931                    > (BUF_Z (b) - BUF_BEG (b)) * 13)
3932                   /* A short file is likely to change a large fraction;
3933                      spare the user annoying messages.  */
3934                   && XINT (b->saved_size) > 5000
3935                   /* These messages are frequent and annoying for `*mail*'.  */
3936                   && !NILP (b->filename)
3937                   && NILP (no_message)
3938                   && disable_auto_save_when_buffer_shrinks)
3939                 {
3940                   /* It has shrunk too much; turn off auto-saving here.
3941                      Unless we're about to crash, in which case auto-save it
3942                      anyway.
3943                      */
3944                   message
3945                     ("Buffer %s has shrunk a lot; auto save turned off there",
3946                      XSTRING_DATA (b->name));
3947                   /* Turn off auto-saving until there's a real save,
3948                      and prevent any more warnings.  */
3949                   b->saved_size = make_int (-1);
3950                   if (!gc_in_progress)
3951                     Fsleep_for (make_int (1));
3952                   continue;
3953                 }
3954               set_buffer_internal (b);
3955               if (!auto_saved && NILP (no_message))
3956                 {
3957                   static CONST unsigned char *msg
3958                     = (CONST unsigned char *) "Auto-saving...";
3959                   echo_area_message (selected_frame (), msg, Qnil,
3960                                      0, strlen ((CONST char *) msg),
3961                                      Qauto_saving);
3962                 }
3963
3964               /* Open the auto-save list file, if necessary.
3965                  We only do this now so that the file only exists
3966                  if we actually auto-saved any files. */
3967               if (!auto_saved && STRINGP (listfile) && listdesc < 0)
3968                 {
3969                   listdesc = open ((char *) XSTRING_DATA (listfile),
3970                                    O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
3971                                    CREAT_MODE);
3972
3973                   /* Arrange to close that file whether or not we get
3974                      an error. */
3975                   if (listdesc >= 0)
3976                     record_unwind_protect (do_auto_save_unwind,
3977                                            make_int (listdesc));
3978                 }
3979
3980               /* Record all the buffers that we are auto-saving in
3981                  the special file that lists them.  For each of
3982                  these buffers, record visited name (if any) and
3983                  auto save name.  */
3984               if (listdesc >= 0)
3985                 {
3986                   CONST Extbyte *auto_save_file_name_ext;
3987                   Extcount auto_save_file_name_ext_len;
3988
3989                   TO_EXTERNAL_FORMAT (LISP_STRING, b->auto_save_file_name,
3990                                       ALLOCA, (auto_save_file_name_ext,
3991                                                auto_save_file_name_ext_len),
3992                                       Qfile_name);
3993                   if (!NILP (b->filename))
3994                     {
3995                       CONST Extbyte *filename_ext;
3996                       Extcount filename_ext_len;
3997
3998                       TO_EXTERNAL_FORMAT (LISP_STRING, b->filename,
3999                                           ALLOCA, (filename_ext,
4000                                                    filename_ext_len),
4001                                           Qfile_name);
4002                       write (listdesc, filename_ext, filename_ext_len);
4003                     }
4004                   write (listdesc, "\n", 1);
4005                   write (listdesc, auto_save_file_name_ext,
4006                          auto_save_file_name_ext_len);
4007                   write (listdesc, "\n", 1);
4008                 }
4009
4010               /* dmoore - In a bad scenario we've set b=XBUFFER(buf)
4011                  based on values in Vbuffer_alist.  auto_save_1 may
4012                  cause lisp handlers to run.  Those handlers may kill
4013                  the buffer and then GC.  Since the buffer is killed,
4014                  it's no longer in Vbuffer_alist so it might get reaped
4015                  by the GC.  We also need to protect tail. */
4016               /* #### There is probably a lot of other code which has
4017                  pointers into buffers which may get blown away by
4018                  handlers. */
4019               {
4020                 struct gcpro ngcpro1, ngcpro2;
4021                 NGCPRO2 (buf, tail);
4022                 condition_case_1 (Qt,
4023                                   auto_save_1, Qnil,
4024                                   auto_save_error, Qnil);
4025                 NUNGCPRO;
4026               }
4027               /* Handler killed our saved current-buffer!  Pick any. */
4028               if (!BUFFER_LIVE_P (XBUFFER (old)))
4029                 XSETBUFFER (old, current_buffer);
4030
4031               set_buffer_internal (XBUFFER (old));
4032               auto_saved++;
4033
4034               /* Handler killed their own buffer! */
4035               if (!BUFFER_LIVE_P(b))
4036                 continue;
4037
4038               b->auto_save_modified = BUF_MODIFF (b);
4039               b->saved_size = make_int (BUF_SIZE (b));
4040               EMACS_GET_TIME (after_time);
4041               /* If auto-save took more than 60 seconds,
4042                  assume it was an NFS failure that got a timeout.  */
4043               if (EMACS_SECS (after_time) - EMACS_SECS (before_time) > 60)
4044                 b->auto_save_failure_time = EMACS_SECS (after_time);
4045             }
4046         }
4047     }
4048
4049   /* Prevent another auto save till enough input events come in.  */
4050   if (auto_saved)
4051     record_auto_save ();
4052
4053   /* If we didn't save anything into the listfile, remove the old
4054      one because nothing needed to be auto-saved.  Do this afterwards
4055      rather than before in case we get a crash attempting to autosave
4056      (in that case we'd still want the old one around). */
4057   if (listdesc < 0 && !auto_saved && STRINGP (listfile))
4058     unlink ((char *) XSTRING_DATA (listfile));
4059
4060   /* Show "...done" only if the echo area would otherwise be empty. */
4061   if (auto_saved && NILP (no_message)
4062       && NILP (clear_echo_area (selected_frame (), Qauto_saving, 0)))
4063     {
4064       static CONST unsigned char *msg
4065         = (CONST unsigned char *)"Auto-saving...done";
4066       echo_area_message (selected_frame (), msg, Qnil, 0,
4067                          strlen ((CONST char *) msg), Qauto_saving);
4068     }
4069
4070   Vquit_flag = oquit;
4071
4072   RETURN_UNGCPRO (unbind_to (speccount, Qnil));
4073 }
4074
4075 DEFUN ("set-buffer-auto-saved", Fset_buffer_auto_saved, 0, 0, 0, /*
4076 Mark current buffer as auto-saved with its current text.
4077 No auto-save file will be written until the buffer changes again.
4078 */
4079        ())
4080 {
4081   current_buffer->auto_save_modified = BUF_MODIFF (current_buffer);
4082   current_buffer->saved_size = make_int (BUF_SIZE (current_buffer));
4083   current_buffer->auto_save_failure_time = -1;
4084   return Qnil;
4085 }
4086
4087 DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure, 0, 0, 0, /*
4088 Clear any record of a recent auto-save failure in the current buffer.
4089 */
4090        ())
4091 {
4092   current_buffer->auto_save_failure_time = -1;
4093   return Qnil;
4094 }
4095
4096 DEFUN ("recent-auto-save-p", Frecent_auto_save_p, 0, 0, 0, /*
4097 Return t if buffer has been auto-saved since last read in or saved.
4098 */
4099        ())
4100 {
4101   return (BUF_SAVE_MODIFF (current_buffer) <
4102           current_buffer->auto_save_modified) ? Qt : Qnil;
4103 }
4104
4105 \f
4106 /************************************************************************/
4107 /*                            initialization                            */
4108 /************************************************************************/
4109
4110 void
4111 syms_of_fileio (void)
4112 {
4113   defsymbol (&Qexpand_file_name, "expand-file-name");
4114   defsymbol (&Qfile_truename, "file-truename");
4115   defsymbol (&Qsubstitute_in_file_name, "substitute-in-file-name");
4116   defsymbol (&Qdirectory_file_name, "directory-file-name");
4117   defsymbol (&Qfile_name_directory, "file-name-directory");
4118   defsymbol (&Qfile_name_nondirectory, "file-name-nondirectory");
4119   defsymbol (&Qunhandled_file_name_directory, "unhandled-file-name-directory");
4120   defsymbol (&Qfile_name_as_directory, "file-name-as-directory");
4121   defsymbol (&Qcopy_file, "copy-file");
4122   defsymbol (&Qmake_directory_internal, "make-directory-internal");
4123   defsymbol (&Qdelete_directory, "delete-directory");
4124   defsymbol (&Qdelete_file, "delete-file");
4125   defsymbol (&Qrename_file, "rename-file");
4126   defsymbol (&Qadd_name_to_file, "add-name-to-file");
4127   defsymbol (&Qmake_symbolic_link, "make-symbolic-link");
4128   defsymbol (&Qfile_exists_p, "file-exists-p");
4129   defsymbol (&Qfile_executable_p, "file-executable-p");
4130   defsymbol (&Qfile_readable_p, "file-readable-p");
4131   defsymbol (&Qfile_symlink_p, "file-symlink-p");
4132   defsymbol (&Qfile_writable_p, "file-writable-p");
4133   defsymbol (&Qfile_directory_p, "file-directory-p");
4134   defsymbol (&Qfile_regular_p, "file-regular-p");
4135   defsymbol (&Qfile_accessible_directory_p, "file-accessible-directory-p");
4136   defsymbol (&Qfile_modes, "file-modes");
4137   defsymbol (&Qset_file_modes, "set-file-modes");
4138   defsymbol (&Qfile_newer_than_file_p, "file-newer-than-file-p");
4139   defsymbol (&Qinsert_file_contents, "insert-file-contents");
4140   defsymbol (&Qwrite_region, "write-region");
4141   defsymbol (&Qverify_visited_file_modtime, "verify-visited-file-modtime");
4142   defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime");
4143   defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */
4144
4145   defsymbol (&Qauto_save_hook, "auto-save-hook");
4146   defsymbol (&Qauto_save_error, "auto-save-error");
4147   defsymbol (&Qauto_saving, "auto-saving");
4148
4149   defsymbol (&Qformat_decode, "format-decode");
4150   defsymbol (&Qformat_annotate_function, "format-annotate-function");
4151
4152   defsymbol (&Qcompute_buffer_file_truename, "compute-buffer-file-truename");
4153   deferror (&Qfile_error, "file-error", "File error", Qio_error);
4154   deferror (&Qfile_already_exists, "file-already-exists",
4155             "File already exists", Qfile_error);
4156
4157   DEFSUBR (Ffind_file_name_handler);
4158
4159   DEFSUBR (Ffile_name_directory);
4160   DEFSUBR (Ffile_name_nondirectory);
4161   DEFSUBR (Funhandled_file_name_directory);
4162   DEFSUBR (Ffile_name_as_directory);
4163   DEFSUBR (Fdirectory_file_name);
4164   DEFSUBR (Fmake_temp_name);
4165   DEFSUBR (Fexpand_file_name);
4166   DEFSUBR (Ffile_truename);
4167   DEFSUBR (Fsubstitute_in_file_name);
4168   DEFSUBR (Fcopy_file);
4169   DEFSUBR (Fmake_directory_internal);
4170   DEFSUBR (Fdelete_directory);
4171   DEFSUBR (Fdelete_file);
4172   DEFSUBR (Frename_file);
4173   DEFSUBR (Fadd_name_to_file);
4174 #ifdef S_IFLNK
4175   DEFSUBR (Fmake_symbolic_link);
4176 #endif /* S_IFLNK */
4177 #ifdef HPUX_NET
4178   DEFSUBR (Fsysnetunam);
4179 #endif /* HPUX_NET */
4180   DEFSUBR (Ffile_name_absolute_p);
4181   DEFSUBR (Ffile_exists_p);
4182   DEFSUBR (Ffile_executable_p);
4183   DEFSUBR (Ffile_readable_p);
4184   DEFSUBR (Ffile_writable_p);
4185   DEFSUBR (Ffile_symlink_p);
4186   DEFSUBR (Ffile_directory_p);
4187   DEFSUBR (Ffile_accessible_directory_p);
4188   DEFSUBR (Ffile_regular_p);
4189   DEFSUBR (Ffile_modes);
4190   DEFSUBR (Fset_file_modes);
4191   DEFSUBR (Fset_default_file_modes);
4192   DEFSUBR (Fdefault_file_modes);
4193   DEFSUBR (Funix_sync);
4194   DEFSUBR (Ffile_newer_than_file_p);
4195   DEFSUBR (Finsert_file_contents_internal);
4196   DEFSUBR (Fwrite_region_internal);
4197   DEFSUBR (Fcar_less_than_car); /* Vomitous! */
4198   DEFSUBR (Fcdr_less_than_cdr); /* Yeah oh yeah bucko .... */
4199 #if 0
4200   DEFSUBR (Fencrypt_string);
4201   DEFSUBR (Fdecrypt_string);
4202 #endif
4203   DEFSUBR (Fverify_visited_file_modtime);
4204   DEFSUBR (Fclear_visited_file_modtime);
4205   DEFSUBR (Fvisited_file_modtime);
4206   DEFSUBR (Fset_visited_file_modtime);
4207
4208   DEFSUBR (Fdo_auto_save);
4209   DEFSUBR (Fset_buffer_auto_saved);
4210   DEFSUBR (Fclear_buffer_auto_save_failure);
4211   DEFSUBR (Frecent_auto_save_p);
4212 }
4213
4214 void
4215 vars_of_fileio (void)
4216 {
4217   DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format /*
4218 *Format in which to write auto-save files.
4219 Should be a list of symbols naming formats that are defined in `format-alist'.
4220 If it is t, which is the default, auto-save files are written in the
4221 same format as a regular save would use.
4222 */ );
4223   Vauto_save_file_format = Qt;
4224
4225   DEFVAR_LISP ("file-name-handler-alist", &Vfile_name_handler_alist /*
4226 *Alist of elements (REGEXP . HANDLER) for file names handled specially.
4227 If a file name matches REGEXP, then all I/O on that file is done by calling
4228 HANDLER.
4229
4230 The first argument given to HANDLER is the name of the I/O primitive
4231 to be handled; the remaining arguments are the arguments that were
4232 passed to that primitive.  For example, if you do
4233     (file-exists-p FILENAME)
4234 and FILENAME is handled by HANDLER, then HANDLER is called like this:
4235     (funcall HANDLER 'file-exists-p FILENAME)
4236 The function `find-file-name-handler' checks this list for a handler
4237 for its argument.
4238 */ );
4239   Vfile_name_handler_alist = Qnil;
4240
4241   DEFVAR_LISP ("after-insert-file-functions", &Vafter_insert_file_functions /*
4242 A list of functions to be called at the end of `insert-file-contents'.
4243 Each is passed one argument, the number of bytes inserted.  It should return
4244 the new byte count, and leave point the same.  If `insert-file-contents' is
4245 intercepted by a handler from `file-name-handler-alist', that handler is
4246 responsible for calling the after-insert-file-functions if appropriate.
4247 */ );
4248   Vafter_insert_file_functions = Qnil;
4249
4250   DEFVAR_LISP ("write-region-annotate-functions",
4251                &Vwrite_region_annotate_functions /*
4252 A list of functions to be called at the start of `write-region'.
4253 Each is passed two arguments, START and END, as for `write-region'.
4254 It should return a list of pairs (POSITION . STRING) of strings to be
4255 effectively inserted at the specified positions of the file being written
4256 \(1 means to insert before the first byte written).  The POSITIONs must be
4257 sorted into increasing order.  If there are several functions in the list,
4258 the several lists are merged destructively.
4259 */ );
4260   Vwrite_region_annotate_functions = Qnil;
4261
4262   DEFVAR_LISP ("write-region-annotations-so-far",
4263                &Vwrite_region_annotations_so_far /*
4264 When an annotation function is called, this holds the previous annotations.
4265 These are the annotations made by other annotation functions
4266 that were already called.  See also `write-region-annotate-functions'.
4267 */ );
4268   Vwrite_region_annotations_so_far = Qnil;
4269
4270   DEFVAR_LISP ("inhibit-file-name-handlers", &Vinhibit_file_name_handlers /*
4271 A list of file name handlers that temporarily should not be used.
4272 This applies only to the operation `inhibit-file-name-operation'.
4273 */ );
4274   Vinhibit_file_name_handlers = Qnil;
4275
4276   DEFVAR_LISP ("inhibit-file-name-operation", &Vinhibit_file_name_operation /*
4277 The operation for which `inhibit-file-name-handlers' is applicable.
4278 */ );
4279   Vinhibit_file_name_operation = Qnil;
4280
4281   DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name /*
4282 File name in which we write a list of all auto save file names.
4283 */ );
4284   Vauto_save_list_file_name = Qnil;
4285
4286   DEFVAR_BOOL ("disable-auto-save-when-buffer-shrinks",
4287                &disable_auto_save_when_buffer_shrinks /*
4288 If non-nil, auto-saving is disabled when a buffer shrinks too much.
4289 This is to prevent you from losing your edits if you accidentally
4290 delete a large chunk of the buffer and don't notice it until too late.
4291 Saving the buffer normally turns auto-save back on.
4292 */ );
4293   disable_auto_save_when_buffer_shrinks = 1;
4294
4295   DEFVAR_LISP ("directory-sep-char", &Vdirectory_sep_char /*
4296 Directory separator character for built-in functions that return file names.
4297 The value should be either ?/ or ?\\ (any other value is treated as ?\\).
4298 This variable affects the built-in functions only on Windows,
4299 on other platforms, it is initialized so that Lisp code can find out
4300 what the normal separator is.
4301 */ );
4302 #ifdef WINDOWSNT
4303   Vdirectory_sep_char = make_char ('\\');
4304 #else
4305    Vdirectory_sep_char = make_char ('/');
4306 #endif
4307 }