main.c: Use fstat(2) on move_file
This allows to reuse the same file descriptor to both open(2) and fstat(2) the file.
This commit is contained in:
parent
f6b84b765d
commit
a578ad6537
54
main.c
54
main.c
|
@ -1057,23 +1057,23 @@ end:
|
|||
static int move_file(const char *const old, const char *const new)
|
||||
{
|
||||
int ret = -1;
|
||||
FILE *const f = fopen(old, "rb");
|
||||
const int fd = open(new, O_WRONLY | O_CREAT, 0600);
|
||||
const int fd_old = open(old, O_RDONLY),
|
||||
fd_new = open(new, O_WRONLY | O_CREAT, 0600);
|
||||
struct stat sb;
|
||||
|
||||
if (!f)
|
||||
if (fd_old < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: fopen(3): %s\n", __func__, strerror(errno));
|
||||
fprintf(stderr, "%s: open(2) fd_old: %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (fd < 0)
|
||||
else if (fd_new < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: open(2): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (stat(old, &sb))
|
||||
else if (fstat(fd_old, &sb))
|
||||
{
|
||||
fprintf(stderr, "%s: stat(2): %s\n", __func__, strerror(errno));
|
||||
fprintf(stderr, "%s: fstat(2): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -1082,24 +1082,30 @@ static int move_file(const char *const old, const char *const new)
|
|||
char buf[BUFSIZ];
|
||||
const off_t left = sb.st_size - i;
|
||||
const size_t rem = left > sizeof buf ? sizeof buf : left;
|
||||
ssize_t w;
|
||||
const ssize_t r = read(fd_old, buf, rem);
|
||||
|
||||
if (!fread(buf, rem, 1, f))
|
||||
if (r < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: fread(3) failed, feof=%d, ferror=%d\n",
|
||||
__func__, feof(f), ferror(f));
|
||||
fprintf(stderr, "%s: read(2): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if ((w = write(fd, buf, rem)) < 0)
|
||||
|
||||
size_t wrem = r;
|
||||
const void *p = buf;
|
||||
|
||||
while (wrem)
|
||||
{
|
||||
fprintf(stderr, "%s: write(2): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (w != rem)
|
||||
{
|
||||
fprintf(stderr, "%s: write(2): expected to write %zu bytes, "
|
||||
"only %ju written\n", __func__, rem, (intmax_t)w);
|
||||
goto end;
|
||||
const ssize_t w = write(fd_new, p, wrem);
|
||||
|
||||
if (w < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: write(2): %s\n",
|
||||
__func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
p = (const char *)p + w;
|
||||
wrem -= w;
|
||||
}
|
||||
|
||||
i += rem;
|
||||
|
@ -1108,15 +1114,15 @@ static int move_file(const char *const old, const char *const new)
|
|||
ret = 0;
|
||||
|
||||
end:
|
||||
if (fd >= 0 && close(fd))
|
||||
if (fd_old >= 0 && close(fd_old))
|
||||
{
|
||||
fprintf(stderr, "%s: close(2): %s\n", __func__, strerror(errno));
|
||||
fprintf(stderr, "%s: close(2) fd_old: %s\n", __func__, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (f && fclose(f))
|
||||
if (fd_new >= 0 && close(fd_new))
|
||||
{
|
||||
fprintf(stderr, "%s: fclose(3): %s\n", __func__, strerror(errno));
|
||||
fprintf(stderr, "%s: close(2) fd_new: %s\n", __func__, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue