Changeset 5973fd0 in mainline


Ignore:
Timestamp:
2008-01-18T23:45:16Z (16 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ae78b53
Parents:
62da45a
Message:

Finish implementation of readdir(). Functions from this family are implemented
via using file descriptors for directories. For example, readdir() is
implemented as read() from an open directory. Of course, FS implementations
must understand that they are asked to read a directory and behave accordingly.

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/tester/vfs/vfs1.c

    r62da45a r5973fd0  
    11/*
    2  * Copyright (c) 2007 Jakub Jermar
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3535#include <unistd.h>
    3636#include <fcntl.h>
     37#include <dirent.h>
    3738#include "../tester.h"
    3839
     
    4142        if (mount("tmpfs", "/", "nulldev0") != EOK)
    4243                return "Mount failed.\n";
     44
     45
     46        DIR *dirp;
     47        struct dirent *dp;
     48
     49        dirp = opendir("/");
     50        if (!dirp)
     51                return "opendir() failed.";
     52        while ((dp = readdir(dirp)))
     53                printf("Discovered %s\n", dp->d_name);
     54        closedir(dirp);
     55
    4356        int fd1 = open("/dir1/file1", 0);
    4457        int fd2 = open("/dir2/file2", 0);
    4558
    4659        if (fd1 < 0)
    47                 return "Open failed.\n";
     60                return "open() failed.\n";
    4861        if (fd2 < 0)
    49                 return "Open failed.\n";
     62                return "open() failed.\n";
    5063
    5164        if (!quiet)
     
    5669        ssize_t cnt = read(fd1, buf, sizeof(buf));
    5770        if (cnt < 0)
    58                 return "Read failed.\n";
     71                return "read() failed.\n";
    5972
    6073        if (!quiet)
  • uspace/lib/libc/generic/vfs.c

    r62da45a r5973fd0  
    244244                return NULL;
    245245        dirp->fd = open(dirname, 0);    /* TODO: must be a directory */
    246         if (!dirp->fd) {
     246        if (dirp->fd < 0) {
    247247                free(dirp);
    248248                return NULL;
    249249        }
    250         dirp->pos = 0;
    251250        return dirp;
    252251}
     
    254253struct dirent *readdir(DIR *dirp)
    255254{
    256         return NULL;    /* TODO */     
     255        ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
     256        if (len <= 0)
     257                return NULL;
     258        return &dirp->res;
    257259}
    258260
    259261void rewinddir(DIR *dirp)
    260262{
    261         dirp->pos = 0;
     263        (void) lseek(dirp->fd, 0, SEEK_SET);
    262264}
    263265
  • uspace/lib/libc/include/dirent.h

    r62da45a r5973fd0  
    4444typedef struct {
    4545        int fd;
    46         unsigned pos;
    4746        struct dirent res;
    4847} DIR;
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r62da45a r5973fd0  
    4646#include <string.h>
    4747#include <stdio.h>
     48#include <assert.h>
    4849#include <sys/types.h>
    4950#include <libadt/hash_table.h>
     
    308309        }
    309310
    310         size_t bytes = max(0, min(dentry->size - pos, len));
    311         (void) ipc_data_read_finalize(callid, dentry->data + pos, bytes);
     311        size_t bytes;
     312        if (dentry->type == TMPFS_FILE) {
     313                bytes = max(0, min(dentry->size - pos, len));
     314                (void) ipc_data_read_finalize(callid, dentry->data + pos,
     315                    bytes);
     316        } else {
     317                int i;
     318                tmpfs_dentry_t *cur = dentry->child;
     319               
     320                assert(dentry->type == TMPFS_DIRECTORY);
     321               
     322                /*
     323                 * Yes, we really use O(n) algorithm here.
     324                 * If it bothers someone, it could be fixed by introducing a
     325                 * hash table.
     326                 */
     327                for (i = 0, cur = dentry->child; i < pos && cur; i++,
     328                    cur = cur->sibling)
     329                        ;
     330
     331                if (!cur) {
     332                        ipc_answer_0(callid, ENOENT);
     333                        ipc_answer_1(rid, ENOENT, 0);
     334                        return;
     335                }
     336
     337                (void) ipc_data_read_finalize(callid, cur->name,
     338                    strlen(cur->name) + 1);
     339                bytes = 1;
     340        }
    312341
    313342        /*
Note: See TracChangeset for help on using the changeset viewer.