24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
|
29 #define _POSIX_PTHREAD_SEMANTIS |
|
30 |
29 #include <stdio.h> |
31 #include <stdio.h> |
30 #include <stdlib.h> |
32 #include <stdlib.h> |
31 #include <unistd.h> |
33 #include <unistd.h> |
32 #include <sys/types.h> |
34 #include <sys/types.h> |
33 |
35 |
323 sys_set_error_status(ctx); |
325 sys_set_error_status(ctx); |
324 } |
326 } |
325 return NULL; |
327 return NULL; |
326 } |
328 } |
327 |
329 |
|
330 SysVFSDir *dir_data = pool ? |
|
331 pool_malloc(pool, sizeof(SysVFSDir)) : malloc(sizeof(SysVFSDir)); |
|
332 if(!dir_data) { |
|
333 closedir(sys_dir); |
|
334 return NULL; |
|
335 } |
|
336 long maxfilelen = fpathconf(dir_fd, _PC_NAME_MAX); |
|
337 size_t entry_len = offsetof(struct dirent, d_name) + maxfilelen + 1; |
|
338 dir_data->cur = pool ? |
|
339 pool_malloc(pool, entry_len) : malloc(entry_len); |
|
340 if(!dir_data->cur) { |
|
341 closedir(sys_dir); |
|
342 return NULL; |
|
343 } |
|
344 dir_data->dir = sys_dir; |
|
345 |
328 VFSDir *dir = pool ? |
346 VFSDir *dir = pool ? |
329 pool_malloc(pool, sizeof(VFSDir)) : malloc(sizeof(VFSDir)); |
347 pool_malloc(pool, sizeof(VFSDir)) : malloc(sizeof(VFSDir)); |
330 if(!dir) { |
348 if(!dir) { |
331 closedir(sys_dir); |
349 closedir(sys_dir); |
332 return NULL; |
350 return NULL; |
333 } |
351 } |
334 dir->ctx = ctx; |
352 dir->ctx = ctx; |
335 dir->data = sys_dir; |
353 dir->data = dir_data; |
336 dir->fd = dir_fd; |
354 dir->fd = dir_fd; |
337 dir->io = &sys_dir_io; |
355 dir->io = &sys_dir_io; |
338 return dir; |
356 return dir; |
339 } |
357 } |
340 |
358 |
471 void sys_file_close(SYS_FILE fd) { |
489 void sys_file_close(SYS_FILE fd) { |
472 close(fd->fd); |
490 close(fd->fd); |
473 } |
491 } |
474 |
492 |
475 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) { |
493 int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat) { |
476 struct dirent *e = readdir(dir->data); |
494 SysVFSDir *dirdata = dir->data; |
477 if(e) { |
495 struct dirent *result = NULL; |
478 char *name = e->d_name; |
496 int s = readdir_r(dirdata->dir, dirdata->cur, &result); |
|
497 if(!s && result) { |
|
498 char *name = result->d_name; |
479 if(!strcmp(name, ".") || !strcmp(name, "..")) { |
499 if(!strcmp(name, ".") || !strcmp(name, "..")) { |
480 return sys_dir_read(dir, entry, getstat); |
500 return sys_dir_read(dir, entry, getstat); |
481 } else { |
501 } else { |
482 entry->name = name; |
502 entry->name = name; |
483 #ifndef OSX |
503 #ifndef OSX |
485 * implement alternative for fstat for OS X and other crappy |
505 * implement alternative for fstat for OS X and other crappy |
486 * Unices |
506 * Unices |
487 */ |
507 */ |
488 if(getstat) { |
508 if(getstat) { |
489 // TODO: check ACLs again for new path |
509 // TODO: check ACLs again for new path |
490 if(fstatat(dir->fd, e->d_name, &entry->stat, 0)) { |
510 if(fstatat(dir->fd, result->d_name, &entry->stat, 0)) { |
491 entry->stat_errno = errno; |
511 entry->stat_errno = errno; |
492 } |
512 } |
493 entry->stat_extra = NULL; |
513 entry->stat_extra = NULL; |
494 } |
514 } |
495 #endif |
515 #endif |
499 return 0; |
519 return 0; |
500 } |
520 } |
501 } |
521 } |
502 |
522 |
503 void sys_dir_close(VFS_DIR dir) { |
523 void sys_dir_close(VFS_DIR dir) { |
504 closedir(dir->data); |
524 SysVFSDir *dirdata = dir->data; |
|
525 closedir(dirdata->dir); |
|
526 |
|
527 pool_handle_t *pool = dir->ctx->pool; |
|
528 if(pool) { |
|
529 pool_free(pool, dirdata->cur); |
|
530 pool_free(pool, dirdata); |
|
531 pool_free(pool, dir); |
|
532 } else { |
|
533 free(dirdata->cur); |
|
534 free(dirdata); |
|
535 free(dir); |
|
536 } |
505 } |
537 } |
506 |
538 |
507 int sys_mkdir(VFSContext *ctx, char *path, SysACL *sysacl) { |
539 int sys_mkdir(VFSContext *ctx, char *path, SysACL *sysacl) { |
508 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
540 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
509 int ret = mkdir(path, mode); |
541 int ret = mkdir(path, mode); |