diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 17 | ||||
| -rw-r--r-- | src/fileio.c | 162 |
2 files changed, 111 insertions, 68 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 1ec84a72d2d..e1e9777fa4f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2013-12-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Plain copy-file no longer chmods an existing destination (Bug#16133). | ||
| 4 | * fileio.c (realmask): Now a static var, not a local. | ||
| 5 | (barf_or_query_if_file_exists): New arg KNOWN_TO_EXIST. | ||
| 6 | Remove arg STATPTR. All uses changed. | ||
| 7 | (Fcopy_file): Do not alter permissions of existing destinations, | ||
| 8 | unless PRESERVE-PERMISSIONS (renamed from | ||
| 9 | PRESERVE-EXTENDED-ATTRIBUTES) is non-nil. | ||
| 10 | Avoid race when testing for existing destinations and for | ||
| 11 | when input and output files are the same. | ||
| 12 | If changing the group fails, adjust both default and | ||
| 13 | preserved permissions so that access is not granted to the | ||
| 14 | wrong group. | ||
| 15 | (Fset_default_file_modes, init_fileio): Update realmask. | ||
| 16 | (Fdefault_file_modes): Use realmask instead of calling umask. | ||
| 17 | |||
| 1 | 2013-12-28 Paul Eggert <eggert@cs.ucla.edu> | 18 | 2013-12-28 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 19 | ||
| 3 | Fix pipe bug with OS X emacs --daemon (Bug#16262). | 20 | Fix pipe bug with OS X emacs --daemon (Bug#16262). |
diff --git a/src/fileio.c b/src/fileio.c index 295d9d748ad..adf69c6f234 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -95,6 +95,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 95 | /* True during writing of auto-save files. */ | 95 | /* True during writing of auto-save files. */ |
| 96 | static bool auto_saving; | 96 | static bool auto_saving; |
| 97 | 97 | ||
| 98 | /* Emacs's real umask. */ | ||
| 99 | static mode_t realmask; | ||
| 100 | |||
| 98 | /* Nonzero umask during creation of auto-save directories. */ | 101 | /* Nonzero umask during creation of auto-save directories. */ |
| 99 | static mode_t auto_saving_dir_umask; | 102 | static mode_t auto_saving_dir_umask; |
| 100 | 103 | ||
| @@ -1858,20 +1861,16 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir) | |||
| 1858 | } | 1861 | } |
| 1859 | 1862 | ||
| 1860 | /* Signal an error if the file ABSNAME already exists. | 1863 | /* Signal an error if the file ABSNAME already exists. |
| 1861 | If INTERACTIVE, ask the user whether to proceed, | 1864 | If KNOWN_TO_EXIST, the file is known to exist. |
| 1862 | and bypass the error if the user says to go ahead. | ||
| 1863 | QUERYSTRING is a name for the action that is being considered | 1865 | QUERYSTRING is a name for the action that is being considered |
| 1864 | to alter the file. | 1866 | to alter the file. |
| 1865 | 1867 | If INTERACTIVE, ask the user whether to proceed, | |
| 1866 | *STATPTR is used to store the stat information if the file exists. | 1868 | and bypass the error if the user says to go ahead. |
| 1867 | If the file does not exist, STATPTR->st_mode is set to 0. | ||
| 1868 | If STATPTR is null, we don't store into it. | ||
| 1869 | |||
| 1870 | If QUICK, ask for y or n, not yes or no. */ | 1869 | If QUICK, ask for y or n, not yes or no. */ |
| 1871 | 1870 | ||
| 1872 | static void | 1871 | static void |
| 1873 | barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, | 1872 | barf_or_query_if_file_exists (Lisp_Object absname, bool known_to_exist, |
| 1874 | bool interactive, struct stat *statptr, | 1873 | const char *querystring, bool interactive, |
| 1875 | bool quick) | 1874 | bool quick) |
| 1876 | { | 1875 | { |
| 1877 | Lisp_Object tem, encoded_filename; | 1876 | Lisp_Object tem, encoded_filename; |
| @@ -1880,14 +1879,16 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, | |||
| 1880 | 1879 | ||
| 1881 | encoded_filename = ENCODE_FILE (absname); | 1880 | encoded_filename = ENCODE_FILE (absname); |
| 1882 | 1881 | ||
| 1883 | /* `stat' is a good way to tell whether the file exists, | 1882 | if (! known_to_exist && lstat (SSDATA (encoded_filename), &statbuf) == 0) |
| 1884 | regardless of what access permissions it has. */ | ||
| 1885 | if (lstat (SSDATA (encoded_filename), &statbuf) >= 0) | ||
| 1886 | { | 1883 | { |
| 1887 | if (S_ISDIR (statbuf.st_mode)) | 1884 | if (S_ISDIR (statbuf.st_mode)) |
| 1888 | xsignal2 (Qfile_error, | 1885 | xsignal2 (Qfile_error, |
| 1889 | build_string ("File is a directory"), absname); | 1886 | build_string ("File is a directory"), absname); |
| 1887 | known_to_exist = true; | ||
| 1888 | } | ||
| 1890 | 1889 | ||
| 1890 | if (known_to_exist) | ||
| 1891 | { | ||
| 1891 | if (! interactive) | 1892 | if (! interactive) |
| 1892 | xsignal2 (Qfile_already_exists, | 1893 | xsignal2 (Qfile_already_exists, |
| 1893 | build_string ("File already exists"), absname); | 1894 | build_string ("File already exists"), absname); |
| @@ -1902,15 +1903,7 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, | |||
| 1902 | if (NILP (tem)) | 1903 | if (NILP (tem)) |
| 1903 | xsignal2 (Qfile_already_exists, | 1904 | xsignal2 (Qfile_already_exists, |
| 1904 | build_string ("File already exists"), absname); | 1905 | build_string ("File already exists"), absname); |
| 1905 | if (statptr) | ||
| 1906 | *statptr = statbuf; | ||
| 1907 | } | 1906 | } |
| 1908 | else | ||
| 1909 | { | ||
| 1910 | if (statptr) | ||
| 1911 | statptr->st_mode = 0; | ||
| 1912 | } | ||
| 1913 | return; | ||
| 1914 | } | 1907 | } |
| 1915 | 1908 | ||
| 1916 | DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6, | 1909 | DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6, |
| @@ -1937,16 +1930,21 @@ A prefix arg makes KEEP-TIME non-nil. | |||
| 1937 | If PRESERVE-UID-GID is non-nil, we try to transfer the | 1930 | If PRESERVE-UID-GID is non-nil, we try to transfer the |
| 1938 | uid and gid of FILE to NEWNAME. | 1931 | uid and gid of FILE to NEWNAME. |
| 1939 | 1932 | ||
| 1940 | If PRESERVE-EXTENDED-ATTRIBUTES is non-nil, we try to copy additional | 1933 | If PRESERVE-PERMISSIONS is non-nil, copy permissions of FILE to NEWNAME; |
| 1941 | attributes of FILE to NEWNAME, such as its SELinux context and ACL | 1934 | this includes the file modes, along with ACL entries and SELinux |
| 1942 | entries (depending on how Emacs was built). */) | 1935 | context if present. Otherwise, if NEWNAME is created its file |
| 1943 | (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, Lisp_Object keep_time, Lisp_Object preserve_uid_gid, Lisp_Object preserve_extended_attributes) | 1936 | permission bits are those of FILE, masked by the default file |
| 1937 | permissions. */) | ||
| 1938 | (Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, | ||
| 1939 | Lisp_Object keep_time, Lisp_Object preserve_uid_gid, | ||
| 1940 | Lisp_Object preserve_permissions) | ||
| 1944 | { | 1941 | { |
| 1945 | struct stat out_st; | ||
| 1946 | Lisp_Object handler; | 1942 | Lisp_Object handler; |
| 1947 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 1943 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 1948 | ptrdiff_t count = SPECPDL_INDEX (); | 1944 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1949 | Lisp_Object encoded_file, encoded_newname; | 1945 | Lisp_Object encoded_file, encoded_newname; |
| 1946 | bool already_exists = false; | ||
| 1947 | mode_t new_mask; | ||
| 1950 | #if HAVE_LIBSELINUX | 1948 | #if HAVE_LIBSELINUX |
| 1951 | security_context_t con; | 1949 | security_context_t con; |
| 1952 | int conlength = 0; | 1950 | int conlength = 0; |
| @@ -1981,22 +1979,20 @@ entries (depending on how Emacs was built). */) | |||
| 1981 | if (!NILP (handler)) | 1979 | if (!NILP (handler)) |
| 1982 | RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname, | 1980 | RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname, |
| 1983 | ok_if_already_exists, keep_time, preserve_uid_gid, | 1981 | ok_if_already_exists, keep_time, preserve_uid_gid, |
| 1984 | preserve_extended_attributes)); | 1982 | preserve_permissions)); |
| 1985 | 1983 | ||
| 1986 | encoded_file = ENCODE_FILE (file); | 1984 | encoded_file = ENCODE_FILE (file); |
| 1987 | encoded_newname = ENCODE_FILE (newname); | 1985 | encoded_newname = ENCODE_FILE (newname); |
| 1988 | 1986 | ||
| 1987 | #ifdef WINDOWSNT | ||
| 1989 | if (NILP (ok_if_already_exists) | 1988 | if (NILP (ok_if_already_exists) |
| 1990 | || INTEGERP (ok_if_already_exists)) | 1989 | || INTEGERP (ok_if_already_exists)) |
| 1991 | barf_or_query_if_file_exists (newname, "copy to it", | 1990 | barf_or_query_if_file_exists (newname, false, "copy to it", |
| 1992 | INTEGERP (ok_if_already_exists), &out_st, 0); | 1991 | INTEGERP (ok_if_already_exists), false); |
| 1993 | else if (stat (SSDATA (encoded_newname), &out_st) < 0) | ||
| 1994 | out_st.st_mode = 0; | ||
| 1995 | 1992 | ||
| 1996 | #ifdef WINDOWSNT | ||
| 1997 | result = w32_copy_file (SSDATA (encoded_file), SSDATA (encoded_newname), | 1993 | result = w32_copy_file (SSDATA (encoded_file), SSDATA (encoded_newname), |
| 1998 | !NILP (keep_time), !NILP (preserve_uid_gid), | 1994 | !NILP (keep_time), !NILP (preserve_uid_gid), |
| 1999 | !NILP (preserve_extended_attributes)); | 1995 | !NILP (preserve_permissions)); |
| 2000 | switch (result) | 1996 | switch (result) |
| 2001 | { | 1997 | { |
| 2002 | case -1: | 1998 | case -1: |
| @@ -2022,7 +2018,7 @@ entries (depending on how Emacs was built). */) | |||
| 2022 | if (fstat (ifd, &st) != 0) | 2018 | if (fstat (ifd, &st) != 0) |
| 2023 | report_file_error ("Input file status", file); | 2019 | report_file_error ("Input file status", file); |
| 2024 | 2020 | ||
| 2025 | if (!NILP (preserve_extended_attributes)) | 2021 | if (!NILP (preserve_permissions)) |
| 2026 | { | 2022 | { |
| 2027 | #if HAVE_LIBSELINUX | 2023 | #if HAVE_LIBSELINUX |
| 2028 | if (is_selinux_enabled ()) | 2024 | if (is_selinux_enabled ()) |
| @@ -2034,32 +2030,44 @@ entries (depending on how Emacs was built). */) | |||
| 2034 | #endif | 2030 | #endif |
| 2035 | } | 2031 | } |
| 2036 | 2032 | ||
| 2037 | if (out_st.st_mode != 0 | ||
| 2038 | && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) | ||
| 2039 | report_file_errno ("Input and output files are the same", | ||
| 2040 | list2 (file, newname), 0); | ||
| 2041 | |||
| 2042 | /* We can copy only regular files. */ | 2033 | /* We can copy only regular files. */ |
| 2043 | if (!S_ISREG (st.st_mode)) | 2034 | if (!S_ISREG (st.st_mode)) |
| 2044 | report_file_errno ("Non-regular file", file, | 2035 | report_file_errno ("Non-regular file", file, |
| 2045 | S_ISDIR (st.st_mode) ? EISDIR : EINVAL); | 2036 | S_ISDIR (st.st_mode) ? EISDIR : EINVAL); |
| 2046 | 2037 | ||
| 2047 | { | ||
| 2048 | #ifndef MSDOS | 2038 | #ifndef MSDOS |
| 2049 | int new_mask = st.st_mode & (!NILP (preserve_uid_gid) ? 0600 : 0666); | 2039 | new_mask = st.st_mode & (!NILP (preserve_uid_gid) ? 0700 : 0777); |
| 2050 | #else | 2040 | #else |
| 2051 | int new_mask = S_IREAD | S_IWRITE; | 2041 | new_mask = S_IREAD | S_IWRITE; |
| 2052 | #endif | 2042 | #endif |
| 2053 | ofd = emacs_open (SSDATA (encoded_newname), | 2043 | |
| 2054 | (O_WRONLY | O_TRUNC | O_CREAT | 2044 | ofd = emacs_open (SSDATA (encoded_newname), O_WRONLY | O_CREAT | O_EXCL, |
| 2055 | | (NILP (ok_if_already_exists) ? O_EXCL : 0)), | 2045 | new_mask); |
| 2056 | new_mask); | 2046 | if (ofd < 0 && errno == EEXIST) |
| 2057 | } | 2047 | { |
| 2048 | if (NILP (ok_if_already_exists) || INTEGERP (ok_if_already_exists)) | ||
| 2049 | barf_or_query_if_file_exists (newname, true, "copy to it", | ||
| 2050 | INTEGERP (ok_if_already_exists), false); | ||
| 2051 | already_exists = true; | ||
| 2052 | ofd = emacs_open (SSDATA (encoded_newname), O_WRONLY, 0); | ||
| 2053 | } | ||
| 2058 | if (ofd < 0) | 2054 | if (ofd < 0) |
| 2059 | report_file_error ("Opening output file", newname); | 2055 | report_file_error ("Opening output file", newname); |
| 2060 | 2056 | ||
| 2061 | record_unwind_protect_int (close_file_unwind, ofd); | 2057 | record_unwind_protect_int (close_file_unwind, ofd); |
| 2062 | 2058 | ||
| 2059 | if (already_exists) | ||
| 2060 | { | ||
| 2061 | struct stat out_st; | ||
| 2062 | if (fstat (ofd, &out_st) != 0) | ||
| 2063 | report_file_error ("Output file status", newname); | ||
| 2064 | if (st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) | ||
| 2065 | report_file_errno ("Input and output files are the same", | ||
| 2066 | list2 (file, newname), 0); | ||
| 2067 | if (ftruncate (ofd, 0) != 0) | ||
| 2068 | report_file_error ("Truncating output file", newname); | ||
| 2069 | } | ||
| 2070 | |||
| 2063 | immediate_quit = 1; | 2071 | immediate_quit = 1; |
| 2064 | QUIT; | 2072 | QUIT; |
| 2065 | while ((n = emacs_read (ifd, buf, sizeof buf)) > 0) | 2073 | while ((n = emacs_read (ifd, buf, sizeof buf)) > 0) |
| @@ -2071,26 +2079,41 @@ entries (depending on how Emacs was built). */) | |||
| 2071 | /* Preserve the original file permissions, and if requested, also its | 2079 | /* Preserve the original file permissions, and if requested, also its |
| 2072 | owner and group. */ | 2080 | owner and group. */ |
| 2073 | { | 2081 | { |
| 2074 | mode_t mode_mask = 07777; | 2082 | mode_t preserved_permissions = st.st_mode & 07777; |
| 2083 | mode_t default_permissions = st.st_mode & 0777 & ~realmask; | ||
| 2075 | if (!NILP (preserve_uid_gid)) | 2084 | if (!NILP (preserve_uid_gid)) |
| 2076 | { | 2085 | { |
| 2077 | /* Attempt to change owner and group. If that doesn't work | 2086 | /* Attempt to change owner and group. If that doesn't work |
| 2078 | attempt to change just the group, as that is sometimes allowed. | 2087 | attempt to change just the group, as that is sometimes allowed. |
| 2079 | Adjust the mode mask to eliminate setuid or setgid bits | 2088 | Adjust the mode mask to eliminate setuid or setgid bits |
| 2080 | that are inappropriate if the owner and group are wrong. */ | 2089 | or group permissions bits that are inappropriate if the |
| 2090 | owner or group are wrong. */ | ||
| 2081 | if (fchown (ofd, st.st_uid, st.st_gid) != 0) | 2091 | if (fchown (ofd, st.st_uid, st.st_gid) != 0) |
| 2082 | { | 2092 | { |
| 2083 | mode_mask &= ~06000; | ||
| 2084 | if (fchown (ofd, -1, st.st_gid) == 0) | 2093 | if (fchown (ofd, -1, st.st_gid) == 0) |
| 2085 | mode_mask |= 02000; | 2094 | preserved_permissions &= ~04000; |
| 2095 | else | ||
| 2096 | { | ||
| 2097 | preserved_permissions &= ~06000; | ||
| 2098 | |||
| 2099 | /* Copy the other bits to the group bits, since the | ||
| 2100 | group is wrong. */ | ||
| 2101 | preserved_permissions &= ~070; | ||
| 2102 | preserved_permissions |= (preserved_permissions & 7) << 3; | ||
| 2103 | default_permissions &= ~070; | ||
| 2104 | default_permissions |= (default_permissions & 7) << 3; | ||
| 2105 | } | ||
| 2086 | } | 2106 | } |
| 2087 | } | 2107 | } |
| 2088 | 2108 | ||
| 2089 | switch (!NILP (preserve_extended_attributes) | 2109 | switch (!NILP (preserve_permissions) |
| 2090 | ? qcopy_acl (SSDATA (encoded_file), ifd, | 2110 | ? qcopy_acl (SSDATA (encoded_file), ifd, |
| 2091 | SSDATA (encoded_newname), ofd, | 2111 | SSDATA (encoded_newname), ofd, |
| 2092 | st.st_mode & mode_mask) | 2112 | preserved_permissions) |
| 2093 | : fchmod (ofd, st.st_mode & mode_mask)) | 2113 | : (already_exists |
| 2114 | || (new_mask & ~realmask) == default_permissions) | ||
| 2115 | ? 0 | ||
| 2116 | : fchmod (ofd, default_permissions)) | ||
| 2094 | { | 2117 | { |
| 2095 | case -2: report_file_error ("Copying permissions from", file); | 2118 | case -2: report_file_error ("Copying permissions from", file); |
| 2096 | case -1: report_file_error ("Copying permissions to", newname); | 2119 | case -1: report_file_error ("Copying permissions to", newname); |
| @@ -2307,8 +2330,8 @@ This is what happens in interactive use with M-x. */) | |||
| 2307 | #endif | 2330 | #endif |
| 2308 | if (NILP (ok_if_already_exists) | 2331 | if (NILP (ok_if_already_exists) |
| 2309 | || INTEGERP (ok_if_already_exists)) | 2332 | || INTEGERP (ok_if_already_exists)) |
| 2310 | barf_or_query_if_file_exists (newname, "rename to it", | 2333 | barf_or_query_if_file_exists (newname, false, "rename to it", |
| 2311 | INTEGERP (ok_if_already_exists), 0, 0); | 2334 | INTEGERP (ok_if_already_exists), false); |
| 2312 | if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) | 2335 | if (rename (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) |
| 2313 | { | 2336 | { |
| 2314 | int rename_errno = errno; | 2337 | int rename_errno = errno; |
| @@ -2387,8 +2410,8 @@ This is what happens in interactive use with M-x. */) | |||
| 2387 | 2410 | ||
| 2388 | if (NILP (ok_if_already_exists) | 2411 | if (NILP (ok_if_already_exists) |
| 2389 | || INTEGERP (ok_if_already_exists)) | 2412 | || INTEGERP (ok_if_already_exists)) |
| 2390 | barf_or_query_if_file_exists (newname, "make it a new name", | 2413 | barf_or_query_if_file_exists (newname, false, "make it a new name", |
| 2391 | INTEGERP (ok_if_already_exists), 0, 0); | 2414 | INTEGERP (ok_if_already_exists), false); |
| 2392 | 2415 | ||
| 2393 | unlink (SSDATA (newname)); | 2416 | unlink (SSDATA (newname)); |
| 2394 | if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) | 2417 | if (link (SSDATA (encoded_file), SSDATA (encoded_newname)) < 0) |
| @@ -2449,8 +2472,8 @@ This happens for interactive use with M-x. */) | |||
| 2449 | 2472 | ||
| 2450 | if (NILP (ok_if_already_exists) | 2473 | if (NILP (ok_if_already_exists) |
| 2451 | || INTEGERP (ok_if_already_exists)) | 2474 | || INTEGERP (ok_if_already_exists)) |
| 2452 | barf_or_query_if_file_exists (linkname, "make it a link", | 2475 | barf_or_query_if_file_exists (linkname, false, "make it a link", |
| 2453 | INTEGERP (ok_if_already_exists), 0, 0); | 2476 | INTEGERP (ok_if_already_exists), false); |
| 2454 | if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0) | 2477 | if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0) |
| 2455 | { | 2478 | { |
| 2456 | /* If we didn't complain already, silently delete existing file. */ | 2479 | /* If we didn't complain already, silently delete existing file. */ |
| @@ -3137,10 +3160,17 @@ The argument MODE should be an integer; only the low 9 bits are used. | |||
| 3137 | This setting is inherited by subprocesses. */) | 3160 | This setting is inherited by subprocesses. */) |
| 3138 | (Lisp_Object mode) | 3161 | (Lisp_Object mode) |
| 3139 | { | 3162 | { |
| 3163 | mode_t oldrealmask, oldumask, newumask; | ||
| 3140 | CHECK_NUMBER (mode); | 3164 | CHECK_NUMBER (mode); |
| 3165 | oldrealmask = realmask; | ||
| 3166 | newumask = ~ XINT (mode) & 0777; | ||
| 3141 | 3167 | ||
| 3142 | umask ((~ XINT (mode)) & 0777); | 3168 | block_input (); |
| 3169 | realmask = newumask; | ||
| 3170 | oldumask = umask (newumask); | ||
| 3171 | unblock_input (); | ||
| 3143 | 3172 | ||
| 3173 | eassert (oldumask == oldrealmask); | ||
| 3144 | return Qnil; | 3174 | return Qnil; |
| 3145 | } | 3175 | } |
| 3146 | 3176 | ||
| @@ -3149,14 +3179,7 @@ DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0, | |||
| 3149 | The value is an integer. */) | 3179 | The value is an integer. */) |
| 3150 | (void) | 3180 | (void) |
| 3151 | { | 3181 | { |
| 3152 | mode_t realmask; | ||
| 3153 | Lisp_Object value; | 3182 | Lisp_Object value; |
| 3154 | |||
| 3155 | block_input (); | ||
| 3156 | realmask = umask (0); | ||
| 3157 | umask (realmask); | ||
| 3158 | unblock_input (); | ||
| 3159 | |||
| 3160 | XSETINT (value, (~ realmask) & 0777); | 3183 | XSETINT (value, (~ realmask) & 0777); |
| 3161 | return value; | 3184 | return value; |
| 3162 | } | 3185 | } |
| @@ -4697,7 +4720,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename, | |||
| 4697 | filename = Fexpand_file_name (filename, Qnil); | 4720 | filename = Fexpand_file_name (filename, Qnil); |
| 4698 | 4721 | ||
| 4699 | if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl)) | 4722 | if (!NILP (mustbenew) && !EQ (mustbenew, Qexcl)) |
| 4700 | barf_or_query_if_file_exists (filename, "overwrite", 1, 0, 1); | 4723 | barf_or_query_if_file_exists (filename, false, "overwrite", true, true); |
| 4701 | 4724 | ||
| 4702 | if (STRINGP (visit)) | 4725 | if (STRINGP (visit)) |
| 4703 | visit_file = Fexpand_file_name (visit, Qnil); | 4726 | visit_file = Fexpand_file_name (visit, Qnil); |
| @@ -5765,6 +5788,9 @@ Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filena | |||
| 5765 | void | 5788 | void |
| 5766 | init_fileio (void) | 5789 | init_fileio (void) |
| 5767 | { | 5790 | { |
| 5791 | realmask = umask (0); | ||
| 5792 | umask (realmask); | ||
| 5793 | |||
| 5768 | valid_timestamp_file_system = 0; | 5794 | valid_timestamp_file_system = 0; |
| 5769 | 5795 | ||
| 5770 | /* fsync can be a significant performance hit. Often it doesn't | 5796 | /* fsync can be a significant performance hit. Often it doesn't |