#endif
/* Nonzero during writing of auto-save files */
-int auto_saving;
+static int auto_saving;
/* Set by auto_save_1 to mode of original file so Fwrite_region will create
a new file with the same mode as the original */
-int auto_save_mode_bits;
+static int auto_save_mode_bits;
/* Set by auto_save_1 if an error occurred during the last auto-save. */
-int auto_save_error_occurred;
+static int auto_save_error_occurred;
/* The symbol bound to coding-system-for-read when
insert-file-contents is called for recovering a file. This is not
an actual coding system name, but just an indicator to tell
insert-file-contents to use `emacs-mule' with a special flag for
auto saving and recovering a file. */
-Lisp_Object Qauto_save_coding;
+static Lisp_Object Qauto_save_coding;
/* Property name of a file name handler,
which gives a list of operations it handles.. */
-Lisp_Object Qoperations;
+static Lisp_Object Qoperations;
/* Lisp functions for translating file formats */
-Lisp_Object Qformat_decode, Qformat_annotate_function;
+static Lisp_Object Qformat_decode, Qformat_annotate_function;
/* Lisp function for setting buffer-file-coding-system and the
multibyteness of the current buffer after inserting a file. */
-Lisp_Object Qafter_insert_file_set_coding;
+static Lisp_Object Qafter_insert_file_set_coding;
-Lisp_Object Qwrite_region_annotate_functions;
+static Lisp_Object Qwrite_region_annotate_functions;
/* Each time an annotation function changes the buffer, the new buffer
is added here. */
-Lisp_Object Vwrite_region_annotation_buffers;
+static Lisp_Object Vwrite_region_annotation_buffers;
#ifdef HAVE_FSYNC
#endif
-Lisp_Object Qdelete_by_moving_to_trash;
+static Lisp_Object Qdelete_by_moving_to_trash;
/* Lisp function for moving files to trash. */
-Lisp_Object Qmove_file_to_trash;
+static Lisp_Object Qmove_file_to_trash;
/* Lisp function for recursively copying directories. */
-Lisp_Object Qcopy_directory;
+static Lisp_Object Qcopy_directory;
/* Lisp function for recursively deleting directories. */
-Lisp_Object Qdelete_directory;
+static Lisp_Object Qdelete_directory;
#ifdef WINDOWSNT
#endif
-Lisp_Object Qfile_error, Qfile_already_exists, Qfile_date_error;
-Lisp_Object Qexcl;
+Lisp_Object Qfile_error;
+static Lisp_Object Qfile_already_exists, Qfile_date_error;
+static Lisp_Object Qexcl;
Lisp_Object Qfile_name_history;
-Lisp_Object Qcar_less_than_car;
+static Lisp_Object Qcar_less_than_car;
-static int a_write (int, Lisp_Object, int, int,
+static Lisp_Object Fmake_symbolic_link (Lisp_Object, Lisp_Object, Lisp_Object);
+static int a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
Lisp_Object *, struct coding_system *);
-static int e_write (int, Lisp_Object, int, int, struct coding_system *);
+static int e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
+ struct coding_system *);
\f
void
str = SSDATA (errstring);
c = STRING_CHAR ((unsigned char *) str);
- Faset (errstring, make_number (0), make_number (DOWNCASE (c)));
+ Faset (errstring, make_number (0), make_number (downcase (c)));
}
xsignal (Qfile_error,
}
\f
-Lisp_Object Qexpand_file_name;
-Lisp_Object Qsubstitute_in_file_name;
-Lisp_Object Qdirectory_file_name;
-Lisp_Object Qfile_name_directory;
-Lisp_Object Qfile_name_nondirectory;
-Lisp_Object Qunhandled_file_name_directory;
-Lisp_Object Qfile_name_as_directory;
-Lisp_Object Qcopy_file;
-Lisp_Object Qmake_directory_internal;
-Lisp_Object Qmake_directory;
-Lisp_Object Qdelete_directory_internal;
+static Lisp_Object Qexpand_file_name;
+static Lisp_Object Qsubstitute_in_file_name;
+static Lisp_Object Qdirectory_file_name;
+static Lisp_Object Qfile_name_directory;
+static Lisp_Object Qfile_name_nondirectory;
+static Lisp_Object Qunhandled_file_name_directory;
+static Lisp_Object Qfile_name_as_directory;
+static Lisp_Object Qcopy_file;
+static Lisp_Object Qmake_directory_internal;
+static Lisp_Object Qmake_directory;
+static Lisp_Object Qdelete_directory_internal;
Lisp_Object Qdelete_file;
-Lisp_Object Qrename_file;
-Lisp_Object Qadd_name_to_file;
-Lisp_Object Qmake_symbolic_link;
+static Lisp_Object Qrename_file;
+static Lisp_Object Qadd_name_to_file;
+static Lisp_Object Qmake_symbolic_link;
Lisp_Object Qfile_exists_p;
-Lisp_Object Qfile_executable_p;
-Lisp_Object Qfile_readable_p;
-Lisp_Object Qfile_writable_p;
-Lisp_Object Qfile_symlink_p;
-Lisp_Object Qaccess_file;
+static Lisp_Object Qfile_executable_p;
+static Lisp_Object Qfile_readable_p;
+static Lisp_Object Qfile_writable_p;
+static Lisp_Object Qfile_symlink_p;
+static Lisp_Object Qaccess_file;
Lisp_Object Qfile_directory_p;
-Lisp_Object Qfile_regular_p;
-Lisp_Object Qfile_accessible_directory_p;
-Lisp_Object Qfile_modes;
-Lisp_Object Qset_file_modes;
-Lisp_Object Qset_file_times;
-Lisp_Object Qfile_selinux_context;
-Lisp_Object Qset_file_selinux_context;
-Lisp_Object Qfile_newer_than_file_p;
+static Lisp_Object Qfile_regular_p;
+static Lisp_Object Qfile_accessible_directory_p;
+static Lisp_Object Qfile_modes;
+static Lisp_Object Qset_file_modes;
+static Lisp_Object Qset_file_times;
+static Lisp_Object Qfile_selinux_context;
+static Lisp_Object Qset_file_selinux_context;
+static Lisp_Object Qfile_newer_than_file_p;
Lisp_Object Qinsert_file_contents;
Lisp_Object Qwrite_region;
-Lisp_Object Qverify_visited_file_modtime;
-Lisp_Object Qset_visited_file_modtime;
+static Lisp_Object Qverify_visited_file_modtime;
+static Lisp_Object Qset_visited_file_modtime;
-DEFUN ("find-file-name-handler", Ffind_file_name_handler, Sfind_file_name_handler, 2, 2, 0,
+DEFUN ("find-file-name-handler", Ffind_file_name_handler,
+ Sfind_file_name_handler, 2, 2, 0,
doc: /* Return FILENAME's handler function for OPERATION, if it has one.
Otherwise, return nil.
A file name is handled if one of the regular expressions in
{
/* This function must not munge the match data. */
Lisp_Object chain, inhibited_handlers, result;
- int pos = -1;
+ ptrdiff_t pos = -1;
result = Qnil;
CHECK_STRING (filename);
if (CONSP (elt))
{
Lisp_Object string = XCAR (elt);
- int match_pos;
+ ptrdiff_t match_pos;
Lisp_Object handler = XCDR (elt);
Lisp_Object operations = Qnil;
}
\f
-char *
-file_name_as_directory (char *out, char *in)
+static char *
+file_name_as_directory (char *out, const char *in)
{
- int size = strlen (in) - 1;
-
- strcpy (out, in);
+ ptrdiff_t len = strlen (in);
- if (size < 0)
+ if (len == 0)
{
out[0] = '.';
out[1] = '/';
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);
* Value is nonzero if the string output is different from the input.
*/
-int
+static int
directory_file_name (char *src, char *dst)
{
- long slen;
+ ptrdiff_t slen;
slen = strlen (src);
{
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);
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)
{
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;
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;
}
{
/* These point to SDATA and need to be careful with string-relocation
during GC (via DECODE_FILE). */
- char *nm, *newdir;
+ char *nm;
+ const char *newdir;
/* 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;
if (!newdir && drive)
{
/* Get default directory if needed to make nm absolute. */
+ char *adir = NULL;
if (!IS_DIRECTORY_SEP (nm[0]))
{
- newdir = alloca (MAXPATHLEN + 1);
- if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
- newdir = NULL;
+ adir = alloca (MAXPATHLEN + 1);
+ if (!getdefdir (toupper (drive) - 'A' + 1, adir))
+ adir = NULL;
}
- if (!newdir)
+ if (!adir)
{
/* Either nm starts with /, or drive isn't mounted. */
- newdir = alloca (4);
- newdir[0] = DRIVE_LETTER (drive);
- newdir[1] = ':';
- newdir[2] = '/';
- newdir[3] = 0;
+ adir = alloca (4);
+ adir[0] = DRIVE_LETTER (drive);
+ adir[1] = ':';
+ adir[2] = '/';
+ adir[3] = 0;
}
+ newdir = adir;
}
#endif /* DOS_NT */
when we have pointers into lisp strings, we accomplish this
indirectly by prepending newdir to nm if necessary, and using
cwd (or the wd of newdir's drive) as the new newdir. */
-
+ char *adir;
if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
{
drive = (unsigned char) newdir[0];
strcat (tmp, nm);
nm = tmp;
}
- newdir = alloca (MAXPATHLEN + 1);
+ adir = alloca (MAXPATHLEN + 1);
if (drive)
{
- if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
+ if (!getdefdir (toupper (drive) - 'A' + 1, adir))
newdir = "/";
}
else
- getwd (newdir);
+ getwd (adir);
+ newdir = adir;
}
/* Strip off drive name from prefix, if present. */
#ifdef WINDOWSNT
if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
{
- char *p;
- newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
- p = newdir + 2;
+ char *adir = strcpy (alloca (strlen (newdir) + 1), newdir);
+ char *p = adir + 2;
while (*p && !IS_DIRECTORY_SEP (*p)) p++;
p++;
while (*p && !IS_DIRECTORY_SEP (*p)) p++;
*p = 0;
+ newdir = adir;
}
else
#endif
unsigned char *nm;
register unsigned char *newdir, *p, *o;
- int tlen;
+ ptrdiff_t tlen;
unsigned char *target;
struct passwd *pw;
int lose;
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);
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)
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);
If QUICK is nonzero, we ask for y or n, not yes or no. */
-void
+static void
barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
int interactive, struct stat *statptr, int quick)
{
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);
on the system, we copy the SELinux context of FILE to NEWNAME. */)
(Lisp_Object file, Lisp_Object newname, Lisp_Object ok_if_already_exists, Lisp_Object keep_time, Lisp_Object preserve_uid_gid, Lisp_Object preserve_selinux_context)
{
- int ifd, ofd, n;
+ int ifd, ofd;
+ int n;
char buf[16 * 1024];
struct stat st, out_st;
Lisp_Object handler;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
int input_file_statable_p;
Lisp_Object encoded_file, encoded_newname;
#if HAVE_LIBSELINUX
| (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));
owner and group. */
if (input_file_statable_p)
{
- if (! NILP (preserve_uid_gid))
- fchown (ofd, st.st_uid, st.st_gid);
- fchmod (ofd, st.st_mode & 07777);
+ 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 */
(Lisp_Object directory)
{
const char *dir;
- Lisp_Object handler;
Lisp_Object encoded_dir;
CHECK_STRING (directory);
{
if (errno == EXDEV)
{
- int count;
+ ptrdiff_t count;
symlink_target = Ffile_symlink_p (file);
if (! NILP (symlink_target))
Fmake_symbolic_link (symlink_target, newname,
return Qnil;
}
}
+ if (errno == ENOSYS)
+ {
+ UNGCPRO;
+ xsignal1 (Qfile_error,
+ build_string ("Symbolic links are not supported"));
+ }
report_file_error ("Making symbolic link", list2 (filename, linkname));
}
check_executable (char *filename)
{
#ifdef DOS_NT
- int len = strlen (filename);
- char *suffix;
struct stat st;
if (stat (filename, &st) < 0)
return 0;
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)
{
Lisp_Object handler;
char *buf;
- int bufsize;
- int valsize;
Lisp_Object val;
+ char readlink_buf[READLINK_BUFSIZE];
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
filename = ENCODE_FILE (filename);
- bufsize = 50;
- buf = NULL;
- do
- {
- bufsize *= 2;
- buf = (char *) xrealloc (buf, bufsize);
- memset (buf, 0, bufsize);
-
- errno = 0;
- valsize = readlink (SSDATA (filename), buf, bufsize);
- if (valsize == -1)
- {
-#ifdef ERANGE
- /* HP-UX reports ERANGE if buffer is too small. */
- if (errno == ERANGE)
- valsize = bufsize;
- else
-#endif
- {
- xfree (buf);
- return Qnil;
- }
- }
- }
- while (valsize >= bufsize);
+ buf = emacs_readlink (SSDATA (filename), readlink_buf);
+ if (! buf)
+ return Qnil;
- val = make_string (buf, valsize);
+ val = build_string (buf);
if (buf[0] == '/' && strchr (buf, ':'))
val = concat2 (build_string ("/:"), val);
- xfree (buf);
+ if (buf != readlink_buf)
+ xfree (buf);
val = DECODE_FILE (val);
return val;
}
return S_ISDIR (st.st_mode) ? Qt : Qnil;
}
-DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, Sfile_accessible_directory_p, 1, 1, 0,
+DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p,
+ Sfile_accessible_directory_p, 1, 1, 0,
doc: /* Return t if file FILENAME names a directory you can open.
For the value to be t, FILENAME must specify the name of a directory as a file,
and the directory must allow you to open files in it. In order to use a
#if HAVE_LIBSELINUX
if (is_selinux_enabled ())
{
- conlength = lgetfilecon (SDATA (absname), &con);
+ conlength = lgetfilecon (SSDATA (absname), &con);
if (conlength > 0)
{
context = context_new (con);
}
#endif
- return Flist (sizeof(values) / sizeof(values[0]), values);
+ return Flist (sizeof (values) / sizeof (values[0]), values);
}
\f
DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
is disabled. */)
(Lisp_Object filename, Lisp_Object context)
{
- Lisp_Object absname, encoded_absname;
+ Lisp_Object absname;
Lisp_Object handler;
+#if HAVE_LIBSELINUX
+ Lisp_Object encoded_absname;
Lisp_Object user = CAR_SAFE (context);
Lisp_Object role = CAR_SAFE (CDR_SAFE (context));
Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
-#if HAVE_LIBSELINUX
security_context_t con;
int fail, conlength;
context_t parsed_con;
if (!NILP (handler))
return call3 (handler, Qset_file_selinux_context, absname, context);
- encoded_absname = ENCODE_FILE (absname);
-
#if HAVE_LIBSELINUX
if (is_selinux_enabled ())
{
/* Get current file context. */
- conlength = lgetfilecon (SDATA (encoded_absname), &con);
+ encoded_absname = ENCODE_FILE (absname);
+ conlength = lgetfilecon (SSDATA (encoded_absname), &con);
if (conlength > 0)
{
parsed_con = context_new (con);
/* Change the parts defined in the parameter.*/
if (STRINGP (user))
{
- if (context_user_set (parsed_con, SDATA (user)))
+ if (context_user_set (parsed_con, SSDATA (user)))
error ("Doing context_user_set");
}
if (STRINGP (role))
{
- if (context_role_set (parsed_con, SDATA (role)))
+ if (context_role_set (parsed_con, SSDATA (role)))
error ("Doing context_role_set");
}
if (STRINGP (type))
{
- if (context_type_set (parsed_con, SDATA (type)))
+ if (context_type_set (parsed_con, SSDATA (type)))
error ("Doing context_type_set");
}
if (STRINGP (range))
{
- if (context_range_set (parsed_con, SDATA (range)))
+ if (context_range_set (parsed_con, SSDATA (range)))
error ("Doing context_range_set");
}
/* Set the modified context back to the file. */
- fail = lsetfilecon (SDATA (encoded_absname), context_str (parsed_con));
+ fail = lsetfilecon (SSDATA (encoded_absname),
+ context_str (parsed_con));
if (fail)
report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil));
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);
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;
\f
DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 2, 0,
- doc: /* Set times of file FILENAME to TIME.
+ doc: /* Set times of file FILENAME to TIMESTAMP.
Set both access and modification times.
Return t on success, else nil.
-Use the current time if TIME is nil. TIME is in the format of
+Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
`current-time'. */)
- (Lisp_Object filename, Lisp_Object time)
+ (Lisp_Object filename, Lisp_Object timestamp)
{
Lisp_Object absname, encoded_absname;
Lisp_Object handler;
time_t sec;
int usec;
- if (! lisp_time_argument (time, &sec, &usec))
+ if (! lisp_time_argument (timestamp, &sec, &usec))
error ("Invalid time specification");
absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
call the corresponding file handler. */
handler = Ffind_file_name_handler (absname, Qset_file_times);
if (!NILP (handler))
- return call3 (handler, Qset_file_times, absname, time);
+ return call3 (handler, Qset_file_times, absname, timestamp);
encoded_absname = ENCODE_FILE (absname);
#ifndef READ_BUF_SIZE
#define READ_BUF_SIZE (64 << 10)
#endif
+/* Some buffer offsets are stored in 'int' variables. */
+verify (READ_BUF_SIZE <= INT_MAX);
/* This function is called after Lisp functions to decide a coding
system are called, or when they cause an error. Before they are
/* Used to pass values from insert-file-contents to read_non_regular. */
static int non_regular_fd;
-static EMACS_INT non_regular_inserted;
-static EMACS_INT non_regular_nbytes;
+static ptrdiff_t non_regular_inserted;
+static int non_regular_nbytes;
/* Read from a non-regular file.
static Lisp_Object
read_non_regular (Lisp_Object ignore)
{
- EMACS_INT nbytes;
+ int nbytes;
immediate_quit = 1;
QUIT;
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
+ <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43772>. */
+ 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,
{
struct stat st;
register int fd;
- EMACS_INT inserted = 0;
+ ptrdiff_t inserted = 0;
int nochange = 0;
- register EMACS_INT how_much;
- register EMACS_INT unprocessed;
- int count = SPECPDL_INDEX ();
+ register ptrdiff_t how_much;
+ off_t beg_offset, end_offset;
+ register int unprocessed;
+ ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
Lisp_Object handler, val, insval, orig_filename, old_undo;
Lisp_Object p;
- EMACS_INT total = 0;
+ ptrdiff_t total = 0;
int not_regular = 0;
+ int save_errno = 0;
char read_buf[READ_BUF_SIZE];
struct coding_system coding;
char buffer[1 << 14];
{
val = call6 (handler, Qinsert_file_contents, filename,
visit, beg, end, replace);
- if (CONSP (val) && CONSP (XCDR (val)))
+ if (CONSP (val) && CONSP (XCDR (val))
+ && RANGED_INTEGERP (0, XCAR (XCDR (val)), ZV - PT))
inserted = XINT (XCAR (XCDR (val)));
goto handled;
}
if (stat (SSDATA (filename), &st) < 0)
#endif /* WINDOWSNT */
{
- if (fd >= 0) emacs_close (fd);
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);
record_unwind_protect (close_file_unwind, make_number (fd));
- /* Can happen on any platform that uses long as type of off_t, but allows
- file sizes to exceed 2Gb, so give a suitable message. */
- if (! not_regular && st.st_size < 0)
- error ("Maximum buffer size exceeded");
-
- /* Prevent redisplay optimizations. */
- current_buffer->clip_changed = 1;
if (!NILP (visit))
{
}
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);
-
- /* Arithmetic overflow can occur if an Emacs integer cannot
- represent the file size, or if the calculations below
- overflow. The calculations below double the file size
- twice, so check that it can be multiplied by 4 safely. */
- if (XINT (end) != st.st_size
- /* Actually, it should test either INT_MAX or LONG_MAX
- depending on which one is used for EMACS_INT. But in
- any case, in practice, this test is redundant with the
- one above.
- || st.st_size > INT_MAX / 4 */)
- error ("Maximum buffer size exceeded");
+ 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);
We assume that the 1K-byte and 3K-byte for heading
and tailing respectively are sufficient for this
purpose. */
- EMACS_INT nread;
+ int nread;
if (st.st_size <= (1024 * 4))
nread = emacs_read (fd, read_buf, 1024 * 4);
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);
else if (nread > 0)
{
struct buffer *prev = current_buffer;
- Lisp_Object buffer;
+ Lisp_Object workbuf;
struct buffer *buf;
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
- buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
- buf = XBUFFER (buffer);
+ workbuf = Fget_buffer_create (build_string (" *code-converting-work*"));
+ buf = XBUFFER (workbuf);
delete_all_overlays (buf);
BVAR (buf, directory) = BVAR (current_buffer, directory);
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));
}
/* same_at_start and same_at_end count bytes,
because file access counts bytes
and BEG and END count bytes. */
- EMACS_INT same_at_start = BEGV_BYTE;
- EMACS_INT same_at_end = ZV_BYTE;
- EMACS_INT overlap;
+ ptrdiff_t same_at_start = BEGV_BYTE;
+ ptrdiff_t same_at_end = ZV_BYTE;
+ ptrdiff_t overlap;
/* There is still a possibility we will find the need to do code
conversion. If that happens, we set this variable to 1 to
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));
}
match the text at the beginning of the buffer. */
while (1)
{
- EMACS_INT nread, bufpos;
+ int nread, bufpos;
nread = emacs_read (fd, buffer, sizeof buffer);
if (nread < 0)
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--;
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));
if (! giveup_match_end)
{
- EMACS_INT temp;
+ ptrdiff_t temp;
/* We win! We can handle REPLACE the optimized way. */
/* 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. */
in a more optimized way. */
if (!NILP (replace) && ! replace_handled && BEGV < ZV)
{
- EMACS_INT same_at_start = BEGV_BYTE;
- EMACS_INT same_at_end = ZV_BYTE;
- EMACS_INT same_at_start_charpos;
- EMACS_INT inserted_chars;
- EMACS_INT overlap;
- EMACS_INT bufpos;
+ ptrdiff_t same_at_start = BEGV_BYTE;
+ ptrdiff_t same_at_end = ZV_BYTE;
+ ptrdiff_t same_at_start_charpos;
+ ptrdiff_t inserted_chars;
+ ptrdiff_t overlap;
+ ptrdiff_t bufpos;
unsigned char *decoded;
- EMACS_INT temp;
- int this_count = SPECPDL_INDEX ();
+ ptrdiff_t temp;
+ ptrdiff_t this = 0;
+ ptrdiff_t this_count = SPECPDL_INDEX ();
int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
Lisp_Object conversion_buffer;
/* 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));
/* 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) */
- EMACS_INT trytry = min (total - how_much,
- READ_BUF_SIZE - unprocessed);
- EMACS_INT this;
+ int trytry = min (total - how_much, READ_BUF_SIZE - unprocessed);
/* Allow quitting out of the actual I/O. */
immediate_quit = 1;
immediate_quit = 0;
if (this <= 0)
- {
- if (this < 0)
- how_much = this;
- break;
- }
+ break;
how_much += this;
/* At this point, HOW_MUCH should equal TOTAL, or should be <= 0
if we couldn't read the file. */
- if (how_much < 0)
+ if (this < 0)
error ("IO error reading %s: %s",
SDATA (orig_filename), emacs_strerror (errno));
}
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;
- if (NILP (visit) && inserted > 0)
+ if (NILP (visit) && total > 0)
{
#ifdef CLASH_DETECTION
if (!NILP (BVAR (current_buffer, file_truename))
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));
}
/* Here, we don't do code conversion in the loop. It is done by
decode_coding_gap after all data are read into the buffer. */
{
- EMACS_INT gap_size = GAP_SIZE;
+ ptrdiff_t gap_size = GAP_SIZE;
while (how_much < total)
{
/* try is reserved in some compilers (Microsoft C) */
- EMACS_INT trytry = min (total - how_much, READ_BUF_SIZE);
- EMACS_INT this;
+ int trytry = min (total - how_much, READ_BUF_SIZE);
+ ptrdiff_t this;
if (not_regular)
{
- Lisp_Object val;
+ Lisp_Object nbytes;
/* Maybe make more room. */
if (gap_size < trytry)
non_regular_fd = fd;
non_regular_inserted = inserted;
non_regular_nbytes = trytry;
- val = internal_condition_case_1 (read_non_regular, Qnil, Qerror,
- read_non_regular_quit);
- if (NILP (val))
+ nbytes = internal_condition_case_1 (read_non_regular,
+ Qnil, Qerror,
+ read_non_regular_quit);
+ if (NILP (nbytes))
{
read_quit = 1;
break;
}
- this = XINT (val);
+ this = XINT (nbytes);
}
else
{
care of marker adjustment. By this way, we can run Lisp
program safely before decoding the inserted text. */
Lisp_Object unwind_data;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count1 = SPECPDL_INDEX ();
unwind_data = Fcons (BVAR (current_buffer, enable_multibyte_characters),
Fcons (BVAR (current_buffer, undo_list),
if (CONSP (coding_system))
coding_system = XCAR (coding_system);
}
- unbind_to (count, Qnil);
+ unbind_to (count1, Qnil);
inserted = Z_BYTE - BEG_BYTE;
}
visit);
if (! NILP (insval))
{
- CHECK_NUMBER (insval);
+ if (! RANGED_INTEGERP (0, insval, ZV - PT))
+ wrong_type_argument (intern ("inserted-chars"), insval);
inserted = XFASTINT (insval);
}
}
if (inserted > 0)
{
/* Don't run point motion or modification hooks when decoding. */
- int count = SPECPDL_INDEX ();
- EMACS_INT old_inserted = inserted;
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ ptrdiff_t old_inserted = inserted;
specbind (Qinhibit_point_motion_hooks, Qt);
specbind (Qinhibit_modification_hooks, Qt);
{
insval = call3 (Qformat_decode,
Qnil, make_number (inserted), visit);
- CHECK_NUMBER (insval);
+ if (! RANGED_INTEGERP (0, insval, ZV - PT))
+ wrong_type_argument (intern ("inserted-chars"), insval);
inserted = XFASTINT (insval);
}
else
Hence we temporarily save `point' and `inserted' here and
restore `point' iff format-decode did not insert or delete
any text. Otherwise we leave `point' at point-min. */
- EMACS_INT opoint = PT;
- EMACS_INT opoint_byte = PT_BYTE;
- EMACS_INT oinserted = ZV - BEGV;
- int ochars_modiff = CHARS_MODIFF;
+ ptrdiff_t opoint = PT;
+ ptrdiff_t opoint_byte = PT_BYTE;
+ ptrdiff_t oinserted = ZV - BEGV;
+ EMACS_INT ochars_modiff = CHARS_MODIFF;
TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
insval = call3 (Qformat_decode,
Qnil, make_number (oinserted), visit);
- CHECK_NUMBER (insval);
+ if (! RANGED_INTEGERP (0, insval, ZV - PT))
+ wrong_type_argument (intern ("inserted-chars"), insval);
if (ochars_modiff == CHARS_MODIFF)
/* format_decode didn't modify buffer's characters => move
point back to position before inserted text and leave
insval = call1 (XCAR (p), make_number (inserted));
if (!NILP (insval))
{
- CHECK_NUMBER (insval);
+ if (! RANGED_INTEGERP (0, insval, ZV - PT))
+ wrong_type_argument (intern ("inserted-chars"), insval);
inserted = XFASTINT (insval);
}
}
{
/* For the rationale of this see the comment on
format-decode above. */
- EMACS_INT opoint = PT;
- EMACS_INT opoint_byte = PT_BYTE;
- EMACS_INT oinserted = ZV - BEGV;
- int ochars_modiff = CHARS_MODIFF;
+ ptrdiff_t opoint = PT;
+ ptrdiff_t opoint_byte = PT_BYTE;
+ ptrdiff_t oinserted = ZV - BEGV;
+ EMACS_INT ochars_modiff = CHARS_MODIFF;
TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
insval = call1 (XCAR (p), make_number (oinserted));
if (!NILP (insval))
{
- CHECK_NUMBER (insval);
+ if (! RANGED_INTEGERP (0, insval, ZV - PT))
+ wrong_type_argument (intern ("inserted-chars"), insval);
if (ochars_modiff == CHARS_MODIFF)
/* after_insert_file_functions didn't modify
buffer's characters => move point back to
Otherwise start with an empty undo_list. */
BVAR (current_buffer, undo_list) = EQ (old_undo, Qt) ? Qt : Qnil;
- unbind_to (count, Qnil);
+ unbind_to (count1, Qnil);
}
/* Call after-change hooks for the inserted text, aside from the case
&& current_buffer->modtime == -1)
{
/* If visiting nonexistent file, return nil. */
+ errno = save_errno;
report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
}
int save_errno = 0;
const char *fn;
struct stat st;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
int count1;
Lisp_Object handler;
Lisp_Object visit_file;
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));
The return value is negative in case of system call failure. */
static int
-a_write (int desc, Lisp_Object string, int pos, register int nchars, Lisp_Object *annot, struct coding_system *coding)
+a_write (int desc, Lisp_Object string, ptrdiff_t pos,
+ register ptrdiff_t nchars, Lisp_Object *annot,
+ struct coding_system *coding)
{
Lisp_Object tem;
- int nextpos;
- int lastpos = pos + nchars;
+ ptrdiff_t nextpos;
+ ptrdiff_t lastpos = pos + nchars;
while (NILP (*annot) || CONSP (*annot))
{
are indexes to the string STRING. */
static int
-e_write (int desc, Lisp_Object string, int start, int end, struct coding_system *coding)
+e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
+ struct coding_system *coding)
{
if (STRINGP (string))
{
}
else
{
- int start_byte = CHAR_TO_BYTE (start);
- int end_byte = CHAR_TO_BYTE (end);
+ ptrdiff_t start_byte = CHAR_TO_BYTE (start);
+ ptrdiff_t end_byte = CHAR_TO_BYTE (end);
coding->src_multibyte = (end - start) < (end_byte - start_byte);
if (CODING_REQUIRE_ENCODING (coding))
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))
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,
{
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
return Qnil;
}
\f
-Lisp_Object
-auto_save_error (Lisp_Object error)
+static Lisp_Object
+auto_save_error (Lisp_Object error_val)
{
Lisp_Object args[3], msg;
int i, nbytes;
args[0] = build_string ("Auto-saving %s: %s");
args[1] = BVAR (current_buffer, name);
- args[2] = Ferror_message_string (error);
+ args[2] = Ferror_message_string (error_val);
msg = Fformat (3, args);
GCPRO1 (msg);
nbytes = SBYTES (msg);
return Qnil;
}
-Lisp_Object
+static Lisp_Object
auto_save_1 (void)
{
struct stat st;
{
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
(Lisp_Object no_message, Lisp_Object current_only)
{
struct buffer *old = current_buffer, *b;
- Lisp_Object tail, buf;
+ Lisp_Object tail, buf, hook;
int auto_saved = 0;
int do_handled_files;
Lisp_Object oquit;
FILE *stream = NULL;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
int orig_minibuffer_auto_raise = minibuffer_auto_raise;
int old_message_p = 0;
struct gcpro gcpro1, gcpro2;
/* No GCPRO needed, because (when it matters) all Lisp_Object variables
point to non-strings reached from Vbuffer_alist. */
- if (!NILP (Vrun_hooks))
- call1 (Vrun_hooks, intern ("auto-save-hook"));
+ hook = intern ("auto-save-hook");
+ Frun_hooks (1, &hook);
if (STRINGP (Vauto_save_list_file_name))
{
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;
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;
}
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;
}
Lisp_Object
Fread_file_name (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object initial, Lisp_Object predicate)
{
- struct gcpro gcpro1, gcpro2;
+ struct gcpro gcpro1;
Lisp_Object args[7];
GCPRO1 (default_filename);
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.
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)));
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,
`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);