Changeset 04803bf in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2011-03-21T22:00:17Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
143932e3
Parents:
b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes (needs fixes).

File:
1 moved

Legend:

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

    rb50b5af2 r04803bf  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar 
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3535#include <vfs/vfs.h>
    3636#include <vfs/canonify.h>
     37#include <macros.h>
    3738#include <stdlib.h>
    3839#include <unistd.h>
     
    4243#include <sys/stat.h>
    4344#include <sys/types.h>
    44 #include <ipc/ipc.h>
    4545#include <ipc/services.h>
     46#include <ipc/ns.h>
    4647#include <async.h>
    47 #include <atomic.h>
    48 #include <futex.h>
     48#include <fibril_synch.h>
    4949#include <errno.h>
    50 #include <string.h>
     50#include <assert.h>
     51#include <str.h>
    5152#include <devmap.h>
    5253#include <ipc/vfs.h>
    5354#include <ipc/devmap.h>
    5455
     56static async_sess_t vfs_session;
     57
     58static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    5559static int vfs_phone = -1;
    56 static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
    57 static futex_t cwd_futex = FUTEX_INITIALIZER;
    58 
    59 DIR *cwd_dir = NULL;
    60 char *cwd_path = NULL;
    61 size_t cwd_size = 0;
     60
     61static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
     62
     63static int cwd_fd = -1;
     64static char *cwd_path = NULL;
     65static size_t cwd_size = 0;
    6266
    6367char *absolutize(const char *path, size_t *retlen)
     
    6569        char *ncwd_path;
    6670        char *ncwd_path_nc;
    67 
    68         futex_down(&cwd_futex);
     71        size_t total_size;
     72
     73        fibril_mutex_lock(&cwd_mutex);
    6974        size_t size = str_size(path);
    7075        if (*path != '/') {
    7176                if (!cwd_path) {
    72                         futex_up(&cwd_futex);
     77                        fibril_mutex_unlock(&cwd_mutex);
    7378                        return NULL;
    7479                }
    75                 ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
     80                total_size = cwd_size + 1 + size + 1;
     81                ncwd_path_nc = malloc(total_size);
    7682                if (!ncwd_path_nc) {
    77                         futex_up(&cwd_futex);
     83                        fibril_mutex_unlock(&cwd_mutex);
    7884                        return NULL;
    7985                }
    80                 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
     86                str_cpy(ncwd_path_nc, total_size, cwd_path);
    8187                ncwd_path_nc[cwd_size] = '/';
    8288                ncwd_path_nc[cwd_size + 1] = '\0';
    8389        } else {
    84                 ncwd_path_nc = malloc(size + 1);
     90                total_size = size + 1;
     91                ncwd_path_nc = malloc(total_size);
    8592                if (!ncwd_path_nc) {
    86                         futex_up(&cwd_futex);
     93                        fibril_mutex_unlock(&cwd_mutex);
    8794                        return NULL;
    8895                }
    8996                ncwd_path_nc[0] = '\0';
    9097        }
    91         str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
     98        str_append(ncwd_path_nc, total_size, path);
    9299        ncwd_path = canonify(ncwd_path_nc, retlen);
    93100        if (!ncwd_path) {
    94                 futex_up(&cwd_futex);
     101                fibril_mutex_unlock(&cwd_mutex);
    95102                free(ncwd_path_nc);
    96103                return NULL;
     
    104111        free(ncwd_path_nc);
    105112        if (!ncwd_path) {
    106                 futex_up(&cwd_futex);
     113                fibril_mutex_unlock(&cwd_mutex);
    107114                return NULL;
    108115        }
    109         futex_up(&cwd_futex);
     116        fibril_mutex_unlock(&cwd_mutex);
    110117        return ncwd_path;
    111118}
    112119
     120/** Connect to VFS service and create session. */
    113121static void vfs_connect(void)
    114122{
    115123        while (vfs_phone < 0)
    116                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
    117 }
    118 
    119 int mount(const char *fs_name, const char *mp, const char *dev,
     124                vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
     125       
     126        async_session_create(&vfs_session, vfs_phone, 0);
     127}
     128
     129/** Start an async exchange on the VFS session.
     130 *
     131 * @return              New phone to be used during the exchange.
     132 */
     133static int vfs_exchange_begin(void)
     134{
     135        fibril_mutex_lock(&vfs_phone_mutex);
     136        if (vfs_phone < 0)
     137                vfs_connect();
     138        fibril_mutex_unlock(&vfs_phone_mutex);
     139
     140        return async_exchange_begin(&vfs_session);
     141}
     142
     143/** End an async exchange on the VFS session.
     144 *
     145 * @param phone         Phone used during the exchange.
     146 */
     147static void vfs_exchange_end(int phone)
     148{
     149        async_exchange_end(&vfs_session, phone);
     150}
     151
     152int mount(const char *fs_name, const char *mp, const char *fqdn,
    120153    const char *opts, unsigned int flags)
    121154{
    122         int res;
    123         ipcarg_t rc;
    124         ipcarg_t rc_orig;
    125         aid_t req;
    126         dev_handle_t dev_handle;
    127        
    128         res = devmap_device_get_handle(dev, &dev_handle, flags);
    129         if (res != EOK)
     155        int null_id = -1;
     156        char null[DEVMAP_NAME_MAXLEN];
     157       
     158        if (str_cmp(fqdn, "") == 0) {
     159                /* No device specified, create a fresh
     160                   null/%d device instead */
     161                null_id = devmap_null_create();
     162               
     163                if (null_id == -1)
     164                        return ENOMEM;
     165               
     166                snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
     167                fqdn = null;
     168        }
     169       
     170        devmap_handle_t devmap_handle;
     171        int res = devmap_device_get_handle(fqdn, &devmap_handle, flags);
     172        if (res != EOK) {
     173                if (null_id != -1)
     174                        devmap_null_destroy(null_id);
     175               
    130176                return res;
     177        }
    131178       
    132179        size_t mpa_size;
    133180        char *mpa = absolutize(mp, &mpa_size);
     181        if (!mpa) {
     182                if (null_id != -1)
     183                        devmap_null_destroy(null_id);
     184               
     185                return ENOMEM;
     186        }
     187       
     188        int vfs_phone = vfs_exchange_begin();
     189
     190        sysarg_t rc_orig;
     191        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
     192        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     193        if (rc != EOK) {
     194                vfs_exchange_end(vfs_phone);
     195                free(mpa);
     196                async_wait_for(req, &rc_orig);
     197               
     198                if (null_id != -1)
     199                        devmap_null_destroy(null_id);
     200               
     201                if (rc_orig == EOK)
     202                        return (int) rc;
     203                else
     204                        return (int) rc_orig;
     205        }
     206       
     207        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
     208        if (rc != EOK) {
     209                vfs_exchange_end(vfs_phone);
     210                free(mpa);
     211                async_wait_for(req, &rc_orig);
     212               
     213                if (null_id != -1)
     214                        devmap_null_destroy(null_id);
     215               
     216                if (rc_orig == EOK)
     217                        return (int) rc;
     218                else
     219                        return (int) rc_orig;
     220        }
     221       
     222        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
     223        if (rc != EOK) {
     224                vfs_exchange_end(vfs_phone);
     225                free(mpa);
     226                async_wait_for(req, &rc_orig);
     227               
     228                if (null_id != -1)
     229                        devmap_null_destroy(null_id);
     230               
     231                if (rc_orig == EOK)
     232                        return (int) rc;
     233                else
     234                        return (int) rc_orig;
     235        }
     236       
     237        /* Ask VFS whether it likes fs_name. */
     238        rc = async_req_0_0(vfs_phone, IPC_M_PING);
     239        if (rc != EOK) {
     240                vfs_exchange_end(vfs_phone);
     241                free(mpa);
     242                async_wait_for(req, &rc_orig);
     243               
     244                if (null_id != -1)
     245                        devmap_null_destroy(null_id);
     246               
     247                if (rc_orig == EOK)
     248                        return (int) rc;
     249                else
     250                        return (int) rc_orig;
     251        }
     252       
     253        vfs_exchange_end(vfs_phone);
     254        free(mpa);
     255        async_wait_for(req, &rc);
     256       
     257        if ((rc != EOK) && (null_id != -1))
     258                devmap_null_destroy(null_id);
     259       
     260        return (int) rc;
     261}
     262
     263int unmount(const char *mp)
     264{
     265        sysarg_t rc;
     266        sysarg_t rc_orig;
     267        aid_t req;
     268        size_t mpa_size;
     269        char *mpa;
     270       
     271        mpa = absolutize(mp, &mpa_size);
    134272        if (!mpa)
    135273                return ENOMEM;
    136274       
    137         futex_down(&vfs_phone_futex);
    138         async_serialize_start();
    139         vfs_connect();
    140        
    141         req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
    142         rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    143         if (rc != EOK) {
    144                 async_wait_for(req, &rc_orig);
    145                 async_serialize_end();
    146                 futex_up(&vfs_phone_futex);
     275        int vfs_phone = vfs_exchange_begin();
     276       
     277        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
     278        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
     279        if (rc != EOK) {
     280                vfs_exchange_end(vfs_phone);
    147281                free(mpa);
    148                 if (rc_orig == EOK)
    149                         return (int) rc;
    150                 else
    151                         return (int) rc_orig;
    152         }
    153        
    154         rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    155         if (rc != EOK) {
    156                 async_wait_for(req, &rc_orig);
    157                 async_serialize_end();
    158                 futex_up(&vfs_phone_futex);
    159                 free(mpa);
    160                 if (rc_orig == EOK)
    161                         return (int) rc;
    162                 else
    163                         return (int) rc_orig;
    164         }
    165 
    166         rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    167         if (rc != EOK) {
    168                 async_wait_for(req, &rc_orig);
    169                 async_serialize_end();
    170                 futex_up(&vfs_phone_futex);
    171                 free(mpa);
    172                 if (rc_orig == EOK)
    173                         return (int) rc;
    174                 else
    175                         return (int) rc_orig;
    176         }
    177 
    178         /* Ask VFS whether it likes fs_name. */
    179         rc = async_req_0_0(vfs_phone, IPC_M_PING);
    180         if (rc != EOK) {
    181                 async_wait_for(req, &rc_orig);
    182                 async_serialize_end();
    183                 futex_up(&vfs_phone_futex);
    184                 free(mpa);
    185                 if (rc_orig == EOK)
    186                         return (int) rc;
    187                 else
    188                         return (int) rc_orig;
    189         }
    190        
    191         async_wait_for(req, &rc);
    192         async_serialize_end();
    193         futex_up(&vfs_phone_futex);
     282                async_wait_for(req, &rc_orig);
     283                if (rc_orig == EOK)
     284                        return (int) rc;
     285                else
     286                        return (int) rc_orig;
     287        }
     288       
     289
     290        vfs_exchange_end(vfs_phone);
    194291        free(mpa);
     292        async_wait_for(req, &rc);
    195293       
    196294        return (int) rc;
    197295}
    198296
    199 static int _open(const char *path, int lflag, int oflag, ...)
    200 {
    201         ipcarg_t rc;
     297static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
     298{
     299        int vfs_phone = vfs_exchange_begin();
     300       
    202301        ipc_call_t answer;
     302        aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
     303        sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
     304       
     305        if (rc != EOK) {
     306                vfs_exchange_end(vfs_phone);
     307
     308                sysarg_t rc_orig;
     309                async_wait_for(req, &rc_orig);
     310               
     311                if (rc_orig == EOK)
     312                        return (int) rc;
     313                else
     314                        return (int) rc_orig;
     315        }
     316       
     317        vfs_exchange_end(vfs_phone);
     318        async_wait_for(req, &rc);
     319       
     320        if (rc != EOK)
     321            return (int) rc;
     322       
     323        return (int) IPC_GET_ARG1(answer);
     324}
     325
     326int open(const char *path, int oflag, ...)
     327{
     328        size_t abs_size;
     329        char *abs = absolutize(path, &abs_size);
     330        if (!abs)
     331                return ENOMEM;
     332       
     333        int ret = open_internal(abs, abs_size, L_FILE, oflag);
     334        free(abs);
     335       
     336        return ret;
     337}
     338
     339int open_node(fdi_node_t *node, int oflag)
     340{
     341        int vfs_phone = vfs_exchange_begin();
     342       
     343        ipc_call_t answer;
     344        aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
     345            node->devmap_handle, node->index, oflag, &answer);
     346       
     347        vfs_exchange_end(vfs_phone);
     348
     349        sysarg_t rc;
     350        async_wait_for(req, &rc);
     351       
     352        if (rc != EOK)
     353                return (int) rc;
     354       
     355        return (int) IPC_GET_ARG1(answer);
     356}
     357
     358int close(int fildes)
     359{
     360        sysarg_t rc;
     361       
     362        int vfs_phone = vfs_exchange_begin();
     363       
     364        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
     365       
     366        vfs_exchange_end(vfs_phone);
     367       
     368        return (int)rc;
     369}
     370
     371ssize_t read(int fildes, void *buf, size_t nbyte)
     372{
     373        sysarg_t rc;
     374        ipc_call_t answer;
     375        aid_t req;
     376
     377        int vfs_phone = vfs_exchange_begin();
     378       
     379        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
     380        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
     381        if (rc != EOK) {
     382                vfs_exchange_end(vfs_phone);
     383
     384                sysarg_t rc_orig;
     385                async_wait_for(req, &rc_orig);
     386
     387                if (rc_orig == EOK)
     388                        return (ssize_t) rc;
     389                else
     390                        return (ssize_t) rc_orig;
     391        }
     392        vfs_exchange_end(vfs_phone);
     393        async_wait_for(req, &rc);
     394        if (rc == EOK)
     395                return (ssize_t) IPC_GET_ARG1(answer);
     396        else
     397                return rc;
     398}
     399
     400ssize_t write(int fildes, const void *buf, size_t nbyte)
     401{
     402        sysarg_t rc;
     403        ipc_call_t answer;
     404        aid_t req;
     405
     406        int vfs_phone = vfs_exchange_begin();
     407       
     408        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
     409        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
     410        if (rc != EOK) {
     411                vfs_exchange_end(vfs_phone);
     412
     413                sysarg_t rc_orig;
     414                async_wait_for(req, &rc_orig);
     415
     416                if (rc_orig == EOK)
     417                        return (ssize_t) rc;
     418                else
     419                        return (ssize_t) rc_orig;
     420        }
     421        vfs_exchange_end(vfs_phone);
     422        async_wait_for(req, &rc);
     423        if (rc == EOK)
     424                return (ssize_t) IPC_GET_ARG1(answer);
     425        else
     426                return -1;
     427}
     428
     429int fsync(int fildes)
     430{
     431        int vfs_phone = vfs_exchange_begin();
     432       
     433        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
     434       
     435        vfs_exchange_end(vfs_phone);
     436       
     437        return (int) rc;
     438}
     439
     440off64_t lseek(int fildes, off64_t offset, int whence)
     441{
     442        int vfs_phone = vfs_exchange_begin();
     443       
     444        sysarg_t newoff_lo;
     445        sysarg_t newoff_hi;
     446        sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     447            LOWER32(offset), UPPER32(offset), whence,
     448            &newoff_lo, &newoff_hi);
     449       
     450        vfs_exchange_end(vfs_phone);
     451       
     452        if (rc != EOK)
     453                return (off64_t) -1;
     454       
     455        return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi);
     456}
     457
     458int ftruncate(int fildes, aoff64_t length)
     459{
     460        sysarg_t rc;
     461       
     462        int vfs_phone = vfs_exchange_begin();
     463       
     464        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     465            LOWER32(length), UPPER32(length));
     466        vfs_exchange_end(vfs_phone);
     467       
     468        return (int) rc;
     469}
     470
     471int fstat(int fildes, struct stat *stat)
     472{
     473        sysarg_t rc;
     474        aid_t req;
     475
     476        int vfs_phone = vfs_exchange_begin();
     477       
     478        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
     479        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
     480        if (rc != EOK) {
     481                vfs_exchange_end(vfs_phone);
     482
     483                sysarg_t rc_orig;
     484                async_wait_for(req, &rc_orig);
     485
     486                if (rc_orig == EOK)
     487                        return (ssize_t) rc;
     488                else
     489                        return (ssize_t) rc_orig;
     490        }
     491        vfs_exchange_end(vfs_phone);
     492        async_wait_for(req, &rc);
     493
     494        return rc;
     495}
     496
     497int stat(const char *path, struct stat *stat)
     498{
     499        sysarg_t rc;
     500        sysarg_t rc_orig;
    203501        aid_t req;
    204502       
     
    208506                return ENOMEM;
    209507       
    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 = ipc_data_write_start(vfs_phone, pa, pa_size);
    216         if (rc != EOK) {
    217                 ipcarg_t rc_orig;
    218        
    219                 async_wait_for(req, &rc_orig);
    220                 async_serialize_end();
    221                 futex_up(&vfs_phone_futex);
     508        int vfs_phone = vfs_exchange_begin();
     509       
     510        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
     511        rc = async_data_write_start(vfs_phone, pa, pa_size);
     512        if (rc != EOK) {
     513                vfs_exchange_end(vfs_phone);
    222514                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);
     515                async_wait_for(req, &rc_orig);
     516                if (rc_orig == EOK)
     517                        return (int) rc;
     518                else
     519                        return (int) rc_orig;
     520        }
     521        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
     522        if (rc != EOK) {
     523                vfs_exchange_end(vfs_phone);
     524                free(pa);
     525                async_wait_for(req, &rc_orig);
     526                if (rc_orig == EOK)
     527                        return (int) rc;
     528                else
     529                        return (int) rc_orig;
     530        }
     531        vfs_exchange_end(vfs_phone);
    231532        free(pa);
    232        
    233         if (rc != EOK)
    234             return (int) rc;
    235        
    236         return (int) IPC_GET_ARG1(answer);
    237 }
    238 
    239 int open(const char *path, int oflag, ...)
    240 {
    241         return _open(path, L_FILE, oflag);
    242 }
    243 
    244 int open_node(fdi_node_t *node, int oflag)
    245 {
    246         futex_down(&vfs_phone_futex);
    247         async_serialize_start();
    248         vfs_connect();
    249        
    250         ipc_call_t answer;
    251         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
    252             node->dev_handle, node->index, oflag, &answer);
    253        
    254         ipcarg_t rc;
    255         async_wait_for(req, &rc);
    256         async_serialize_end();
    257         futex_up(&vfs_phone_futex);
    258        
    259         if (rc != EOK)
    260                 return (int) rc;
    261        
    262         return (int) IPC_GET_ARG1(answer);
    263 }
    264 
    265 int close(int fildes)
    266 {
    267         ipcarg_t rc;
    268        
    269         futex_down(&vfs_phone_futex);
    270         async_serialize_start();
    271         vfs_connect();
    272        
    273         rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    274        
    275         async_serialize_end();
    276         futex_up(&vfs_phone_futex);
    277        
    278         return (int)rc;
    279 }
    280 
    281 ssize_t read(int fildes, void *buf, size_t nbyte)
    282 {
    283         ipcarg_t rc;
    284         ipc_call_t answer;
    285         aid_t req;
    286 
    287         futex_down(&vfs_phone_futex);
    288         async_serialize_start();
    289         vfs_connect();
    290        
    291         req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    292         rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);
    293         if (rc != EOK) {
    294                 ipcarg_t rc_orig;
    295        
    296                 async_wait_for(req, &rc_orig);
    297                 async_serialize_end();
    298                 futex_up(&vfs_phone_futex);
    299                 if (rc_orig == EOK)
    300                         return (ssize_t) rc;
    301                 else
    302                         return (ssize_t) rc_orig;
    303         }
    304         async_wait_for(req, &rc);
    305         async_serialize_end();
    306         futex_up(&vfs_phone_futex);
    307         if (rc == EOK)
    308                 return (ssize_t) IPC_GET_ARG1(answer);
    309         else
    310                 return rc;
    311 }
    312 
    313 ssize_t write(int fildes, const void *buf, size_t nbyte)
    314 {
    315         ipcarg_t rc;
    316         ipc_call_t answer;
    317         aid_t req;
    318 
    319         futex_down(&vfs_phone_futex);
    320         async_serialize_start();
    321         vfs_connect();
    322        
    323         req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    324         rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);
    325         if (rc != EOK) {
    326                 ipcarg_t rc_orig;
    327        
    328                 async_wait_for(req, &rc_orig);
    329                 async_serialize_end();
    330                 futex_up(&vfs_phone_futex);
    331                 if (rc_orig == EOK)
    332                         return (ssize_t) rc;
    333                 else
    334                         return (ssize_t) rc_orig;
    335         }
    336         async_wait_for(req, &rc);
    337         async_serialize_end();
    338         futex_up(&vfs_phone_futex);
    339         if (rc == EOK)
    340                 return (ssize_t) IPC_GET_ARG1(answer);
    341         else
    342                 return -1;
    343 }
    344 
    345 int fsync(int fildes)
    346 {
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
    350        
    351         ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    352        
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
    355        
    356         return (int) rc;
    357 }
    358 
    359 off_t lseek(int fildes, off_t offset, int whence)
    360 {
    361         ipcarg_t rc;
    362 
    363         futex_down(&vfs_phone_futex);
    364         async_serialize_start();
    365         vfs_connect();
    366        
    367         ipcarg_t newoffs;
    368         rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
    369             &newoffs);
    370 
    371         async_serialize_end();
    372         futex_up(&vfs_phone_futex);
    373 
    374         if (rc != EOK)
    375                 return (off_t) -1;
    376        
    377         return (off_t) newoffs;
    378 }
    379 
    380 int ftruncate(int fildes, off_t length)
    381 {
    382         ipcarg_t rc;
    383        
    384         futex_down(&vfs_phone_futex);
    385         async_serialize_start();
    386         vfs_connect();
    387        
    388         rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
    389         async_serialize_end();
    390         futex_up(&vfs_phone_futex);
    391         return (int) rc;
    392 }
    393 
    394 int fstat(int fildes, struct stat *stat)
    395 {
    396         ipcarg_t rc;
    397         aid_t req;
    398 
    399         futex_down(&vfs_phone_futex);
    400         async_serialize_start();
    401         vfs_connect();
    402        
    403         req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    404         rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
    405         if (rc != EOK) {
    406                 ipcarg_t rc_orig;
    407                
    408                 async_wait_for(req, &rc_orig);
    409                 async_serialize_end();
    410                 futex_up(&vfs_phone_futex);
    411                 if (rc_orig == EOK)
    412                         return (ssize_t) rc;
    413                 else
    414                         return (ssize_t) rc_orig;
    415         }
    416         async_wait_for(req, &rc);
    417         async_serialize_end();
    418         futex_up(&vfs_phone_futex);
    419 
     533        async_wait_for(req, &rc);
    420534        return rc;
    421535}
    422536
    423 int stat(const char *path, struct stat *stat)
    424 {
    425         ipcarg_t rc;
    426         ipcarg_t rc_orig;
     537DIR *opendir(const char *dirname)
     538{
     539        DIR *dirp = malloc(sizeof(DIR));
     540        if (!dirp)
     541                return NULL;
     542       
     543        size_t abs_size;
     544        char *abs = absolutize(dirname, &abs_size);
     545        if (!abs) {
     546                free(dirp);
     547                return NULL;
     548        }
     549       
     550        int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
     551        free(abs);
     552       
     553        if (ret < 0) {
     554                free(dirp);
     555                return NULL;
     556        }
     557       
     558        dirp->fd = ret;
     559        return dirp;
     560}
     561
     562struct dirent *readdir(DIR *dirp)
     563{
     564        ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
     565        if (len <= 0)
     566                return NULL;
     567        return &dirp->res;
     568}
     569
     570void rewinddir(DIR *dirp)
     571{
     572        (void) lseek(dirp->fd, 0, SEEK_SET);
     573}
     574
     575int closedir(DIR *dirp)
     576{
     577        (void) close(dirp->fd);
     578        free(dirp);
     579        return 0;
     580}
     581
     582int mkdir(const char *path, mode_t mode)
     583{
     584        sysarg_t rc;
    427585        aid_t req;
    428586       
     
    432590                return ENOMEM;
    433591       
    434         futex_down(&vfs_phone_futex);
    435         async_serialize_start();
    436         vfs_connect();
    437        
    438         req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    439         rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    440         if (rc != EOK) {
    441                 async_wait_for(req, &rc_orig);
    442                 async_serialize_end();
    443                 futex_up(&vfs_phone_futex);
     592        int vfs_phone = vfs_exchange_begin();
     593       
     594        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
     595        rc = async_data_write_start(vfs_phone, pa, pa_size);
     596        if (rc != EOK) {
     597                vfs_exchange_end(vfs_phone);
    444598                free(pa);
    445                 if (rc_orig == EOK)
    446                         return (int) rc;
    447                 else
    448                         return (int) rc_orig;
    449         }
    450         rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));
    451         if (rc != EOK) {
    452                 async_wait_for(req, &rc_orig);
    453                 async_serialize_end();
    454                 futex_up(&vfs_phone_futex);
    455                 free(pa);
    456                 if (rc_orig == EOK)
    457                         return (int) rc;
    458                 else
    459                         return (int) rc_orig;
    460         }
    461         async_wait_for(req, &rc);
    462         async_serialize_end();
    463         futex_up(&vfs_phone_futex);
     599
     600                sysarg_t rc_orig;
     601                async_wait_for(req, &rc_orig);
     602
     603                if (rc_orig == EOK)
     604                        return (int) rc;
     605                else
     606                        return (int) rc_orig;
     607        }
     608        vfs_exchange_end(vfs_phone);
    464609        free(pa);
     610        async_wait_for(req, &rc);
    465611        return rc;
    466612}
    467613
    468 DIR *opendir(const char *dirname)
    469 {
    470         DIR *dirp = malloc(sizeof(DIR));
    471         if (!dirp)
    472                 return NULL;
    473         dirp->fd = _open(dirname, L_DIRECTORY, 0);
    474         if (dirp->fd < 0) {
    475                 free(dirp);
    476                 return NULL;
    477         }
    478         return dirp;
    479 }
    480 
    481 struct dirent *readdir(DIR *dirp)
    482 {
    483         ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
    484         if (len <= 0)
    485                 return NULL;
    486         return &dirp->res;
    487 }
    488 
    489 void rewinddir(DIR *dirp)
    490 {
    491         (void) lseek(dirp->fd, 0, SEEK_SET);
    492 }
    493 
    494 int closedir(DIR *dirp)
    495 {
    496         (void) close(dirp->fd);
    497         free(dirp);
    498         return 0;
    499 }
    500 
    501 int mkdir(const char *path, mode_t mode)
    502 {
    503         ipcarg_t rc;
     614static int _unlink(const char *path, int lflag)
     615{
     616        sysarg_t rc;
    504617        aid_t req;
    505618       
     
    508621        if (!pa)
    509622                return ENOMEM;
    510        
    511         futex_down(&vfs_phone_futex);
    512         async_serialize_start();
    513         vfs_connect();
    514        
    515         req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    516         rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    517         if (rc != EOK) {
    518                 ipcarg_t rc_orig;
    519        
    520                 async_wait_for(req, &rc_orig);
    521                 async_serialize_end();
    522                 futex_up(&vfs_phone_futex);
     623
     624        int vfs_phone = vfs_exchange_begin();
     625       
     626        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
     627        rc = async_data_write_start(vfs_phone, pa, pa_size);
     628        if (rc != EOK) {
     629                vfs_exchange_end(vfs_phone);
    523630                free(pa);
    524                 if (rc_orig == EOK)
    525                         return (int) rc;
    526                 else
    527                         return (int) rc_orig;
    528         }
    529         async_wait_for(req, &rc);
    530         async_serialize_end();
    531         futex_up(&vfs_phone_futex);
     631
     632                sysarg_t rc_orig;
     633                async_wait_for(req, &rc_orig);
     634
     635                if (rc_orig == EOK)
     636                        return (int) rc;
     637                else
     638                        return (int) rc_orig;
     639        }
     640        vfs_exchange_end(vfs_phone);
    532641        free(pa);
     642        async_wait_for(req, &rc);
    533643        return rc;
    534644}
    535645
    536 static int _unlink(const char *path, int lflag)
    537 {
    538         ipcarg_t rc;
    539         aid_t req;
    540        
    541         size_t pa_size;
    542         char *pa = absolutize(path, &pa_size);
    543         if (!pa)
    544                 return ENOMEM;
    545 
    546         futex_down(&vfs_phone_futex);
    547         async_serialize_start();
    548         vfs_connect();
    549        
    550         req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    551         rc = ipc_data_write_start(vfs_phone, pa, pa_size);
    552         if (rc != EOK) {
    553                 ipcarg_t rc_orig;
    554 
    555                 async_wait_for(req, &rc_orig);
    556                 async_serialize_end();
    557                 futex_up(&vfs_phone_futex);
    558                 free(pa);
    559                 if (rc_orig == EOK)
    560                         return (int) rc;
    561                 else
    562                         return (int) rc_orig;
    563         }
    564         async_wait_for(req, &rc);
    565         async_serialize_end();
    566         futex_up(&vfs_phone_futex);
    567         free(pa);
    568         return rc;
    569 }
    570 
    571646int unlink(const char *path)
    572647{
     
    581656int rename(const char *old, const char *new)
    582657{
    583         ipcarg_t rc;
    584         ipcarg_t rc_orig;
     658        sysarg_t rc;
     659        sysarg_t rc_orig;
    585660        aid_t req;
    586661       
     
    597672        }
    598673
    599         futex_down(&vfs_phone_futex);
    600         async_serialize_start();
    601         vfs_connect();
     674        int vfs_phone = vfs_exchange_begin();
    602675       
    603676        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    604         rc = ipc_data_write_start(vfs_phone, olda, olda_size);
    605         if (rc != EOK) {
    606                 async_wait_for(req, &rc_orig);
    607                 async_serialize_end();
    608                 futex_up(&vfs_phone_futex);
     677        rc = async_data_write_start(vfs_phone, olda, olda_size);
     678        if (rc != EOK) {
     679                vfs_exchange_end(vfs_phone);
    609680                free(olda);
    610681                free(newa);
    611                 if (rc_orig == EOK)
    612                         return (int) rc;
    613                 else
    614                         return (int) rc_orig;
    615         }
    616         rc = ipc_data_write_start(vfs_phone, newa, newa_size);
    617         if (rc != EOK) {
    618                 async_wait_for(req, &rc_orig);
    619                 async_serialize_end();
    620                 futex_up(&vfs_phone_futex);
     682                async_wait_for(req, &rc_orig);
     683                if (rc_orig == EOK)
     684                        return (int) rc;
     685                else
     686                        return (int) rc_orig;
     687        }
     688        rc = async_data_write_start(vfs_phone, newa, newa_size);
     689        if (rc != EOK) {
     690                vfs_exchange_end(vfs_phone);
    621691                free(olda);
    622692                free(newa);
    623                 if (rc_orig == EOK)
    624                         return (int) rc;
    625                 else
    626                         return (int) rc_orig;
    627         }
    628         async_wait_for(req, &rc);
    629         async_serialize_end();
    630         futex_up(&vfs_phone_futex);
     693                async_wait_for(req, &rc_orig);
     694                if (rc_orig == EOK)
     695                        return (int) rc;
     696                else
     697                        return (int) rc_orig;
     698        }
     699        vfs_exchange_end(vfs_phone);
    631700        free(olda);
    632701        free(newa);
     702        async_wait_for(req, &rc);
    633703        return rc;
    634704}
     
    636706int chdir(const char *path)
    637707{
    638         size_t pa_size;
    639         char *pa = absolutize(path, &pa_size);
    640         if (!pa)
     708        size_t abs_size;
     709        char *abs = absolutize(path, &abs_size);
     710        if (!abs)
    641711                return ENOMEM;
    642 
    643         DIR *d = opendir(pa);
    644         if (!d) {
    645                 free(pa);
     712       
     713        int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
     714       
     715        if (fd < 0) {
     716                free(abs);
    646717                return ENOENT;
    647718        }
    648 
    649         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;
    660         futex_up(&cwd_futex);
     719       
     720        fibril_mutex_lock(&cwd_mutex);
     721       
     722        if (cwd_fd >= 0)
     723                close(cwd_fd);
     724       
     725       
     726        if (cwd_path)
     727                free(cwd_path);
     728       
     729        cwd_fd = fd;
     730        cwd_path = abs;
     731        cwd_size = abs_size;
     732       
     733        fibril_mutex_unlock(&cwd_mutex);
    661734        return EOK;
    662735}
     
    664737char *getcwd(char *buf, size_t size)
    665738{
    666         if (!size)
     739        if (size == 0)
    667740                return NULL;
    668         futex_down(&cwd_futex);
    669         if (size < cwd_size + 1) {
    670                 futex_up(&cwd_futex);
     741       
     742        fibril_mutex_lock(&cwd_mutex);
     743       
     744        if ((cwd_size == 0) || (size < cwd_size + 1)) {
     745                fibril_mutex_unlock(&cwd_mutex);
    671746                return NULL;
    672747        }
     748       
    673749        str_cpy(buf, size, cwd_path);
    674         futex_up(&cwd_futex);
     750        fibril_mutex_unlock(&cwd_mutex);
     751       
    675752        return buf;
    676753}
     
    683760        rc = fstat(fildes, &stat);
    684761
    685         if (!stat.devfs_stat.device)
     762        if (!stat.device)
    686763                return -1;
    687764       
    688         return devmap_device_connect(stat.devfs_stat.device, 0);
     765        return devmap_device_connect(stat.device, 0);
    689766}
    690767
     
    698775        if (rc == EOK) {
    699776                node->fs_handle = stat.fs_handle;
    700                 node->dev_handle = stat.dev_handle;
     777                node->devmap_handle = stat.devmap_handle;
    701778                node->index = stat.index;
    702779        }
    703780       
    704781        return rc;
     782}
     783
     784int dup2(int oldfd, int newfd)
     785{
     786        int vfs_phone = vfs_exchange_begin();
     787       
     788        sysarg_t ret;
     789        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
     790       
     791        vfs_exchange_end(vfs_phone);
     792       
     793        if (rc == EOK)
     794                return (int) ret;
     795       
     796        return (int) rc;
    705797}
    706798
Note: See TracChangeset for help on using the changeset viewer.