aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1992-07-22 03:27:55 +0000
committerRichard M. Stallman1992-07-22 03:27:55 +0000
commit32f4334dcef11f3b06b04e05618a27f477e96449 (patch)
treec40577083f8292e56e4627ee425d58bccf457724 /src
parente59a84533d670449f4e42feab72b4427527b2e61 (diff)
downloademacs-32f4334dcef11f3b06b04e05618a27f477e96449.tar.gz
emacs-32f4334dcef11f3b06b04e05618a27f477e96449.zip
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/dired.c49
-rw-r--r--src/fileio.c281
2 files changed, 317 insertions, 13 deletions
diff --git a/src/dired.c b/src/dired.c
index a3b02f089ff..e43620fe0fe 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -64,6 +64,10 @@ extern struct direct *readdir ();
64Lisp_Object Vcompletion_ignored_extensions; 64Lisp_Object Vcompletion_ignored_extensions;
65 65
66Lisp_Object Qcompletion_ignore_case; 66Lisp_Object Qcompletion_ignore_case;
67
68Lisp_Object Qdirectory_files;
69Lisp_Object Qfile_name_completion;
70Lisp_Object Qfile_name_all_completions;
67 71
68DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0, 72DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
69 "Return a list of names of files in DIRECTORY.\n\ 73 "Return a list of names of files in DIRECTORY.\n\
@@ -78,6 +82,23 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.\n\
78 DIR *d; 82 DIR *d;
79 int length; 83 int length;
80 Lisp_Object list, name; 84 Lisp_Object list, name;
85 Lisp_Object handler;
86
87 /* If the file name has special constructs in it,
88 call the corresponding file handler. */
89 handler = find_file_handler (filename);
90 if (!NILP (handler))
91 {
92 Lisp_Object args[6];
93
94 args[0] = handler;
95 args[1] = Qdirectory_files;
96 args[2] = dirname;
97 args[3] = full;
98 args[4] = match;
99 args[5] = nosort;
100 return Ffuncall (6, args);
101 }
81 102
82 if (!NILP (match)) 103 if (!NILP (match))
83 { 104 {
@@ -158,6 +179,7 @@ Returns nil if DIR contains no name starting with FILE.")
158 (file, dirname) 179 (file, dirname)
159 Lisp_Object file, dirname; 180 Lisp_Object file, dirname;
160{ 181{
182 Lisp_Object handler;
161 /* Don't waste time trying to complete a null string. 183 /* Don't waste time trying to complete a null string.
162 Besides, this case happens when user is being asked for 184 Besides, this case happens when user is being asked for
163 a directory name and has supplied one ending in a /. 185 a directory name and has supplied one ending in a /.
@@ -165,6 +187,13 @@ Returns nil if DIR contains no name starting with FILE.")
165 even if there are some unique characters in that directory. */ 187 even if there are some unique characters in that directory. */
166 if (XTYPE (file) == Lisp_String && XSTRING (file)->size == 0) 188 if (XTYPE (file) == Lisp_String && XSTRING (file)->size == 0)
167 return file; 189 return file;
190
191 /* If the file name has special constructs in it,
192 call the corresponding file handler. */
193 handler = find_file_handler (filename);
194 if (!NILP (handler))
195 return call3 (handler, Qfile_name_completion, file, dirname);
196
168 return file_name_completion (file, dirname, 0, 0); 197 return file_name_completion (file, dirname, 0, 0);
169} 198}
170 199
@@ -175,6 +204,14 @@ These are all file names in directory DIR which begin with FILE.")
175 (file, dirname) 204 (file, dirname)
176 Lisp_Object file, dirname; 205 Lisp_Object file, dirname;
177{ 206{
207 Lisp_Object handler;
208
209 /* If the file name has special constructs in it,
210 call the corresponding file handler. */
211 handler = find_file_handler (filename);
212 if (!NILP (handler))
213 return call3 (handler, Qfile_name_all_completions, file, dirname);
214
178 return file_name_completion (file, dirname, 1, 0); 215 return file_name_completion (file, dirname, 1, 0);
179} 216}
180 217
@@ -409,8 +446,16 @@ If file does not exists, returns nil.")
409 struct stat s; 446 struct stat s;
410 struct stat sdir; 447 struct stat sdir;
411 char modes[10]; 448 char modes[10];
449 Lisp_Object handler;
412 450
413 filename = Fexpand_file_name (filename, Qnil); 451 filename = Fexpand_file_name (filename, Qnil);
452
453 /* If the file name has special constructs in it,
454 call the corresponding file handler. */
455 handler = find_file_handler (filename);
456 if (!NILP (handler))
457 return call2 (handler, Qfile_attributes, filename);
458
414 if (lstat (XSTRING (filename)->data, &s) < 0) 459 if (lstat (XSTRING (filename)->data, &s) < 0)
415 return Qnil; 460 return Qnil;
416 461
@@ -457,6 +502,10 @@ If file does not exists, returns nil.")
457 502
458syms_of_dired () 503syms_of_dired ()
459{ 504{
505 Qdirectory_files = intern ("directory-files");
506 Qfile_name_completion = intern ("file-name-completion");
507 Qfile_name_all_completions = intern ("file-name-all-completions");
508
460 defsubr (&Sdirectory_files); 509 defsubr (&Sdirectory_files);
461 defsubr (&Sfile_name_completion); 510 defsubr (&Sfile_name_completion);
462#ifdef VMS 511#ifdef VMS
diff --git a/src/fileio.c b/src/fileio.c
index 4ff7dfeee87..95e570a666d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -87,6 +87,10 @@ int auto_saving;
87 a new file with the same mode as the original */ 87 a new file with the same mode as the original */
88int auto_save_mode_bits; 88int auto_save_mode_bits;
89 89
90/* Alist of elements (REGEXP . HANDLER) for file names
91 whose I/O is done with a special handler. */
92Lisp_Object Vfile_name_handler_alist;
93
90/* Nonzero means, when reading a filename in the minibuffer, 94/* Nonzero means, when reading a filename in the minibuffer,
91 start out by inserting the default directory into the minibuffer. */ 95 start out by inserting the default directory into the minibuffer. */
92int insert_default_directory; 96int insert_default_directory;
@@ -124,6 +128,52 @@ close_file_unwind (fd)
124 close (XFASTINT (fd)); 128 close (XFASTINT (fd));
125} 129}
126 130
131Lisp_Object Qcopy_file;
132Lisp_Object Qmake_directory;
133Lisp_Object Qdelete_directory;
134Lisp_Object Qdelete_file;
135Lisp_Object Qrename_file;
136Lisp_Object Qadd_name_to_file;
137Lisp_Object Qmake_symbolic_link;
138Lisp_Object Qfile_exists_p;
139Lisp_Object Qfile_executable_p;
140Lisp_Object Qfile_readable_p;
141Lisp_Object Qfile_symlink_p;
142Lisp_Object Qfile_writable_p;
143Lisp_Object Qfile_directory_p;
144Lisp_Object Qfile_accessible_directory_p;
145Lisp_Object Qfile_modes;
146Lisp_Object Qset_file_modes;
147Lisp_Object Qfile_newer_than_file_p;
148Lisp_Object Qinsert_file_contents;
149Lisp_Object Qwrite_region;
150Lisp_Object Qverify_visited_file_modtime;
151
152/* If FILENAME is handled specially on account of its syntax,
153 return its handler function. Otherwise, return nil. */
154
155Lisp_Object
156find_file_handler (filename)
157 Lisp_Object filename;
158{
159 Lisp_Object chain;
160 for (chain = Vfile_handler_alist; XTYPE (chain) == Lisp_Cons;
161 chain = XCONS (chain)->cdr)
162 {
163 Lisp_Object elt;
164 elt = XCONS (chain)->car;
165 if (XTYPE (elt) == Lisp_Cons)
166 {
167 Lisp_Object string;
168 string = XCONS (elt)->car;
169 if (XTYPE (string) == Lisp_String
170 && fast_string_match (string, filename))
171 return XCONS (elt)->cdr;
172 }
173 }
174 return Qnil;
175}
176
127DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, 177DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory,
128 1, 1, 0, 178 1, 1, 0,
129 "Return the directory component in file name NAME.\n\ 179 "Return the directory component in file name NAME.\n\
@@ -1383,6 +1433,7 @@ A prefix arg makes KEEP-TIME non-nil.")
1383 int ifd, ofd, n; 1433 int ifd, ofd, n;
1384 char buf[16 * 1024]; 1434 char buf[16 * 1024];
1385 struct stat st; 1435 struct stat st;
1436 Lisp_Object handler;
1386 struct gcpro gcpro1, gcpro2; 1437 struct gcpro gcpro1, gcpro2;
1387 int count = specpdl_ptr - specpdl; 1438 int count = specpdl_ptr - specpdl;
1388 1439
@@ -1391,6 +1442,13 @@ A prefix arg makes KEEP-TIME non-nil.")
1391 CHECK_STRING (newname, 1); 1442 CHECK_STRING (newname, 1);
1392 filename = Fexpand_file_name (filename, Qnil); 1443 filename = Fexpand_file_name (filename, Qnil);
1393 newname = Fexpand_file_name (newname, Qnil); 1444 newname = Fexpand_file_name (newname, Qnil);
1445
1446 /* If the file name has special constructs in it,
1447 call the corresponding file handler. */
1448 handler = find_file_handler (filename);
1449 if (!NILP (handler))
1450 return call3 (handler, Qcopy_file, filename, newname);
1451
1394 if (NILP (ok_if_already_exists) 1452 if (NILP (ok_if_already_exists)
1395 || XTYPE (ok_if_already_exists) == Lisp_Int) 1453 || XTYPE (ok_if_already_exists) == Lisp_Int)
1396 barf_or_query_if_file_exists (newname, "copy to it", 1454 barf_or_query_if_file_exists (newname, "copy to it",
@@ -1452,15 +1510,21 @@ DEFUN ("make-directory", Fmake_directory, Smake_directory, 1, 1, "FMake director
1452 Lisp_Object dirname; 1510 Lisp_Object dirname;
1453{ 1511{
1454 unsigned char *dir; 1512 unsigned char *dir;
1513 Lisp_Object handler;
1455 1514
1456 CHECK_STRING (dirname, 0); 1515 CHECK_STRING (dirname, 0);
1457 dirname = Fexpand_file_name (dirname, Qnil); 1516 dirname = Fexpand_file_name (dirname, Qnil);
1517
1518 handler = find_file_handler (dirname);
1519 if (!NILP (handler))
1520 return call2 (handler, Qmake_directory, dirname);
1521
1458 dir = XSTRING (dirname)->data; 1522 dir = XSTRING (dirname)->data;
1459 1523
1460 if (mkdir (dir, 0777) != 0) 1524 if (mkdir (dir, 0777) != 0)
1461 report_file_error ("Creating directory", Flist (1, &dirname)); 1525 report_file_error ("Creating directory", Flist (1, &dirname));
1462 1526
1463 return Qnil; 1527 return Qnil;
1464} 1528}
1465 1529
1466DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ", 1530DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ",
@@ -1469,11 +1533,16 @@ DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete
1469 Lisp_Object dirname; 1533 Lisp_Object dirname;
1470{ 1534{
1471 unsigned char *dir; 1535 unsigned char *dir;
1536 Lisp_Object handler;
1472 1537
1473 CHECK_STRING (dirname, 0); 1538 CHECK_STRING (dirname, 0);
1474 dirname = Fexpand_file_name (dirname, Qnil); 1539 dirname = Fexpand_file_name (dirname, Qnil);
1475 dir = XSTRING (dirname)->data; 1540 dir = XSTRING (dirname)->data;
1476 1541
1542 handler = find_file_handler (dirname);
1543 if (!NILP (handler))
1544 return call2 (handler, Qdelete_directory, dirname);
1545
1477 if (rmdir (dir) != 0) 1546 if (rmdir (dir) != 0)
1478 report_file_error ("Removing directory", Flist (1, &dirname)); 1547 report_file_error ("Removing directory", Flist (1, &dirname));
1479 1548
@@ -1486,8 +1555,14 @@ If file has multiple names, it continues to exist with the other names.")
1486 (filename) 1555 (filename)
1487 Lisp_Object filename; 1556 Lisp_Object filename;
1488{ 1557{
1558 Lisp_Object handler;
1489 CHECK_STRING (filename, 0); 1559 CHECK_STRING (filename, 0);
1490 filename = Fexpand_file_name (filename, Qnil); 1560 filename = Fexpand_file_name (filename, Qnil);
1561
1562 handler = find_file_handler (filename);
1563 if (!NILP (handler))
1564 return call2 (handler, Qdelete_file, filename);
1565
1491 if (0 > unlink (XSTRING (filename)->data)) 1566 if (0 > unlink (XSTRING (filename)->data))
1492 report_file_error ("Removing old name", Flist (1, &filename)); 1567 report_file_error ("Removing old name", Flist (1, &filename));
1493 return Qnil; 1568 return Qnil;
@@ -1507,6 +1582,7 @@ This is what happens in interactive use with M-x.")
1507#ifdef NO_ARG_ARRAY 1582#ifdef NO_ARG_ARRAY
1508 Lisp_Object args[2]; 1583 Lisp_Object args[2];
1509#endif 1584#endif
1585 Lisp_Object handler;
1510 struct gcpro gcpro1, gcpro2; 1586 struct gcpro gcpro1, gcpro2;
1511 1587
1512 GCPRO2 (filename, newname); 1588 GCPRO2 (filename, newname);
@@ -1514,6 +1590,13 @@ This is what happens in interactive use with M-x.")
1514 CHECK_STRING (newname, 1); 1590 CHECK_STRING (newname, 1);
1515 filename = Fexpand_file_name (filename, Qnil); 1591 filename = Fexpand_file_name (filename, Qnil);
1516 newname = Fexpand_file_name (newname, Qnil); 1592 newname = Fexpand_file_name (newname, Qnil);
1593
1594 /* If the file name has special constructs in it,
1595 call the corresponding file handler. */
1596 handler = find_file_handler (filename);
1597 if (!NILP (handler))
1598 return call3 (handler, Qrename_file, filename, newname);
1599
1517 if (NILP (ok_if_already_exists) 1600 if (NILP (ok_if_already_exists)
1518 || XTYPE (ok_if_already_exists) == Lisp_Int) 1601 || XTYPE (ok_if_already_exists) == Lisp_Int)
1519 barf_or_query_if_file_exists (newname, "rename to it", 1602 barf_or_query_if_file_exists (newname, "rename to it",
@@ -1558,6 +1641,7 @@ This is what happens in interactive use with M-x.")
1558#ifdef NO_ARG_ARRAY 1641#ifdef NO_ARG_ARRAY
1559 Lisp_Object args[2]; 1642 Lisp_Object args[2];
1560#endif 1643#endif
1644 Lisp_Object handler;
1561 struct gcpro gcpro1, gcpro2; 1645 struct gcpro gcpro1, gcpro2;
1562 1646
1563 GCPRO2 (filename, newname); 1647 GCPRO2 (filename, newname);
@@ -1565,6 +1649,13 @@ This is what happens in interactive use with M-x.")
1565 CHECK_STRING (newname, 1); 1649 CHECK_STRING (newname, 1);
1566 filename = Fexpand_file_name (filename, Qnil); 1650 filename = Fexpand_file_name (filename, Qnil);
1567 newname = Fexpand_file_name (newname, Qnil); 1651 newname = Fexpand_file_name (newname, Qnil);
1652
1653 /* If the file name has special constructs in it,
1654 call the corresponding file handler. */
1655 handler = find_file_handler (filename);
1656 if (!NILP (handler))
1657 return call3 (handler, Qadd_name_to_file, filename, newname);
1658
1568 if (NILP (ok_if_already_exists) 1659 if (NILP (ok_if_already_exists)
1569 || XTYPE (ok_if_already_exists) == Lisp_Int) 1660 || XTYPE (ok_if_already_exists) == Lisp_Int)
1570 barf_or_query_if_file_exists (newname, "make it a new name", 1661 barf_or_query_if_file_exists (newname, "make it a new name",
@@ -1599,6 +1690,7 @@ This happens for interactive use with M-x.")
1599#ifdef NO_ARG_ARRAY 1690#ifdef NO_ARG_ARRAY
1600 Lisp_Object args[2]; 1691 Lisp_Object args[2];
1601#endif 1692#endif
1693 Lisp_Object handler;
1602 struct gcpro gcpro1, gcpro2; 1694 struct gcpro gcpro1, gcpro2;
1603 1695
1604 GCPRO2 (filename, linkname); 1696 GCPRO2 (filename, linkname);
@@ -1608,6 +1700,13 @@ This happens for interactive use with M-x.")
1608 filename = Fexpand_file_name (filename, Qnil); 1700 filename = Fexpand_file_name (filename, Qnil);
1609#endif 1701#endif
1610 linkname = Fexpand_file_name (linkname, Qnil); 1702 linkname = Fexpand_file_name (linkname, Qnil);
1703
1704 /* If the file name has special constructs in it,
1705 call the corresponding file handler. */
1706 handler = find_file_handler (filename);
1707 if (!NILP (handler))
1708 return call3 (handler, Qmake_symbolic_link, filename, newname);
1709
1611 if (NILP (ok_if_already_exists) 1710 if (NILP (ok_if_already_exists)
1612 || XTYPE (ok_if_already_exists) == Lisp_Int) 1711 || XTYPE (ok_if_already_exists) == Lisp_Int)
1613 barf_or_query_if_file_exists (linkname, "make it a link", 1712 barf_or_query_if_file_exists (linkname, "make it a link",
@@ -1714,9 +1813,17 @@ See also `file-readable-p' and `file-attributes'.")
1714 Lisp_Object filename; 1813 Lisp_Object filename;
1715{ 1814{
1716 Lisp_Object abspath; 1815 Lisp_Object abspath;
1816 Lisp_Object handler;
1717 1817
1718 CHECK_STRING (filename, 0); 1818 CHECK_STRING (filename, 0);
1719 abspath = Fexpand_file_name (filename, Qnil); 1819 abspath = Fexpand_file_name (filename, Qnil);
1820
1821 /* If the file name has special constructs in it,
1822 call the corresponding file handler. */
1823 handler = find_file_handler (filename);
1824 if (!NILP (handler))
1825 return call2 (handler, Qfile_exists_p, filename);
1826
1720 return (access (XSTRING (abspath)->data, 0) >= 0) ? Qt : Qnil; 1827 return (access (XSTRING (abspath)->data, 0) >= 0) ? Qt : Qnil;
1721} 1828}
1722 1829
@@ -1728,9 +1835,17 @@ For directories this means you can change to that directory.")
1728 1835
1729{ 1836{
1730 Lisp_Object abspath; 1837 Lisp_Object abspath;
1838 Lisp_Object handler;
1731 1839
1732 CHECK_STRING (filename, 0); 1840 CHECK_STRING (filename, 0);
1733 abspath = Fexpand_file_name (filename, Qnil); 1841 abspath = Fexpand_file_name (filename, Qnil);
1842
1843 /* If the file name has special constructs in it,
1844 call the corresponding file handler. */
1845 handler = find_file_handler (filename);
1846 if (!NILP (handler))
1847 return call2 (handler, Qfile_executable_p, filename);
1848
1734 return (access (XSTRING (abspath)->data, 1) >= 0) ? Qt : Qnil; 1849 return (access (XSTRING (abspath)->data, 1) >= 0) ? Qt : Qnil;
1735} 1850}
1736 1851
@@ -1741,9 +1856,17 @@ See also `file-exists-p' and `file-attributes'.")
1741 Lisp_Object filename; 1856 Lisp_Object filename;
1742{ 1857{
1743 Lisp_Object abspath; 1858 Lisp_Object abspath;
1859 Lisp_Object handler;
1744 1860
1745 CHECK_STRING (filename, 0); 1861 CHECK_STRING (filename, 0);
1746 abspath = Fexpand_file_name (filename, Qnil); 1862 abspath = Fexpand_file_name (filename, Qnil);
1863
1864 /* If the file name has special constructs in it,
1865 call the corresponding file handler. */
1866 handler = find_file_handler (filename);
1867 if (!NILP (handler))
1868 return call2 (handler, Qfile_readable_p, filename);
1869
1747 return (access (XSTRING (abspath)->data, 4) >= 0) ? Qt : Qnil; 1870 return (access (XSTRING (abspath)->data, 4) >= 0) ? Qt : Qnil;
1748} 1871}
1749 1872
@@ -1759,10 +1882,17 @@ Otherwise returns NIL.")
1759 int bufsize; 1882 int bufsize;
1760 int valsize; 1883 int valsize;
1761 Lisp_Object val; 1884 Lisp_Object val;
1885 Lisp_Object handler;
1762 1886
1763 CHECK_STRING (filename, 0); 1887 CHECK_STRING (filename, 0);
1764 filename = Fexpand_file_name (filename, Qnil); 1888 filename = Fexpand_file_name (filename, Qnil);
1765 1889
1890 /* If the file name has special constructs in it,
1891 call the corresponding file handler. */
1892 handler = find_file_handler (filename);
1893 if (!NILP (handler))
1894 return call2 (handler, Qfile_symlink_p, filename);
1895
1766 bufsize = 100; 1896 bufsize = 100;
1767 while (1) 1897 while (1)
1768 { 1898 {
@@ -1795,9 +1925,17 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
1795 Lisp_Object filename; 1925 Lisp_Object filename;
1796{ 1926{
1797 Lisp_Object abspath, dir; 1927 Lisp_Object abspath, dir;
1928 Lisp_Object handler;
1798 1929
1799 CHECK_STRING (filename, 0); 1930 CHECK_STRING (filename, 0);
1800 abspath = Fexpand_file_name (filename, Qnil); 1931 abspath = Fexpand_file_name (filename, Qnil);
1932
1933 /* If the file name has special constructs in it,
1934 call the corresponding file handler. */
1935 handler = find_file_handler (filename);
1936 if (!NILP (handler))
1937 return call2 (handler, Qfile_writable_p, filename);
1938
1801 if (access (XSTRING (abspath)->data, 0) >= 0) 1939 if (access (XSTRING (abspath)->data, 0) >= 0)
1802 return (access (XSTRING (abspath)->data, 2) >= 0) ? Qt : Qnil; 1940 return (access (XSTRING (abspath)->data, 2) >= 0) ? Qt : Qnil;
1803 dir = Ffile_name_directory (abspath); 1941 dir = Ffile_name_directory (abspath);
@@ -1818,9 +1956,16 @@ if the directory so specified exists and really is a directory.")
1818{ 1956{
1819 register Lisp_Object abspath; 1957 register Lisp_Object abspath;
1820 struct stat st; 1958 struct stat st;
1959 Lisp_Object handler;
1821 1960
1822 abspath = expand_and_dir_to_file (filename, current_buffer->directory); 1961 abspath = expand_and_dir_to_file (filename, current_buffer->directory);
1823 1962
1963 /* If the file name has special constructs in it,
1964 call the corresponding file handler. */
1965 handler = find_file_handler (filename);
1966 if (!NILP (handler))
1967 return call2 (handler, Qfile_directory_p, filename);
1968
1824 if (stat (XSTRING (abspath)->data, &st) < 0) 1969 if (stat (XSTRING (abspath)->data, &st) < 0)
1825 return Qnil; 1970 return Qnil;
1826 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil; 1971 return (st.st_mode & S_IFMT) == S_IFDIR ? Qt : Qnil;
@@ -1836,6 +1981,14 @@ searchable directory.")
1836 (filename) 1981 (filename)
1837 Lisp_Object filename; 1982 Lisp_Object filename;
1838{ 1983{
1984 Lisp_Object handler;
1985
1986 /* If the file name has special constructs in it,
1987 call the corresponding file handler. */
1988 handler = find_file_handler (filename);
1989 if (!NILP (handler))
1990 return call2 (handler, Qfile_accessible_directory_p, filename);
1991
1839 if (NILP (Ffile_directory_p (filename)) 1992 if (NILP (Ffile_directory_p (filename))
1840 || NILP (Ffile_executable_p (filename))) 1993 || NILP (Ffile_executable_p (filename)))
1841 return Qnil; 1994 return Qnil;
@@ -1850,9 +2003,16 @@ DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
1850{ 2003{
1851 Lisp_Object abspath; 2004 Lisp_Object abspath;
1852 struct stat st; 2005 struct stat st;
2006 Lisp_Object handler;
1853 2007
1854 abspath = expand_and_dir_to_file (filename, current_buffer->directory); 2008 abspath = expand_and_dir_to_file (filename, current_buffer->directory);
1855 2009
2010 /* If the file name has special constructs in it,
2011 call the corresponding file handler. */
2012 handler = find_file_handler (filename);
2013 if (!NILP (handler))
2014 return call2 (handler, Qfile_modes, filename);
2015
1856 if (stat (XSTRING (abspath)->data, &st) < 0) 2016 if (stat (XSTRING (abspath)->data, &st) < 0)
1857 return Qnil; 2017 return Qnil;
1858 return make_number (st.st_mode & 07777); 2018 return make_number (st.st_mode & 07777);
@@ -1865,10 +2025,17 @@ Only the 12 low bits of MODE are used.")
1865 Lisp_Object filename, mode; 2025 Lisp_Object filename, mode;
1866{ 2026{
1867 Lisp_Object abspath; 2027 Lisp_Object abspath;
2028 Lisp_Object handler;
1868 2029
1869 abspath = Fexpand_file_name (filename, current_buffer->directory); 2030 abspath = Fexpand_file_name (filename, current_buffer->directory);
1870 CHECK_NUMBER (mode, 1); 2031 CHECK_NUMBER (mode, 1);
1871 2032
2033 /* If the file name has special constructs in it,
2034 call the corresponding file handler. */
2035 handler = find_file_handler (filename);
2036 if (!NILP (handler))
2037 return call3 (handler, Qset_file_modes, filename, mode);
2038
1872#ifndef APOLLO 2039#ifndef APOLLO
1873 if (chmod (XSTRING (abspath)->data, XINT (mode)) < 0) 2040 if (chmod (XSTRING (abspath)->data, XINT (mode)) < 0)
1874 report_file_error ("Doing chmod", Fcons (abspath, Qnil)); 2041 report_file_error ("Doing chmod", Fcons (abspath, Qnil));
@@ -1953,23 +2120,29 @@ otherwise, if FILE2 does not exist, the answer is t.")
1953 (file1, file2) 2120 (file1, file2)
1954 Lisp_Object file1, file2; 2121 Lisp_Object file1, file2;
1955{ 2122{
1956 Lisp_Object abspath; 2123 Lisp_Object abspath1, abspath2;
1957 struct stat st; 2124 struct stat st;
1958 int mtime1; 2125 int mtime1;
2126 Lisp_Object handler;
1959 2127
1960 CHECK_STRING (file1, 0); 2128 CHECK_STRING (file1, 0);
1961 CHECK_STRING (file2, 0); 2129 CHECK_STRING (file2, 0);
1962 2130
1963 abspath = expand_and_dir_to_file (file1, current_buffer->directory); 2131 abspath1 = expand_and_dir_to_file (file1, current_buffer->directory);
2132 abspath2 = expand_and_dir_to_file (file2, current_buffer->directory);
1964 2133
1965 if (stat (XSTRING (abspath)->data, &st) < 0) 2134 /* If the file name has special constructs in it,
2135 call the corresponding file handler. */
2136 handler = find_file_handler (abspath1);
2137 if (!NILP (handler))
2138 return call3 (handler, Qfile_newer_than_file_p, abspath1, abspath2);
2139
2140 if (stat (XSTRING (abspath1)->data, &st) < 0)
1966 return Qnil; 2141 return Qnil;
1967 2142
1968 mtime1 = st.st_mtime; 2143 mtime1 = st.st_mtime;
1969 2144
1970 abspath = expand_and_dir_to_file (file2, current_buffer->directory); 2145 if (stat (XSTRING (abspath2)->data, &st) < 0)
1971
1972 if (stat (XSTRING (abspath)->data, &st) < 0)
1973 return Qt; 2146 return Qt;
1974 2147
1975 return (mtime1 > st.st_mtime) ? Qt : Qnil; 2148 return (mtime1 > st.st_mtime) ? Qt : Qnil;
@@ -1992,7 +2165,10 @@ before the error is signaled.")
1992 register int how_much; 2165 register int how_much;
1993 int count = specpdl_ptr - specpdl; 2166 int count = specpdl_ptr - specpdl;
1994 struct gcpro gcpro1; 2167 struct gcpro gcpro1;
1995 2168 Lisp_Object handler, val;
2169
2170 val = Qnil;
2171
1996 GCPRO1 (filename); 2172 GCPRO1 (filename);
1997 if (!NILP (current_buffer->read_only)) 2173 if (!NILP (current_buffer->read_only))
1998 Fbarf_if_buffer_read_only(); 2174 Fbarf_if_buffer_read_only();
@@ -2000,6 +2176,16 @@ before the error is signaled.")
2000 CHECK_STRING (filename, 0); 2176 CHECK_STRING (filename, 0);
2001 filename = Fexpand_file_name (filename, Qnil); 2177 filename = Fexpand_file_name (filename, Qnil);
2002 2178
2179 /* If the file name has special constructs in it,
2180 call the corresponding file handler. */
2181 handler = find_file_handler (filename);
2182 if (!NILP (handler))
2183 {
2184 val = call3 (handler, Qinsert_file_contents, filename, visit);
2185 st.st_mtime = 0;
2186 goto handled;
2187 }
2188
2003 fd = -1; 2189 fd = -1;
2004 2190
2005#ifndef APOLLO 2191#ifndef APOLLO
@@ -2088,6 +2274,7 @@ before the error is signaled.")
2088 XSTRING (filename)->data, err_str (errno)); 2274 XSTRING (filename)->data, err_str (errno));
2089 2275
2090 notfound: 2276 notfound:
2277 handled:
2091 2278
2092 if (!NILP (visit)) 2279 if (!NILP (visit))
2093 { 2280 {
@@ -2100,18 +2287,23 @@ before the error is signaled.")
2100 current_buffer->auto_save_modified = MODIFF; 2287 current_buffer->auto_save_modified = MODIFF;
2101 XFASTINT (current_buffer->save_length) = Z - BEG; 2288 XFASTINT (current_buffer->save_length) = Z - BEG;
2102#ifdef CLASH_DETECTION 2289#ifdef CLASH_DETECTION
2103 if (!NILP (current_buffer->filename)) 2290 if (NILP (handler))
2104 unlock_file (current_buffer->filename); 2291 {
2105 unlock_file (filename); 2292 if (!NILP (current_buffer->filename))
2293 unlock_file (current_buffer->filename);
2294 unlock_file (filename);
2295 }
2106#endif /* CLASH_DETECTION */ 2296#endif /* CLASH_DETECTION */
2107 current_buffer->filename = filename; 2297 current_buffer->filename = filename;
2108 /* If visiting nonexistent file, return nil. */ 2298 /* If visiting nonexistent file, return nil. */
2109 if (st.st_mtime == -1) 2299 if (current_buffer->modtime == -1)
2110 report_file_error ("Opening input file", Fcons (filename, Qnil)); 2300 report_file_error ("Opening input file", Fcons (filename, Qnil));
2111 } 2301 }
2112 2302
2113 signal_after_change (point, 0, inserted); 2303 signal_after_change (point, 0, inserted);
2114 2304
2305 if (!NILP (val))
2306 RETURN_UNGCPRO (val);
2115 RETURN_UNGCPRO (Fcons (filename, 2307 RETURN_UNGCPRO (Fcons (filename,
2116 Fcons (make_number (inserted), 2308 Fcons (make_number (inserted),
2117 Qnil))); 2309 Qnil)));
@@ -2157,6 +2349,35 @@ to the file, instead of any buffer contents, and END is ignored.")
2157 filename = Fexpand_file_name (filename, Qnil); 2349 filename = Fexpand_file_name (filename, Qnil);
2158 fn = XSTRING (filename)->data; 2350 fn = XSTRING (filename)->data;
2159 2351
2352 /* If the file name has special constructs in it,
2353 call the corresponding file handler. */
2354 handler = find_file_handler (filename);
2355 if (!NILP (handler))
2356 {
2357 Lisp_Object args[7];
2358 Lisp_Object val;
2359 args[0] = handler;
2360 args[1] = Qwrite_region;
2361 args[2] = start;
2362 args[3] = end;
2363 args[4] = filename;
2364 args[5] = append;
2365 args[6] = visit;
2366 val = Ffuncall (7, args);
2367
2368 /* Do this before reporting IO error
2369 to avoid a "file has changed on disk" warning on
2370 next attempt to save. */
2371 if (EQ (visit, Qt))
2372 {
2373 current_buffer->modtime = 0;
2374 current_buffer->save_modified = MODIFF;
2375 XFASTINT (current_buffer->save_length) = Z - BEG;
2376 current_buffer->filename = filename;
2377 }
2378 return val;
2379 }
2380
2160#ifdef CLASH_DETECTION 2381#ifdef CLASH_DETECTION
2161 if (!auto_saving) 2382 if (!auto_saving)
2162 lock_file (filename); 2383 lock_file (filename);
@@ -2410,6 +2631,7 @@ This means that the file has not been changed since it was visited or saved.")
2410{ 2631{
2411 struct buffer *b; 2632 struct buffer *b;
2412 struct stat st; 2633 struct stat st;
2634 Lisp_Object handler;
2413 2635
2414 CHECK_BUFFER (buf, 0); 2636 CHECK_BUFFER (buf, 0);
2415 b = XBUFFER (buf); 2637 b = XBUFFER (buf);
@@ -2417,6 +2639,12 @@ This means that the file has not been changed since it was visited or saved.")
2417 if (XTYPE (b->filename) != Lisp_String) return Qt; 2639 if (XTYPE (b->filename) != Lisp_String) return Qt;
2418 if (b->modtime == 0) return Qt; 2640 if (b->modtime == 0) return Qt;
2419 2641
2642 /* If the file name has special constructs in it,
2643 call the corresponding file handler. */
2644 handler = find_file_handler (filename);
2645 if (!NILP (handler))
2646 return call2 (handler, Qverify_visited_file_modtime, filename);
2647
2420 if (stat (XSTRING (b->filename)->data, &st) < 0) 2648 if (stat (XSTRING (b->filename)->data, &st) < 0)
2421 { 2649 {
2422 /* If the file doesn't exist now and didn't exist before, 2650 /* If the file doesn't exist now and didn't exist before,
@@ -2456,8 +2684,14 @@ or if the file itself has been changed for some known benign reason.")
2456 struct stat st; 2684 struct stat st;
2457 2685
2458 filename = Fexpand_file_name (current_buffer->filename, Qnil); 2686 filename = Fexpand_file_name (current_buffer->filename, Qnil);
2687
2688 /* If the file name has special constructs in it,
2689 call the corresponding file handler. */
2690 handler = find_file_handler (filename);
2691 if (!NILP (handler))
2692 current_buffer->modtime = 0;
2459 2693
2460 if (stat (XSTRING (filename)->data, &st) >= 0) 2694 else if (stat (XSTRING (filename)->data, &st) >= 0)
2461 current_buffer->modtime = st.st_mtime; 2695 current_buffer->modtime = st.st_mtime;
2462 2696
2463 return Qnil; 2697 return Qnil;
@@ -2831,6 +3065,27 @@ DIR defaults to current buffer's directory default.")
2831 3065
2832syms_of_fileio () 3066syms_of_fileio ()
2833{ 3067{
3068 Qcopy_file = intern ("copy-file");
3069 Qmake_directory = intern ("make-directory");
3070 Qdelete_directory = intern ("delete-directory");
3071 Qdelete_file = intern ("delete-file");
3072 Qrename_file = intern ("rename-file");
3073 Qadd_name_to_file = intern ("add-name-to-file");
3074 Qmake_symbolic_link = intern ("make-symbolic-link");
3075 Qfile_exists_p = intern ("file-exists-p");
3076 Qfile_executable_p = intern ("file-executable-p");
3077 Qfile_readable_p = intern ("file-readable-p");
3078 Qfile_symlink_p = intern ("file-symlink-p");
3079 Qfile_writable_p = intern ("file-writable-p");
3080 Qfile_directory_p = intern ("file-directory-p");
3081 Qfile_accessible_directory_p = intern ("file-accessible-directory-p");
3082 Qfile_modes = intern ("file-modes");
3083 Qset_file_modes = intern ("set-file-modes");
3084 Qfile_newer_than_file_p = intern ("file-newer-than-file-p");
3085 Qinsert_file_contents = intern ("insert-file-contents");
3086 Qwrite_region = intern ("write-region");
3087 Qverify_visited_file_modtime = intern ("verify-visited-file-modtime");
3088
2834 Qfile_error = intern ("file-error"); 3089 Qfile_error = intern ("file-error");
2835 staticpro (&Qfile_error); 3090 staticpro (&Qfile_error);
2836 Qfile_already_exists = intern("file-already-exists"); 3091 Qfile_already_exists = intern("file-already-exists");