libalpm/util: use low-level I/O for copyfile and checksum routines
This removes an unnecessary level of buffering. We are not doing line-based I/O here, so we can read in blocks of 8K at a time directly from the file. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
ba7a056d58
commit
ed3cd75736
1 changed files with 61 additions and 55 deletions
|
@ -125,46 +125,50 @@ int _alpm_makepath_mode(const char *path, mode_t mode)
|
||||||
|
|
||||||
int _alpm_copyfile(const char *src, const char *dest)
|
int _alpm_copyfile(const char *src, const char *dest)
|
||||||
{
|
{
|
||||||
FILE *in, *out;
|
|
||||||
size_t len;
|
|
||||||
char *buf;
|
char *buf;
|
||||||
int ret = 0;
|
int in, out, ret = 1;
|
||||||
|
ssize_t nread;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
in = fopen(src, "rb");
|
MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
|
||||||
if(in == NULL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
out = fopen(dest, "wb");
|
|
||||||
if(out == NULL) {
|
|
||||||
fclose(in);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, ret = 1; goto cleanup);
|
OPEN(in, src, O_RDONLY);
|
||||||
|
do {
|
||||||
/* do the actual file copy */
|
out = open(dest, O_WRONLY | O_CREAT, 0000);
|
||||||
while((len = fread(buf, 1, ALPM_BUFFER_SIZE, in))) {
|
} while(out == -1 && errno == EINTR);
|
||||||
size_t nwritten = 0;
|
if(in < 0 || out < 0) {
|
||||||
nwritten = fwrite(buf, 1, len, out);
|
|
||||||
if((nwritten != len) || ferror(out)) {
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fstat(in, &st) || fchmod(out, st.st_mode)) {
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* chmod dest to permissions of src */
|
/* do the actual file copy */
|
||||||
struct stat statbuf;
|
while((nread = read(in, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) {
|
||||||
if(!fstat(fileno(in), &statbuf)) {
|
ssize_t nwrite = 0;
|
||||||
fchmod(fileno(out), statbuf.st_mode);
|
if(nread < 0) {
|
||||||
} else {
|
continue;
|
||||||
/* stat was unsuccessful */
|
|
||||||
ret = 1;
|
|
||||||
}
|
}
|
||||||
|
do {
|
||||||
|
nwrite = write(out, buf + nwrite, nread);
|
||||||
|
if(nwrite >= 0) {
|
||||||
|
nread -= nwrite;
|
||||||
|
} else if(errno != EINTR) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} while(nread > 0);
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
fclose(in);
|
|
||||||
fclose(out);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
if(in >= 0) {
|
||||||
|
CLOSE(in);
|
||||||
|
}
|
||||||
|
if(out >= 0) {
|
||||||
|
CLOSE(out);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,49 +734,51 @@ int _alpm_lstat(const char *path, struct stat *buf)
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
static int md5_file(const char *path, unsigned char output[16])
|
static int md5_file(const char *path, unsigned char output[16])
|
||||||
{
|
{
|
||||||
FILE *f;
|
|
||||||
size_t n;
|
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
ssize_t n;
|
||||||
|
int fd;
|
||||||
|
|
||||||
CALLOC(buf, ALPM_BUFFER_SIZE, sizeof(unsigned char), return 1);
|
MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
|
||||||
|
|
||||||
if((f = fopen(path, "rb")) == NULL) {
|
OPEN(fd, path, O_RDONLY);
|
||||||
|
if(fd < 0) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5_Init(&ctx);
|
MD5_Init(&ctx);
|
||||||
|
|
||||||
while((n = fread(buf, 1, ALPM_BUFFER_SIZE, f)) > 0) {
|
while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) {
|
||||||
|
if(n < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
MD5_Update(&ctx, buf, n);
|
MD5_Update(&ctx, buf, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5_Final(output, &ctx);
|
CLOSE(fd);
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(MD5_CTX));
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
if(ferror(f) != 0) {
|
if(n < 0) {
|
||||||
fclose(f);
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
MD5_Final(output, &ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* third param is so we match the PolarSSL definition */
|
/* third param is so we match the PolarSSL definition */
|
||||||
static int sha2_file(const char *path, unsigned char output[32], int is224)
|
static int sha2_file(const char *path, unsigned char output[32], int is224)
|
||||||
{
|
{
|
||||||
FILE *f;
|
|
||||||
size_t n;
|
|
||||||
SHA256_CTX ctx;
|
SHA256_CTX ctx;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
ssize_t n;
|
||||||
|
int fd;
|
||||||
|
|
||||||
CALLOC(buf, ALPM_BUFFER_SIZE, sizeof(unsigned char), return 1);
|
MALLOC(buf, (size_t)ALPM_BUFFER_SIZE, return 1);
|
||||||
|
|
||||||
if((f = fopen(path, "rb")) == NULL) {
|
OPEN(fd, path, O_RDONLY);
|
||||||
|
if(fd < 0) {
|
||||||
free(buf);
|
free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -783,7 +789,10 @@ static int sha2_file(const char *path, unsigned char output[32], int is224)
|
||||||
SHA256_Init(&ctx);
|
SHA256_Init(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
while((n = fread(buf, 1, ALPM_BUFFER_SIZE, f)) > 0) {
|
while((n = read(fd, buf, ALPM_BUFFER_SIZE)) > 0 || errno == EINTR) {
|
||||||
|
if(n < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(is224) {
|
if(is224) {
|
||||||
SHA224_Update(&ctx, buf, n);
|
SHA224_Update(&ctx, buf, n);
|
||||||
} else {
|
} else {
|
||||||
|
@ -791,21 +800,18 @@ static int sha2_file(const char *path, unsigned char output[32], int is224)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLOSE(fd);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
if(n < 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if(is224) {
|
if(is224) {
|
||||||
SHA224_Final(output, &ctx);
|
SHA224_Final(output, &ctx);
|
||||||
} else {
|
} else {
|
||||||
SHA256_Final(output, &ctx);
|
SHA256_Final(output, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&ctx, 0, sizeof(SHA256_CTX));
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
if(ferror(f) != 0) {
|
|
||||||
fclose(f);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue