isomorfeus-ferret 0.15.0 → 0.16.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.
@@ -1,479 +0,0 @@
1
- #include "frt_store.h"
2
- #include "frt_lang.h"
3
- #include <time.h>
4
- #include <sys/types.h>
5
- #include <fcntl.h>
6
- #include <sys/stat.h>
7
- #include <errno.h>
8
- #include <string.h>
9
- #include <stdio.h>
10
- #if (defined POSH_OS_WIN32 || defined POSH_OS_WIN64) && !defined __MINGW32__
11
- # include <io.h>
12
- # include "frt_win32.h"
13
- # ifndef sleep
14
- # define sleep _sleep
15
- # endif
16
- # ifndef DIR_SEPARATOR
17
- # define DIR_SEPARATOR "\\"
18
- # define DIR_SEPARATOR_CHAR '\\'
19
- # endif
20
- # ifndef S_IRUSR
21
- # define S_IRUSR _S_IREAD
22
- # endif
23
- # ifndef S_IWUSR
24
- # define S_IWUSR _S_IWRITE
25
- # endif
26
- #else
27
- # define DIR_SEPARATOR "/"
28
- # define DIR_SEPARATOR_CHAR '/'
29
- # include <unistd.h>
30
- # include <dirent.h>
31
- #endif
32
- #ifndef O_BINARY
33
- # define O_BINARY 0
34
- #endif
35
-
36
- extern void frt_micro_sleep(const int micro_seconds);
37
-
38
- /**
39
- * Create a filepath for a file in the store using the operating systems
40
- * default file seperator.
41
- */
42
- static char *join_path(char *buf, const char *base, const char *filename) {
43
- snprintf(buf, FRT_MAX_FILE_PATH, "%s"DIR_SEPARATOR"%s", base, filename);
44
- return buf;
45
- }
46
-
47
- static void fs_touch(FrtStore *store, const char *filename) {
48
- int f;
49
- char path[FRT_MAX_FILE_PATH];
50
- join_path(path, store->dir.path, filename);
51
- if ((f = creat(path, store->file_mode)) == 0) {
52
- FRT_RAISE(FRT_IO_ERROR, "couldn't create file %s: <%s>", path,
53
- strerror(errno));
54
- }
55
- close(f);
56
- }
57
-
58
- static int fs_exists(FrtStore *store, const char *filename) {
59
- int fd;
60
- char path[FRT_MAX_FILE_PATH];
61
- join_path(path, store->dir.path, filename);
62
- fd = open(path, 0);
63
- if (fd < 0) {
64
- if (errno != ENOENT) {
65
- FRT_RAISE(FRT_IO_ERROR, "checking existance of %s: <%s>", path,
66
- strerror(errno));
67
- }
68
- return false;
69
- }
70
- close(fd);
71
- return true;
72
- }
73
-
74
- static int fs_remove(FrtStore *store, const char *filename) {
75
- char path[FRT_MAX_FILE_PATH];
76
- return remove(join_path(path, store->dir.path, filename));
77
- }
78
-
79
- static void fs_rename(FrtStore *store, const char *from, const char *to) {
80
- char path1[FRT_MAX_FILE_PATH], path2[FRT_MAX_FILE_PATH];
81
-
82
- #if defined POSH_OS_WIN32 || defined POSH_OS_WIN64
83
- remove(join_path(path1, store->dir.path, to));
84
- #endif
85
-
86
- if (rename(join_path(path1, store->dir.path, from),
87
- join_path(path2, store->dir.path, to)) < 0) {
88
- FRT_RAISE(FRT_IO_ERROR, "couldn't rename file \"%s\" to \"%s\": <%s>",
89
- path1, path2, strerror(errno));
90
- }
91
- }
92
-
93
- static int fs_count(FrtStore *store) {
94
- int cnt = 0;
95
- struct dirent *de;
96
- DIR *d = opendir(store->dir.path);
97
-
98
- if (!d) {
99
- FRT_RAISE(FRT_IO_ERROR, "counting files in %s: <%s>",
100
- store->dir.path, strerror(errno));
101
- }
102
-
103
- while ((de = readdir(d)) != NULL) {
104
- if (de->d_name[0] > '/') { /* skip ., .., / and '\0'*/
105
- cnt++;
106
- }
107
- }
108
- closedir(d);
109
-
110
- return cnt;
111
- }
112
-
113
- static void fs_each(FrtStore *store, void (*func)(const char *fname, void *arg), void *arg) {
114
- struct dirent *de;
115
- DIR *d = opendir(store->dir.path);
116
-
117
- if (!d) {
118
- FRT_RAISE(FRT_IO_ERROR, "doing 'each' in %s: <%s>",
119
- store->dir.path, strerror(errno));
120
- }
121
-
122
- while ((de = readdir(d)) != NULL) {
123
- if (de->d_name[0] > '/' /* skip ., .., / and '\0'*/
124
- && !frt_file_is_lock(de->d_name)) {
125
- func(de->d_name, arg);
126
- }
127
- }
128
- closedir(d);
129
- }
130
-
131
- static void fs_clear_locks(FrtStore *store) {
132
- struct dirent *de;
133
- DIR *d = opendir(store->dir.path);
134
-
135
- if (!d) {
136
- FRT_RAISE(FRT_IO_ERROR, "clearing locks in %s: <%s>",
137
- store->dir.path, strerror(errno));
138
- }
139
-
140
- while ((de = readdir(d)) != NULL) {
141
- if (frt_file_is_lock(de->d_name)) {
142
- char path[FRT_MAX_FILE_PATH];
143
- remove(join_path(path, store->dir.path, de->d_name));
144
- }
145
- }
146
- closedir(d);
147
- }
148
-
149
- static void remove_if_index_file(const char *base_path, const char *file_name) {
150
- char path[FRT_MAX_FILE_PATH];
151
- char *basename;
152
- join_path(path, base_path, file_name);
153
- /* get basename of path */
154
- basename = strrchr(path, DIR_SEPARATOR_CHAR);
155
- basename = (basename ? basename + 1 : path);
156
- /* we don't want to delete non-index files here */
157
- if (frt_file_name_filter_is_index_file(basename, true)) {
158
- remove(path);
159
- }
160
- }
161
-
162
- static void fs_clear(FrtStore *store) {
163
- struct dirent *de;
164
- DIR *d = opendir(store->dir.path);
165
-
166
- if (!d) {
167
- FRT_RAISE(FRT_IO_ERROR, "clearing files in %s: <%s>",
168
- store->dir.path, strerror(errno));
169
- }
170
-
171
- while ((de = readdir(d)) != NULL) {
172
- if (de->d_name[0] > '/' /* skip ., .., / and '\0'*/
173
- && !frt_file_is_lock(de->d_name)) {
174
- remove_if_index_file(store->dir.path, de->d_name);
175
- }
176
- }
177
- closedir(d);
178
- }
179
-
180
- /**
181
- * Clear all files which belong to the index. Use fs_clear to clear the
182
- * directory regardless of the files origin.
183
- */
184
- static void fs_clear_all(FrtStore *store) {
185
- struct dirent *de;
186
- DIR *d = opendir(store->dir.path);
187
-
188
- if (!d) {
189
- FRT_RAISE(FRT_IO_ERROR, "clearing all files in %s: <%s>",
190
- store->dir.path, strerror(errno));
191
- }
192
-
193
- while ((de = readdir(d)) != NULL) {
194
- if (de->d_name[0] > '/') { /* skip ., .., / and '\0'*/
195
- remove_if_index_file(store->dir.path, de->d_name);
196
- }
197
- }
198
- closedir(d);
199
- }
200
-
201
- /**
202
- * Destroy the store.
203
- *
204
- * @param p the store to destroy
205
- * @rb_raise FRT_IO_ERROR if there is an error deleting the locks
206
- */
207
- static void fs_destroy(FrtStore *store) {
208
- FRT_TRY
209
- fs_clear_locks(store);
210
- FRT_XCATCHALL
211
- FRT_HANDLED();
212
- FRT_XENDTRY
213
- free(store->dir.path);
214
- }
215
-
216
- static frt_off_t fs_length(FrtStore *store, const char *filename) {
217
- char path[FRT_MAX_FILE_PATH];
218
- struct stat stt;
219
-
220
- if (stat(join_path(path, store->dir.path, filename), &stt)) {
221
- FRT_RAISE(FRT_IO_ERROR, "getting lenth of %s: <%s>", path,
222
- strerror(errno));
223
- }
224
-
225
- return stt.st_size;
226
- }
227
-
228
- static void fso_flush_i(FrtOutStream *os, const frt_uchar *src, int len) {
229
- if (len == 0) { return; }
230
- if (len != write(os->file.fd, src, len)) {
231
- FRT_RAISE(FRT_IO_ERROR, "flushing src of length %d, <%s>", len,
232
- strerror(errno));
233
- }
234
- }
235
-
236
- static void fso_seek_i(FrtOutStream *os, frt_off_t pos) {
237
- #if (defined POSH_OS_WIN32 || defined POSH_OS_WIN64)
238
- if (_lseeki64(os->file.fd, pos, SEEK_SET) < 0)
239
- #else
240
- if (lseek(os->file.fd, pos, SEEK_SET) < 0)
241
- #endif
242
- {
243
- FRT_RAISE(FRT_IO_ERROR, "seeking position %"FRT_OFF_T_PFX"d: <%s>",
244
- pos, strerror(errno));
245
- }
246
- }
247
-
248
- static void fso_close_i(FrtOutStream *os) {
249
- if (close(os->file.fd)) {
250
- FRT_RAISE(FRT_IO_ERROR, "closing file: <%s>", strerror(errno));
251
- }
252
- }
253
-
254
- static const struct FrtOutStreamMethods FS_OUT_STREAM_METHODS = {
255
- fso_flush_i,
256
- fso_seek_i,
257
- fso_close_i
258
- };
259
-
260
- static FrtOutStream *fs_new_output(FrtStore *store, const char *filename) {
261
- char path[FRT_MAX_FILE_PATH];
262
- int fd = open(join_path(path, store->dir.path, filename), O_WRONLY | O_CREAT | O_BINARY, store->file_mode);
263
- if (fd < 0) {
264
- FRT_RAISE(FRT_IO_ERROR, "couldn't create OutStream %s: <%s>",
265
- path, strerror(errno));
266
- }
267
-
268
- FrtOutStream *os = frt_os_new();
269
- os->file.fd = fd;
270
- os->m = &FS_OUT_STREAM_METHODS;
271
- return os;
272
- }
273
-
274
- static void fsi_read_i(FrtInStream *is, frt_uchar *path, int len) {
275
- int fd = is->f->file.fd;
276
- frt_off_t pos = frt_is_pos(is);
277
- if (pos != lseek(fd, 0, SEEK_CUR)) {
278
- lseek(fd, pos, SEEK_SET);
279
- }
280
- if (read(fd, path, len) != len) {
281
- /* win: the wrong value can be returned for some reason so double check */
282
- if (lseek(fd, 0, SEEK_CUR) != (pos + len)) {
283
- FRT_RAISE(FRT_IO_ERROR, "couldn't read %d chars from %s: <%s>",
284
- len, path, strerror(errno));
285
- }
286
- }
287
- }
288
-
289
- static void fsi_seek_i(FrtInStream *is, frt_off_t pos) {
290
- #if (defined POSH_OS_WIN32 || defined POSH_OS_WIN64)
291
- if (_lseeki64(is->f->file.fd, pos, SEEK_SET) < 0)
292
- #else
293
- if (lseek(is->f->file.fd, pos, SEEK_SET) < 0)
294
- #endif
295
- {
296
- FRT_RAISE(FRT_IO_ERROR, "seeking pos %"FRT_OFF_T_PFX"d: <%s>",
297
- pos, strerror(errno));
298
- }
299
- }
300
-
301
- static void fsi_close_i(FrtInStream *is) {
302
- if (close(is->f->file.fd)) {
303
- FRT_RAISE(FRT_IO_ERROR, "%s", strerror(errno));
304
- }
305
- if (is->d.path) free(is->d.path);
306
- }
307
-
308
- static frt_off_t fsi_length_i(FrtInStream *is) {
309
- struct stat stt;
310
- if (fstat(is->f->file.fd, &stt)) {
311
- FRT_RAISE(FRT_IO_ERROR, "fstat failed: <%s>", strerror(errno));
312
- }
313
- return stt.st_size;
314
- }
315
-
316
- static const struct FrtInStreamMethods FS_IN_STREAM_METHODS = {
317
- fsi_read_i,
318
- fsi_seek_i,
319
- fsi_length_i,
320
- fsi_close_i
321
- };
322
-
323
- static FrtInStream *fs_open_input(FrtStore *store, const char *filename) {
324
- FrtInStream *is;
325
- char path[FRT_MAX_FILE_PATH];
326
- int fd = open(join_path(path, store->dir.path, filename), O_RDONLY | O_BINARY);
327
- if (fd < 0) {
328
- FRT_RAISE(FRT_FILE_NOT_FOUND_ERROR,
329
- "tried to open \"%s\" but it doesn't exist: <%s>",
330
- path, strerror(errno));
331
- }
332
- is = frt_is_new();
333
- is->f->file.fd = fd;
334
- is->f->ref_cnt = 1;
335
- is->d.path = frt_estrdup(path);
336
- is->m = &FS_IN_STREAM_METHODS;
337
- return is;
338
- }
339
-
340
- #define LOCK_OBTAIN_TIMEOUT 50
341
-
342
- static int fs_lock_obtain(FrtLock *lock) {
343
- int f;
344
- int trys = LOCK_OBTAIN_TIMEOUT;
345
- while (((f =
346
- open(lock->name, O_CREAT | O_EXCL | O_RDWR,
347
- S_IRUSR | S_IWUSR)) < 0) && (trys > 0)) {
348
-
349
- /* sleep for 10 milliseconds */
350
- frt_micro_sleep(10000);
351
- trys--;
352
- }
353
- if (f >= 0) {
354
- close(f);
355
- return true;
356
- } else {
357
- return false;
358
- }
359
- }
360
-
361
- static int fs_lock_is_locked(FrtLock *lock) {
362
- int f = open(lock->name, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
363
- if (f >= 0) {
364
- if (close(f) || remove(lock->name)) {
365
- FRT_RAISE(FRT_IO_ERROR, "couldn't close lock \"%s\": <%s>", lock->name,
366
- strerror(errno));
367
- }
368
- return false;
369
- }
370
- else {
371
- return true;
372
- }
373
- }
374
-
375
- static void fs_lock_release(FrtLock *lock) {
376
- remove(lock->name);
377
- }
378
-
379
- static FrtLock *fs_open_lock_i(FrtStore *store, const char *lockname) {
380
- FrtLock *lock = FRT_ALLOC(FrtLock);
381
- char lname[100];
382
- char path[FRT_MAX_FILE_PATH];
383
- snprintf(lname, 100, "%s%s.lck", FRT_LOCK_PREFIX, lockname);
384
- lock->name = frt_estrdup(join_path(path, store->dir.path, lname));
385
- lock->store = store;
386
- FRT_REF(store);
387
- lock->obtain = &fs_lock_obtain;
388
- lock->release = &fs_lock_release;
389
- lock->is_locked = &fs_lock_is_locked;
390
- lock->rlock = Qnil;
391
- return lock;
392
- }
393
-
394
- static void fs_close_lock_i(FrtLock *lock) {
395
- frt_store_close(lock->store);
396
- remove(lock->name);
397
- free(lock->name);
398
- free(lock);
399
- }
400
-
401
- static FrtHash *fs_stores = NULL;
402
-
403
- static pthread_mutex_t fs_stores_mutex = PTHREAD_MUTEX_INITIALIZER;
404
-
405
- static void fs_close_i(FrtStore *store) {
406
- pthread_mutex_lock(&fs_stores_mutex);
407
- frt_h_del(fs_stores, store->dir.path);
408
- pthread_mutex_unlock(&fs_stores_mutex);
409
- }
410
-
411
- static FrtStore *fs_store_new(const char *pathname)
412
- {
413
- FrtStore *new_store = frt_store_new();
414
-
415
- new_store->file_mode = S_IRUSR | S_IWUSR;
416
- #if !defined POSH_OS_WIN32 && !defined POSH_OS_WIN64
417
- struct stat stt;
418
- if (!stat(pathname, &stt)) {
419
- gid_t st_gid = stt.st_gid;
420
- bool is_grp = (st_gid == getgid());
421
-
422
- if (!is_grp) {
423
- int size = getgroups(0, NULL);
424
- gid_t list[size];
425
-
426
- if (getgroups(size, list) != -1) {
427
- int i = 0;
428
- while (i < size && !(is_grp = (st_gid == list[i]))) i++;
429
- }
430
- }
431
-
432
- if (is_grp) {
433
- if (stt.st_mode & S_IWGRP) {
434
- umask(S_IWOTH);
435
- }
436
- new_store->file_mode |= stt.st_mode & (S_IRGRP | S_IWGRP);
437
- }
438
- }
439
- #endif
440
-
441
- new_store->dir.path = frt_estrdup(pathname);
442
- new_store->touch = &fs_touch;
443
- new_store->exists = &fs_exists;
444
- new_store->remove = &fs_remove;
445
- new_store->rename = &fs_rename;
446
- new_store->count = &fs_count;
447
- new_store->close_i = &fs_close_i;
448
- new_store->clear = &fs_clear;
449
- new_store->clear_all = &fs_clear_all;
450
- new_store->clear_locks = &fs_clear_locks;
451
- new_store->length = &fs_length;
452
- new_store->each = &fs_each;
453
- new_store->new_output = &fs_new_output;
454
- new_store->open_input = &fs_open_input;
455
- new_store->open_lock_i = &fs_open_lock_i;
456
- new_store->close_lock_i = &fs_close_lock_i;
457
- return new_store;
458
- }
459
-
460
- FrtStore *frt_open_fs_store(const char *pathname) {
461
- FrtStore *store = NULL;
462
-
463
- if (!fs_stores) {
464
- fs_stores = frt_h_new_str(NULL, (frt_free_ft)fs_destroy);
465
- frt_register_for_cleanup(fs_stores, (frt_free_ft)frt_h_destroy);
466
- }
467
-
468
- pthread_mutex_lock(&fs_stores_mutex);
469
- store = (FrtStore *)frt_h_get(fs_stores, pathname);
470
- if (store) {
471
- FRT_REF(store);
472
- } else {
473
- store = fs_store_new(pathname);
474
- frt_h_set(fs_stores, store->dir.path, store);
475
- }
476
- pthread_mutex_unlock(&fs_stores_mutex);
477
-
478
- return store;
479
- }
@@ -1,25 +0,0 @@
1
- #include "frt_store.h"
2
- #include "test_store.h"
3
- #include "test.h"
4
-
5
- /**
6
- * Test a FileSystem store
7
- */
8
- TestSuite *ts_fs_store(TestSuite *suite)
9
- {
10
-
11
- #if defined POSH_OS_WIN32 || defined POSH_OS_WIN64
12
- FrtStore *store = frt_open_fs_store(".\\test\\testdir\\store");
13
- #else
14
- FrtStore *store = frt_open_fs_store("./test/testdir/store");
15
- #endif
16
- store->clear(store);
17
-
18
- suite = ADD_SUITE(suite);
19
-
20
- create_test_store_suite(suite, store);
21
-
22
- frt_store_close(store);
23
-
24
- return suite;
25
- }