return abspath;
}
\f
+/* Signal an error if the file ABSNAME already exists.
+ If INTERACTIVE is nonzero, ask the user whether to proceed,
+ and bypass the error if the user says to go ahead.
+ QUERYSTRING is a name for the action that is being considered
+ to alter the file.
+ *STATPTR is used to store the stat information if the file exists.
+ If the file does not exist, STATPTR->st_mode is set to 0. */
+
void
-barf_or_query_if_file_exists (absname, querystring, interactive)
+barf_or_query_if_file_exists (absname, querystring, interactive, statptr)
Lisp_Object absname;
unsigned char *querystring;
int interactive;
+ struct stat *statptr;
{
register Lisp_Object tem;
struct stat statbuf;
Fsignal (Qfile_already_exists,
Fcons (build_string ("File already exists"),
Fcons (absname, Qnil)));
+ if (statptr)
+ *statptr = statbuf;
+ }
+ else
+ {
+ if (statptr)
+ statptr->st_mode = 0;
}
return;
}
{
int ifd, ofd, n;
char buf[16 * 1024];
- struct stat st;
+ struct stat st, out_st;
Lisp_Object handler;
struct gcpro gcpro1, gcpro2;
int count = specpdl_ptr - specpdl;
if (NILP (ok_if_already_exists)
|| INTEGERP (ok_if_already_exists))
barf_or_query_if_file_exists (newname, "copy to it",
- INTEGERP (ok_if_already_exists));
+ INTEGERP (ok_if_already_exists), &out_st);
+ else if (stat (XSTRING (newname)->data, &out_st) < 0)
+ out_st.st_mode = 0;
ifd = open (XSTRING (filename)->data, O_RDONLY);
if (ifd < 0)
copyable by us. */
input_file_statable_p = (fstat (ifd, &st) >= 0);
+#ifndef DOS_NT
+ if (out_st.st_mode != 0
+ && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
+ {
+ errno = 0;
+ report_file_error ("Input and output files are the same",
+ Fcons (filename, Fcons (newname, Qnil)));
+ }
+#endif
+
#if defined (S_ISREG) && defined (S_ISLNK)
if (input_file_statable_p)
{
/* Get a better looking error message. */
errno = EISDIR;
#endif /* EISDIR */
- report_file_error ("Non-regular file", Fcons (filename, Qnil));
+ report_file_error ("Non-regular file", Fcons (filename, Qnil));
}
}
#endif /* S_ISREG && S_ISLNK */
#endif /* not MSDOS */
#endif /* VMS */
if (ofd < 0)
- report_file_error ("Opening output file", Fcons (newname, Qnil));
+ report_file_error ("Opening output file", Fcons (newname, Qnil));
record_unwind_protect (close_file_unwind, make_number (ofd));
QUIT;
while ((n = read (ifd, buf, sizeof buf)) > 0)
if (write (ofd, buf, n) != n)
- report_file_error ("I/O error", Fcons (newname, Qnil));
+ report_file_error ("I/O error", Fcons (newname, Qnil));
immediate_quit = 0;
/* Closing the output clobbers the file times on some systems. */
if (set_file_times (XSTRING (newname)->data, atime, mtime))
report_file_error ("I/O error", Fcons (newname, Qnil));
}
+#ifndef MSDOS
+ chmod (XSTRING (newname)->data, st.st_mode & 07777);
+#else /* MSDOS */
+#if defined (__DJGPP__) && __DJGPP__ > 1
+ /* In DJGPP v2.0 and later, fstat usually returns true file mode bits,
+ and if it can't, it tells so. Otherwise, under MSDOS we usually
+ get only the READ bit, which will make the copied file read-only,
+ so it's better not to chmod at all. */
+ if ((_djstat_flags & _STFAIL_WRITEBIT) == 0)
chmod (XSTRING (newname)->data, st.st_mode & 07777);
+#endif /* DJGPP version 2 or newer */
+#endif /* MSDOS */
}
close (ifd);
if (NILP (ok_if_already_exists)
|| INTEGERP (ok_if_already_exists))
barf_or_query_if_file_exists (newname, "rename to it",
- INTEGERP (ok_if_already_exists));
+ INTEGERP (ok_if_already_exists), 0);
#ifndef BSD4_1
if (0 > rename (XSTRING (filename)->data, XSTRING (newname)->data))
#else
if (NILP (ok_if_already_exists)
|| INTEGERP (ok_if_already_exists))
barf_or_query_if_file_exists (newname, "make it a new name",
- INTEGERP (ok_if_already_exists));
+ INTEGERP (ok_if_already_exists), 0);
#ifdef WINDOWSNT
/* Windows does not support this operation. */
report_file_error ("Adding new name", Flist (2, &filename));
if (NILP (ok_if_already_exists)
|| INTEGERP (ok_if_already_exists))
barf_or_query_if_file_exists (linkname, "make it a link",
- INTEGERP (ok_if_already_exists));
+ INTEGERP (ok_if_already_exists), 0);
if (0 > symlink (XSTRING (filename)->data, XSTRING (linkname)->data))
{
/* If we didn't complain already, silently delete existing file. */
&& len >= 5
&& (stricmp ((suffix = filename + len-4), ".com") == 0
|| stricmp (suffix, ".exe") == 0
- || stricmp (suffix, ".bat") == 0));
+ || stricmp (suffix, ".bat") == 0)
+ || (st.st_mode & S_IFMT) == S_IFDIR);
#else /* not DOS_NT */
#ifdef HAVE_EACCESS
return (eaccess (filename, 1) >= 0);
Otherwise loop around and scan the preceding bufferfull. */
if (bufpos != 0)
break;
+ /* If display current starts at beginning of line,
+ keep it that way. */
+ if (XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+ XWINDOW (selected_window)->start_at_line_beg = Fbolp ();
}
immediate_quit = 0;
nwritten += XINT (end) - tem;
save_errno = errno;
}
-
- if (nwritten == 0)
- {
- /* If file was empty, still need to write the annotations */
- failure = 0 > a_write (desc, "", 0, XINT (start), &annotations);
- save_errno = errno;
- }
+ }
+ else
+ {
+ /* If file was empty, still need to write the annotations */
+ failure = 0 > a_write (desc, "", 0, XINT (start), &annotations);
+ save_errno = errno;
}
immediate_quit = 0;
Vinhibit_file_name_operation = Qnil;
DEFVAR_LISP ("auto-save-list-file-name", &Vauto_save_list_file_name,
- "File name in which we write a list of all auto save file names.");
+ "File name in which we write a list of all auto save file names.\n\
+This variable is initialized automatically from `auto-save-list-file-prefix'\n\
+shortly after Emacs reads your `.emacs' file, if you have not yet given it\n\
+a non-nil value.");
Vauto_save_list_file_name = Qnil;
defsubr (&Sfind_file_name_handler);