Parent: [6b0fd3] (diff)

Child: [2a3075] (diff)

Download this file

copyfile.cpp    66 lines (55 with data), 1.5 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#ifndef lint
static char rcsid[] = "@(#$Id: copyfile.cpp,v 1.2 2005-12-05 16:13:34 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string>
using std::string;
#include "debuglog.h"
#define CPBSIZ 8192
#define COPYFILE_NOERRUNLINK 1
bool copyfile(const char *src, const char *dst, string &reason, int flags = 0)
{
int sfd = -1;
int dfd = -1;
bool ret = false;
char buf[CPBSIZ];
reason.erase();
LOGDEB(("copyfile: %s to %s\n", src, dst));
if ((sfd = open(src, O_RDONLY)) < 0) {
reason += string("open ") + src + ": " + strerror(errno);
goto out;
}
if ((dfd = open(dst, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
reason += string("open/creat ") + dst + ": " + strerror(errno);
// If we fail because of an open/truncate error, we do not want to unlink
// the file, we might succeed...
flags |= COPYFILE_NOERRUNLINK;
goto out;
}
for (;;) {
int didread;
didread = read(sfd, buf, CPBSIZ);
if (didread < 0) {
reason += string("read src ") + src + ": " + strerror(errno);
goto out;
}
if (didread == 0)
break;
if (write(dfd, buf, didread) != didread) {
reason += string("write dst ") + src + ": " + strerror(errno);
goto out;
}
}
ret = true;
out:
if (ret == false && !(flags&COPYFILE_NOERRUNLINK))
unlink(dst);
if (sfd >= 0)
close(sfd);
if (dfd >= 0)
close(dfd);
return ret;
}