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];
|
||||
string path = hash2path(store, hash, buf);
|
||||
// TODO: check that the hash matches
|
||||
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);
|
||||
char buf[PATH_MAX];
|
||||
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)
|
||||
|
||||
@@ -157,87 +157,6 @@ int file_size(Handle fd, size_t *len)
|
||||
#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)
|
||||
{
|
||||
char zt[PATH_MAX];
|
||||
|
||||
+21
-4
@@ -1174,7 +1174,7 @@ int mock_connect(SOCKET fd, void *addr, size_t addr_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static NATIVE_HANDLE
|
||||
static int
|
||||
wrap_native_file_into_desc(NATIVE_HANDLE handle)
|
||||
{
|
||||
if (current_process->num_desc == MAX_DESCRIPTORS) {
|
||||
@@ -1290,7 +1290,12 @@ HANDLE mock_CreateFileW(WCHAR *lpFileName, DWORD dwDesiredAccess,
|
||||
dwFlagsAndAttributes, hTemplateFile);
|
||||
if (handle == 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)
|
||||
@@ -1506,7 +1511,13 @@ int mock_open(char *path, int flags, int mode)
|
||||
int fd = open(path, flags, mode);
|
||||
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)
|
||||
@@ -1634,7 +1645,13 @@ int mock_mkstemp(char *path)
|
||||
int fd = mkstemp(path);
|
||||
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)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SYSTEM_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
Reference in New Issue
Block a user