Progress
This commit is contained in:
+22
-1
@@ -90,6 +90,7 @@ static int load_chunk(ChunkStore *store, SHA256 hash, string *data)
|
|||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
string path = hash2path(store, hash, buf);
|
string path = hash2path(store, hash, buf);
|
||||||
|
// TODO: check that the hash matches
|
||||||
return file_read_all(path, data);
|
return file_read_all(path, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,27 @@ static int store_chunk(ChunkStore *store, string data, SHA256 *hash)
|
|||||||
sha256(data.ptr, data.len, (uint8_t*) hash->data);
|
sha256(data.ptr, data.len, (uint8_t*) hash->data);
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
string path = hash2path(store, *hash, buf);
|
string path = hash2path(store, *hash, buf);
|
||||||
return file_write_atomic(path, data);
|
|
||||||
|
// Note that this write is not atomic. If we crash
|
||||||
|
// while writing, we'll get an inconsistent file.
|
||||||
|
// This is okay as long as we check that the hash
|
||||||
|
// is correct while reading back the data.
|
||||||
|
Handle fd;
|
||||||
|
if (file_open(path, &fd) < 0)
|
||||||
|
return -1;
|
||||||
|
int copied = 0;
|
||||||
|
while (copied < data.len) {
|
||||||
|
int ret = file_write(fd,
|
||||||
|
data.ptr + copied,
|
||||||
|
data.len - copied);
|
||||||
|
if (ret < 0) {
|
||||||
|
file_close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
copied += ret;
|
||||||
|
}
|
||||||
|
file_close(fd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chunk_store_get(ChunkStore *store, SHA256 hash, string *data)
|
static int chunk_store_get(ChunkStore *store, SHA256 hash, string *data)
|
||||||
|
|||||||
@@ -157,87 +157,6 @@ int file_size(Handle fd, size_t *len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: port to windows
|
|
||||||
#ifndef _WIN32
|
|
||||||
// TODO: test this
|
|
||||||
static string parent_path(string path)
|
|
||||||
{
|
|
||||||
if (path.len > 0 && path.ptr[path.len-1] == '/')
|
|
||||||
path.len--;
|
|
||||||
|
|
||||||
if (path.len == 0)
|
|
||||||
return S("");
|
|
||||||
|
|
||||||
while (path.len > 0 && path.ptr[path.len-1] != '/')
|
|
||||||
path.len--;
|
|
||||||
|
|
||||||
if (path.len > 0)
|
|
||||||
path.len--;
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
static int write_bytes(int fd, string data)
|
|
||||||
{
|
|
||||||
size_t written = 0;
|
|
||||||
while (written < (size_t) data.len) {
|
|
||||||
int ret = sys_write(fd, data.ptr + written, data.len - written);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
written += (size_t) ret;
|
|
||||||
}
|
|
||||||
assert((size_t) data.len == written);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int file_write_atomic(string path, string content)
|
|
||||||
{
|
|
||||||
string parent = parent_path(path);
|
|
||||||
|
|
||||||
char pattern[] = "/tmp_XXXXXXXX";
|
|
||||||
|
|
||||||
char tmp_path[PATH_MAX];
|
|
||||||
if (parent.len + strlen(pattern) >= (int) sizeof(tmp_path))
|
|
||||||
return -1;
|
|
||||||
memcpy(tmp_path, parent.ptr, parent.len);
|
|
||||||
memcpy(tmp_path + parent.len, pattern, strlen(pattern));
|
|
||||||
tmp_path[parent.len + strlen(pattern)] = '\0';
|
|
||||||
|
|
||||||
int fd = sys_mkstemp(tmp_path);
|
|
||||||
if (fd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (write_bytes(fd, content) < 0) {
|
|
||||||
sys_close(fd);
|
|
||||||
sys_remove(tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (sys__commit(fd)) {
|
|
||||||
sys_close(fd);
|
|
||||||
sys_remove(tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (sys_fsync(fd)) {
|
|
||||||
sys_close(fd);
|
|
||||||
sys_remove(tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (rename_file_or_dir((string) { tmp_path, strlen(tmp_path) }, path)) {
|
|
||||||
sys_remove(tmp_path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int create_dir(string path)
|
int create_dir(string path)
|
||||||
{
|
{
|
||||||
char zt[PATH_MAX];
|
char zt[PATH_MAX];
|
||||||
|
|||||||
+21
-4
@@ -1174,7 +1174,7 @@ int mock_connect(SOCKET fd, void *addr, size_t addr_len)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NATIVE_HANDLE
|
static int
|
||||||
wrap_native_file_into_desc(NATIVE_HANDLE handle)
|
wrap_native_file_into_desc(NATIVE_HANDLE handle)
|
||||||
{
|
{
|
||||||
if (current_process->num_desc == MAX_DESCRIPTORS) {
|
if (current_process->num_desc == MAX_DESCRIPTORS) {
|
||||||
@@ -1290,7 +1290,12 @@ HANDLE mock_CreateFileW(WCHAR *lpFileName, DWORD dwDesiredAccess,
|
|||||||
dwFlagsAndAttributes, hTemplateFile);
|
dwFlagsAndAttributes, hTemplateFile);
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
return wrap_native_file_into_desc(handle);
|
int fd = wrap_native_file_into_desc(handle);
|
||||||
|
if (fd < 0) {
|
||||||
|
CloseHandle(handle);
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
return (HANDLE) fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL mock_CloseHandle(HANDLE handle)
|
BOOL mock_CloseHandle(HANDLE handle)
|
||||||
@@ -1506,7 +1511,13 @@ int mock_open(char *path, int flags, int mode)
|
|||||||
int fd = open(path, flags, mode);
|
int fd = open(path, flags, mode);
|
||||||
if (fd < 0) return -1;
|
if (fd < 0) return -1;
|
||||||
|
|
||||||
return wrap_native_file_into_desc(fd);
|
int wrapped_fd = wrap_native_file_into_desc(fd);
|
||||||
|
if (wrapped_fd < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapped_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mock_close(int fd)
|
int mock_close(int fd)
|
||||||
@@ -1634,7 +1645,13 @@ int mock_mkstemp(char *path)
|
|||||||
int fd = mkstemp(path);
|
int fd = mkstemp(path);
|
||||||
if (fd < 0) return fd;
|
if (fd < 0) return fd;
|
||||||
|
|
||||||
return wrap_native_file_into_desc(fd);
|
int wrapped_fd = wrap_native_file_into_desc(fd);
|
||||||
|
if (wrapped_fd < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapped_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* mock_realpath(char *path, char *dst)
|
char* mock_realpath(char *path, char *dst)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SYSTEM_INCLUDED
|
#define SYSTEM_INCLUDED
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|||||||
Reference in New Issue
Block a user