aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c359
1 files changed, 251 insertions, 108 deletions
diff --git a/src/fileio.c b/src/fileio.c
index c6f8dfe4683..7efe919a9f0 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1,6 +1,6 @@
1/* File IO for GNU Emacs. 1/* File IO for GNU Emacs.
2 2
3Copyright (C) 1985-1988, 1993-2011 Free Software Foundation, Inc. 3Copyright (C) 1985-1988, 1993-2012 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -62,7 +62,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
62 62
63#ifdef DOS_NT 63#ifdef DOS_NT
64/* On Windows, drive letters must be alphabetic - on DOS, the Netware 64/* On Windows, drive letters must be alphabetic - on DOS, the Netware
65 redirector allows the six letters between 'Z' and 'a' as well. */ 65 redirector allows the six letters between 'Z' and 'a' as well. */
66#ifdef MSDOS 66#ifdef MSDOS
67#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z') 67#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
68#endif 68#endif
@@ -70,7 +70,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
70#define IS_DRIVE(x) isalpha ((unsigned char) (x)) 70#define IS_DRIVE(x) isalpha ((unsigned char) (x))
71#endif 71#endif
72/* Need to lower-case the drive letter, or else expanded 72/* Need to lower-case the drive letter, or else expanded
73 filenames will sometimes compare inequal, because 73 filenames will sometimes compare unequal, because
74 `expand-file-name' doesn't always down-case the drive letter. */ 74 `expand-file-name' doesn't always down-case the drive letter. */
75#define DRIVE_LETTER(x) (tolower ((unsigned char) (x))) 75#define DRIVE_LETTER(x) (tolower ((unsigned char) (x)))
76#endif 76#endif
@@ -90,6 +90,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
90/* Nonzero during writing of auto-save files */ 90/* Nonzero during writing of auto-save files */
91static int auto_saving; 91static int auto_saving;
92 92
93/* Nonzero umask during creation of auto-save directories */
94static int auto_saving_dir_umask;
95
93/* Set by auto_save_1 to mode of original file so Fwrite_region will create 96/* Set by auto_save_1 to mode of original file so Fwrite_region will create
94 a new file with the same mode as the original */ 97 a new file with the same mode as the original */
95static int auto_save_mode_bits; 98static int auto_save_mode_bits;
@@ -325,7 +328,11 @@ Given a Unix syntax file name, returns a string ending in slash. */)
325 call the corresponding file handler. */ 328 call the corresponding file handler. */
326 handler = Ffind_file_name_handler (filename, Qfile_name_directory); 329 handler = Ffind_file_name_handler (filename, Qfile_name_directory);
327 if (!NILP (handler)) 330 if (!NILP (handler))
328 return call2 (handler, Qfile_name_directory, filename); 331 {
332 Lisp_Object handled_name = call2 (handler, Qfile_name_directory,
333 filename);
334 return STRINGP (handled_name) ? handled_name : Qnil;
335 }
329 336
330 filename = FILE_SYSTEM_CASE (filename); 337 filename = FILE_SYSTEM_CASE (filename);
331#ifdef DOS_NT 338#ifdef DOS_NT
@@ -338,7 +345,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
338 345
339 while (p != beg && !IS_DIRECTORY_SEP (p[-1]) 346 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
340#ifdef DOS_NT 347#ifdef DOS_NT
341 /* only recognise drive specifier at the beginning */ 348 /* only recognize drive specifier at the beginning */
342 && !(p[-1] == ':' 349 && !(p[-1] == ':'
343 /* handle the "/:d:foo" and "/:foo" cases correctly */ 350 /* handle the "/:d:foo" and "/:foo" cases correctly */
344 && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg)) 351 && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
@@ -394,14 +401,20 @@ or the entire name if it contains no slash. */)
394 call the corresponding file handler. */ 401 call the corresponding file handler. */
395 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory); 402 handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
396 if (!NILP (handler)) 403 if (!NILP (handler))
397 return call2 (handler, Qfile_name_nondirectory, filename); 404 {
405 Lisp_Object handled_name = call2 (handler, Qfile_name_nondirectory,
406 filename);
407 if (STRINGP (handled_name))
408 return handled_name;
409 error ("Invalid handler in `file-name-handler-alist'");
410 }
398 411
399 beg = SSDATA (filename); 412 beg = SSDATA (filename);
400 end = p = beg + SBYTES (filename); 413 end = p = beg + SBYTES (filename);
401 414
402 while (p != beg && !IS_DIRECTORY_SEP (p[-1]) 415 while (p != beg && !IS_DIRECTORY_SEP (p[-1])
403#ifdef DOS_NT 416#ifdef DOS_NT
404 /* only recognise drive specifier at beginning */ 417 /* only recognize drive specifier at beginning */
405 && !(p[-1] == ':' 418 && !(p[-1] == ':'
406 /* handle the "/:d:foo" case correctly */ 419 /* handle the "/:d:foo" case correctly */
407 && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg)))) 420 && (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
@@ -431,7 +444,11 @@ get a current directory to run processes in. */)
431 call the corresponding file handler. */ 444 call the corresponding file handler. */
432 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory); 445 handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory);
433 if (!NILP (handler)) 446 if (!NILP (handler))
434 return call2 (handler, Qunhandled_file_name_directory, filename); 447 {
448 Lisp_Object handled_name = call2 (handler, Qunhandled_file_name_directory,
449 filename);
450 return STRINGP (handled_name) ? handled_name : Qnil;
451 }
435 452
436 return Ffile_name_directory (filename); 453 return Ffile_name_directory (filename);
437} 454}
@@ -485,7 +502,13 @@ For a Unix-syntax file name, just appends a slash. */)
485 call the corresponding file handler. */ 502 call the corresponding file handler. */
486 handler = Ffind_file_name_handler (file, Qfile_name_as_directory); 503 handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
487 if (!NILP (handler)) 504 if (!NILP (handler))
488 return call2 (handler, Qfile_name_as_directory, file); 505 {
506 Lisp_Object handled_name = call2 (handler, Qfile_name_as_directory,
507 file);
508 if (STRINGP (handled_name))
509 return handled_name;
510 error ("Invalid handler in `file-name-handler-alist'");
511 }
489 512
490 buf = (char *) alloca (SBYTES (file) + 10); 513 buf = (char *) alloca (SBYTES (file) + 10);
491 file_name_as_directory (buf, SSDATA (file)); 514 file_name_as_directory (buf, SSDATA (file));
@@ -544,7 +567,13 @@ In Unix-syntax, this function just removes the final slash. */)
544 call the corresponding file handler. */ 567 call the corresponding file handler. */
545 handler = Ffind_file_name_handler (directory, Qdirectory_file_name); 568 handler = Ffind_file_name_handler (directory, Qdirectory_file_name);
546 if (!NILP (handler)) 569 if (!NILP (handler))
547 return call2 (handler, Qdirectory_file_name, directory); 570 {
571 Lisp_Object handled_name = call2 (handler, Qdirectory_file_name,
572 directory);
573 if (STRINGP (handled_name))
574 return handled_name;
575 error ("Invalid handler in `file-name-handler-alist'");
576 }
548 577
549 buf = (char *) alloca (SBYTES (directory) + 20); 578 buf = (char *) alloca (SBYTES (directory) + 20);
550 directory_file_name (SSDATA (directory), buf); 579 directory_file_name (SSDATA (directory), buf);
@@ -587,9 +616,9 @@ make_temp_name (Lisp_Object prefix, int base64_p)
587{ 616{
588 Lisp_Object val; 617 Lisp_Object val;
589 int len, clen; 618 int len, clen;
590 intmax_t pid; 619 printmax_t pid;
591 char *p, *data; 620 char *p, *data;
592 char pidbuf[INT_BUFSIZE_BOUND (pid_t)]; 621 char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
593 int pidlen; 622 int pidlen;
594 623
595 CHECK_STRING (prefix); 624 CHECK_STRING (prefix);
@@ -611,7 +640,7 @@ make_temp_name (Lisp_Object prefix, int base64_p)
611 else 640 else
612 { 641 {
613#ifdef HAVE_LONG_FILE_NAMES 642#ifdef HAVE_LONG_FILE_NAMES
614 pidlen = sprintf (pidbuf, "%"PRIdMAX, pid); 643 pidlen = sprintf (pidbuf, "%"pMd, pid);
615#else 644#else
616 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6; 645 pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
617 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6; 646 pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
@@ -744,7 +773,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
744 int is_escaped = 0; 773 int is_escaped = 0;
745#endif /* DOS_NT */ 774#endif /* DOS_NT */
746 ptrdiff_t length; 775 ptrdiff_t length;
747 Lisp_Object handler, result; 776 Lisp_Object handler, result, handled_name;
748 int multibyte; 777 int multibyte;
749 Lisp_Object hdir; 778 Lisp_Object hdir;
750 779
@@ -754,7 +783,14 @@ filesystem tree, not (expand-file-name ".." dirname). */)
754 call the corresponding file handler. */ 783 call the corresponding file handler. */
755 handler = Ffind_file_name_handler (name, Qexpand_file_name); 784 handler = Ffind_file_name_handler (name, Qexpand_file_name);
756 if (!NILP (handler)) 785 if (!NILP (handler))
757 return call3 (handler, Qexpand_file_name, name, default_directory); 786 {
787 handled_name = call3 (handler, Qexpand_file_name,
788 name, default_directory);
789 if (STRINGP (handled_name))
790 return handled_name;
791 error ("Invalid handler in `file-name-handler-alist'");
792 }
793
758 794
759 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ 795 /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
760 if (NILP (default_directory)) 796 if (NILP (default_directory))
@@ -780,7 +816,13 @@ filesystem tree, not (expand-file-name ".." dirname). */)
780 { 816 {
781 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); 817 handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
782 if (!NILP (handler)) 818 if (!NILP (handler))
783 return call3 (handler, Qexpand_file_name, name, default_directory); 819 {
820 handled_name = call3 (handler, Qexpand_file_name,
821 name, default_directory);
822 if (STRINGP (handled_name))
823 return handled_name;
824 error ("Invalid handler in `file-name-handler-alist'");
825 }
784 } 826 }
785 827
786 { 828 {
@@ -1281,7 +1323,13 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1281 to be expanded again. */ 1323 to be expanded again. */
1282 handler = Ffind_file_name_handler (result, Qexpand_file_name); 1324 handler = Ffind_file_name_handler (result, Qexpand_file_name);
1283 if (!NILP (handler)) 1325 if (!NILP (handler))
1284 return call3 (handler, Qexpand_file_name, result, default_directory); 1326 {
1327 handled_name = call3 (handler, Qexpand_file_name,
1328 result, default_directory);
1329 if (STRINGP (handled_name))
1330 return handled_name;
1331 error ("Invalid handler in `file-name-handler-alist'");
1332 }
1285 1333
1286 return result; 1334 return result;
1287} 1335}
@@ -1472,7 +1520,7 @@ search_embedded_absfilename (char *nm, char *endp)
1472 if ((0 1520 if ((0
1473 || IS_DIRECTORY_SEP (p[-1])) 1521 || IS_DIRECTORY_SEP (p[-1]))
1474 && file_name_absolute_p (p) 1522 && file_name_absolute_p (p)
1475#if defined (WINDOWSNT) || defined(CYGWIN) 1523#if defined (WINDOWSNT) || defined (CYGWIN)
1476 /* // at start of file name is meaningful in Apollo, 1524 /* // at start of file name is meaningful in Apollo,
1477 WindowsNT and Cygwin systems. */ 1525 WindowsNT and Cygwin systems. */
1478 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm) 1526 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm)
@@ -1534,7 +1582,13 @@ those `/' is discarded. */)
1534 call the corresponding file handler. */ 1582 call the corresponding file handler. */
1535 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name); 1583 handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
1536 if (!NILP (handler)) 1584 if (!NILP (handler))
1537 return call2 (handler, Qsubstitute_in_file_name, filename); 1585 {
1586 Lisp_Object handled_name = call2 (handler, Qsubstitute_in_file_name,
1587 filename);
1588 if (STRINGP (handled_name))
1589 return handled_name;
1590 error ("Invalid handler in `file-name-handler-alist'");
1591 }
1538 1592
1539 /* Always work on a copy of the string, in case GC happens during 1593 /* Always work on a copy of the string, in case GC happens during
1540 decode of environment variables, causing the original Lisp_String 1594 decode of environment variables, causing the original Lisp_String
@@ -1553,7 +1607,7 @@ those `/' is discarded. */)
1553 if (p) 1607 if (p)
1554 /* Start over with the new string, so we check the file-name-handler 1608 /* Start over with the new string, so we check the file-name-handler
1555 again. Important with filenames like "/home/foo//:/hello///there" 1609 again. Important with filenames like "/home/foo//:/hello///there"
1556 which whould substitute to "/:/hello///there" rather than "/there". */ 1610 which would substitute to "/:/hello///there" rather than "/there". */
1557 return Fsubstitute_in_file_name 1611 return Fsubstitute_in_file_name
1558 (make_specified_string (p, -1, endp - p, multibyte)); 1612 (make_specified_string (p, -1, endp - p, multibyte));
1559 1613
@@ -1937,10 +1991,19 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
1937 | (NILP (ok_if_already_exists) ? O_EXCL : 0), 1991 | (NILP (ok_if_already_exists) ? O_EXCL : 0),
1938 S_IREAD | S_IWRITE); 1992 S_IREAD | S_IWRITE);
1939#else /* not MSDOS */ 1993#else /* not MSDOS */
1940 ofd = emacs_open (SSDATA (encoded_newname), 1994 {
1941 O_WRONLY | O_TRUNC | O_CREAT 1995 int new_mask = 0666;
1942 | (NILP (ok_if_already_exists) ? O_EXCL : 0), 1996 if (input_file_statable_p)
1943 0666); 1997 {
1998 if (!NILP (preserve_uid_gid))
1999 new_mask = 0600;
2000 new_mask &= st.st_mode;
2001 }
2002 ofd = emacs_open (SSDATA (encoded_newname),
2003 (O_WRONLY | O_TRUNC | O_CREAT
2004 | (NILP (ok_if_already_exists) ? O_EXCL : 0)),
2005 new_mask);
2006 }
1944#endif /* not MSDOS */ 2007#endif /* not MSDOS */
1945 if (ofd < 0) 2008 if (ofd < 0)
1946 report_file_error ("Opening output file", Fcons (newname, Qnil)); 2009 report_file_error ("Opening output file", Fcons (newname, Qnil));
@@ -1959,9 +2022,21 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
1959 owner and group. */ 2022 owner and group. */
1960 if (input_file_statable_p) 2023 if (input_file_statable_p)
1961 { 2024 {
1962 if (!NILP (preserve_uid_gid) && fchown (ofd, st.st_uid, st.st_gid) != 0) 2025 int mode_mask = 07777;
1963 report_file_error ("Doing chown", Fcons (newname, Qnil)); 2026 if (!NILP (preserve_uid_gid))
1964 if (fchmod (ofd, st.st_mode & 07777) != 0) 2027 {
2028 /* Attempt to change owner and group. If that doesn't work
2029 attempt to change just the group, as that is sometimes allowed.
2030 Adjust the mode mask to eliminate setuid or setgid bits
2031 that are inappropriate if the owner and group are wrong. */
2032 if (fchown (ofd, st.st_uid, st.st_gid) != 0)
2033 {
2034 mode_mask &= ~06000;
2035 if (fchown (ofd, -1, st.st_gid) == 0)
2036 mode_mask |= 02000;
2037 }
2038 }
2039 if (fchmod (ofd, st.st_mode & mode_mask) != 0)
1965 report_file_error ("Doing chmod", Fcons (newname, Qnil)); 2040 report_file_error ("Doing chmod", Fcons (newname, Qnil));
1966 } 2041 }
1967#endif /* not MSDOS */ 2042#endif /* not MSDOS */
@@ -2041,7 +2116,7 @@ DEFUN ("make-directory-internal", Fmake_directory_internal,
2041#ifdef WINDOWSNT 2116#ifdef WINDOWSNT
2042 if (mkdir (dir) != 0) 2117 if (mkdir (dir) != 0)
2043#else 2118#else
2044 if (mkdir (dir, 0777) != 0) 2119 if (mkdir (dir, 0777 & ~auto_saving_dir_umask) != 0)
2045#endif 2120#endif
2046 report_file_error ("Creating directory", list1 (directory)); 2121 report_file_error ("Creating directory", list1 (directory));
2047 2122
@@ -2395,15 +2470,27 @@ check_writable (const char *filename)
2395 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); 2470 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode));
2396#else /* not MSDOS */ 2471#else /* not MSDOS */
2397#ifdef HAVE_EUIDACCESS 2472#ifdef HAVE_EUIDACCESS
2398 return (euidaccess (filename, 2) >= 0); 2473 int res = (euidaccess (filename, 2) >= 0);
2399#else 2474#ifdef CYGWIN
2475 /* euidaccess may have returned failure because Cygwin couldn't
2476 determine the file's UID or GID; if so, we return success. */
2477 if (!res)
2478 {
2479 struct stat st;
2480 if (stat (filename, &st) < 0)
2481 return 0;
2482 res = (st.st_uid == -1 || st.st_gid == -1);
2483 }
2484#endif /* CYGWIN */
2485 return res;
2486#else /* not HAVE_EUIDACCESS */
2400 /* Access isn't quite right because it uses the real uid 2487 /* Access isn't quite right because it uses the real uid
2401 and we really want to test with the effective uid. 2488 and we really want to test with the effective uid.
2402 But Unix doesn't give us a right way to do it. 2489 But Unix doesn't give us a right way to do it.
2403 Opening with O_WRONLY could work for an ordinary file, 2490 Opening with O_WRONLY could work for an ordinary file,
2404 but would lose for directories. */ 2491 but would lose for directories. */
2405 return (access (filename, 2) >= 0); 2492 return (access (filename, 2) >= 0);
2406#endif 2493#endif /* not HAVE_EUIDACCESS */
2407#endif /* not MSDOS */ 2494#endif /* not MSDOS */
2408} 2495}
2409 2496
@@ -2476,7 +2563,7 @@ See also `file-exists-p' and `file-attributes'. */)
2476 2563
2477 absname = ENCODE_FILE (absname); 2564 absname = ENCODE_FILE (absname);
2478 2565
2479#if defined(DOS_NT) || defined(macintosh) 2566#if defined (DOS_NT) || defined (macintosh)
2480 /* Under MS-DOS, Windows, and Macintosh, open does not work for 2567 /* Under MS-DOS, Windows, and Macintosh, open does not work for
2481 directories. */ 2568 directories. */
2482 if (access (SDATA (absname), 0) == 0) 2569 if (access (SDATA (absname), 0) == 0)
@@ -2711,9 +2798,13 @@ See `file-symlink-p' to distinguish symlinks. */)
2711 2798
2712DEFUN ("file-selinux-context", Ffile_selinux_context, 2799DEFUN ("file-selinux-context", Ffile_selinux_context,
2713 Sfile_selinux_context, 1, 1, 0, 2800 Sfile_selinux_context, 1, 1, 0,
2714 doc: /* Return SELinux context of file named FILENAME, 2801 doc: /* Return SELinux context of file named FILENAME.
2715as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil) 2802The return value is a list (USER ROLE TYPE RANGE), where the list
2716if file does not exist, is not accessible, or SELinux is disabled */) 2803elements are strings naming the user, role, type, and range of the
2804file's SELinux security context.
2805
2806Return (nil nil nil nil) if the file is nonexistent or inaccessible,
2807or if SELinux is disabled, or if Emacs lacks SELinux support. */)
2717 (Lisp_Object filename) 2808 (Lisp_Object filename)
2718{ 2809{
2719 Lisp_Object absname; 2810 Lisp_Object absname;
@@ -2761,14 +2852,17 @@ if file does not exist, is not accessible, or SELinux is disabled */)
2761 } 2852 }
2762#endif 2853#endif
2763 2854
2764 return Flist (sizeof(values) / sizeof(values[0]), values); 2855 return Flist (sizeof (values) / sizeof (values[0]), values);
2765} 2856}
2766 2857
2767DEFUN ("set-file-selinux-context", Fset_file_selinux_context, 2858DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
2768 Sset_file_selinux_context, 2, 2, 0, 2859 Sset_file_selinux_context, 2, 2, 0,
2769 doc: /* Set SELinux context of file named FILENAME to CONTEXT 2860 doc: /* Set SELinux context of file named FILENAME to CONTEXT.
2770as a list ("user", "role", "type", "range"). Has no effect if SELinux 2861CONTEXT should be a list (USER ROLE TYPE RANGE), where the list
2771is disabled. */) 2862elements are strings naming the components of a SELinux context.
2863
2864This function does nothing if SELinux is disabled, or if Emacs was not
2865compiled with SELinux support. */)
2772 (Lisp_Object filename, Lisp_Object context) 2866 (Lisp_Object filename, Lisp_Object context)
2773{ 2867{
2774 Lisp_Object absname; 2868 Lisp_Object absname;
@@ -2832,7 +2926,7 @@ is disabled. */)
2832 context_free (parsed_con); 2926 context_free (parsed_con);
2833 } 2927 }
2834 else 2928 else
2835 report_file_error("Doing lgetfilecon", Fcons (absname, Qnil)); 2929 report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil));
2836 2930
2837 if (con) 2931 if (con)
2838 freecon (con); 2932 freecon (con);
@@ -2891,7 +2985,7 @@ symbolic notation, like the `chmod' command from GNU Coreutils. */)
2891 2985
2892 encoded_absname = ENCODE_FILE (absname); 2986 encoded_absname = ENCODE_FILE (absname);
2893 2987
2894 if (chmod (SSDATA (encoded_absname), XINT (mode)) < 0) 2988 if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0)
2895 report_file_error ("Doing chmod", Fcons (absname, Qnil)); 2989 report_file_error ("Doing chmod", Fcons (absname, Qnil));
2896 2990
2897 return Qnil; 2991 return Qnil;
@@ -3158,6 +3252,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3158 EMACS_INT inserted = 0; 3252 EMACS_INT inserted = 0;
3159 int nochange = 0; 3253 int nochange = 0;
3160 register EMACS_INT how_much; 3254 register EMACS_INT how_much;
3255 off_t beg_offset, end_offset;
3161 register EMACS_INT unprocessed; 3256 register EMACS_INT unprocessed;
3162 int count = SPECPDL_INDEX (); 3257 int count = SPECPDL_INDEX ();
3163 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 3258 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
@@ -3165,6 +3260,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3165 Lisp_Object p; 3260 Lisp_Object p;
3166 EMACS_INT total = 0; 3261 EMACS_INT total = 0;
3167 int not_regular = 0; 3262 int not_regular = 0;
3263 int save_errno = 0;
3168 char read_buf[READ_BUF_SIZE]; 3264 char read_buf[READ_BUF_SIZE];
3169 struct coding_system coding; 3265 struct coding_system coding;
3170 char buffer[1 << 14]; 3266 char buffer[1 << 14];
@@ -3228,9 +3324,11 @@ variable `last-coding-system-used' to the coding system actually used. */)
3228#endif /* WINDOWSNT */ 3324#endif /* WINDOWSNT */
3229 { 3325 {
3230 badopen: 3326 badopen:
3327 save_errno = errno;
3231 if (NILP (visit)) 3328 if (NILP (visit))
3232 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 3329 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
3233 st.st_mtime = -1; 3330 st.st_mtime = -1;
3331 st.st_size = -1;
3234 how_much = 0; 3332 how_much = 0;
3235 if (!NILP (Vcoding_system_for_read)) 3333 if (!NILP (Vcoding_system_for_read))
3236 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read); 3334 Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
@@ -3263,15 +3361,6 @@ variable `last-coding-system-used' to the coding system actually used. */)
3263 record_unwind_protect (close_file_unwind, make_number (fd)); 3361 record_unwind_protect (close_file_unwind, make_number (fd));
3264 3362
3265 3363
3266 /* Check whether the size is too large or negative, which can happen on a
3267 platform that allows file sizes greater than the maximum off_t value. */
3268 if (! not_regular
3269 && ! (0 <= st.st_size && st.st_size <= BUF_BYTES_MAX))
3270 buffer_overflow ();
3271
3272 /* Prevent redisplay optimizations. */
3273 current_buffer->clip_changed = 1;
3274
3275 if (!NILP (visit)) 3364 if (!NILP (visit))
3276 { 3365 {
3277 if (!NILP (beg) || !NILP (end)) 3366 if (!NILP (beg) || !NILP (end))
@@ -3281,26 +3370,64 @@ variable `last-coding-system-used' to the coding system actually used. */)
3281 } 3370 }
3282 3371
3283 if (!NILP (beg)) 3372 if (!NILP (beg))
3284 CHECK_NUMBER (beg); 3373 {
3374 if (! (RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t))))
3375 wrong_type_argument (intern ("file-offset"), beg);
3376 beg_offset = XFASTINT (beg);
3377 }
3285 else 3378 else
3286 XSETFASTINT (beg, 0); 3379 beg_offset = 0;
3287 3380
3288 if (!NILP (end)) 3381 if (!NILP (end))
3289 CHECK_NUMBER (end); 3382 {
3383 if (! (RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t))))
3384 wrong_type_argument (intern ("file-offset"), end);
3385 end_offset = XFASTINT (end);
3386 }
3290 else 3387 else
3291 { 3388 {
3292 if (! not_regular) 3389 if (not_regular)
3390 end_offset = TYPE_MAXIMUM (off_t);
3391 else
3293 { 3392 {
3294 XSETINT (end, st.st_size); 3393 end_offset = st.st_size;
3394
3395 /* A negative size can happen on a platform that allows file
3396 sizes greater than the maximum off_t value. */
3397 if (end_offset < 0)
3398 buffer_overflow ();
3295 3399
3296 /* The file size returned from stat may be zero, but data 3400 /* The file size returned from stat may be zero, but data
3297 may be readable nonetheless, for example when this is a 3401 may be readable nonetheless, for example when this is a
3298 file in the /proc filesystem. */ 3402 file in the /proc filesystem. */
3299 if (st.st_size == 0) 3403 if (end_offset == 0)
3300 XSETINT (end, READ_BUF_SIZE); 3404 end_offset = READ_BUF_SIZE;
3301 } 3405 }
3302 } 3406 }
3303 3407
3408 /* Check now whether the buffer will become too large,
3409 in the likely case where the file's length is not changing.
3410 This saves a lot of needless work before a buffer overflow. */
3411 if (! not_regular)
3412 {
3413 /* The likely offset where we will stop reading. We could read
3414 more (or less), if the file grows (or shrinks) as we read it. */
3415 off_t likely_end = min (end_offset, st.st_size);
3416
3417 if (beg_offset < likely_end)
3418 {
3419 ptrdiff_t buf_bytes =
3420 Z_BYTE - (!NILP (replace) ? ZV_BYTE - BEGV_BYTE : 0);
3421 ptrdiff_t buf_growth_max = BUF_BYTES_MAX - buf_bytes;
3422 off_t likely_growth = likely_end - beg_offset;
3423 if (buf_growth_max < likely_growth)
3424 buffer_overflow ();
3425 }
3426 }
3427
3428 /* Prevent redisplay optimizations. */
3429 current_buffer->clip_changed = 1;
3430
3304 if (EQ (Vcoding_system_for_read, Qauto_save_coding)) 3431 if (EQ (Vcoding_system_for_read, Qauto_save_coding))
3305 { 3432 {
3306 coding_system = coding_inherit_eol_type (Qutf_8_emacs, Qunix); 3433 coding_system = coding_inherit_eol_type (Qutf_8_emacs, Qunix);
@@ -3444,9 +3571,9 @@ variable `last-coding-system-used' to the coding system actually used. */)
3444 give up on handling REPLACE in the optimized way. */ 3571 give up on handling REPLACE in the optimized way. */
3445 int giveup_match_end = 0; 3572 int giveup_match_end = 0;
3446 3573
3447 if (XINT (beg) != 0) 3574 if (beg_offset != 0)
3448 { 3575 {
3449 if (emacs_lseek (fd, XINT (beg), SEEK_SET) < 0) 3576 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3450 report_file_error ("Setting file position", 3577 report_file_error ("Setting file position",
3451 Fcons (orig_filename, Qnil)); 3578 Fcons (orig_filename, Qnil));
3452 } 3579 }
@@ -3494,7 +3621,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3494 immediate_quit = 0; 3621 immediate_quit = 0;
3495 /* If the file matches the buffer completely, 3622 /* If the file matches the buffer completely,
3496 there's no need to replace anything. */ 3623 there's no need to replace anything. */
3497 if (same_at_start - BEGV_BYTE == XINT (end)) 3624 if (same_at_start - BEGV_BYTE == end_offset - beg_offset)
3498 { 3625 {
3499 emacs_close (fd); 3626 emacs_close (fd);
3500 specpdl_ptr--; 3627 specpdl_ptr--;
@@ -3509,16 +3636,17 @@ variable `last-coding-system-used' to the coding system actually used. */)
3509 already found that decoding is necessary, don't waste time. */ 3636 already found that decoding is necessary, don't waste time. */
3510 while (!giveup_match_end) 3637 while (!giveup_match_end)
3511 { 3638 {
3512 EMACS_INT total_read, nread, bufpos, curpos, trial; 3639 int total_read, nread, bufpos, trial;
3640 off_t curpos;
3513 3641
3514 /* At what file position are we now scanning? */ 3642 /* At what file position are we now scanning? */
3515 curpos = XINT (end) - (ZV_BYTE - same_at_end); 3643 curpos = end_offset - (ZV_BYTE - same_at_end);
3516 /* If the entire file matches the buffer tail, stop the scan. */ 3644 /* If the entire file matches the buffer tail, stop the scan. */
3517 if (curpos == 0) 3645 if (curpos == 0)
3518 break; 3646 break;
3519 /* How much can we scan in the next step? */ 3647 /* How much can we scan in the next step? */
3520 trial = min (curpos, sizeof buffer); 3648 trial = min (curpos, sizeof buffer);
3521 if (emacs_lseek (fd, curpos - trial, SEEK_SET) < 0) 3649 if (lseek (fd, curpos - trial, SEEK_SET) < 0)
3522 report_file_error ("Setting file position", 3650 report_file_error ("Setting file position",
3523 Fcons (orig_filename, Qnil)); 3651 Fcons (orig_filename, Qnil));
3524 3652
@@ -3585,13 +3713,14 @@ variable `last-coding-system-used' to the coding system actually used. */)
3585 3713
3586 /* Don't try to reuse the same piece of text twice. */ 3714 /* Don't try to reuse the same piece of text twice. */
3587 overlap = (same_at_start - BEGV_BYTE 3715 overlap = (same_at_start - BEGV_BYTE
3588 - (same_at_end + st.st_size - ZV)); 3716 - (same_at_end
3717 + (! NILP (end) ? end_offset : st.st_size) - ZV_BYTE));
3589 if (overlap > 0) 3718 if (overlap > 0)
3590 same_at_end += overlap; 3719 same_at_end += overlap;
3591 3720
3592 /* Arrange to read only the nonmatching middle part of the file. */ 3721 /* Arrange to read only the nonmatching middle part of the file. */
3593 XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE)); 3722 beg_offset += same_at_start - BEGV_BYTE;
3594 XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end)); 3723 end_offset -= ZV_BYTE - same_at_end;
3595 3724
3596 del_range_byte (same_at_start, same_at_end, 0); 3725 del_range_byte (same_at_start, same_at_end, 0);
3597 /* Insert from the file at the proper position. */ 3726 /* Insert from the file at the proper position. */
@@ -3630,13 +3759,14 @@ variable `last-coding-system-used' to the coding system actually used. */)
3630 int this_count = SPECPDL_INDEX (); 3759 int this_count = SPECPDL_INDEX ();
3631 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3760 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3632 Lisp_Object conversion_buffer; 3761 Lisp_Object conversion_buffer;
3762 struct gcpro gcpro1;
3633 3763
3634 conversion_buffer = code_conversion_save (1, multibyte); 3764 conversion_buffer = code_conversion_save (1, multibyte);
3635 3765
3636 /* First read the whole file, performing code conversion into 3766 /* First read the whole file, performing code conversion into
3637 CONVERSION_BUFFER. */ 3767 CONVERSION_BUFFER. */
3638 3768
3639 if (emacs_lseek (fd, XINT (beg), SEEK_SET) < 0) 3769 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3640 report_file_error ("Setting file position", 3770 report_file_error ("Setting file position",
3641 Fcons (orig_filename, Qnil)); 3771 Fcons (orig_filename, Qnil));
3642 3772
@@ -3650,7 +3780,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3650 { 3780 {
3651 /* We read one bunch by one (READ_BUF_SIZE bytes) to allow 3781 /* We read one bunch by one (READ_BUF_SIZE bytes) to allow
3652 quitting while reading a huge while. */ 3782 quitting while reading a huge while. */
3653 /* try is reserved in some compilers (Microsoft C) */ 3783 /* `try'' is reserved in some compilers (Microsoft C). */
3654 EMACS_INT trytry = min (total - how_much, 3784 EMACS_INT trytry = min (total - how_much,
3655 READ_BUF_SIZE - unprocessed); 3785 READ_BUF_SIZE - unprocessed);
3656 3786
@@ -3803,7 +3933,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
3803 } 3933 }
3804 3934
3805 if (! not_regular) 3935 if (! not_regular)
3806 total = XINT (end) - XINT (beg); 3936 total = end_offset - beg_offset;
3807 else 3937 else
3808 /* For a special file, all we can do is guess. */ 3938 /* For a special file, all we can do is guess. */
3809 total = READ_BUF_SIZE; 3939 total = READ_BUF_SIZE;
@@ -3824,9 +3954,9 @@ variable `last-coding-system-used' to the coding system actually used. */)
3824 if (GAP_SIZE < total) 3954 if (GAP_SIZE < total)
3825 make_gap (total - GAP_SIZE); 3955 make_gap (total - GAP_SIZE);
3826 3956
3827 if (XINT (beg) != 0 || !NILP (replace)) 3957 if (beg_offset != 0 || !NILP (replace))
3828 { 3958 {
3829 if (emacs_lseek (fd, XINT (beg), SEEK_SET) < 0) 3959 if (lseek (fd, beg_offset, SEEK_SET) < 0)
3830 report_file_error ("Setting file position", 3960 report_file_error ("Setting file position",
3831 Fcons (orig_filename, Qnil)); 3961 Fcons (orig_filename, Qnil));
3832 } 3962 }
@@ -4043,6 +4173,16 @@ variable `last-coding-system-used' to the coding system actually used. */)
4043 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted, 4173 adjust_after_insert (PT, PT_BYTE, PT + inserted, PT_BYTE + inserted,
4044 inserted); 4174 inserted);
4045 4175
4176 /* Call after-change hooks for the inserted text, aside from the case
4177 of normal visiting (not with REPLACE), which is done in a new buffer
4178 "before" the buffer is changed. */
4179 if (inserted > 0 && total > 0
4180 && (NILP (visit) || !NILP (replace)))
4181 {
4182 signal_after_change (PT, 0, inserted);
4183 update_compositions (PT, PT, CHECK_BORDER);
4184 }
4185
4046 /* Now INSERTED is measured in characters. */ 4186 /* Now INSERTED is measured in characters. */
4047 4187
4048 handled: 4188 handled:
@@ -4119,7 +4259,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
4119 /* If REPLACE is non-nil and we succeeded in not replacing the 4259 /* If REPLACE is non-nil and we succeeded in not replacing the
4120 beginning or end of the buffer text with the file's contents, 4260 beginning or end of the buffer text with the file's contents,
4121 call format-decode with `point' positioned at the beginning 4261 call format-decode with `point' positioned at the beginning
4122 of the buffer and `inserted' equalling the number of 4262 of the buffer and `inserted' equaling the number of
4123 characters in the buffer. Otherwise, format-decode might 4263 characters in the buffer. Otherwise, format-decode might
4124 fail to correctly analyze the beginning or end of the buffer. 4264 fail to correctly analyze the beginning or end of the buffer.
4125 Hence we temporarily save `point' and `inserted' here and 4265 Hence we temporarily save `point' and `inserted' here and
@@ -4213,20 +4353,11 @@ variable `last-coding-system-used' to the coding system actually used. */)
4213 unbind_to (count1, Qnil); 4353 unbind_to (count1, Qnil);
4214 } 4354 }
4215 4355
4216 /* Call after-change hooks for the inserted text, aside from the case
4217 of normal visiting (not with REPLACE), which is done in a new buffer
4218 "before" the buffer is changed. */
4219 if (inserted > 0 && total > 0
4220 && (NILP (visit) || !NILP (replace)))
4221 {
4222 signal_after_change (PT, 0, inserted);
4223 update_compositions (PT, PT, CHECK_BORDER);
4224 }
4225
4226 if (!NILP (visit) 4356 if (!NILP (visit)
4227 && current_buffer->modtime == -1) 4357 && current_buffer->modtime == -1)
4228 { 4358 {
4229 /* If visiting nonexistent file, return nil. */ 4359 /* If visiting nonexistent file, return nil. */
4360 errno = save_errno;
4230 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 4361 report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
4231 } 4362 }
4232 4363
@@ -4555,7 +4686,7 @@ This calls `write-region-annotate-functions' at the start, and
4555 4686
4556 if (!NILP (append) && !NILP (Ffile_regular_p (filename))) 4687 if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
4557 { 4688 {
4558 long ret; 4689 off_t ret;
4559 4690
4560 if (NUMBERP (append)) 4691 if (NUMBERP (append))
4561 ret = emacs_lseek (desc, XINT (append), SEEK_CUR); 4692 ret = emacs_lseek (desc, XINT (append), SEEK_CUR);
@@ -4564,7 +4695,9 @@ This calls `write-region-annotate-functions' at the start, and
4564 if (ret < 0) 4695 if (ret < 0)
4565 { 4696 {
4566#ifdef CLASH_DETECTION 4697#ifdef CLASH_DETECTION
4698 save_errno = errno;
4567 if (!auto_saving) unlock_file (lockname); 4699 if (!auto_saving) unlock_file (lockname);
4700 errno = save_errno;
4568#endif /* CLASH_DETECTION */ 4701#endif /* CLASH_DETECTION */
4569 UNGCPRO; 4702 UNGCPRO;
4570 report_file_error ("Lseek error", Fcons (filename, Qnil)); 4703 report_file_error ("Lseek error", Fcons (filename, Qnil));
@@ -4991,9 +5124,10 @@ Next attempt to save will certainly not complain of a discrepancy. */)
4991DEFUN ("visited-file-modtime", Fvisited_file_modtime, 5124DEFUN ("visited-file-modtime", Fvisited_file_modtime,
4992 Svisited_file_modtime, 0, 0, 0, 5125 Svisited_file_modtime, 0, 0, 0,
4993 doc: /* Return the current buffer's recorded visited file modification time. 5126 doc: /* Return the current buffer's recorded visited file modification time.
4994The value is a list of the form (HIGH LOW), like the time values 5127The value is a list of the form (HIGH LOW), like the time values that
4995that `file-attributes' returns. If the current buffer has no recorded 5128`file-attributes' returns. If the current buffer has no recorded file
4996file modification time, this function returns 0. 5129modification time, this function returns 0. If the visited file
5130doesn't exist, HIGH will be -1.
4997See Info node `(elisp)Modification Time' for more details. */) 5131See Info node `(elisp)Modification Time' for more details. */)
4998 (void) 5132 (void)
4999{ 5133{
@@ -5093,11 +5227,11 @@ auto_save_1 (void)
5093 { 5227 {
5094 if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0) 5228 if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0)
5095 /* But make sure we can overwrite it later! */ 5229 /* But make sure we can overwrite it later! */
5096 auto_save_mode_bits = st.st_mode | 0600; 5230 auto_save_mode_bits = (st.st_mode | 0600) & 0777;
5097 else if ((modes = Ffile_modes (BVAR (current_buffer, filename)), 5231 else if ((modes = Ffile_modes (BVAR (current_buffer, filename)),
5098 INTEGERP (modes))) 5232 INTEGERP (modes)))
5099 /* Remote files don't cooperate with stat. */ 5233 /* Remote files don't cooperate with stat. */
5100 auto_save_mode_bits = XINT (modes) | 0600; 5234 auto_save_mode_bits = (XINT (modes) | 0600) & 0777;
5101 } 5235 }
5102 5236
5103 return 5237 return
@@ -5132,16 +5266,18 @@ do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */
5132static Lisp_Object 5266static Lisp_Object
5133do_auto_save_make_dir (Lisp_Object dir) 5267do_auto_save_make_dir (Lisp_Object dir)
5134{ 5268{
5135 Lisp_Object mode; 5269 Lisp_Object result;
5136 5270
5137 call2 (Qmake_directory, dir, Qt); 5271 auto_saving_dir_umask = 077;
5138 XSETFASTINT (mode, 0700); 5272 result = call2 (Qmake_directory, dir, Qt);
5139 return Fset_file_modes (dir, mode); 5273 auto_saving_dir_umask = 0;
5274 return result;
5140} 5275}
5141 5276
5142static Lisp_Object 5277static Lisp_Object
5143do_auto_save_eh (Lisp_Object ignore) 5278do_auto_save_eh (Lisp_Object ignore)
5144{ 5279{
5280 auto_saving_dir_umask = 0;
5145 return Qnil; 5281 return Qnil;
5146} 5282}
5147 5283
@@ -5209,7 +5345,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5209 dir = Ffile_name_directory (listfile); 5345 dir = Ffile_name_directory (listfile);
5210 if (NILP (Ffile_directory_p (dir))) 5346 if (NILP (Ffile_directory_p (dir)))
5211 internal_condition_case_1 (do_auto_save_make_dir, 5347 internal_condition_case_1 (do_auto_save_make_dir,
5212 dir, Fcons (Fcons (Qfile_error, Qnil), Qnil), 5348 dir, Qt,
5213 do_auto_save_eh); 5349 do_auto_save_eh);
5214 UNGCPRO; 5350 UNGCPRO;
5215 } 5351 }
@@ -5284,7 +5420,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5284 EMACS_GET_TIME (before_time); 5420 EMACS_GET_TIME (before_time);
5285 5421
5286 /* If we had a failure, don't try again for 20 minutes. */ 5422 /* If we had a failure, don't try again for 20 minutes. */
5287 if (b->auto_save_failure_time >= 0 5423 if (b->auto_save_failure_time > 0
5288 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200) 5424 && EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
5289 continue; 5425 continue;
5290 5426
@@ -5363,7 +5499,7 @@ No auto-save file will be written until the buffer changes again. */)
5363 they're not autosaved. */ 5499 they're not autosaved. */
5364 BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF; 5500 BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
5365 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); 5501 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
5366 current_buffer->auto_save_failure_time = -1; 5502 current_buffer->auto_save_failure_time = 0;
5367 return Qnil; 5503 return Qnil;
5368} 5504}
5369 5505
@@ -5372,7 +5508,7 @@ DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
5372 doc: /* Clear any record of a recent auto-save failure in the current buffer. */) 5508 doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
5373 (void) 5509 (void)
5374{ 5510{
5375 current_buffer->auto_save_failure_time = -1; 5511 current_buffer->auto_save_failure_time = 0;
5376 return Qnil; 5512 return Qnil;
5377} 5513}
5378 5514
@@ -5511,18 +5647,25 @@ of file names regardless of the current language environment. */);
5511 make_pure_c_string ("Cannot set file date")); 5647 make_pure_c_string ("Cannot set file date"));
5512 5648
5513 DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist, 5649 DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist,
5514 doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially. 5650 doc: /* Alist of elements (REGEXP . HANDLER) for file names handled specially.
5515If a file name matches REGEXP, then all I/O on that file is done by calling 5651If a file name matches REGEXP, all I/O on that file is done by calling
5516HANDLER. 5652HANDLER. If a file name matches more than one handler, the handler
5517 5653whose match starts last in the file name gets precedence. The
5518The first argument given to HANDLER is the name of the I/O primitive 5654function `find-file-name-handler' checks this list for a handler for
5519to be handled; the remaining arguments are the arguments that were 5655its argument.
5520passed to that primitive. For example, if you do 5656
5521 (file-exists-p FILENAME) 5657HANDLER should be a function. The first argument given to it is the
5522and FILENAME is handled by HANDLER, then HANDLER is called like this: 5658name of the I/O primitive to be handled; the remaining arguments are
5523 (funcall HANDLER 'file-exists-p FILENAME) 5659the arguments that were passed to that primitive. For example, if you
5524The function `find-file-name-handler' checks this list for a handler 5660do (file-exists-p FILENAME) and FILENAME is handled by HANDLER, then
5525for its argument. */); 5661HANDLER is called like this:
5662
5663 (funcall HANDLER 'file-exists-p FILENAME)
5664
5665Note that HANDLER must be able to handle all I/O primitives; if it has
5666nothing special to do for a primitive, it should reinvoke the
5667primitive to handle the operation \"the usual way\".
5668See Info node `(elisp)Magic File Names' for more details. */);
5526 Vfile_name_handler_alist = Qnil; 5669 Vfile_name_handler_alist = Qnil;
5527 5670
5528 DEFVAR_LISP ("set-auto-coding-function", 5671 DEFVAR_LISP ("set-auto-coding-function",