aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorRichard M. Stallman1994-09-24 23:24:52 +0000
committerRichard M. Stallman1994-09-24 23:24:52 +0000
commit3beeedfef771cfc8961873b79d935793f2aeaecb (patch)
tree8606341788f1c893dc565b8a23426f4c68844f2f /src/fileio.c
parent0df7d18aa0263e5183fd0ed98620df88522c8870 (diff)
downloademacs-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.
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c77
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
2180static int
2181check_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
2208static int
2209check_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
2178DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, 2236DEFUN ("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
2222DEFUN ("file-readable-p", Ffile_readable_p, Sfile_readable_p, 1, 1, 0, 2280DEFUN ("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\
3850Value is not expanded---you must call `expand-file-name' yourself.\n\ 3909Value is not expanded---you must call `expand-file-name' yourself.\n\
3851Default name to DEFAULT if user enters a null string.\n\ 3910Default 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\
3853Fourth arg MUSTMATCH non-nil means require existing file's name.\n\ 3913Fourth 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\
3855Fifth arg INITIAL specifies text to start with.\n\ 3915Fifth 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");