vfs.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <vfs/vfs.h>
00036 #include <vfs/canonify.h>
00037 #include <macros.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040 #include <dirent.h>
00041 #include <fcntl.h>
00042 #include <stdio.h>
00043 #include <sys/stat.h>
00044 #include <sys/types.h>
00045 #include <ipc/services.h>
00046 #include <ipc/ns.h>
00047 #include <async.h>
00048 #include <fibril_synch.h>
00049 #include <errno.h>
00050 #include <assert.h>
00051 #include <str.h>
00052 #include <devmap.h>
00053 #include <ipc/vfs.h>
00054 #include <ipc/devmap.h>
00055 
00056 static async_sess_t vfs_session;
00057 
00058 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
00059 static int vfs_phone = -1;
00060 
00061 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
00062 
00063 static int cwd_fd = -1;
00064 static char *cwd_path = NULL;
00065 static size_t cwd_size = 0;
00066 
00067 char *absolutize(const char *path, size_t *retlen)
00068 {
00069         char *ncwd_path;
00070         char *ncwd_path_nc;
00071         size_t total_size; 
00072 
00073         fibril_mutex_lock(&cwd_mutex);
00074         size_t size = str_size(path);
00075         if (*path != '/') {
00076                 if (!cwd_path) {
00077                         fibril_mutex_unlock(&cwd_mutex);
00078                         return NULL;
00079                 }
00080                 total_size = cwd_size + 1 + size + 1;
00081                 ncwd_path_nc = malloc(total_size);
00082                 if (!ncwd_path_nc) {
00083                         fibril_mutex_unlock(&cwd_mutex);
00084                         return NULL;
00085                 }
00086                 str_cpy(ncwd_path_nc, total_size, cwd_path);
00087                 ncwd_path_nc[cwd_size] = '/';
00088                 ncwd_path_nc[cwd_size + 1] = '\0';
00089         } else {
00090                 total_size = size + 1;
00091                 ncwd_path_nc = malloc(total_size);
00092                 if (!ncwd_path_nc) {
00093                         fibril_mutex_unlock(&cwd_mutex);
00094                         return NULL;
00095                 }
00096                 ncwd_path_nc[0] = '\0';
00097         }
00098         str_append(ncwd_path_nc, total_size, path);
00099         ncwd_path = canonify(ncwd_path_nc, retlen);
00100         if (!ncwd_path) {
00101                 fibril_mutex_unlock(&cwd_mutex);
00102                 free(ncwd_path_nc);
00103                 return NULL;
00104         }
00105         /*
00106          * We need to clone ncwd_path because canonify() works in-place and thus
00107          * the address in ncwd_path need not be the same as ncwd_path_nc, even
00108          * though they both point into the same dynamically allocated buffer.
00109          */
00110         ncwd_path = str_dup(ncwd_path);
00111         free(ncwd_path_nc);
00112         if (!ncwd_path) {
00113                 fibril_mutex_unlock(&cwd_mutex);
00114                 return NULL;
00115         }
00116         fibril_mutex_unlock(&cwd_mutex);
00117         return ncwd_path;
00118 }
00119 
00121 static void vfs_connect(void)
00122 {
00123         while (vfs_phone < 0)
00124                 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
00125         
00126         async_session_create(&vfs_session, vfs_phone, 0);
00127 }
00128 
00133 static int vfs_exchange_begin(void)
00134 {
00135         fibril_mutex_lock(&vfs_phone_mutex);
00136         if (vfs_phone < 0)
00137                 vfs_connect();
00138         fibril_mutex_unlock(&vfs_phone_mutex);
00139 
00140         return async_exchange_begin(&vfs_session);
00141 }
00142 
00147 static void vfs_exchange_end(int phone)
00148 {
00149         async_exchange_end(&vfs_session, phone);
00150 }
00151 
00152 int mount(const char *fs_name, const char *mp, const char *fqdn,
00153     const char *opts, unsigned int flags)
00154 {
00155         int null_id = -1;
00156         char null[DEVMAP_NAME_MAXLEN];
00157         
00158         if (str_cmp(fqdn, "") == 0) {
00159                 /* No device specified, create a fresh
00160                    null/%d device instead */
00161                 null_id = devmap_null_create();
00162                 
00163                 if (null_id == -1)
00164                         return ENOMEM;
00165                 
00166                 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
00167                 fqdn = null;
00168         }
00169         
00170         devmap_handle_t devmap_handle;
00171         int res = devmap_device_get_handle(fqdn, &devmap_handle, flags);
00172         if (res != EOK) {
00173                 if (null_id != -1)
00174                         devmap_null_destroy(null_id);
00175                 
00176                 return res;
00177         }
00178         
00179         size_t mpa_size;
00180         char *mpa = absolutize(mp, &mpa_size);
00181         if (!mpa) {
00182                 if (null_id != -1)
00183                         devmap_null_destroy(null_id);
00184                 
00185                 return ENOMEM;
00186         }
00187         
00188         int vfs_phone = vfs_exchange_begin();
00189 
00190         sysarg_t rc_orig;
00191         aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
00192         sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
00193         if (rc != EOK) {
00194                 vfs_exchange_end(vfs_phone);
00195                 free(mpa);
00196                 async_wait_for(req, &rc_orig);
00197                 
00198                 if (null_id != -1)
00199                         devmap_null_destroy(null_id);
00200                 
00201                 if (rc_orig == EOK)
00202                         return (int) rc;
00203                 else
00204                         return (int) rc_orig;
00205         }
00206         
00207         rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
00208         if (rc != EOK) {
00209                 vfs_exchange_end(vfs_phone);
00210                 free(mpa);
00211                 async_wait_for(req, &rc_orig);
00212                 
00213                 if (null_id != -1)
00214                         devmap_null_destroy(null_id);
00215                 
00216                 if (rc_orig == EOK)
00217                         return (int) rc;
00218                 else
00219                         return (int) rc_orig;
00220         }
00221         
00222         rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
00223         if (rc != EOK) {
00224                 vfs_exchange_end(vfs_phone);
00225                 free(mpa);
00226                 async_wait_for(req, &rc_orig);
00227                 
00228                 if (null_id != -1)
00229                         devmap_null_destroy(null_id);
00230                 
00231                 if (rc_orig == EOK)
00232                         return (int) rc;
00233                 else
00234                         return (int) rc_orig;
00235         }
00236         
00237         /* Ask VFS whether it likes fs_name. */
00238         rc = async_req_0_0(vfs_phone, IPC_M_PING);
00239         if (rc != EOK) {
00240                 vfs_exchange_end(vfs_phone);
00241                 free(mpa);
00242                 async_wait_for(req, &rc_orig);
00243                 
00244                 if (null_id != -1)
00245                         devmap_null_destroy(null_id);
00246                 
00247                 if (rc_orig == EOK)
00248                         return (int) rc;
00249                 else
00250                         return (int) rc_orig;
00251         }
00252         
00253         vfs_exchange_end(vfs_phone);
00254         free(mpa);
00255         async_wait_for(req, &rc);
00256         
00257         if ((rc != EOK) && (null_id != -1))
00258                 devmap_null_destroy(null_id);
00259         
00260         return (int) rc;
00261 }
00262 
00263 int unmount(const char *mp)
00264 {
00265         sysarg_t rc;
00266         sysarg_t rc_orig;
00267         aid_t req;
00268         size_t mpa_size;
00269         char *mpa;
00270         
00271         mpa = absolutize(mp, &mpa_size);
00272         if (!mpa)
00273                 return ENOMEM;
00274         
00275         int vfs_phone = vfs_exchange_begin();
00276         
00277         req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
00278         rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
00279         if (rc != EOK) {
00280                 vfs_exchange_end(vfs_phone);
00281                 free(mpa);
00282                 async_wait_for(req, &rc_orig);
00283                 if (rc_orig == EOK)
00284                         return (int) rc;
00285                 else
00286                         return (int) rc_orig;
00287         }
00288         
00289 
00290         vfs_exchange_end(vfs_phone);
00291         free(mpa);
00292         async_wait_for(req, &rc);
00293         
00294         return (int) rc;
00295 }
00296 
00297 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
00298 {
00299         int vfs_phone = vfs_exchange_begin();
00300         
00301         ipc_call_t answer;
00302         aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
00303         sysarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
00304         
00305         if (rc != EOK) {
00306                 vfs_exchange_end(vfs_phone);
00307 
00308                 sysarg_t rc_orig;
00309                 async_wait_for(req, &rc_orig);
00310                 
00311                 if (rc_orig == EOK)
00312                         return (int) rc;
00313                 else
00314                         return (int) rc_orig;
00315         }
00316         
00317         vfs_exchange_end(vfs_phone);
00318         async_wait_for(req, &rc);
00319         
00320         if (rc != EOK)
00321             return (int) rc;
00322         
00323         return (int) IPC_GET_ARG1(answer);
00324 }
00325 
00326 int open(const char *path, int oflag, ...)
00327 {
00328         size_t abs_size;
00329         char *abs = absolutize(path, &abs_size);
00330         if (!abs)
00331                 return ENOMEM;
00332         
00333         int ret = open_internal(abs, abs_size, L_FILE, oflag);
00334         free(abs);
00335         
00336         return ret;
00337 }
00338 
00339 int open_node(fdi_node_t *node, int oflag)
00340 {
00341         int vfs_phone = vfs_exchange_begin();
00342         
00343         ipc_call_t answer;
00344         aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
00345             node->devmap_handle, node->index, oflag, &answer);
00346         
00347         vfs_exchange_end(vfs_phone);
00348 
00349         sysarg_t rc;
00350         async_wait_for(req, &rc);
00351         
00352         if (rc != EOK)
00353                 return (int) rc;
00354         
00355         return (int) IPC_GET_ARG1(answer);
00356 }
00357 
00358 int close(int fildes)
00359 {
00360         sysarg_t rc;
00361         
00362         int vfs_phone = vfs_exchange_begin();
00363         
00364         rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
00365         
00366         vfs_exchange_end(vfs_phone);
00367         
00368         return (int)rc;
00369 }
00370 
00371 ssize_t read(int fildes, void *buf, size_t nbyte) 
00372 {
00373         sysarg_t rc;
00374         ipc_call_t answer;
00375         aid_t req;
00376 
00377         int vfs_phone = vfs_exchange_begin();
00378         
00379         req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
00380         rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte,
00381             IPC_XF_RESTRICT);
00382         if (rc != EOK) {
00383                 vfs_exchange_end(vfs_phone);
00384 
00385                 sysarg_t rc_orig;
00386                 async_wait_for(req, &rc_orig);
00387 
00388                 if (rc_orig == EOK)
00389                         return (ssize_t) rc;
00390                 else
00391                         return (ssize_t) rc_orig;
00392         }
00393         vfs_exchange_end(vfs_phone);
00394         async_wait_for(req, &rc);
00395         if (rc == EOK)
00396                 return (ssize_t) IPC_GET_ARG1(answer);
00397         else
00398                 return rc;
00399 }
00400 
00401 ssize_t write(int fildes, const void *buf, size_t nbyte) 
00402 {
00403         sysarg_t rc;
00404         ipc_call_t answer;
00405         aid_t req;
00406 
00407         int vfs_phone = vfs_exchange_begin();
00408         
00409         req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
00410         rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte,
00411             IPC_XF_RESTRICT);
00412         if (rc != EOK) {
00413                 vfs_exchange_end(vfs_phone);
00414 
00415                 sysarg_t rc_orig;
00416                 async_wait_for(req, &rc_orig);
00417 
00418                 if (rc_orig == EOK)
00419                         return (ssize_t) rc;
00420                 else
00421                         return (ssize_t) rc_orig;
00422         }
00423         vfs_exchange_end(vfs_phone);
00424         async_wait_for(req, &rc);
00425         if (rc == EOK)
00426                 return (ssize_t) IPC_GET_ARG1(answer);
00427         else
00428                 return -1;
00429 }
00430 
00431 int fsync(int fildes)
00432 {
00433         int vfs_phone = vfs_exchange_begin();
00434         
00435         sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
00436         
00437         vfs_exchange_end(vfs_phone);
00438         
00439         return (int) rc;
00440 }
00441 
00442 off64_t lseek(int fildes, off64_t offset, int whence)
00443 {
00444         int vfs_phone = vfs_exchange_begin();
00445         
00446         sysarg_t newoff_lo;
00447         sysarg_t newoff_hi;
00448         sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
00449             LOWER32(offset), UPPER32(offset), whence,
00450             &newoff_lo, &newoff_hi);
00451         
00452         vfs_exchange_end(vfs_phone);
00453         
00454         if (rc != EOK)
00455                 return (off64_t) -1;
00456         
00457         return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi);
00458 }
00459 
00460 int ftruncate(int fildes, aoff64_t length)
00461 {
00462         sysarg_t rc;
00463         
00464         int vfs_phone = vfs_exchange_begin();
00465         
00466         rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
00467             LOWER32(length), UPPER32(length));
00468         vfs_exchange_end(vfs_phone);
00469         
00470         return (int) rc;
00471 }
00472 
00473 int fstat(int fildes, struct stat *stat)
00474 {
00475         sysarg_t rc;
00476         aid_t req;
00477 
00478         int vfs_phone = vfs_exchange_begin();
00479         
00480         req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
00481         rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
00482         if (rc != EOK) {
00483                 vfs_exchange_end(vfs_phone);
00484 
00485                 sysarg_t rc_orig;
00486                 async_wait_for(req, &rc_orig);
00487 
00488                 if (rc_orig == EOK)
00489                         return (ssize_t) rc;
00490                 else
00491                         return (ssize_t) rc_orig;
00492         }
00493         vfs_exchange_end(vfs_phone);
00494         async_wait_for(req, &rc);
00495 
00496         return rc;
00497 }
00498 
00499 int stat(const char *path, struct stat *stat)
00500 {
00501         sysarg_t rc;
00502         sysarg_t rc_orig;
00503         aid_t req;
00504         
00505         size_t pa_size;
00506         char *pa = absolutize(path, &pa_size);
00507         if (!pa)
00508                 return ENOMEM;
00509         
00510         int vfs_phone = vfs_exchange_begin();
00511         
00512         req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
00513         rc = async_data_write_start(vfs_phone, pa, pa_size);
00514         if (rc != EOK) {
00515                 vfs_exchange_end(vfs_phone);
00516                 free(pa);
00517                 async_wait_for(req, &rc_orig);
00518                 if (rc_orig == EOK)
00519                         return (int) rc;
00520                 else
00521                         return (int) rc_orig;
00522         }
00523         rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
00524         if (rc != EOK) {
00525                 vfs_exchange_end(vfs_phone);
00526                 free(pa);
00527                 async_wait_for(req, &rc_orig);
00528                 if (rc_orig == EOK)
00529                         return (int) rc;
00530                 else
00531                         return (int) rc_orig;
00532         }
00533         vfs_exchange_end(vfs_phone);
00534         free(pa);
00535         async_wait_for(req, &rc);
00536         return rc;
00537 }
00538 
00539 DIR *opendir(const char *dirname)
00540 {
00541         DIR *dirp = malloc(sizeof(DIR));
00542         if (!dirp)
00543                 return NULL;
00544         
00545         size_t abs_size;
00546         char *abs = absolutize(dirname, &abs_size);
00547         if (!abs) {
00548                 free(dirp);
00549                 return NULL;
00550         }
00551         
00552         int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
00553         free(abs);
00554         
00555         if (ret < 0) {
00556                 free(dirp);
00557                 return NULL;
00558         }
00559         
00560         dirp->fd = ret;
00561         return dirp;
00562 }
00563 
00564 struct dirent *readdir(DIR *dirp)
00565 {
00566         ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
00567         if (len <= 0)
00568                 return NULL;
00569         return &dirp->res;
00570 }
00571 
00572 void rewinddir(DIR *dirp)
00573 {
00574         (void) lseek(dirp->fd, 0, SEEK_SET);
00575 }
00576 
00577 int closedir(DIR *dirp)
00578 {
00579         (void) close(dirp->fd);
00580         free(dirp);
00581         return 0;
00582 }
00583 
00584 int mkdir(const char *path, mode_t mode)
00585 {
00586         sysarg_t rc;
00587         aid_t req;
00588         
00589         size_t pa_size;
00590         char *pa = absolutize(path, &pa_size);
00591         if (!pa)
00592                 return ENOMEM;
00593         
00594         int vfs_phone = vfs_exchange_begin();
00595         
00596         req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
00597         rc = async_data_write_start(vfs_phone, pa, pa_size);
00598         if (rc != EOK) {
00599                 vfs_exchange_end(vfs_phone);
00600                 free(pa);
00601 
00602                 sysarg_t rc_orig;
00603                 async_wait_for(req, &rc_orig);
00604 
00605                 if (rc_orig == EOK)
00606                         return (int) rc;
00607                 else
00608                         return (int) rc_orig;
00609         }
00610         vfs_exchange_end(vfs_phone);
00611         free(pa);
00612         async_wait_for(req, &rc);
00613         return rc;
00614 }
00615 
00616 static int _unlink(const char *path, int lflag)
00617 {
00618         sysarg_t rc;
00619         aid_t req;
00620         
00621         size_t pa_size;
00622         char *pa = absolutize(path, &pa_size);
00623         if (!pa)
00624                 return ENOMEM;
00625 
00626         int vfs_phone = vfs_exchange_begin();
00627         
00628         req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
00629         rc = async_data_write_start(vfs_phone, pa, pa_size);
00630         if (rc != EOK) {
00631                 vfs_exchange_end(vfs_phone);
00632                 free(pa);
00633 
00634                 sysarg_t rc_orig;
00635                 async_wait_for(req, &rc_orig);
00636 
00637                 if (rc_orig == EOK)
00638                         return (int) rc;
00639                 else
00640                         return (int) rc_orig;
00641         }
00642         vfs_exchange_end(vfs_phone);
00643         free(pa);
00644         async_wait_for(req, &rc);
00645         return rc;
00646 }
00647 
00648 int unlink(const char *path)
00649 {
00650         return _unlink(path, L_NONE);
00651 }
00652 
00653 int rmdir(const char *path)
00654 {
00655         return _unlink(path, L_DIRECTORY);
00656 }
00657 
00658 int rename(const char *old, const char *new)
00659 {
00660         sysarg_t rc;
00661         sysarg_t rc_orig;
00662         aid_t req;
00663         
00664         size_t olda_size;
00665         char *olda = absolutize(old, &olda_size);
00666         if (!olda)
00667                 return ENOMEM;
00668 
00669         size_t newa_size;
00670         char *newa = absolutize(new, &newa_size);
00671         if (!newa) {
00672                 free(olda);
00673                 return ENOMEM;
00674         }
00675 
00676         int vfs_phone = vfs_exchange_begin();
00677         
00678         req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
00679         rc = async_data_write_start(vfs_phone, olda, olda_size);
00680         if (rc != EOK) {
00681                 vfs_exchange_end(vfs_phone);
00682                 free(olda);
00683                 free(newa);
00684                 async_wait_for(req, &rc_orig);
00685                 if (rc_orig == EOK)
00686                         return (int) rc;
00687                 else
00688                         return (int) rc_orig;
00689         }
00690         rc = async_data_write_start(vfs_phone, newa, newa_size);
00691         if (rc != EOK) {
00692                 vfs_exchange_end(vfs_phone);
00693                 free(olda);
00694                 free(newa);
00695                 async_wait_for(req, &rc_orig);
00696                 if (rc_orig == EOK)
00697                         return (int) rc;
00698                 else
00699                         return (int) rc_orig;
00700         }
00701         vfs_exchange_end(vfs_phone);
00702         free(olda);
00703         free(newa);
00704         async_wait_for(req, &rc);
00705         return rc;
00706 }
00707 
00708 int chdir(const char *path)
00709 {
00710         size_t abs_size;
00711         char *abs = absolutize(path, &abs_size);
00712         if (!abs)
00713                 return ENOMEM;
00714         
00715         int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
00716         
00717         if (fd < 0) {
00718                 free(abs);
00719                 return ENOENT;
00720         }
00721         
00722         fibril_mutex_lock(&cwd_mutex);
00723         
00724         if (cwd_fd >= 0)
00725                 close(cwd_fd);
00726         
00727         
00728         if (cwd_path)
00729                 free(cwd_path);
00730         
00731         cwd_fd = fd;
00732         cwd_path = abs;
00733         cwd_size = abs_size;
00734         
00735         fibril_mutex_unlock(&cwd_mutex);
00736         return EOK;
00737 }
00738 
00739 char *getcwd(char *buf, size_t size)
00740 {
00741         if (size == 0)
00742                 return NULL;
00743         
00744         fibril_mutex_lock(&cwd_mutex);
00745         
00746         if ((cwd_size == 0) || (size < cwd_size + 1)) {
00747                 fibril_mutex_unlock(&cwd_mutex);
00748                 return NULL;
00749         }
00750         
00751         str_cpy(buf, size, cwd_path);
00752         fibril_mutex_unlock(&cwd_mutex);
00753         
00754         return buf;
00755 }
00756 
00757 int fd_phone(int fildes)
00758 {
00759         struct stat stat;
00760         
00761         int rc = fstat(fildes, &stat);
00762         if (rc != 0)
00763                 return rc;
00764         
00765         if (!stat.device)
00766                 return -1;
00767         
00768         return devmap_device_connect(stat.device, 0);
00769 }
00770 
00771 int fd_node(int fildes, fdi_node_t *node)
00772 {
00773         struct stat stat;
00774         int rc;
00775 
00776         rc = fstat(fildes, &stat);
00777         
00778         if (rc == EOK) {
00779                 node->fs_handle = stat.fs_handle;
00780                 node->devmap_handle = stat.devmap_handle;
00781                 node->index = stat.index;
00782         }
00783         
00784         return rc;
00785 }
00786 
00787 int dup2(int oldfd, int newfd)
00788 {
00789         int vfs_phone = vfs_exchange_begin();
00790         
00791         sysarg_t ret;
00792         sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
00793         
00794         vfs_exchange_end(vfs_phone);
00795         
00796         if (rc == EOK)
00797                 return (int) ret;
00798         
00799         return (int) rc;
00800 }
00801 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7