diff options
| author | Richard M. Stallman | 1994-09-24 23:24:52 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-09-24 23:24:52 +0000 |
| commit | 3beeedfef771cfc8961873b79d935793f2aeaecb (patch) | |
| tree | 8606341788f1c893dc565b8a23426f4c68844f2f | |
| parent | 0df7d18aa0263e5183fd0ed98620df88522c8870 (diff) | |
| download | emacs-3beeedfef771cfc8961873b79d935793f2aeaecb.tar.gz emacs-3beeedfef771cfc8961873b79d935793f2aeaecb.zip | |
(Ffile_writable_p): Use stat to test for existence.
(check_executable, check_writable): New functions.
(Ffile_executable_p, Ffile_writable_p): Use the new functions.
(Fread_file_name): If DEFAULT is nil and INITIAL is not,
use INITIAL to set DEFAULT.
| -rw-r--r-- | src/fileio.c | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/src/fileio.c b/src/fileio.c index b0b01cef50e..6f3d7663182 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -2174,6 +2174,64 @@ On Unix, this is a name starting with a `/' or a `~'.") | |||
| 2174 | else | 2174 | else |
| 2175 | return Qnil; | 2175 | return Qnil; |
| 2176 | } | 2176 | } |
| 2177 | |||
| 2178 | /* Return nonzero if file FILENAME exists and can be executed. */ | ||
| 2179 | |||
| 2180 | static int | ||
| 2181 | check_executable (filename) | ||
| 2182 | char *filename; | ||
| 2183 | { | ||
| 2184 | #ifdef __HURD__ | ||
| 2185 | mach_port_t file; | ||
| 2186 | int access_mode; | ||
| 2187 | |||
| 2188 | file = path_lookup (filename, 0, 0); | ||
| 2189 | if (file == MACH_PORT_NULL) | ||
| 2190 | /* File can't be opened. */ | ||
| 2191 | access_mode = 0; | ||
| 2192 | else | ||
| 2193 | { | ||
| 2194 | file_access (file, &access_mode); | ||
| 2195 | mach_port_deallocate (mach_task_self (), file); | ||
| 2196 | } | ||
| 2197 | return !!(access_mode & O_EXEC); | ||
| 2198 | #else | ||
| 2199 | /* Access isn't quite right because it uses the real uid | ||
| 2200 | and we really want to test with the effective uid. | ||
| 2201 | But Unix doesn't give us a right way to do it. */ | ||
| 2202 | return (access (filename, 1) >= 0); | ||
| 2203 | #endif | ||
| 2204 | } | ||
| 2205 | |||
| 2206 | /* Return nonzero if file FILENAME exists and can be written. */ | ||
| 2207 | |||
| 2208 | static int | ||
| 2209 | check_writable (filename) | ||
| 2210 | char *filename; | ||
| 2211 | { | ||
| 2212 | #ifdef __HURD__ | ||
| 2213 | mach_port_t file; | ||
| 2214 | int access_mode; | ||
| 2215 | |||
| 2216 | file = path_lookup (filename, 0, 0); | ||
| 2217 | if (file == MACH_PORT_NULL) | ||
| 2218 | /* File can't be opened. */ | ||
| 2219 | access_mode = 0; | ||
| 2220 | else | ||
| 2221 | { | ||
| 2222 | file_access (file, &access_mode); | ||
| 2223 | mach_port_deallocate (mach_task_self (), file); | ||
| 2224 | } | ||
| 2225 | return !!(access_mode & O_WRITE); | ||
| 2226 | #else | ||
| 2227 | /* Access isn't quite right because it uses the real uid | ||
| 2228 | and we really want to test with the effective uid. | ||
| 2229 | But Unix doesn't give us a right way to do it. | ||
| 2230 | Opening with O_WRONLY could work for an ordinary file, | ||
| 2231 | but would lose for directories. */ | ||
| 2232 | return (access (filename, 2) >= 0); | ||
| 2233 | #endif | ||
| 2234 | } | ||
| 2177 | 2235 | ||
| 2178 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, | 2236 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, |
| 2179 | "Return t if file FILENAME exists. (This does not mean you can read it.)\n\ | 2237 | "Return t if file FILENAME exists. (This does not mean you can read it.)\n\ |
| @@ -2216,7 +2274,7 @@ For a directory, this means you can access files in that directory.") | |||
| 2216 | if (!NILP (handler)) | 2274 | if (!NILP (handler)) |
| 2217 | return call2 (handler, Qfile_executable_p, abspath); | 2275 | return call2 (handler, Qfile_executable_p, abspath); |
| 2218 | 2276 | ||
| 2219 | return (access (XSTRING (abspath)->data, 1) >= 0) ? Qt : Qnil; | 2277 | return (check_executable (XSTRING (abspath)->data) ? Qt : Qnil); |
| 2220 | } | 2278 | } |
| 2221 | 2279 | ||
| 2222 | DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0, | 2280 | DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0, |
| @@ -2301,6 +2359,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2301 | { | 2359 | { |
| 2302 | Lisp_Object abspath, dir; | 2360 | Lisp_Object abspath, dir; |
| 2303 | Lisp_Object handler; | 2361 | Lisp_Object handler; |
| 2362 | struct stat statbuf; | ||
| 2304 | 2363 | ||
| 2305 | CHECK_STRING (filename, 0); | 2364 | CHECK_STRING (filename, 0); |
| 2306 | abspath = Fexpand_file_name (filename, Qnil); | 2365 | abspath = Fexpand_file_name (filename, Qnil); |
| @@ -2311,8 +2370,8 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2311 | if (!NILP (handler)) | 2370 | if (!NILP (handler)) |
| 2312 | return call2 (handler, Qfile_writable_p, abspath); | 2371 | return call2 (handler, Qfile_writable_p, abspath); |
| 2313 | 2372 | ||
| 2314 | if (access (XSTRING (abspath)->data, 0) >= 0) | 2373 | if (stat (XSTRING (abspath)->data, &statbuf) >= 0) |
| 2315 | return (access (XSTRING (abspath)->data, 2) >= 0 | 2374 | return (check_writable (XSTRING (abspath)->data) |
| 2316 | ? Qt : Qnil); | 2375 | ? Qt : Qnil); |
| 2317 | dir = Ffile_name_directory (abspath); | 2376 | dir = Ffile_name_directory (abspath); |
| 2318 | #ifdef VMS | 2377 | #ifdef VMS |
| @@ -2323,7 +2382,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, | |||
| 2323 | if (!NILP (dir)) | 2382 | if (!NILP (dir)) |
| 2324 | dir = Fdirectory_file_name (dir); | 2383 | dir = Fdirectory_file_name (dir); |
| 2325 | #endif /* MSDOS */ | 2384 | #endif /* MSDOS */ |
| 2326 | return (access (!NILP (dir) ? (char *) XSTRING (dir)->data : "", 2) >= 0 | 2385 | return (check_writable (!NILP (dir) ? (char *) XSTRING (dir)->data : "") |
| 2327 | ? Qt : Qnil); | 2386 | ? Qt : Qnil); |
| 2328 | } | 2387 | } |
| 2329 | 2388 | ||
| @@ -3849,7 +3908,8 @@ DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 5, 0, | |||
| 3849 | "Read file name, prompting with PROMPT and completing in directory DIR.\n\ | 3908 | "Read file name, prompting with PROMPT and completing in directory DIR.\n\ |
| 3850 | Value is not expanded---you must call `expand-file-name' yourself.\n\ | 3909 | Value is not expanded---you must call `expand-file-name' yourself.\n\ |
| 3851 | Default name to DEFAULT if user enters a null string.\n\ | 3910 | Default name to DEFAULT if user enters a null string.\n\ |
| 3852 | (If DEFAULT is omitted, the visited file name is used.)\n\ | 3911 | (If DEFAULT is omitted, the visited file name is used,\n\ |
| 3912 | except that if INITIAL is specified, that combined with DIR is used.)\n\ | ||
| 3853 | Fourth arg MUSTMATCH non-nil means require existing file's name.\n\ | 3913 | Fourth arg MUSTMATCH non-nil means require existing file's name.\n\ |
| 3854 | Non-nil and non-t means also require confirmation after completion.\n\ | 3914 | Non-nil and non-t means also require confirmation after completion.\n\ |
| 3855 | Fifth arg INITIAL specifies text to start with.\n\ | 3915 | Fifth arg INITIAL specifies text to start with.\n\ |
| @@ -3865,7 +3925,12 @@ DIR defaults to current buffer's directory default.") | |||
| 3865 | if (NILP (dir)) | 3925 | if (NILP (dir)) |
| 3866 | dir = current_buffer->directory; | 3926 | dir = current_buffer->directory; |
| 3867 | if (NILP (defalt)) | 3927 | if (NILP (defalt)) |
| 3868 | defalt = current_buffer->filename; | 3928 | { |
| 3929 | if (! NILP (initial)) | ||
| 3930 | defalt = Fexpand_file_name (initial, dir); | ||
| 3931 | else | ||
| 3932 | defalt = current_buffer->filename; | ||
| 3933 | } | ||
| 3869 | 3934 | ||
| 3870 | /* If dir starts with user's homedir, change that to ~. */ | 3935 | /* If dir starts with user's homedir, change that to ~. */ |
| 3871 | homedir = (char *) egetenv ("HOME"); | 3936 | homedir = (char *) egetenv ("HOME"); |