Move copy between files into its own module

This commit is contained in:
Kovid Goyal
2021-11-24 16:42:52 +05:30
parent f081d6a421
commit 732ff7ee58
3 changed files with 68 additions and 59 deletions

View File

@@ -368,5 +368,5 @@ void play_canberra_sound(const char *which_sound, const char *event_id, bool is_
SPRITE_MAP_HANDLE alloc_sprite_map(unsigned int, unsigned int);
SPRITE_MAP_HANDLE free_sprite_map(SPRITE_MAP_HANDLE);
const char* get_hyperlink_for_id(const HYPERLINK_POOL_HANDLE, hyperlink_id_type id, bool only_url);
bool copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf, size_t bufsz);
void log_event(const char *format, ...) __attribute__((format(printf, 1, 2)));

View File

@@ -7,10 +7,6 @@
#define EXTRA_INIT if (PyModule_AddFunctions(module, module_methods) != 0) return false;
#define MAX_KEY_SIZE 256u
#if __linux__
#define HAS_SENDFILE
#endif
#include "disk-cache.h"
#include "safe-wrappers.h"
#include "kitty-uthash.h"
@@ -22,9 +18,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#ifdef HAS_SENDFILE
#include <sys/sendfile.h>
#endif
typedef struct {
@@ -113,57 +106,6 @@ open_cache_file(const char *cache_path) {
}
// Write loop {{{
static bool
copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf, size_t bufsz) {
#ifdef HAS_SENDFILE
(void)buf; (void)bufsz;
unsigned num_of_consecutive_zero_returns = 128;
while (len) {
off_t r = in_pos;
ssize_t n = sendfile(outfd, infd, &r, len);
if (n < 0) {
if (errno != EAGAIN) return false;
continue;
}
if (n == 0) {
// happens if input file is truncated
if (!--num_of_consecutive_zero_returns) return false;
continue;
};
num_of_consecutive_zero_returns = 128;
in_pos += n; len -= n;
}
#else
while (len) {
ssize_t amt_read = pread(infd, buf, MIN(len, bufsz), in_pos);
if (amt_read < 0) {
if (errno == EINTR || errno == EAGAIN) continue;
return false;
}
if (amt_read == 0) {
errno = EIO;
return false;
}
len -= amt_read;
in_pos += amt_read;
uint8_t *p = buf;
while(amt_read) {
ssize_t amt_written = write(outfd, p, amt_read);
if (amt_written < 0) {
if (errno == EINTR || errno == EAGAIN) continue;
return false;
}
if (amt_written == 0) {
errno = EIO;
return false;
}
amt_read -= amt_written;
p += amt_written;
}
}
#endif
return true;
}
static off_t
size_of_cache_file(DiskCache *self) {

67
kitty/fast-file-copy.c Normal file
View File

@@ -0,0 +1,67 @@
/*
* fast-file-copy.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "data-types.h"
#if __linux__
#define HAS_SENDFILE
#endif
#ifdef HAS_SENDFILE
#include <sys/sendfile.h>
#endif
bool
copy_between_files(int infd, int outfd, off_t in_pos, size_t len, uint8_t *buf, size_t bufsz) {
#ifdef HAS_SENDFILE
(void)buf; (void)bufsz;
unsigned num_of_consecutive_zero_returns = 128;
while (len) {
off_t r = in_pos;
ssize_t n = sendfile(outfd, infd, &r, len);
if (n < 0) {
if (errno != EAGAIN) return false;
continue;
}
if (n == 0) {
// happens if input file is truncated
if (!--num_of_consecutive_zero_returns) return false;
continue;
};
num_of_consecutive_zero_returns = 128;
in_pos += n; len -= n;
}
#else
while (len) {
ssize_t amt_read = pread(infd, buf, MIN(len, bufsz), in_pos);
if (amt_read < 0) {
if (errno == EINTR || errno == EAGAIN) continue;
return false;
}
if (amt_read == 0) {
errno = EIO;
return false;
}
len -= amt_read;
in_pos += amt_read;
uint8_t *p = buf;
while(amt_read) {
ssize_t amt_written = write(outfd, p, amt_read);
if (amt_written < 0) {
if (errno == EINTR || errno == EAGAIN) continue;
return false;
}
if (amt_written == 0) {
errno = EIO;
return false;
}
amt_read -= amt_written;
p += amt_written;
}
}
#endif
return true;
}