src/server/daemon/vfs.c

changeset 105
63d9051fe35c
parent 97
09fbefc0e6a9
child 165
6942a8c3e737
child 171
af7e2d80dee6
equal deleted inserted replaced
104:a8acbb12f27c 105:63d9051fe35c
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);

mercurial