diff options
Diffstat (limited to 'src/fileio.c')
| -rw-r--r-- | src/fileio.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/fileio.c b/src/fileio.c index b4eda01afcc..5de5bc2b021 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -52,6 +52,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 52 | #define NOMINMAX 1 | 52 | #define NOMINMAX 1 |
| 53 | #include <windows.h> | 53 | #include <windows.h> |
| 54 | #include <fcntl.h> | 54 | #include <fcntl.h> |
| 55 | #include <sys/file.h> | ||
| 55 | #endif /* not WINDOWSNT */ | 56 | #endif /* not WINDOWSNT */ |
| 56 | 57 | ||
| 57 | #ifdef MSDOS | 58 | #ifdef MSDOS |
| @@ -668,7 +669,6 @@ make_temp_name (Lisp_Object prefix, bool base64_p) | |||
| 668 | 669 | ||
| 669 | while (1) | 670 | while (1) |
| 670 | { | 671 | { |
| 671 | struct stat ignored; | ||
| 672 | unsigned num = make_temp_name_count; | 672 | unsigned num = make_temp_name_count; |
| 673 | 673 | ||
| 674 | p[0] = make_temp_name_tbl[num & 63], num >>= 6; | 674 | p[0] = make_temp_name_tbl[num & 63], num >>= 6; |
| @@ -680,7 +680,7 @@ make_temp_name (Lisp_Object prefix, bool base64_p) | |||
| 680 | make_temp_name_count += 25229; | 680 | make_temp_name_count += 25229; |
| 681 | make_temp_name_count %= 225307; | 681 | make_temp_name_count %= 225307; |
| 682 | 682 | ||
| 683 | if (stat (data, &ignored) < 0) | 683 | if (!check_existing (data)) |
| 684 | { | 684 | { |
| 685 | /* We want to return only if errno is ENOENT. */ | 685 | /* We want to return only if errno is ENOENT. */ |
| 686 | if (errno == ENOENT) | 686 | if (errno == ENOENT) |
| @@ -2423,6 +2423,21 @@ On Unix, this is a name starting with a `/' or a `~'. */) | |||
| 2423 | return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil; | 2423 | return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil; |
| 2424 | } | 2424 | } |
| 2425 | 2425 | ||
| 2426 | /* Return true if FILENAME exists. */ | ||
| 2427 | bool | ||
| 2428 | check_existing (const char *filename) | ||
| 2429 | { | ||
| 2430 | #ifdef DOS_NT | ||
| 2431 | /* The full emulation of Posix 'stat' is too expensive on | ||
| 2432 | DOS/Windows, when all we want to know is whether the file exists. | ||
| 2433 | So we use 'access' instead, which is much more lightweight. */ | ||
| 2434 | return (access (filename, F_OK) >= 0); | ||
| 2435 | #else | ||
| 2436 | struct stat st; | ||
| 2437 | return (stat (filename, &st) >= 0); | ||
| 2438 | #endif | ||
| 2439 | } | ||
| 2440 | |||
| 2426 | /* Return true if file FILENAME exists and can be executed. */ | 2441 | /* Return true if file FILENAME exists and can be executed. */ |
| 2427 | 2442 | ||
| 2428 | static bool | 2443 | static bool |
| @@ -2490,7 +2505,6 @@ Use `file-symlink-p' to test for such links. */) | |||
| 2490 | { | 2505 | { |
| 2491 | Lisp_Object absname; | 2506 | Lisp_Object absname; |
| 2492 | Lisp_Object handler; | 2507 | Lisp_Object handler; |
| 2493 | struct stat statbuf; | ||
| 2494 | 2508 | ||
| 2495 | CHECK_STRING (filename); | 2509 | CHECK_STRING (filename); |
| 2496 | absname = Fexpand_file_name (filename, Qnil); | 2510 | absname = Fexpand_file_name (filename, Qnil); |
| @@ -2503,7 +2517,7 @@ Use `file-symlink-p' to test for such links. */) | |||
| 2503 | 2517 | ||
| 2504 | absname = ENCODE_FILE (absname); | 2518 | absname = ENCODE_FILE (absname); |
| 2505 | 2519 | ||
| 2506 | return (stat (SSDATA (absname), &statbuf) >= 0) ? Qt : Qnil; | 2520 | return (check_existing (SSDATA (absname))) ? Qt : Qnil; |
| 2507 | } | 2521 | } |
| 2508 | 2522 | ||
| 2509 | DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0, | 2523 | DEFUN ("file-executable-p", Ffile_executable_p, Sfile_executable_p, 1, 1, 0, |
| @@ -2584,7 +2598,6 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2584 | { | 2598 | { |
| 2585 | Lisp_Object absname, dir, encoded; | 2599 | Lisp_Object absname, dir, encoded; |
| 2586 | Lisp_Object handler; | 2600 | Lisp_Object handler; |
| 2587 | struct stat statbuf; | ||
| 2588 | 2601 | ||
| 2589 | CHECK_STRING (filename); | 2602 | CHECK_STRING (filename); |
| 2590 | absname = Fexpand_file_name (filename, Qnil); | 2603 | absname = Fexpand_file_name (filename, Qnil); |
| @@ -2596,7 +2609,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2596 | return call2 (handler, Qfile_writable_p, absname); | 2609 | return call2 (handler, Qfile_writable_p, absname); |
| 2597 | 2610 | ||
| 2598 | encoded = ENCODE_FILE (absname); | 2611 | encoded = ENCODE_FILE (absname); |
| 2599 | if (stat (SSDATA (encoded), &statbuf) >= 0) | 2612 | if (check_existing (SSDATA (encoded))) |
| 2600 | return (check_writable (SSDATA (encoded)) | 2613 | return (check_writable (SSDATA (encoded)) |
| 2601 | ? Qt : Qnil); | 2614 | ? Qt : Qnil); |
| 2602 | 2615 | ||
| @@ -2611,9 +2624,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2611 | /* The read-only attribute of the parent directory doesn't affect | 2624 | /* The read-only attribute of the parent directory doesn't affect |
| 2612 | whether a file or directory can be created within it. Some day we | 2625 | whether a file or directory can be created within it. Some day we |
| 2613 | should check ACLs though, which do affect this. */ | 2626 | should check ACLs though, which do affect this. */ |
| 2614 | if (stat (SDATA (dir), &statbuf) < 0) | 2627 | return (access (SDATA (dir), D_OK) < 0) ? Qnil : Qt; |
| 2615 | return Qnil; | ||
| 2616 | return S_ISDIR (statbuf.st_mode) ? Qt : Qnil; | ||
| 2617 | #else | 2628 | #else |
| 2618 | return (check_writable (!NILP (dir) ? SSDATA (dir) : "") | 2629 | return (check_writable (!NILP (dir) ? SSDATA (dir) : "") |
| 2619 | ? Qt : Qnil); | 2630 | ? Qt : Qnil); |