X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/b9345dfd4b5479ec624f1870723a8ea5c9c719e7..b6e64c4136905ab4f00194c360bd6cd3cd767b9c:/src/fileio.c
diff --git a/src/fileio.c b/src/fileio.c
index 7e6fd8c82a..5f7a8ad397 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -62,7 +62,7 @@ along with GNU Emacs. If not, see . */
#ifdef DOS_NT
/* On Windows, drive letters must be alphabetic - on DOS, the Netware
- redirector allows the six letters between 'Z' and 'a' as well. */
+ redirector allows the six letters between 'Z' and 'a' as well. */
#ifdef MSDOS
#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
#endif
@@ -70,7 +70,7 @@ along with GNU Emacs. If not, see . */
#define IS_DRIVE(x) isalpha ((unsigned char) (x))
#endif
/* Need to lower-case the drive letter, or else expanded
- filenames will sometimes compare inequal, because
+ filenames will sometimes compare unequal, because
`expand-file-name' doesn't always down-case the drive letter. */
#define DRIVE_LETTER(x) (tolower ((unsigned char) (x)))
#endif
@@ -338,7 +338,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef DOS_NT
- /* only recognise drive specifier at the beginning */
+ /* only recognize drive specifier at the beginning */
&& !(p[-1] == ':'
/* handle the "/:d:foo" and "/:foo" cases correctly */
&& ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg))
@@ -401,7 +401,7 @@ or the entire name if it contains no slash. */)
while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef DOS_NT
- /* only recognise drive specifier at beginning */
+ /* only recognize drive specifier at beginning */
&& !(p[-1] == ':'
/* handle the "/:d:foo" case correctly */
&& (p == beg + 2 || (p == beg + 4 && IS_DIRECTORY_SEP (*beg))))
@@ -440,11 +440,9 @@ get a current directory to run processes in. */)
static char *
file_name_as_directory (char *out, const char *in)
{
- int size = strlen (in) - 1;
+ ptrdiff_t len = strlen (in);
- strcpy (out, in);
-
- if (size < 0)
+ if (len == 0)
{
out[0] = '.';
out[1] = '/';
@@ -452,11 +450,13 @@ file_name_as_directory (char *out, const char *in)
return out;
}
+ strcpy (out, in);
+
/* For Unix syntax, Append a slash if necessary */
- if (!IS_DIRECTORY_SEP (out[size]))
+ if (!IS_DIRECTORY_SEP (out[len - 1]))
{
- out[size + 1] = DIRECTORY_SEP;
- out[size + 2] = '\0';
+ out[len] = DIRECTORY_SEP;
+ out[len + 1] = '\0';
}
#ifdef DOS_NT
dostounix_filename (out);
@@ -503,7 +503,7 @@ For a Unix-syntax file name, just appends a slash. */)
static int
directory_file_name (char *src, char *dst)
{
- long slen;
+ ptrdiff_t slen;
slen = strlen (src);
@@ -587,9 +587,9 @@ make_temp_name (Lisp_Object prefix, int base64_p)
{
Lisp_Object val;
int len, clen;
- int pid;
+ printmax_t pid;
char *p, *data;
- char pidbuf[20];
+ char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
int pidlen;
CHECK_STRING (prefix);
@@ -599,7 +599,7 @@ make_temp_name (Lisp_Object prefix, int base64_p)
three are incremented if the file already exists. This ensures
262144 unique file names per PID per PREFIX. */
- pid = (int) getpid ();
+ pid = getpid ();
if (base64_p)
{
@@ -611,8 +611,7 @@ make_temp_name (Lisp_Object prefix, int base64_p)
else
{
#ifdef HAVE_LONG_FILE_NAMES
- sprintf (pidbuf, "%d", pid);
- pidlen = strlen (pidbuf);
+ pidlen = sprintf (pidbuf, "%"pMd, pid);
#else
pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;
@@ -643,7 +642,7 @@ make_temp_name (Lisp_Object prefix, int base64_p)
if (!make_temp_name_count_initialized_p)
{
- make_temp_name_count = (unsigned) time (NULL);
+ make_temp_name_count = time (NULL);
make_temp_name_count_initialized_p = 1;
}
@@ -737,14 +736,14 @@ filesystem tree, not (expand-file-name ".." dirname). */)
/* This should only point to alloca'd data. */
char *target;
- int tlen;
+ ptrdiff_t tlen;
struct passwd *pw;
#ifdef DOS_NT
int drive = 0;
int collapse_newdir = 1;
int is_escaped = 0;
#endif /* DOS_NT */
- int length;
+ ptrdiff_t length;
Lisp_Object handler, result;
int multibyte;
Lisp_Object hdir;
@@ -1314,7 +1313,7 @@ See also the function `substitute-in-file-name'.")
unsigned char *nm;
register unsigned char *newdir, *p, *o;
- int tlen;
+ ptrdiff_t tlen;
unsigned char *target;
struct passwd *pw;
int lose;
@@ -1366,7 +1365,7 @@ See also the function `substitute-in-file-name'.")
unsigned char *user = nm + 1;
/* Find end of name. */
unsigned char *ptr = (unsigned char *) strchr (user, '/');
- int len = ptr ? ptr - user : strlen (user);
+ ptrdiff_t len = ptr ? ptr - user : strlen (user);
/* Copy the user name into temp storage. */
o = (unsigned char *) alloca (len + 1);
memcpy (o, user, len);
@@ -1473,7 +1472,7 @@ search_embedded_absfilename (char *nm, char *endp)
if ((0
|| IS_DIRECTORY_SEP (p[-1]))
&& file_name_absolute_p (p)
-#if defined (WINDOWSNT) || defined(CYGWIN)
+#if defined (WINDOWSNT) || defined (CYGWIN)
/* // at start of file name is meaningful in Apollo,
WindowsNT and Cygwin systems. */
&& !(IS_DIRECTORY_SEP (p[0]) && p - 1 == nm)
@@ -1554,7 +1553,7 @@ those `/' is discarded. */)
if (p)
/* Start over with the new string, so we check the file-name-handler
again. Important with filenames like "/home/foo//:/hello///there"
- which whould substitute to "/:/hello///there" rather than "/there". */
+ which would substitute to "/:/hello///there" rather than "/there". */
return Fsubstitute_in_file_name
(make_specified_string (p, -1, endp - p, multibyte));
@@ -1672,7 +1671,7 @@ those `/' is discarded. */)
else
{
Lisp_Object orig, decoded;
- int orig_length, decoded_length;
+ ptrdiff_t orig_length, decoded_length;
orig_length = strlen (o);
orig = make_unibyte_string (o, orig_length);
decoded = DECODE_FILE (orig);
@@ -1756,6 +1755,10 @@ barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
regardless of what access permissions it has. */
if (lstat (SSDATA (encoded_filename), &statbuf) >= 0)
{
+ if (S_ISDIR (statbuf.st_mode))
+ xsignal2 (Qfile_error,
+ build_string ("File is a directory"), absname);
+
if (! interactive)
xsignal2 (Qfile_already_exists,
build_string ("File already exists"), absname);
@@ -1934,10 +1937,19 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
| (NILP (ok_if_already_exists) ? O_EXCL : 0),
S_IREAD | S_IWRITE);
#else /* not MSDOS */
- ofd = emacs_open (SSDATA (encoded_newname),
- O_WRONLY | O_TRUNC | O_CREAT
- | (NILP (ok_if_already_exists) ? O_EXCL : 0),
- 0666);
+ {
+ int new_mask = 0666;
+ if (input_file_statable_p)
+ {
+ if (!NILP (preserve_uid_gid))
+ new_mask = 0600;
+ new_mask &= st.st_mode;
+ }
+ ofd = emacs_open (SSDATA (encoded_newname),
+ (O_WRONLY | O_TRUNC | O_CREAT
+ | (NILP (ok_if_already_exists) ? O_EXCL : 0)),
+ new_mask);
+ }
#endif /* not MSDOS */
if (ofd < 0)
report_file_error ("Opening output file", Fcons (newname, Qnil));
@@ -1956,9 +1968,21 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
owner and group. */
if (input_file_statable_p)
{
- if (!NILP (preserve_uid_gid) && fchown (ofd, st.st_uid, st.st_gid) != 0)
- report_file_error ("Doing chown", Fcons (newname, Qnil));
- if (fchmod (ofd, st.st_mode & 07777) != 0)
+ int mode_mask = 07777;
+ if (!NILP (preserve_uid_gid))
+ {
+ /* Attempt to change owner and group. If that doesn't work
+ attempt to change just the group, as that is sometimes allowed.
+ Adjust the mode mask to eliminate setuid or setgid bits
+ that are inappropriate if the owner and group are wrong. */
+ if (fchown (ofd, st.st_uid, st.st_gid) != 0)
+ {
+ mode_mask &= ~06000;
+ if (fchown (ofd, -1, st.st_gid) == 0)
+ mode_mask |= 02000;
+ }
+ }
+ if (fchmod (ofd, st.st_mode & mode_mask) != 0)
report_file_error ("Doing chmod", Fcons (newname, Qnil));
}
#endif /* not MSDOS */
@@ -2473,7 +2497,7 @@ See also `file-exists-p' and `file-attributes'. */)
absname = ENCODE_FILE (absname);
-#if defined(DOS_NT) || defined(macintosh)
+#if defined (DOS_NT) || defined (macintosh)
/* Under MS-DOS, Windows, and Macintosh, open does not work for
directories. */
if (access (SDATA (absname), 0) == 0)
@@ -2758,7 +2782,7 @@ if file does not exist, is not accessible, or SELinux is disabled */)
}
#endif
- return Flist (sizeof(values) / sizeof(values[0]), values);
+ return Flist (sizeof (values) / sizeof (values[0]), values);
}
DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
@@ -2829,7 +2853,7 @@ is disabled. */)
context_free (parsed_con);
}
else
- report_file_error("Doing lgetfilecon", Fcons (absname, Qnil));
+ report_file_error ("Doing lgetfilecon", Fcons (absname, Qnil));
if (con)
freecon (con);
@@ -2888,7 +2912,7 @@ symbolic notation, like the `chmod' command from GNU Coreutils. */)
encoded_absname = ENCODE_FILE (absname);
- if (chmod (SSDATA (encoded_absname), XINT (mode)) < 0)
+ if (chmod (SSDATA (encoded_absname), XINT (mode) & 07777) < 0)
report_file_error ("Doing chmod", Fcons (absname, Qnil));
return Qnil;
@@ -3109,6 +3133,21 @@ read_non_regular_quit (Lisp_Object ignore)
return Qnil;
}
+/* Reposition FD to OFFSET, based on WHENCE. This acts like lseek
+ except that it also tests for OFFSET being out of lseek's range. */
+static off_t
+emacs_lseek (int fd, EMACS_INT offset, int whence)
+{
+ /* Use "&" rather than "&&" to suppress a bogus GCC warning; see
+ . */
+ if (! ((TYPE_MINIMUM (off_t) <= offset) & (offset <= TYPE_MAXIMUM (off_t))))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ return lseek (fd, offset, whence);
+}
+
DEFUN ("insert-file-contents", Finsert_file_contents, Sinsert_file_contents,
1, 5, 0,
@@ -3140,6 +3179,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
EMACS_INT inserted = 0;
int nochange = 0;
register EMACS_INT how_much;
+ off_t beg_offset, end_offset;
register EMACS_INT unprocessed;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
@@ -3147,6 +3187,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
Lisp_Object p;
EMACS_INT total = 0;
int not_regular = 0;
+ int save_errno = 0;
char read_buf[READ_BUF_SIZE];
struct coding_system coding;
char buffer[1 << 14];
@@ -3210,9 +3251,11 @@ variable `last-coding-system-used' to the coding system actually used. */)
#endif /* WINDOWSNT */
{
badopen:
+ save_errno = errno;
if (NILP (visit))
report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
st.st_mtime = -1;
+ st.st_size = -1;
how_much = 0;
if (!NILP (Vcoding_system_for_read))
Fset (Qbuffer_file_coding_system, Vcoding_system_for_read);
@@ -3245,15 +3288,6 @@ variable `last-coding-system-used' to the coding system actually used. */)
record_unwind_protect (close_file_unwind, make_number (fd));
- /* Check whether the size is too large or negative, which can happen on a
- platform that allows file sizes greater than the maximum off_t value. */
- if (! not_regular
- && ! (0 <= st.st_size && st.st_size <= MOST_POSITIVE_FIXNUM))
- error ("Maximum buffer size exceeded");
-
- /* Prevent redisplay optimizations. */
- current_buffer->clip_changed = 1;
-
if (!NILP (visit))
{
if (!NILP (beg) || !NILP (end))
@@ -3263,26 +3297,64 @@ variable `last-coding-system-used' to the coding system actually used. */)
}
if (!NILP (beg))
- CHECK_NUMBER (beg);
+ {
+ if (! (RANGED_INTEGERP (0, beg, TYPE_MAXIMUM (off_t))))
+ wrong_type_argument (intern ("file-offset"), beg);
+ beg_offset = XFASTINT (beg);
+ }
else
- XSETFASTINT (beg, 0);
+ beg_offset = 0;
if (!NILP (end))
- CHECK_NUMBER (end);
+ {
+ if (! (RANGED_INTEGERP (0, end, TYPE_MAXIMUM (off_t))))
+ wrong_type_argument (intern ("file-offset"), end);
+ end_offset = XFASTINT (end);
+ }
else
{
- if (! not_regular)
+ if (not_regular)
+ end_offset = TYPE_MAXIMUM (off_t);
+ else
{
- XSETINT (end, st.st_size);
+ end_offset = st.st_size;
+
+ /* A negative size can happen on a platform that allows file
+ sizes greater than the maximum off_t value. */
+ if (end_offset < 0)
+ buffer_overflow ();
/* The file size returned from stat may be zero, but data
may be readable nonetheless, for example when this is a
file in the /proc filesystem. */
- if (st.st_size == 0)
- XSETINT (end, READ_BUF_SIZE);
+ if (end_offset == 0)
+ end_offset = READ_BUF_SIZE;
}
}
+ /* Check now whether the buffer will become too large,
+ in the likely case where the file's length is not changing.
+ This saves a lot of needless work before a buffer overflow. */
+ if (! not_regular)
+ {
+ /* The likely offset where we will stop reading. We could read
+ more (or less), if the file grows (or shrinks) as we read it. */
+ off_t likely_end = min (end_offset, st.st_size);
+
+ if (beg_offset < likely_end)
+ {
+ ptrdiff_t buf_bytes =
+ Z_BYTE - (!NILP (replace) ? ZV_BYTE - BEGV_BYTE : 0);
+ ptrdiff_t buf_growth_max = BUF_BYTES_MAX - buf_bytes;
+ off_t likely_growth = likely_end - beg_offset;
+ if (buf_growth_max < likely_growth)
+ buffer_overflow ();
+ }
+ }
+
+ /* Prevent redisplay optimizations. */
+ current_buffer->clip_changed = 1;
+
if (EQ (Vcoding_system_for_read, Qauto_save_coding))
{
coding_system = coding_inherit_eol_type (Qutf_8_emacs, Qunix);
@@ -3317,7 +3389,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
nread = emacs_read (fd, read_buf, 1024);
if (nread >= 0)
{
- if (lseek (fd, st.st_size - (1024 * 3), 0) < 0)
+ if (lseek (fd, st.st_size - (1024 * 3), SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
nread += emacs_read (fd, read_buf + nread, 1024 * 3);
@@ -3361,7 +3433,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
specpdl_ptr--;
/* Rewind the file for the actual read done later. */
- if (lseek (fd, 0, 0) < 0)
+ if (lseek (fd, 0, SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
}
@@ -3426,9 +3498,9 @@ variable `last-coding-system-used' to the coding system actually used. */)
give up on handling REPLACE in the optimized way. */
int giveup_match_end = 0;
- if (XINT (beg) != 0)
+ if (beg_offset != 0)
{
- if (lseek (fd, XINT (beg), 0) < 0)
+ if (lseek (fd, beg_offset, SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
}
@@ -3476,7 +3548,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
immediate_quit = 0;
/* If the file matches the buffer completely,
there's no need to replace anything. */
- if (same_at_start - BEGV_BYTE == XINT (end))
+ if (same_at_start - BEGV_BYTE == end_offset - beg_offset)
{
emacs_close (fd);
specpdl_ptr--;
@@ -3491,16 +3563,17 @@ variable `last-coding-system-used' to the coding system actually used. */)
already found that decoding is necessary, don't waste time. */
while (!giveup_match_end)
{
- EMACS_INT total_read, nread, bufpos, curpos, trial;
+ int total_read, nread, bufpos, trial;
+ off_t curpos;
/* At what file position are we now scanning? */
- curpos = XINT (end) - (ZV_BYTE - same_at_end);
+ curpos = end_offset - (ZV_BYTE - same_at_end);
/* If the entire file matches the buffer tail, stop the scan. */
if (curpos == 0)
break;
/* How much can we scan in the next step? */
trial = min (curpos, sizeof buffer);
- if (lseek (fd, curpos - trial, 0) < 0)
+ if (lseek (fd, curpos - trial, SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
@@ -3567,13 +3640,14 @@ variable `last-coding-system-used' to the coding system actually used. */)
/* Don't try to reuse the same piece of text twice. */
overlap = (same_at_start - BEGV_BYTE
- - (same_at_end + st.st_size - ZV));
+ - (same_at_end
+ + (! NILP (end) ? end_offset : st.st_size) - ZV_BYTE));
if (overlap > 0)
same_at_end += overlap;
/* Arrange to read only the nonmatching middle part of the file. */
- XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
- XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
+ beg_offset += same_at_start - BEGV_BYTE;
+ end_offset -= ZV_BYTE - same_at_end;
del_range_byte (same_at_start, same_at_end, 0);
/* Insert from the file at the proper position. */
@@ -3612,13 +3686,14 @@ variable `last-coding-system-used' to the coding system actually used. */)
int this_count = SPECPDL_INDEX ();
int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
Lisp_Object conversion_buffer;
+ struct gcpro gcpro1;
conversion_buffer = code_conversion_save (1, multibyte);
/* First read the whole file, performing code conversion into
CONVERSION_BUFFER. */
- if (lseek (fd, XINT (beg), 0) < 0)
+ if (lseek (fd, beg_offset, SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
@@ -3632,7 +3707,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
{
/* We read one bunch by one (READ_BUF_SIZE bytes) to allow
quitting while reading a huge while. */
- /* try is reserved in some compilers (Microsoft C) */
+ /* `try'' is reserved in some compilers (Microsoft C). */
EMACS_INT trytry = min (total - how_much,
READ_BUF_SIZE - unprocessed);
@@ -3785,16 +3860,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
}
if (! not_regular)
- {
- register Lisp_Object temp;
-
- total = XINT (end) - XINT (beg);
-
- /* Make sure point-max won't overflow after this insertion. */
- XSETINT (temp, total);
- if (total != XINT (temp))
- error ("Maximum buffer size exceeded");
- }
+ total = end_offset - beg_offset;
else
/* For a special file, all we can do is guess. */
total = READ_BUF_SIZE;
@@ -3815,9 +3881,9 @@ variable `last-coding-system-used' to the coding system actually used. */)
if (GAP_SIZE < total)
make_gap (total - GAP_SIZE);
- if (XINT (beg) != 0 || !NILP (replace))
+ if (beg_offset != 0 || !NILP (replace))
{
- if (lseek (fd, XINT (beg), 0) < 0)
+ if (lseek (fd, beg_offset, SEEK_SET) < 0)
report_file_error ("Setting file position",
Fcons (orig_filename, Qnil));
}
@@ -4218,6 +4284,7 @@ variable `last-coding-system-used' to the coding system actually used. */)
&& current_buffer->modtime == -1)
{
/* If visiting nonexistent file, return nil. */
+ errno = save_errno;
report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
}
@@ -4546,16 +4613,18 @@ This calls `write-region-annotate-functions' at the start, and
if (!NILP (append) && !NILP (Ffile_regular_p (filename)))
{
- long ret;
+ off_t ret;
if (NUMBERP (append))
- ret = lseek (desc, XINT (append), 1);
+ ret = emacs_lseek (desc, XINT (append), SEEK_CUR);
else
- ret = lseek (desc, 0, 2);
+ ret = lseek (desc, 0, SEEK_END);
if (ret < 0)
{
#ifdef CLASH_DETECTION
+ save_errno = errno;
if (!auto_saving) unlock_file (lockname);
+ errno = save_errno;
#endif /* CLASH_DETECTION */
UNGCPRO;
report_file_error ("Lseek error", Fcons (filename, Qnil));
@@ -4960,7 +5029,7 @@ See Info node `(elisp)Modification Time' for more details. */)
if ((st.st_mtime == b->modtime
/* If both are positive, accept them if they are off by one second. */
|| (st.st_mtime > 0 && b->modtime > 0
- && (st.st_mtime == b->modtime + 1
+ && (st.st_mtime - 1 == b->modtime
|| st.st_mtime == b->modtime - 1)))
&& (st.st_size == b->modtime_size
|| b->modtime_size < 0))
@@ -4982,15 +5051,16 @@ Next attempt to save will certainly not complain of a discrepancy. */)
DEFUN ("visited-file-modtime", Fvisited_file_modtime,
Svisited_file_modtime, 0, 0, 0,
doc: /* Return the current buffer's recorded visited file modification time.
-The value is a list of the form (HIGH LOW), like the time values
-that `file-attributes' returns. If the current buffer has no recorded
-file modification time, this function returns 0.
+The value is a list of the form (HIGH LOW), like the time values that
+`file-attributes' returns. If the current buffer has no recorded file
+modification time, this function returns 0. If the visited file
+doesn't exist, HIGH will be -1.
See Info node `(elisp)Modification Time' for more details. */)
(void)
{
if (! current_buffer->modtime)
return make_number (0);
- return make_time ((time_t) current_buffer->modtime);
+ return make_time (current_buffer->modtime);
}
DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
@@ -5005,7 +5075,7 @@ An argument specifies the modification time value to use
{
if (!NILP (time_list))
{
- current_buffer->modtime = cons_to_long (time_list);
+ CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime);
current_buffer->modtime_size = -1;
}
else
@@ -5084,11 +5154,11 @@ auto_save_1 (void)
{
if (stat (SSDATA (BVAR (current_buffer, filename)), &st) >= 0)
/* But make sure we can overwrite it later! */
- auto_save_mode_bits = st.st_mode | 0600;
+ auto_save_mode_bits = (st.st_mode | 0600) & 0777;
else if ((modes = Ffile_modes (BVAR (current_buffer, filename)),
INTEGERP (modes)))
/* Remote files don't cooperate with stat. */
- auto_save_mode_bits = XINT (modes) | 0600;
+ auto_save_mode_bits = (XINT (modes) | 0600) & 0777;
}
return
@@ -5275,7 +5345,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
EMACS_GET_TIME (before_time);
/* If we had a failure, don't try again for 20 minutes. */
- if (b->auto_save_failure_time >= 0
+ if (b->auto_save_failure_time > 0
&& EMACS_SECS (before_time) - b->auto_save_failure_time < 1200)
continue;
@@ -5354,7 +5424,7 @@ No auto-save file will be written until the buffer changes again. */)
they're not autosaved. */
BUF_AUTOSAVE_MODIFF (current_buffer) = MODIFF;
XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
- current_buffer->auto_save_failure_time = -1;
+ current_buffer->auto_save_failure_time = 0;
return Qnil;
}
@@ -5363,7 +5433,7 @@ DEFUN ("clear-buffer-auto-save-failure", Fclear_buffer_auto_save_failure,
doc: /* Clear any record of a recent auto-save failure in the current buffer. */)
(void)
{
- current_buffer->auto_save_failure_time = -1;
+ current_buffer->auto_save_failure_time = 0;
return Qnil;
}
@@ -5420,92 +5490,50 @@ Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filena
void
syms_of_fileio (void)
{
- Qoperations = intern_c_string ("operations");
- Qexpand_file_name = intern_c_string ("expand-file-name");
- Qsubstitute_in_file_name = intern_c_string ("substitute-in-file-name");
- Qdirectory_file_name = intern_c_string ("directory-file-name");
- Qfile_name_directory = intern_c_string ("file-name-directory");
- Qfile_name_nondirectory = intern_c_string ("file-name-nondirectory");
- Qunhandled_file_name_directory = intern_c_string ("unhandled-file-name-directory");
- Qfile_name_as_directory = intern_c_string ("file-name-as-directory");
- Qcopy_file = intern_c_string ("copy-file");
- Qmake_directory_internal = intern_c_string ("make-directory-internal");
- Qmake_directory = intern_c_string ("make-directory");
- Qdelete_directory_internal = intern_c_string ("delete-directory-internal");
- Qdelete_file = intern_c_string ("delete-file");
- Qrename_file = intern_c_string ("rename-file");
- Qadd_name_to_file = intern_c_string ("add-name-to-file");
- Qmake_symbolic_link = intern_c_string ("make-symbolic-link");
- Qfile_exists_p = intern_c_string ("file-exists-p");
- Qfile_executable_p = intern_c_string ("file-executable-p");
- Qfile_readable_p = intern_c_string ("file-readable-p");
- Qfile_writable_p = intern_c_string ("file-writable-p");
- Qfile_symlink_p = intern_c_string ("file-symlink-p");
- Qaccess_file = intern_c_string ("access-file");
- Qfile_directory_p = intern_c_string ("file-directory-p");
- Qfile_regular_p = intern_c_string ("file-regular-p");
- Qfile_accessible_directory_p = intern_c_string ("file-accessible-directory-p");
- Qfile_modes = intern_c_string ("file-modes");
- Qset_file_modes = intern_c_string ("set-file-modes");
- Qset_file_times = intern_c_string ("set-file-times");
- Qfile_selinux_context = intern_c_string("file-selinux-context");
- Qset_file_selinux_context = intern_c_string("set-file-selinux-context");
- Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p");
- Qinsert_file_contents = intern_c_string ("insert-file-contents");
- Qwrite_region = intern_c_string ("write-region");
- Qverify_visited_file_modtime = intern_c_string ("verify-visited-file-modtime");
- Qset_visited_file_modtime = intern_c_string ("set-visited-file-modtime");
- Qauto_save_coding = intern_c_string ("auto-save-coding");
-
- staticpro (&Qoperations);
- staticpro (&Qexpand_file_name);
- staticpro (&Qsubstitute_in_file_name);
- staticpro (&Qdirectory_file_name);
- staticpro (&Qfile_name_directory);
- staticpro (&Qfile_name_nondirectory);
- staticpro (&Qunhandled_file_name_directory);
- staticpro (&Qfile_name_as_directory);
- staticpro (&Qcopy_file);
- staticpro (&Qmake_directory_internal);
- staticpro (&Qmake_directory);
- staticpro (&Qdelete_directory_internal);
- staticpro (&Qdelete_file);
- staticpro (&Qrename_file);
- staticpro (&Qadd_name_to_file);
- staticpro (&Qmake_symbolic_link);
- staticpro (&Qfile_exists_p);
- staticpro (&Qfile_executable_p);
- staticpro (&Qfile_readable_p);
- staticpro (&Qfile_writable_p);
- staticpro (&Qaccess_file);
- staticpro (&Qfile_symlink_p);
- staticpro (&Qfile_directory_p);
- staticpro (&Qfile_regular_p);
- staticpro (&Qfile_accessible_directory_p);
- staticpro (&Qfile_modes);
- staticpro (&Qset_file_modes);
- staticpro (&Qset_file_times);
- staticpro (&Qfile_selinux_context);
- staticpro (&Qset_file_selinux_context);
- staticpro (&Qfile_newer_than_file_p);
- staticpro (&Qinsert_file_contents);
- staticpro (&Qwrite_region);
- staticpro (&Qverify_visited_file_modtime);
- staticpro (&Qset_visited_file_modtime);
- staticpro (&Qauto_save_coding);
-
- Qfile_name_history = intern_c_string ("file-name-history");
+ DEFSYM (Qoperations, "operations");
+ DEFSYM (Qexpand_file_name, "expand-file-name");
+ DEFSYM (Qsubstitute_in_file_name, "substitute-in-file-name");
+ DEFSYM (Qdirectory_file_name, "directory-file-name");
+ DEFSYM (Qfile_name_directory, "file-name-directory");
+ DEFSYM (Qfile_name_nondirectory, "file-name-nondirectory");
+ DEFSYM (Qunhandled_file_name_directory, "unhandled-file-name-directory");
+ DEFSYM (Qfile_name_as_directory, "file-name-as-directory");
+ DEFSYM (Qcopy_file, "copy-file");
+ DEFSYM (Qmake_directory_internal, "make-directory-internal");
+ DEFSYM (Qmake_directory, "make-directory");
+ DEFSYM (Qdelete_directory_internal, "delete-directory-internal");
+ DEFSYM (Qdelete_file, "delete-file");
+ DEFSYM (Qrename_file, "rename-file");
+ DEFSYM (Qadd_name_to_file, "add-name-to-file");
+ DEFSYM (Qmake_symbolic_link, "make-symbolic-link");
+ DEFSYM (Qfile_exists_p, "file-exists-p");
+ DEFSYM (Qfile_executable_p, "file-executable-p");
+ DEFSYM (Qfile_readable_p, "file-readable-p");
+ DEFSYM (Qfile_writable_p, "file-writable-p");
+ DEFSYM (Qfile_symlink_p, "file-symlink-p");
+ DEFSYM (Qaccess_file, "access-file");
+ DEFSYM (Qfile_directory_p, "file-directory-p");
+ DEFSYM (Qfile_regular_p, "file-regular-p");
+ DEFSYM (Qfile_accessible_directory_p, "file-accessible-directory-p");
+ DEFSYM (Qfile_modes, "file-modes");
+ DEFSYM (Qset_file_modes, "set-file-modes");
+ DEFSYM (Qset_file_times, "set-file-times");
+ DEFSYM (Qfile_selinux_context, "file-selinux-context");
+ DEFSYM (Qset_file_selinux_context, "set-file-selinux-context");
+ DEFSYM (Qfile_newer_than_file_p, "file-newer-than-file-p");
+ DEFSYM (Qinsert_file_contents, "insert-file-contents");
+ DEFSYM (Qwrite_region, "write-region");
+ DEFSYM (Qverify_visited_file_modtime, "verify-visited-file-modtime");
+ DEFSYM (Qset_visited_file_modtime, "set-visited-file-modtime");
+ DEFSYM (Qauto_save_coding, "auto-save-coding");
+
+ DEFSYM (Qfile_name_history, "file-name-history");
Fset (Qfile_name_history, Qnil);
- staticpro (&Qfile_name_history);
- Qfile_error = intern_c_string ("file-error");
- staticpro (&Qfile_error);
- Qfile_already_exists = intern_c_string ("file-already-exists");
- staticpro (&Qfile_already_exists);
- Qfile_date_error = intern_c_string ("file-date-error");
- staticpro (&Qfile_date_error);
- Qexcl = intern_c_string ("excl");
- staticpro (&Qexcl);
+ DEFSYM (Qfile_error, "file-error");
+ DEFSYM (Qfile_already_exists, "file-already-exists");
+ DEFSYM (Qfile_date_error, "file-date-error");
+ DEFSYM (Qexcl, "excl");
DEFVAR_LISP ("file-name-coding-system", Vfile_name_coding_system,
doc: /* *Coding system for encoding file names.
@@ -5523,15 +5551,10 @@ instead use `file-name-coding-system' to get a constant encoding
of file names regardless of the current language environment. */);
Vdefault_file_name_coding_system = Qnil;
- Qformat_decode = intern_c_string ("format-decode");
- staticpro (&Qformat_decode);
- Qformat_annotate_function = intern_c_string ("format-annotate-function");
- staticpro (&Qformat_annotate_function);
- Qafter_insert_file_set_coding = intern_c_string ("after-insert-file-set-coding");
- staticpro (&Qafter_insert_file_set_coding);
-
- Qcar_less_than_car = intern_c_string ("car-less-than-car");
- staticpro (&Qcar_less_than_car);
+ DEFSYM (Qformat_decode, "format-decode");
+ DEFSYM (Qformat_annotate_function, "format-annotate-function");
+ DEFSYM (Qafter_insert_file_set_coding, "after-insert-file-set-coding");
+ DEFSYM (Qcar_less_than_car, "car-less-than-car");
Fput (Qfile_error, Qerror_conditions,
Fpurecopy (list2 (Qfile_error, Qerror)));
@@ -5610,9 +5633,7 @@ After `write-region' completes, Emacs calls the function stored in
current when building the annotations (i.e., at least once), with that
buffer current. */);
Vwrite_region_annotate_functions = Qnil;
- staticpro (&Qwrite_region_annotate_functions);
- Qwrite_region_annotate_functions
- = intern_c_string ("write-region-annotate-functions");
+ DEFSYM (Qwrite_region_annotate_functions, "write-region-annotate-functions");
DEFVAR_LISP ("write-region-post-annotation-function",
Vwrite_region_post_annotation_function,
@@ -5676,12 +5697,10 @@ This includes interactive calls to `delete-file' and
`delete-directory' and the Dired deletion commands. */);
delete_by_moving_to_trash = 0;
Qdelete_by_moving_to_trash = intern_c_string ("delete-by-moving-to-trash");
- Qmove_file_to_trash = intern_c_string ("move-file-to-trash");
- staticpro (&Qmove_file_to_trash);
- Qcopy_directory = intern_c_string ("copy-directory");
- staticpro (&Qcopy_directory);
- Qdelete_directory = intern_c_string ("delete-directory");
- staticpro (&Qdelete_directory);
+
+ DEFSYM (Qmove_file_to_trash, "move-file-to-trash");
+ DEFSYM (Qcopy_directory, "copy-directory");
+ DEFSYM (Qdelete_directory, "delete-directory");
defsubr (&Sfind_file_name_handler);
defsubr (&Sfile_name_directory);