Revert "split out copy_file_fd"

This reverts commit 41203ad6abceb6dca39b2dab0adbd8fa711e1f89.
This commit is contained in:
Andrea Corallo 2019-12-24 08:18:08 +01:00
parent df62baa7d4
commit 080dacda78
2 changed files with 39 additions and 53 deletions

View file

@ -1989,55 +1989,6 @@ clone_file (int dest, int source)
}
#endif
/* Copy data to OFD from IFD if possible. Return NEWSIZE. */
off_t
copy_file_fd (int ofd, int ifd, struct stat *st, Lisp_Object newname,
Lisp_Object file)
{
off_t newsize;
if (clone_file (ofd, ifd))
newsize = st->st_size;
else
{
off_t insize = st->st_size;
ssize_t copied;
for (newsize = 0; newsize < insize; newsize += copied)
{
/* Copy at most COPY_MAX bytes at a time; this is min
(PTRDIFF_MAX, SIZE_MAX) truncated to a value that is
surely aligned well. */
ssize_t ssize_max = TYPE_MAXIMUM (ssize_t);
ptrdiff_t copy_max = min (ssize_max, SIZE_MAX) >> 30 << 30;
off_t intail = insize - newsize;
ptrdiff_t len = min (intail, copy_max);
copied = copy_file_range (ifd, NULL, ofd, NULL, len, 0);
if (copied <= 0)
break;
maybe_quit ();
}
/* Fall back on read+write if copy_file_range failed, or if the
input is empty and so could be a /proc file. read+write will
either succeed, or report an error more precisely than
copy_file_range would. */
if (newsize != insize || insize == 0)
{
char buf[MAX_ALLOCA];
for (; (copied = emacs_read_quit (ifd, buf, sizeof buf));
newsize += copied)
{
if (copied < 0)
report_file_error ("Read error", file);
if (emacs_write_quit (ofd, buf, copied) != copied)
report_file_error ("Write error", newname);
}
}
}
return newsize;
}
DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
"fCopy file: \nGCopy %s to file: \np\nP",
doc: /* Copy FILE to NEWNAME. Both args must be strings.
@ -2192,7 +2143,45 @@ permissions. */)
maybe_quit ();
newsize = copy_file_fd (ofd, ifd, &st, newname, file);
if (clone_file (ofd, ifd))
newsize = st.st_size;
else
{
off_t insize = st.st_size;
ssize_t copied;
for (newsize = 0; newsize < insize; newsize += copied)
{
/* Copy at most COPY_MAX bytes at a time; this is min
(PTRDIFF_MAX, SIZE_MAX) truncated to a value that is
surely aligned well. */
ssize_t ssize_max = TYPE_MAXIMUM (ssize_t);
ptrdiff_t copy_max = min (ssize_max, SIZE_MAX) >> 30 << 30;
off_t intail = insize - newsize;
ptrdiff_t len = min (intail, copy_max);
copied = copy_file_range (ifd, NULL, ofd, NULL, len, 0);
if (copied <= 0)
break;
maybe_quit ();
}
/* Fall back on read+write if copy_file_range failed, or if the
input is empty and so could be a /proc file. read+write will
either succeed, or report an error more precisely than
copy_file_range would. */
if (newsize != insize || insize == 0)
{
char buf[MAX_ALLOCA];
for (; (copied = emacs_read_quit (ifd, buf, sizeof buf));
newsize += copied)
{
if (copied < 0)
report_file_error ("Read error", file);
if (emacs_write_quit (ofd, buf, copied) != copied)
report_file_error ("Write error", newname);
}
}
}
/* Truncate any existing output file after writing the data. This
is more likely to work than truncation before writing, if the

View file

@ -34,8 +34,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <intprops.h>
#include <verify.h>
#include <sys/stat.h>
INLINE_HEADER_BEGIN
/* Define a TYPE constant ID as an externally visible name. Use like this:
@ -4320,7 +4318,6 @@ extern char *splice_dir_file (char *, char const *, char const *);
extern bool file_name_absolute_p (const char *);
extern char const *get_homedir (void);
extern Lisp_Object expand_and_dir_to_file (Lisp_Object);
extern off_t copy_file_fd (int, int, struct stat *, Lisp_Object, Lisp_Object);
extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, int);