X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/678fb7066698ebfe3aecba722294025ed26da01b..2fa85638a036673b63055a86c6bd5b7b789a9d9d:/src/fileio.c diff --git a/src/fileio.c b/src/fileio.c index 9e940c9a32..0d1a87b65b 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1,6 +1,6 @@ /* File IO for GNU Emacs. -Copyright (C) 1985-1988, 1993-2012 Free Software Foundation, Inc. +Copyright (C) 1985-1988, 1993-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -328,7 +328,11 @@ Given a Unix syntax file name, returns a string ending in slash. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (filename, Qfile_name_directory); if (!NILP (handler)) - return call2 (handler, Qfile_name_directory, filename); + { + Lisp_Object handled_name = call2 (handler, Qfile_name_directory, + filename); + return STRINGP (handled_name) ? handled_name : Qnil; + } filename = FILE_SYSTEM_CASE (filename); #ifdef DOS_NT @@ -397,7 +401,13 @@ or the entire name if it contains no slash. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory); if (!NILP (handler)) - return call2 (handler, Qfile_name_nondirectory, filename); + { + Lisp_Object handled_name = call2 (handler, Qfile_name_nondirectory, + filename); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } beg = SSDATA (filename); end = p = beg + SBYTES (filename); @@ -434,7 +444,11 @@ get a current directory to run processes in. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (filename, Qunhandled_file_name_directory); if (!NILP (handler)) - return call2 (handler, Qunhandled_file_name_directory, filename); + { + Lisp_Object handled_name = call2 (handler, Qunhandled_file_name_directory, + filename); + return STRINGP (handled_name) ? handled_name : Qnil; + } return Ffile_name_directory (filename); } @@ -488,7 +502,13 @@ For a Unix-syntax file name, just appends a slash. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (file, Qfile_name_as_directory); if (!NILP (handler)) - return call2 (handler, Qfile_name_as_directory, file); + { + Lisp_Object handled_name = call2 (handler, Qfile_name_as_directory, + file); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } buf = (char *) alloca (SBYTES (file) + 10); file_name_as_directory (buf, SSDATA (file)); @@ -547,7 +567,13 @@ In Unix-syntax, this function just removes the final slash. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (directory, Qdirectory_file_name); if (!NILP (handler)) - return call2 (handler, Qdirectory_file_name, directory); + { + Lisp_Object handled_name = call2 (handler, Qdirectory_file_name, + directory); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } buf = (char *) alloca (SBYTES (directory) + 20); directory_file_name (SSDATA (directory), buf); @@ -747,7 +773,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) int is_escaped = 0; #endif /* DOS_NT */ ptrdiff_t length; - Lisp_Object handler, result; + Lisp_Object handler, result, handled_name; int multibyte; Lisp_Object hdir; @@ -757,7 +783,14 @@ filesystem tree, not (expand-file-name ".." dirname). */) call the corresponding file handler. */ handler = Ffind_file_name_handler (name, Qexpand_file_name); if (!NILP (handler)) - return call3 (handler, Qexpand_file_name, name, default_directory); + { + handled_name = call3 (handler, Qexpand_file_name, + name, default_directory); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } + /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ if (NILP (default_directory)) @@ -783,7 +816,13 @@ filesystem tree, not (expand-file-name ".." dirname). */) { handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); if (!NILP (handler)) - return call3 (handler, Qexpand_file_name, name, default_directory); + { + handled_name = call3 (handler, Qexpand_file_name, + name, default_directory); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } } { @@ -1284,7 +1323,13 @@ filesystem tree, not (expand-file-name ".." dirname). */) to be expanded again. */ handler = Ffind_file_name_handler (result, Qexpand_file_name); if (!NILP (handler)) - return call3 (handler, Qexpand_file_name, result, default_directory); + { + handled_name = call3 (handler, Qexpand_file_name, + result, default_directory); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } return result; } @@ -1537,7 +1582,13 @@ those `/' is discarded. */) call the corresponding file handler. */ handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name); if (!NILP (handler)) - return call2 (handler, Qsubstitute_in_file_name, filename); + { + Lisp_Object handled_name = call2 (handler, Qsubstitute_in_file_name, + filename); + if (STRINGP (handled_name)) + return handled_name; + error ("Invalid handler in `file-name-handler-alist'"); + } /* Always work on a copy of the string, in case GC happens during decode of environment variables, causing the original Lisp_String @@ -1993,9 +2044,10 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) #if HAVE_LIBSELINUX if (conlength > 0) { - /* Set the modified context back to the file. */ + /* Set the modified context back to the file. */ fail = fsetfilecon (ofd, con); - if (fail) + /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ + if (fail && errno != ENOTSUP) report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil)); freecon (con); @@ -2747,9 +2799,13 @@ See `file-symlink-p' to distinguish symlinks. */) DEFUN ("file-selinux-context", Ffile_selinux_context, Sfile_selinux_context, 1, 1, 0, - doc: /* Return SELinux context of file named FILENAME, -as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil) -if file does not exist, is not accessible, or SELinux is disabled */) + doc: /* Return SELinux context of file named FILENAME. +The return value is a list (USER ROLE TYPE RANGE), where the list +elements are strings naming the user, role, type, and range of the +file's SELinux security context. + +Return (nil nil nil nil) if the file is nonexistent or inaccessible, +or if SELinux is disabled, or if Emacs lacks SELinux support. */) (Lisp_Object filename) { Lisp_Object absname; @@ -2802,9 +2858,12 @@ if file does not exist, is not accessible, or SELinux is disabled */) DEFUN ("set-file-selinux-context", Fset_file_selinux_context, Sset_file_selinux_context, 2, 2, 0, - doc: /* Set SELinux context of file named FILENAME to CONTEXT -as a list ("user", "role", "type", "range"). Has no effect if SELinux -is disabled. */) + doc: /* Set SELinux context of file named FILENAME to CONTEXT. +CONTEXT should be a list (USER ROLE TYPE RANGE), where the list +elements are strings naming the components of a SELinux context. + +This function does nothing if SELinux is disabled, or if Emacs was not +compiled with SELinux support. */) (Lisp_Object filename, Lisp_Object context) { Lisp_Object absname; @@ -2859,10 +2918,11 @@ is disabled. */) error ("Doing context_range_set"); } - /* Set the modified context back to the file. */ + /* Set the modified context back to the file. */ fail = lsetfilecon (SSDATA (encoded_absname), context_str (parsed_con)); - if (fail) + /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ + if (fail && errno != ENOTSUP) report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil)); context_free (parsed_con); @@ -5589,18 +5649,25 @@ of file names regardless of the current language environment. */); make_pure_c_string ("Cannot set file date")); DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist, - doc: /* *Alist of elements (REGEXP . HANDLER) for file names handled specially. -If a file name matches REGEXP, then all I/O on that file is done by calling -HANDLER. - -The first argument given to HANDLER is the name of the I/O primitive -to be handled; the remaining arguments are the arguments that were -passed to that primitive. For example, if you do - (file-exists-p FILENAME) -and FILENAME is handled by HANDLER, then HANDLER is called like this: - (funcall HANDLER 'file-exists-p FILENAME) -The function `find-file-name-handler' checks this list for a handler -for its argument. */); + doc: /* Alist of elements (REGEXP . HANDLER) for file names handled specially. +If a file name matches REGEXP, all I/O on that file is done by calling +HANDLER. If a file name matches more than one handler, the handler +whose match starts last in the file name gets precedence. The +function `find-file-name-handler' checks this list for a handler for +its argument. + +HANDLER should be a function. The first argument given to it is the +name of the I/O primitive to be handled; the remaining arguments are +the arguments that were passed to that primitive. For example, if you +do (file-exists-p FILENAME) and FILENAME is handled by HANDLER, then +HANDLER is called like this: + + (funcall HANDLER 'file-exists-p FILENAME) + +Note that HANDLER must be able to handle all I/O primitives; if it has +nothing special to do for a primitive, it should reinvoke the +primitive to handle the operation \"the usual way\". +See Info node `(elisp)Magic File Names' for more details. */); Vfile_name_handler_alist = Qnil; DEFVAR_LISP ("set-auto-coding-function",