Changeset 5fec355 in mainline for uspace/lib/libc/generic/vfs/vfs.c


Ignore:
Timestamp:
2008-03-03T00:35:51Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
adc8a63
Parents:
1526594c
Message:

Add support for relative paths: chdir() and getcwd().

File:
1 edited

Legend:

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

    r1526594c r5fec355  
    3333 */
    3434 
    35 #include <vfs.h>
     35#include <vfs/vfs.h>
     36#include <vfs/canonify.h>
    3637#include <stdlib.h>
    3738#include <unistd.h>
     
    5051
    5152int vfs_phone = -1;
    52 atomic_t vfs_phone_futex = FUTEX_INITIALIZER;
     53futex_t vfs_phone_futex = FUTEX_INITIALIZER;
     54
     55futex_t cwd_futex = FUTEX_INITIALIZER;
     56DIR *cwd_dir = NULL;
     57char *cwd_path = NULL;
     58size_t cwd_len = 0;
     59
     60static char *absolutize(const char *path)
     61{
     62        char *ncwd_path;
     63
     64        futex_down(&cwd_futex);
     65        size_t len = strlen(path);
     66        if (*path != '/') {
     67                if (!cwd_path) {
     68                        futex_up(&cwd_futex);
     69                        return NULL;
     70                }
     71                ncwd_path = malloc(len + cwd_len + 1);
     72                if (!ncwd_path) {
     73                        futex_up(&cwd_futex);
     74                        return NULL;
     75                }
     76                strcpy(ncwd_path, cwd_path);
     77                ncwd_path[cwd_len] = '/';
     78                ncwd_path[cwd_len + 1] = '\0';
     79        } else {
     80                ncwd_path = malloc(len + 1);
     81                if (!ncwd_path) {
     82                        futex_up(&cwd_futex);
     83                        return NULL;
     84                }
     85                ncwd_path[0] = '\0';
     86        }
     87        strcat(ncwd_path, path);
     88        futex_up(&cwd_futex);
     89        return ncwd_path;
     90}
    5391
    5492static int vfs_connect(void)
     
    67105        int dev_handle = 0;     /* TODO */
    68106
    69         futex_down(&vfs_phone_futex);
    70         async_serialize_start();
    71         if (vfs_phone < 0) {
    72                 res = vfs_connect();
    73                 if (res < 0) {
    74                         async_serialize_end();
    75                         futex_up(&vfs_phone_futex);
     107        char *mpa = absolutize(mp);
     108        if (!mpa)
     109                return ENOMEM;
     110        size_t mpc_len;
     111        char *mpc = canonify(mpa, &mpc_len);
     112        if (!mpc) {
     113                free(mpa);
     114                return EINVAL;
     115        }
     116
     117        futex_down(&vfs_phone_futex);
     118        async_serialize_start();
     119        if (vfs_phone < 0) {
     120                res = vfs_connect();
     121                if (res < 0) {
     122                        async_serialize_end();
     123                        futex_up(&vfs_phone_futex);
     124                        free(mpa);
    76125                        return res;
    77126                }
     
    83132                async_serialize_end();
    84133                futex_up(&vfs_phone_futex);
     134                free(mpa);
    85135                return (int) rc;
    86136        }
    87         rc = ipc_data_write_start(vfs_phone, (void *)mp, strlen(mp));
    88         if (rc != EOK) {
    89                 async_wait_for(req, NULL);
    90                 async_serialize_end();
    91                 futex_up(&vfs_phone_futex);
     137        rc = ipc_data_write_start(vfs_phone, (void *)mpc, mpc_len);
     138        if (rc != EOK) {
     139                async_wait_for(req, NULL);
     140                async_serialize_end();
     141                futex_up(&vfs_phone_futex);
     142                free(mpa);
    92143                return (int) rc;
    93144        }
     
    95146        async_serialize_end();
    96147        futex_up(&vfs_phone_futex);
     148        free(mpa);
    97149        return (int) rc;
    98150}
     
    105157        aid_t req;
    106158       
    107         futex_down(&vfs_phone_futex);
    108         async_serialize_start();
    109         if (vfs_phone < 0) {
    110                 res = vfs_connect();
    111                 if (res < 0) {
    112                         async_serialize_end();
    113                         futex_up(&vfs_phone_futex);
     159        char *pa = absolutize(path);
     160        if (!pa)
     161                return ENOMEM;
     162        size_t pc_len;
     163        char *pc = canonify(pa, &pc_len);
     164        if (!pc) {
     165                free(pa);
     166                return EINVAL;
     167        }
     168       
     169        futex_down(&vfs_phone_futex);
     170        async_serialize_start();
     171        if (vfs_phone < 0) {
     172                res = vfs_connect();
     173                if (res < 0) {
     174                        async_serialize_end();
     175                        futex_up(&vfs_phone_futex);
     176                        free(pa);
    114177                        return res;
    115178                }
    116179        }
    117180        req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
    118         rc = ipc_data_write_start(vfs_phone, path, strlen(path));
    119         if (rc != EOK) {
    120                 async_wait_for(req, NULL);
    121                 async_serialize_end();
    122                 futex_up(&vfs_phone_futex);
     181        rc = ipc_data_write_start(vfs_phone, pc, pc_len);
     182        if (rc != EOK) {
     183                async_wait_for(req, NULL);
     184                async_serialize_end();
     185                futex_up(&vfs_phone_futex);
     186                free(pa);
    123187                return (int) rc;
    124188        }
     
    126190        async_serialize_end();
    127191        futex_up(&vfs_phone_futex);
     192        free(pa);
    128193        return (int) IPC_GET_ARG1(answer);
    129194}
     
    315380        aid_t req;
    316381       
    317         futex_down(&vfs_phone_futex);
    318         async_serialize_start();
    319         if (vfs_phone < 0) {
    320                 res = vfs_connect();
    321                 if (res < 0) {
    322                         async_serialize_end();
    323                         futex_up(&vfs_phone_futex);
     382        char *pa = absolutize(path);
     383        if (!pa)
     384                return ENOMEM;
     385        size_t pc_len;
     386        char *pc = canonify(pa, &pc_len);
     387        if (!pc) {
     388                free(pa);
     389                return EINVAL;
     390        }
     391
     392        futex_down(&vfs_phone_futex);
     393        async_serialize_start();
     394        if (vfs_phone < 0) {
     395                res = vfs_connect();
     396                if (res < 0) {
     397                        async_serialize_end();
     398                        futex_up(&vfs_phone_futex);
     399                        free(pa);
    324400                        return res;
    325401                }
    326402        }
    327403        req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
    328         rc = ipc_data_write_start(vfs_phone, path, strlen(path));
    329         if (rc != EOK) {
    330                 async_wait_for(req, NULL);
    331                 async_serialize_end();
    332                 futex_up(&vfs_phone_futex);
     404        rc = ipc_data_write_start(vfs_phone, pc, pc_len);
     405        if (rc != EOK) {
     406                async_wait_for(req, NULL);
     407                async_serialize_end();
     408                futex_up(&vfs_phone_futex);
     409                free(pa);
    333410                return (int) rc;
    334411        }
     
    336413        async_serialize_end();
    337414        futex_up(&vfs_phone_futex);
     415        free(pa);
    338416        return EOK;
    339417}
     
    345423        aid_t req;
    346424       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         if (vfs_phone < 0) {
    350                 res = vfs_connect();
    351                 if (res < 0) {
    352                         async_serialize_end();
    353                         futex_up(&vfs_phone_futex);
     425        char *pa = absolutize(path);
     426        if (!pa)
     427                return ENOMEM;
     428        size_t pc_len;
     429        char *pc = canonify(pa, &pc_len);
     430        if (!pc) {
     431                free(pa);
     432                return EINVAL;
     433        }
     434        futex_down(&vfs_phone_futex);
     435        async_serialize_start();
     436        if (vfs_phone < 0) {
     437                res = vfs_connect();
     438                if (res < 0) {
     439                        async_serialize_end();
     440                        futex_up(&vfs_phone_futex);
     441                        free(pa);
    354442                        return res;
    355443                }
    356444        }
    357445        req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
    358         rc = ipc_data_write_start(vfs_phone, path, strlen(path));
    359         if (rc != EOK) {
    360                 async_wait_for(req, NULL);
    361                 async_serialize_end();
    362                 futex_up(&vfs_phone_futex);
     446        rc = ipc_data_write_start(vfs_phone, pc, pc_len);
     447        if (rc != EOK) {
     448                async_wait_for(req, NULL);
     449                async_serialize_end();
     450                futex_up(&vfs_phone_futex);
     451                free(pa);
    363452                return (int) rc;
    364453        }
     
    366455        async_serialize_end();
    367456        futex_up(&vfs_phone_futex);
     457        free(pa);
    368458        return EOK;
    369459}
     
    377467{
    378468        return _unlink(path, L_DIRECTORY);
     469}
     470
     471int chdir(const char *path)
     472{
     473        char *pa = absolutize(path);
     474        if (!pa)
     475                return ENOMEM;
     476        size_t pc_len;
     477        char *pc = canonify(pa, &pc_len);
     478        if (!pc) {
     479                free(pa);
     480                return ENOENT;
     481        }
     482
     483        DIR *d = opendir(pc);
     484        if (!d) {
     485                free(pa);
     486                return ENOENT;
     487        }
     488
     489        futex_down(&cwd_futex);
     490        if (cwd_dir) {
     491                closedir(cwd_dir);
     492                cwd_dir = NULL;
     493                free(cwd_path);
     494                cwd_path = NULL;
     495                cwd_len = 0;
     496        }
     497        cwd_dir = d;
     498        cwd_path = pc;
     499        cwd_len = pc_len;
     500        futex_up(&cwd_futex);
     501}
     502
     503char *getcwd(char *buf, size_t size)
     504{
     505        if (!size)
     506                return NULL;
     507        futex_down(&cwd_futex);
     508        if (size < cwd_len + 1) {
     509                futex_up(&cwd_futex);
     510                return NULL;
     511        }
     512        strcpy(buf, cwd_path);
     513        futex_up(&cwd_futex);
     514        return buf;
    379515}
    380516
Note: See TracChangeset for help on using the changeset viewer.