ruby-libstorj 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +111 -0
- data/Guardfile +21 -0
- data/LICENSE +502 -0
- data/README.md +262 -0
- data/Rakefile +76 -0
- data/ext/libstorj/.gitignore +47 -0
- data/ext/libstorj/.travis.yml +27 -0
- data/ext/libstorj/Doxyfile +2427 -0
- data/ext/libstorj/LICENSE +502 -0
- data/ext/libstorj/Makefile.am +6 -0
- data/ext/libstorj/README.md +198 -0
- data/ext/libstorj/autogen.sh +3 -0
- data/ext/libstorj/configure.ac +64 -0
- data/ext/libstorj/depends/Makefile +153 -0
- data/ext/libstorj/depends/config.guess +1462 -0
- data/ext/libstorj/depends/config.sub +1823 -0
- data/ext/libstorj/depends/extract-osx-sdk.sh +33 -0
- data/ext/libstorj/depends/packages/cctools.mk +7 -0
- data/ext/libstorj/depends/packages/clang.mk +7 -0
- data/ext/libstorj/depends/packages/gmp.mk +23 -0
- data/ext/libstorj/depends/packages/gnutls.mk +25 -0
- data/ext/libstorj/depends/packages/json-c.mk +7 -0
- data/ext/libstorj/depends/packages/libcurl.mk +39 -0
- data/ext/libstorj/depends/packages/libmicrohttpd.mk +7 -0
- data/ext/libstorj/depends/packages/libuv.mk +7 -0
- data/ext/libstorj/depends/packages/nettle.mk +30 -0
- data/ext/libstorj/libstorj.pc.in +11 -0
- data/ext/libstorj/src/Makefile.am +23 -0
- data/ext/libstorj/src/bip39.c +233 -0
- data/ext/libstorj/src/bip39.h +64 -0
- data/ext/libstorj/src/bip39_english.h +2074 -0
- data/ext/libstorj/src/cli.c +1494 -0
- data/ext/libstorj/src/crypto.c +525 -0
- data/ext/libstorj/src/crypto.h +178 -0
- data/ext/libstorj/src/downloader.c +1923 -0
- data/ext/libstorj/src/downloader.h +163 -0
- data/ext/libstorj/src/http.c +688 -0
- data/ext/libstorj/src/http.h +175 -0
- data/ext/libstorj/src/rs.c +962 -0
- data/ext/libstorj/src/rs.h +99 -0
- data/ext/libstorj/src/storj.c +1523 -0
- data/ext/libstorj/src/storj.h +1014 -0
- data/ext/libstorj/src/uploader.c +2736 -0
- data/ext/libstorj/src/uploader.h +181 -0
- data/ext/libstorj/src/utils.c +336 -0
- data/ext/libstorj/src/utils.h +65 -0
- data/ext/libstorj/test/Makefile.am +27 -0
- data/ext/libstorj/test/mockbridge.c +260 -0
- data/ext/libstorj/test/mockbridge.json +687 -0
- data/ext/libstorj/test/mockbridgeinfo.json +1836 -0
- data/ext/libstorj/test/mockfarmer.c +358 -0
- data/ext/libstorj/test/storjtests.h +41 -0
- data/ext/libstorj/test/tests.c +1617 -0
- data/ext/libstorj/test/tests_rs.c +869 -0
- data/ext/ruby-libstorj/extconf.rb +8 -0
- data/ext/ruby-libstorj/ruby-libstorj.cc +17 -0
- data/lib/ruby-libstorj.rb +1 -0
- data/lib/ruby-libstorj/arg_forwarding_task.rb +58 -0
- data/lib/ruby-libstorj/env.rb +178 -0
- data/lib/ruby-libstorj/ext/bucket.rb +71 -0
- data/lib/ruby-libstorj/ext/create_bucket_request.rb +53 -0
- data/lib/ruby-libstorj/ext/curl_code.rb +139 -0
- data/lib/ruby-libstorj/ext/ext.rb +71 -0
- data/lib/ruby-libstorj/ext/file.rb +84 -0
- data/lib/ruby-libstorj/ext/get_bucket_request.rb +45 -0
- data/lib/ruby-libstorj/ext/json_request.rb +51 -0
- data/lib/ruby-libstorj/ext/list_files_request.rb +63 -0
- data/lib/ruby-libstorj/ext/types.rb +226 -0
- data/lib/ruby-libstorj/ext/upload_options.rb +38 -0
- data/lib/ruby-libstorj/libstorj.rb +22 -0
- data/lib/ruby-libstorj/mixins/storj.rb +27 -0
- data/lib/ruby-libstorj/struct.rb +42 -0
- data/ruby-libstorj.gemspec +57 -0
- data/spec/helpers/options.yml.example +22 -0
- data/spec/helpers/shared_rake_examples.rb +132 -0
- data/spec/helpers/storj_options.rb +96 -0
- data/spec/helpers/upload.data +3 -0
- data/spec/helpers/upload.data.sha256 +1 -0
- data/spec/libstorj_spec.rb +0 -0
- data/spec/ruby-libstorj/arg_forwarding_task_spec.rb +311 -0
- data/spec/ruby-libstorj/env_spec.rb +353 -0
- data/spec/ruby-libstorj/ext_spec.rb +75 -0
- data/spec/ruby-libstorj/json_request_spec.rb +13 -0
- data/spec/ruby-libstorj/libstorj_spec.rb +81 -0
- data/spec/ruby-libstorj/struct_spec.rb +64 -0
- data/spec/spec_helper.rb +113 -0
- metadata +136 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file uploader.h
|
|
3
|
+
* @brief Storj upload methods and definitions.
|
|
4
|
+
*
|
|
5
|
+
* Structures and functions useful for uploading files.
|
|
6
|
+
*/
|
|
7
|
+
#ifndef STORJ_UPLOADER_H
|
|
8
|
+
#define STORJ_UPLOADER_H
|
|
9
|
+
#include "storj.h"
|
|
10
|
+
#include "http.h"
|
|
11
|
+
#include "utils.h"
|
|
12
|
+
#include "crypto.h"
|
|
13
|
+
#include "rs.h"
|
|
14
|
+
|
|
15
|
+
#define STORJ_NULL -1
|
|
16
|
+
#define STORJ_MAX_REPORT_TRIES 2
|
|
17
|
+
#define STORJ_MAX_PUSH_FRAME_COUNT 6
|
|
18
|
+
|
|
19
|
+
typedef enum {
|
|
20
|
+
CANCELED = 0,
|
|
21
|
+
AWAITING_PREPARE_FRAME = 1,
|
|
22
|
+
PREPARING_FRAME = 2,
|
|
23
|
+
AWAITING_PUSH_FRAME = 3,
|
|
24
|
+
PUSHING_FRAME = 4,
|
|
25
|
+
AWAITING_PUSH_SHARD = 5,
|
|
26
|
+
PUSHING_SHARD = 6,
|
|
27
|
+
COMPLETED_PUSH_SHARD = 7
|
|
28
|
+
} storj_state_progress_t;
|
|
29
|
+
|
|
30
|
+
typedef enum {
|
|
31
|
+
PREPARE_FRAME_LIMIT = 1,
|
|
32
|
+
PUSH_FRAME_LIMIT = 32,
|
|
33
|
+
PUSH_SHARD_LIMIT = 32
|
|
34
|
+
} storj_state_progress_limits_t;
|
|
35
|
+
|
|
36
|
+
typedef struct {
|
|
37
|
+
/* state should not be modified in worker threads */
|
|
38
|
+
storj_upload_state_t *upload_state;
|
|
39
|
+
int status_code;
|
|
40
|
+
int error_status;
|
|
41
|
+
shard_meta_t *shard_meta;
|
|
42
|
+
// Position in shard meta array
|
|
43
|
+
int shard_meta_index;
|
|
44
|
+
// Either parity file pointer or original file
|
|
45
|
+
FILE *shard_file;
|
|
46
|
+
storj_log_levels_t *log;
|
|
47
|
+
} frame_builder_t;
|
|
48
|
+
|
|
49
|
+
typedef struct {
|
|
50
|
+
int error_status;
|
|
51
|
+
/* state should not be modified in worker threads */
|
|
52
|
+
storj_upload_state_t *upload_state;
|
|
53
|
+
} parity_shard_req_t;
|
|
54
|
+
|
|
55
|
+
typedef struct {
|
|
56
|
+
int error_status;
|
|
57
|
+
/* state should not be modified in worker threads */
|
|
58
|
+
storj_upload_state_t *upload_state;
|
|
59
|
+
} encrypt_file_req_t;
|
|
60
|
+
|
|
61
|
+
typedef struct {
|
|
62
|
+
storj_http_options_t *http_options;
|
|
63
|
+
storj_bridge_options_t *options;
|
|
64
|
+
int status_code;
|
|
65
|
+
int error_status;
|
|
66
|
+
storj_log_levels_t *log;
|
|
67
|
+
int shard_index;
|
|
68
|
+
int shard_meta_index;
|
|
69
|
+
FILE *shard_file;
|
|
70
|
+
uv_async_t progress_handle;
|
|
71
|
+
uint64_t start;
|
|
72
|
+
uint64_t end;
|
|
73
|
+
|
|
74
|
+
/* state should not be modified in worker threads */
|
|
75
|
+
storj_upload_state_t *upload_state;
|
|
76
|
+
bool *canceled;
|
|
77
|
+
} push_shard_request_t;
|
|
78
|
+
|
|
79
|
+
typedef struct {
|
|
80
|
+
storj_http_options_t *http_options;
|
|
81
|
+
storj_bridge_options_t *options;
|
|
82
|
+
char *token;
|
|
83
|
+
const char *bucket_id;
|
|
84
|
+
char *bucket_op;
|
|
85
|
+
/* state should not be modified in worker threads */
|
|
86
|
+
storj_upload_state_t *upload_state;
|
|
87
|
+
int status_code;
|
|
88
|
+
int error_status;
|
|
89
|
+
storj_log_levels_t *log;
|
|
90
|
+
} request_token_t;
|
|
91
|
+
|
|
92
|
+
typedef struct {
|
|
93
|
+
storj_http_options_t *http_options;
|
|
94
|
+
storj_bridge_options_t *options;
|
|
95
|
+
/* state should not be modified in worker threads */
|
|
96
|
+
storj_upload_state_t *upload_state;
|
|
97
|
+
char *frame_id;
|
|
98
|
+
int status_code;
|
|
99
|
+
int error_status;
|
|
100
|
+
|
|
101
|
+
// Add shard to frame
|
|
102
|
+
int shard_meta_index;
|
|
103
|
+
farmer_pointer_t *farmer_pointer;
|
|
104
|
+
|
|
105
|
+
storj_log_levels_t *log;
|
|
106
|
+
} frame_request_t;
|
|
107
|
+
|
|
108
|
+
typedef struct {
|
|
109
|
+
storj_http_options_t *http_options;
|
|
110
|
+
storj_bridge_options_t *options;
|
|
111
|
+
/* state should not be modified in worker threads */
|
|
112
|
+
storj_upload_state_t *upload_state;
|
|
113
|
+
int status_code;
|
|
114
|
+
int error_status;
|
|
115
|
+
struct json_object *response;
|
|
116
|
+
storj_log_levels_t *log;
|
|
117
|
+
} post_to_bucket_request_t;
|
|
118
|
+
|
|
119
|
+
typedef struct {
|
|
120
|
+
uint32_t pointer_index;
|
|
121
|
+
storj_http_options_t *http_options;
|
|
122
|
+
storj_bridge_options_t *options;
|
|
123
|
+
int status_code;
|
|
124
|
+
storj_exchange_report_t *report;
|
|
125
|
+
/* state should not be modified in worker threads */
|
|
126
|
+
storj_upload_state_t *state;
|
|
127
|
+
} shard_send_report_t;
|
|
128
|
+
|
|
129
|
+
static farmer_pointer_t *farmer_pointer_new();
|
|
130
|
+
static shard_meta_t *shard_meta_new();
|
|
131
|
+
static uv_work_t *shard_meta_work_new(int index, storj_upload_state_t *state);
|
|
132
|
+
static uv_work_t *frame_work_new(int *index, storj_upload_state_t *state);
|
|
133
|
+
static uv_work_t *uv_work_new();
|
|
134
|
+
static int prepare_encryption_key(storj_upload_state_t *state,
|
|
135
|
+
char *pre_pass,
|
|
136
|
+
int pre_pass_size,
|
|
137
|
+
char *pre_salt,
|
|
138
|
+
int pre_salt_size);
|
|
139
|
+
|
|
140
|
+
static int check_in_progress(storj_upload_state_t *state, int status);
|
|
141
|
+
char *create_tmp_name(storj_upload_state_t *state, char *extension);
|
|
142
|
+
|
|
143
|
+
static void shard_meta_cleanup(shard_meta_t *shard_meta);
|
|
144
|
+
static void pointer_cleanup(farmer_pointer_t *farmer_pointer);
|
|
145
|
+
static void cleanup_state(storj_upload_state_t *state);
|
|
146
|
+
static void free_encryption_ctx(storj_encryption_ctx_t *ctx);
|
|
147
|
+
|
|
148
|
+
static void queue_next_work(storj_upload_state_t *state);
|
|
149
|
+
|
|
150
|
+
static void queue_request_frame_id(storj_upload_state_t *state);
|
|
151
|
+
static void queue_prepare_frame(storj_upload_state_t *state, int index);
|
|
152
|
+
static void queue_push_frame(storj_upload_state_t *state, int index);
|
|
153
|
+
static void queue_push_shard(storj_upload_state_t *state, int index);
|
|
154
|
+
static void queue_create_bucket_entry(storj_upload_state_t *state);
|
|
155
|
+
static void queue_send_exchange_report(storj_upload_state_t *state, int index);
|
|
156
|
+
static void queue_create_encrypted_file(storj_upload_state_t *state);
|
|
157
|
+
|
|
158
|
+
static void request_token(uv_work_t *work);
|
|
159
|
+
static void request_frame_id(uv_work_t *work);
|
|
160
|
+
static void prepare_frame(uv_work_t *work);
|
|
161
|
+
static void push_frame(uv_work_t *work);
|
|
162
|
+
static void push_shard(uv_work_t *work);
|
|
163
|
+
static void create_bucket_entry(uv_work_t *work);
|
|
164
|
+
static void send_exchange_report(uv_work_t *work);
|
|
165
|
+
static void create_encrypted_file(uv_work_t *work);
|
|
166
|
+
|
|
167
|
+
static void after_request_token(uv_work_t *work, int status);
|
|
168
|
+
static void after_request_frame_id(uv_work_t *work, int status);
|
|
169
|
+
static void after_prepare_frame(uv_work_t *work, int status);
|
|
170
|
+
static void after_push_frame(uv_work_t *work, int status);
|
|
171
|
+
static void after_push_shard(uv_work_t *work, int status);
|
|
172
|
+
static void after_create_bucket_entry(uv_work_t *work, int status);
|
|
173
|
+
static void after_send_exchange_report(uv_work_t *work, int status);
|
|
174
|
+
static void after_create_encrypted_file(uv_work_t *work, int status);
|
|
175
|
+
|
|
176
|
+
static void queue_verify_bucket_id(storj_upload_state_t *state);
|
|
177
|
+
static void queue_verify_file_id(storj_upload_state_t *state);
|
|
178
|
+
static void verify_bucket_id_callback(uv_work_t *work_req, int status);
|
|
179
|
+
static void verify_file_id_callback(uv_work_t *work_req, int status);
|
|
180
|
+
|
|
181
|
+
#endif /* STORJ_UPLOADER_H */
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
#include "utils.h"
|
|
2
|
+
|
|
3
|
+
char *hex2str(size_t length, uint8_t *data)
|
|
4
|
+
{
|
|
5
|
+
size_t encode_len = BASE16_ENCODE_LENGTH(length);
|
|
6
|
+
uint8_t *result = calloc(encode_len + 1, sizeof(uint8_t));
|
|
7
|
+
if (!result) {
|
|
8
|
+
return NULL;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
base16_encode_update(result, length, data);
|
|
12
|
+
|
|
13
|
+
return (char *)result;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
void print_int_array(uint8_t *array, unsigned length)
|
|
17
|
+
{
|
|
18
|
+
printf("{");
|
|
19
|
+
for (int i = 0; i < length; i++) {
|
|
20
|
+
printf("%i", array[i]);
|
|
21
|
+
if (i != length - 1) {
|
|
22
|
+
printf(",");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
printf("}\n");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
uint8_t *str2hex(size_t length, char *data)
|
|
29
|
+
{
|
|
30
|
+
char *result = calloc(BASE16_DECODE_LENGTH(length) + 1, sizeof(char));
|
|
31
|
+
if (!result) {
|
|
32
|
+
return NULL;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
struct base16_decode_ctx *ctx = malloc(sizeof(struct base16_decode_ctx));
|
|
36
|
+
base16_decode_init(ctx);
|
|
37
|
+
|
|
38
|
+
size_t decode_len = 0;
|
|
39
|
+
if (!base16_decode_update(ctx, &decode_len, (uint8_t *)result,
|
|
40
|
+
length, (uint8_t *)data)) {
|
|
41
|
+
free(result);
|
|
42
|
+
free(ctx);
|
|
43
|
+
return NULL;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!base16_decode_final(ctx)) {
|
|
47
|
+
free(result);
|
|
48
|
+
free(ctx);
|
|
49
|
+
return NULL;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
free(ctx);
|
|
53
|
+
return (uint8_t *)result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
char *str_concat_many(int count, ...)
|
|
57
|
+
{
|
|
58
|
+
int length = 1;
|
|
59
|
+
|
|
60
|
+
va_list args;
|
|
61
|
+
va_start(args, count);
|
|
62
|
+
for (int i = 0; i < count; i++) {
|
|
63
|
+
char *item = va_arg(args, char *);
|
|
64
|
+
length += strlen(item);
|
|
65
|
+
}
|
|
66
|
+
va_end(args);
|
|
67
|
+
|
|
68
|
+
char *combined = calloc(length, sizeof(char));
|
|
69
|
+
if (!combined) {
|
|
70
|
+
return NULL;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
va_start(args, count);
|
|
74
|
+
for (int i = 0; i < count; i++) {
|
|
75
|
+
char *item = va_arg(args, char *);
|
|
76
|
+
strcat(combined, item);
|
|
77
|
+
}
|
|
78
|
+
va_end(args);
|
|
79
|
+
|
|
80
|
+
return combined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void random_buffer(uint8_t *buf, size_t len)
|
|
84
|
+
{
|
|
85
|
+
static FILE *frand = NULL;
|
|
86
|
+
#ifdef _WIN32
|
|
87
|
+
HCRYPTPROV hProvider;
|
|
88
|
+
int ret = CryptAcquireContext(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
|
|
89
|
+
assert(ret);
|
|
90
|
+
ret = CryptGenRandom(hProvider, len, buf);
|
|
91
|
+
assert(ret);
|
|
92
|
+
CryptReleaseContext(hProvider, 0);
|
|
93
|
+
#else
|
|
94
|
+
if (!frand) {
|
|
95
|
+
frand = fopen("/dev/urandom", "r");
|
|
96
|
+
}
|
|
97
|
+
size_t len_read = fread(buf, 1, len, frand);
|
|
98
|
+
(void)len_read;
|
|
99
|
+
assert(len_read == len);
|
|
100
|
+
#endif
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
uint64_t shard_size(int hops)
|
|
104
|
+
{
|
|
105
|
+
return MIN_SHARD_SIZE * pow(2, hops);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
uint64_t get_time_milliseconds() {
|
|
109
|
+
#ifdef _WIN32
|
|
110
|
+
|
|
111
|
+
// Time between windows epoch and standard epoch
|
|
112
|
+
const int64_t time_to_epoch = 116444736000000000LL;
|
|
113
|
+
|
|
114
|
+
FILETIME ft;
|
|
115
|
+
|
|
116
|
+
GetSystemTimeAsFileTime(&ft);
|
|
117
|
+
|
|
118
|
+
LARGE_INTEGER li;
|
|
119
|
+
li.LowPart = ft.dwLowDateTime;
|
|
120
|
+
li.HighPart = ft.dwHighDateTime;
|
|
121
|
+
li.QuadPart -= time_to_epoch;
|
|
122
|
+
li.QuadPart /= 10000;
|
|
123
|
+
|
|
124
|
+
uint64_t milliseconds = li.QuadPart;
|
|
125
|
+
#else
|
|
126
|
+
struct timeval t;
|
|
127
|
+
gettimeofday(&t, NULL);
|
|
128
|
+
uint64_t milliseconds = t.tv_sec * 1000LL + t.tv_usec / 1000;
|
|
129
|
+
#endif
|
|
130
|
+
|
|
131
|
+
return milliseconds;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
void memset_zero(void *v, size_t n)
|
|
135
|
+
{
|
|
136
|
+
#ifdef _WIN32
|
|
137
|
+
SecureZeroMemory(v, n);
|
|
138
|
+
#else
|
|
139
|
+
volatile unsigned char *p = v;
|
|
140
|
+
while (n--) {
|
|
141
|
+
*p++ = 0;
|
|
142
|
+
}
|
|
143
|
+
#endif
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
uint64_t determine_shard_size(uint64_t file_size, int accumulator)
|
|
147
|
+
{
|
|
148
|
+
if (file_size <= 0) {
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
accumulator = accumulator ? accumulator : 0;
|
|
153
|
+
|
|
154
|
+
// Determine hops back by accumulator
|
|
155
|
+
int hops = ((accumulator - SHARD_MULTIPLES_BACK) < 0 ) ?
|
|
156
|
+
0 : accumulator - SHARD_MULTIPLES_BACK;
|
|
157
|
+
|
|
158
|
+
uint64_t byte_multiple = shard_size(accumulator);
|
|
159
|
+
double check = (double) file_size / byte_multiple;
|
|
160
|
+
|
|
161
|
+
// Determine if bytemultiple is highest bytemultiple that is still <= size
|
|
162
|
+
if (check > 0 && check <= 1) {
|
|
163
|
+
while (hops > 0 && shard_size(hops) > MAX_SHARD_SIZE) {
|
|
164
|
+
hops = hops - 1 <= 0 ? 0 : hops - 1;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return shard_size(hops);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Maximum of 2 ^ 41 * 8 * 1024 * 1024
|
|
171
|
+
if (accumulator > 41) {
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return determine_shard_size(file_size, ++accumulator);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#ifdef _WIN32
|
|
179
|
+
ssize_t pread(int fd, void *buf, size_t count, uint64_t offset)
|
|
180
|
+
{
|
|
181
|
+
long unsigned int read_bytes = 0;
|
|
182
|
+
|
|
183
|
+
OVERLAPPED overlapped;
|
|
184
|
+
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
|
185
|
+
|
|
186
|
+
overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32);
|
|
187
|
+
overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
|
188
|
+
|
|
189
|
+
HANDLE file = (HANDLE)_get_osfhandle(fd);
|
|
190
|
+
SetLastError(0);
|
|
191
|
+
bool RF = ReadFile(file, buf, count, &read_bytes, &overlapped);
|
|
192
|
+
|
|
193
|
+
// For some reason it errors when it hits end of file so we don't want to check that
|
|
194
|
+
if ((RF == 0) && GetLastError() != ERROR_HANDLE_EOF) {
|
|
195
|
+
errno = GetLastError();
|
|
196
|
+
// printf ("Error reading file : %d\n", GetLastError());
|
|
197
|
+
return -1;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return read_bytes;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
ssize_t pwrite(int fd, const void *buf, size_t count, uint64_t offset)
|
|
204
|
+
{
|
|
205
|
+
long unsigned int written_bytes = 0;
|
|
206
|
+
|
|
207
|
+
OVERLAPPED overlapped;
|
|
208
|
+
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
|
209
|
+
|
|
210
|
+
overlapped.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 32);
|
|
211
|
+
overlapped.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
|
|
212
|
+
|
|
213
|
+
HANDLE file = (HANDLE)_get_osfhandle(fd);
|
|
214
|
+
SetLastError(0);
|
|
215
|
+
bool RF = WriteFile(file, buf, count, &written_bytes, &overlapped);
|
|
216
|
+
if ((RF == 0)) {
|
|
217
|
+
errno = GetLastError();
|
|
218
|
+
// printf ("Error reading file :%d\n", GetLastError());
|
|
219
|
+
return -1;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return written_bytes;
|
|
223
|
+
}
|
|
224
|
+
#endif
|
|
225
|
+
|
|
226
|
+
int allocatefile(int fd, uint64_t length)
|
|
227
|
+
{
|
|
228
|
+
#ifdef _WIN32
|
|
229
|
+
HANDLE file = (HANDLE)_get_osfhandle(fd);
|
|
230
|
+
if (file == INVALID_HANDLE_VALUE) {
|
|
231
|
+
return EBADF;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
int status = 0;
|
|
235
|
+
|
|
236
|
+
LARGE_INTEGER size;
|
|
237
|
+
size.HighPart = (uint32_t)((length & 0xFFFFFFFF00000000LL) >> 32);
|
|
238
|
+
size.LowPart = (uint32_t)(length & 0xFFFFFFFFLL);
|
|
239
|
+
|
|
240
|
+
if (!SetFilePointerEx(file, size, 0, FILE_BEGIN)) {
|
|
241
|
+
status = GetLastError();
|
|
242
|
+
goto win_finished;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!SetEndOfFile(file)) {
|
|
246
|
+
status = GetLastError();
|
|
247
|
+
goto win_finished;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
win_finished:
|
|
251
|
+
|
|
252
|
+
return status;
|
|
253
|
+
#elif HAVE_POSIX_FALLOCATE
|
|
254
|
+
return posix_fallocate(fd, 0, length);
|
|
255
|
+
#elif __unix__
|
|
256
|
+
if (fallocate(fd, 0, 0, length)) {
|
|
257
|
+
return errno;
|
|
258
|
+
}
|
|
259
|
+
return 0;
|
|
260
|
+
#elif __linux__
|
|
261
|
+
if (fallocate(fd, 0, 0, length)) {
|
|
262
|
+
return errno;
|
|
263
|
+
}
|
|
264
|
+
return 0;
|
|
265
|
+
#elif __APPLE__
|
|
266
|
+
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, length, 0};
|
|
267
|
+
// Try to get a continous chunk of disk space
|
|
268
|
+
int ret = fcntl(fd, F_PREALLOCATE, &store);
|
|
269
|
+
if (-1 == ret) {
|
|
270
|
+
// OK, perhaps we are too fragmented, allocate non-continuous
|
|
271
|
+
store.fst_flags = F_ALLOCATEALL;
|
|
272
|
+
ret = fcntl(fd, F_PREALLOCATE, &store);
|
|
273
|
+
if ( -1 == ret) {
|
|
274
|
+
return -1;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return ftruncate(fd, length);
|
|
278
|
+
#else
|
|
279
|
+
return -1;
|
|
280
|
+
#endif
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
int unmap_file(uint8_t *map, uint64_t filesize)
|
|
285
|
+
{
|
|
286
|
+
#ifdef _WIN32
|
|
287
|
+
if (!FlushViewOfFile(map, filesize)) {
|
|
288
|
+
return GetLastError();
|
|
289
|
+
}
|
|
290
|
+
if (!UnmapViewOfFile(map)) {
|
|
291
|
+
return GetLastError();
|
|
292
|
+
}
|
|
293
|
+
#else
|
|
294
|
+
if (munmap(map, filesize)) {
|
|
295
|
+
return errno;
|
|
296
|
+
}
|
|
297
|
+
#endif
|
|
298
|
+
return 0;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
int map_file(int fd, uint64_t filesize, uint8_t **map, bool read_only)
|
|
302
|
+
{
|
|
303
|
+
int status = 0;
|
|
304
|
+
#ifdef _WIN32
|
|
305
|
+
HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
|
306
|
+
if (fh == INVALID_HANDLE_VALUE) {
|
|
307
|
+
return EBADF;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
int prot = read_only ? PAGE_READONLY : PAGE_READWRITE;
|
|
311
|
+
|
|
312
|
+
HANDLE mh = CreateFileMapping(fh, NULL, prot, 0, 0, NULL);
|
|
313
|
+
if (!mh) {
|
|
314
|
+
status = GetLastError();
|
|
315
|
+
goto win_finished;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
prot = read_only ? FILE_MAP_READ : FILE_MAP_WRITE;
|
|
319
|
+
|
|
320
|
+
*map = MapViewOfFileEx(mh, prot, 0, 0, filesize, NULL);
|
|
321
|
+
if (!*map) {
|
|
322
|
+
status = GetLastError();
|
|
323
|
+
goto win_finished;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
win_finished:
|
|
327
|
+
CloseHandle(mh);
|
|
328
|
+
#else
|
|
329
|
+
int prot = read_only ? PROT_READ : PROT_READ | PROT_WRITE;
|
|
330
|
+
*map = (uint8_t *)mmap(NULL, filesize, prot, MAP_SHARED, fd, 0);
|
|
331
|
+
if (*map == MAP_FAILED) {
|
|
332
|
+
status = errno;
|
|
333
|
+
}
|
|
334
|
+
#endif
|
|
335
|
+
return status;
|
|
336
|
+
}
|