Changeset 2b88074b in mainline for uspace/lib/libc/generic/vfs/vfs.c


Ignore:
Timestamp:
2009-10-29T22:06:46Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
2e983c7
Parents:
14ecd6c
Message:

vfs: file descriptors housekeeping changes

  • add support for allocating new file descriptors from the end of the fd range (O_DESC)
  • add support for assigning of an already opened file to a free file descriptor

vfs: VFS_OUT_CLOSE is called only when the file reference count is about to drop to zero
vfs: implement VFS_IN_DUP

libc: optimize current working directory housekeeping

  • using opendir() was an overkill
  • allocate current working directory file descriptor from the end of the fd range using O_DESC (so it doesn't mess with the well-known descriptors 0, 1 and 2)

libc: implement dup2() (via VFS_IN_DUP)

getvc: change stdin/stdout/stderr by a slightly more elegant way (using dup2())

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/vfs/vfs.c

    r14ecd6c r2b88074b  
    5757static futex_t cwd_futex = FUTEX_INITIALIZER;
    5858
    59 DIR *cwd_dir = NULL;
    60 char *cwd_path = NULL;
    61 size_t cwd_size = 0;
     59static int cwd_fd = -1;
     60static char *cwd_path = NULL;
     61static size_t cwd_size = 0;
    6262
    6363char *absolutize(const char *path, size_t *retlen)
     
    197197}
    198198
    199 static int _open(const char *path, int lflag, int oflag, ...)
    200 {
    201         ipcarg_t rc;
     199static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
     200{
     201        futex_down(&vfs_phone_futex);
     202        async_serialize_start();
     203        vfs_connect();
     204       
    202205        ipc_call_t answer;
    203         aid_t req;
    204        
    205         size_t pa_size;
    206         char *pa = absolutize(path, &pa_size);
    207         if (!pa)
    208                 return ENOMEM;
    209        
    210         futex_down(&vfs_phone_futex);
    211         async_serialize_start();
    212         vfs_connect();
    213        
    214         req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
    215         rc = async_data_write_start(vfs_phone, pa, pa_size);
     206        aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     207        ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
     208       
    216209        if (rc != EOK) {
    217210                ipcarg_t rc_orig;
    218        
    219                 async_wait_for(req, &rc_orig);
    220                 async_serialize_end();
    221                 futex_up(&vfs_phone_futex);
    222                 free(pa);
    223                 if (rc_orig == EOK)
    224                         return (int) rc;
    225                 else
    226                         return (int) rc_orig;
    227         }
    228         async_wait_for(req, &rc);
    229         async_serialize_end();
    230         futex_up(&vfs_phone_futex);
    231         free(pa);
     211                async_wait_for(req, &rc_orig);
     212               
     213                async_serialize_end();
     214                futex_up(&vfs_phone_futex);
     215               
     216                if (rc_orig == EOK)
     217                        return (int) rc;
     218                else
     219                        return (int) rc_orig;
     220        }
     221       
     222        async_wait_for(req, &rc);
     223        async_serialize_end();
     224        futex_up(&vfs_phone_futex);
    232225       
    233226        if (rc != EOK)
     
    239232int open(const char *path, int oflag, ...)
    240233{
    241         return _open(path, L_FILE, oflag);
     234        size_t abs_size;
     235        char *abs = absolutize(path, &abs_size);
     236        if (!abs)
     237                return ENOMEM;
     238       
     239        int ret = open_internal(abs, abs_size, L_FILE, oflag);
     240        free(abs);
     241       
     242        return ret;
    242243}
    243244
     
    471472        if (!dirp)
    472473                return NULL;
    473         dirp->fd = _open(dirname, L_DIRECTORY, 0);
    474         if (dirp->fd < 0) {
     474       
     475        size_t abs_size;
     476        char *abs = absolutize(dirname, &abs_size);
     477        if (!abs) {
     478                free(dirp);
     479                return ENOMEM;
     480        }
     481       
     482        int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
     483        free(abs);
     484       
     485        if (ret < 0) {
    475486                free(dirp);
    476487                return NULL;
    477488        }
     489       
     490        dirp->fd = ret;
    478491        return dirp;
    479492}
     
    636649int chdir(const char *path)
    637650{
    638         size_t pa_size;
    639         char *pa = absolutize(path, &pa_size);
    640         if (!pa)
    641                 return ENOMEM;
    642 
    643         DIR *d = opendir(pa);
    644         if (!d) {
    645                 free(pa);
     651        size_t abs_size;
     652        char *abs = absolutize(path, &abs_size);
     653        if (!abs)
     654                return ENOMEM;
     655       
     656        int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
     657       
     658        if (fd < 0) {
     659                free(abs);
    646660                return ENOENT;
    647661        }
    648 
     662       
    649663        futex_down(&cwd_futex);
    650         if (cwd_dir) {
    651                 closedir(cwd_dir);
    652                 cwd_dir = NULL;
    653                 free(cwd_path);
    654                 cwd_path = NULL;
    655                 cwd_size = 0;
    656         }
    657         cwd_dir = d;
    658         cwd_path = pa;
    659         cwd_size = pa_size;
     664       
     665        if (cwd_fd >= 0)
     666                close(cwd_fd);
     667       
     668       
     669        if (cwd_path)
     670                free(cwd_path);
     671       
     672        cwd_fd = fd;
     673        cwd_path = abs;
     674        cwd_size = abs_size;
     675       
    660676        futex_up(&cwd_futex);
    661677        return EOK;
     
    664680char *getcwd(char *buf, size_t size)
    665681{
    666         if (!cwd_size)
     682        if (size == 0)
    667683                return NULL;
    668         if (!size)
    669                 return NULL;
     684       
    670685        futex_down(&cwd_futex);
    671         if (size < cwd_size + 1) {
     686       
     687        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    672688                futex_up(&cwd_futex);
    673689                return NULL;
    674690        }
     691       
    675692        str_cpy(buf, size, cwd_path);
    676693        futex_up(&cwd_futex);
     694       
    677695        return buf;
    678696}
     
    707725}
    708726
     727int dup2(int oldfd, int newfd)
     728{
     729        futex_down(&vfs_phone_futex);
     730        async_serialize_start();
     731        vfs_connect();
     732       
     733        ipcarg_t ret;
     734        ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
     735       
     736        async_serialize_end();
     737        futex_up(&vfs_phone_futex);
     738       
     739        if (rc == EOK)
     740                return (int) ret;
     741       
     742        return (int) rc;
     743}
     744
    709745/** @}
    710746 */
Note: See TracChangeset for help on using the changeset viewer.