diff options
| author | Richard M. Stallman | 1992-07-22 03:27:55 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1992-07-22 03:27:55 +0000 |
| commit | 32f4334dcef11f3b06b04e05618a27f477e96449 (patch) | |
| tree | c40577083f8292e56e4627ee425d58bccf457724 /src | |
| parent | e59a84533d670449f4e42feab72b4427527b2e61 (diff) | |
| download | emacs-32f4334dcef11f3b06b04e05618a27f477e96449.tar.gz emacs-32f4334dcef11f3b06b04e05618a27f477e96449.zip | |
*** empty log message ***
Diffstat (limited to 'src')
| -rw-r--r-- | src/dired.c | 49 | ||||
| -rw-r--r-- | src/fileio.c | 281 |
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 (); | |||
| 64 | Lisp_Object Vcompletion_ignored_extensions; | 64 | Lisp_Object Vcompletion_ignored_extensions; |
| 65 | 65 | ||
| 66 | Lisp_Object Qcompletion_ignore_case; | 66 | Lisp_Object Qcompletion_ignore_case; |
| 67 | |||
| 68 | Lisp_Object Qdirectory_files; | ||
| 69 | Lisp_Object Qfile_name_completion; | ||
| 70 | Lisp_Object Qfile_name_all_completions; | ||
| 67 | 71 | ||
| 68 | DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0, | 72 | DEFUN ("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 | ||
| 458 | syms_of_dired () | 503 | syms_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 */ |
| 88 | int auto_save_mode_bits; | 88 | int 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. */ | ||
| 92 | Lisp_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. */ |
| 92 | int insert_default_directory; | 96 | int insert_default_directory; |
| @@ -124,6 +128,52 @@ close_file_unwind (fd) | |||
| 124 | close (XFASTINT (fd)); | 128 | close (XFASTINT (fd)); |
| 125 | } | 129 | } |
| 126 | 130 | ||
| 131 | Lisp_Object Qcopy_file; | ||
| 132 | Lisp_Object Qmake_directory; | ||
| 133 | Lisp_Object Qdelete_directory; | ||
| 134 | Lisp_Object Qdelete_file; | ||
| 135 | Lisp_Object Qrename_file; | ||
| 136 | Lisp_Object Qadd_name_to_file; | ||
| 137 | Lisp_Object Qmake_symbolic_link; | ||
| 138 | Lisp_Object Qfile_exists_p; | ||
| 139 | Lisp_Object Qfile_executable_p; | ||
| 140 | Lisp_Object Qfile_readable_p; | ||
| 141 | Lisp_Object Qfile_symlink_p; | ||
| 142 | Lisp_Object Qfile_writable_p; | ||
| 143 | Lisp_Object Qfile_directory_p; | ||
| 144 | Lisp_Object Qfile_accessible_directory_p; | ||
| 145 | Lisp_Object Qfile_modes; | ||
| 146 | Lisp_Object Qset_file_modes; | ||
| 147 | Lisp_Object Qfile_newer_than_file_p; | ||
| 148 | Lisp_Object Qinsert_file_contents; | ||
| 149 | Lisp_Object Qwrite_region; | ||
| 150 | Lisp_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 | |||
| 155 | Lisp_Object | ||
| 156 | find_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 | |||
| 127 | DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, | 177 | DEFUN ("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 | ||
| 1466 | DEFUN ("delete-directory", Fdelete_directory, Sdelete_directory, 1, 1, "FDelete directory: ", | 1530 | DEFUN ("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 | ||
| 2832 | syms_of_fileio () | 3066 | syms_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"); |