Changeset 1dff985 in mainline for uspace/lib/c/generic/vfs/vfs.c


Ignore:
Timestamp:
2017-03-03T21:32:38Z (7 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c577a9a
Parents:
5b46ec8 (diff), b8dbe2f (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 from lp:~zarevucky-jiri/helenos/vfs-2.5 up to revision 1926

File:
1 edited

Legend:

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

    r5b46ec8 r1dff985  
    9393}
    9494
     95int _vfs_walk(int parent, const char *path, int flags)
     96{
     97        async_exch_t *exch = vfs_exchange_begin();
     98       
     99        ipc_call_t answer;
     100        aid_t req = async_send_2(exch, VFS_IN_WALK, parent, flags, &answer);
     101        sysarg_t rc = async_data_write_start(exch, path, str_size(path));
     102        vfs_exchange_end(exch);
     103               
     104        sysarg_t rc_orig;
     105        async_wait_for(req, &rc_orig);
     106
     107        if (rc_orig != EOK) {
     108                return (int) rc_orig;
     109        }
     110               
     111        if (rc != EOK) {
     112                return (int) rc;
     113        }
     114       
     115        return (int) IPC_GET_ARG1(answer);
     116}
     117
     118int _vfs_open(int fildes, int mode)
     119{
     120        async_exch_t *exch = vfs_exchange_begin();
     121        sysarg_t rc = async_req_2_0(exch, VFS_IN_OPEN2, fildes, mode);
     122        vfs_exchange_end(exch);
     123       
     124        return (int) rc;
     125}
     126
    95127char *vfs_absolutize(const char *path, size_t *retlen)
    96128{
     
    229261        }
    230262       
    231         /* Ask VFS whether it likes fs_name. */
    232         rc = async_req_0_0(exch, VFS_IN_PING);
    233         if (rc != EOK) {
    234                 vfs_exchange_end(exch);
    235                 free(mpa);
    236                 async_wait_for(req, &rc_orig);
    237                
    238                 if (null_id != -1)
    239                         loc_null_destroy(null_id);
    240                
    241                 if (rc_orig == EOK)
    242                         return (int) rc;
    243                 else
    244                         return (int) rc_orig;
    245         }
    246        
    247263        vfs_exchange_end(exch);
    248264        free(mpa);
     
    289305}
    290306
    291 /** Open file (internal).
    292  *
    293  * @param abs Absolute path to file
    294  * @param abs_size Size of @a abs string
    295  * @param lflag L_xxx flags
    296  * @param oflag O_xxx flags
    297  * @param fd Place to store new file descriptor
    298  *
    299  * @return EOK on success, non-zero error code on error
    300  */
    301 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag,
    302     int *fd)
    303 {
    304         async_exch_t *exch = vfs_exchange_begin();
    305        
    306         ipc_call_t answer;
    307         aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer);
    308         sysarg_t rc = async_data_write_start(exch, abs, abs_size);
    309        
    310         if (rc != EOK) {
    311                 vfs_exchange_end(exch);
    312 
    313                 sysarg_t rc_orig;
    314                 async_wait_for(req, &rc_orig);
    315                
    316                 if (rc_orig == EOK)
    317                         return (int) rc;
    318                 else
    319                         return (int) rc_orig;
    320         }
    321        
    322         vfs_exchange_end(exch);
    323         async_wait_for(req, &rc);
    324        
    325         if (rc != EOK)
    326             return (int) rc;
    327        
    328         *fd = (int) IPC_GET_ARG1(answer);
    329         return EOK;
     307static int walk_flags(int oflags)
     308{
     309        int flags = 0;
     310        if (oflags & O_CREAT) {
     311                if (oflags & O_EXCL) {
     312                        flags |= WALK_MUST_CREATE;
     313                } else {
     314                        flags |= WALK_MAY_CREATE;
     315                }
     316        }
     317        return flags;
    330318}
    331319
     
    341329int open(const char *path, int oflag, ...)
    342330{
     331        // FIXME: Some applications call this incorrectly.
     332        if ((oflag & (O_RDONLY|O_WRONLY|O_RDWR)) == 0) {
     333                oflag |= O_RDWR;
     334        }
     335
     336        assert((((oflag & O_RDONLY) != 0) + ((oflag & O_WRONLY) != 0) + ((oflag & O_RDWR) != 0)) == 1);
     337       
    343338        size_t abs_size;
    344339        char *abs = vfs_absolutize(path, &abs_size);
    345         int fd = -1;
    346        
    347         if (abs == NULL) {
    348                 errno = ENOMEM;
    349                 return -1;
    350         }
    351        
    352         int rc = open_internal(abs, abs_size, L_FILE, oflag, &fd);
    353         free(abs);
    354        
    355         if (rc != EOK) {
    356                 errno = rc;
    357                 return -1;
    358         }
    359        
    360         return fd;
     340        if (!abs) {
     341                return ENOMEM;
     342        }
     343       
     344        int ret = _vfs_walk(-1, abs, walk_flags(oflag) | WALK_REGULAR);
     345        if (ret < 0) {
     346                return ret;
     347        }
     348       
     349        int mode =
     350                ((oflag & O_RDWR) ? MODE_READ|MODE_WRITE : 0) |
     351                ((oflag & O_RDONLY) ? MODE_READ : 0) |
     352                ((oflag & O_WRONLY) ? MODE_WRITE : 0) |
     353                ((oflag & O_APPEND) ? MODE_APPEND : 0);
     354       
     355        int rc = _vfs_open(ret, mode);
     356        if (rc < 0) {
     357                // _vfs_put(ret);
     358                close(ret);
     359                return rc;
     360        }
     361       
     362        if (oflag & O_TRUNC) {
     363                assert(oflag & O_WRONLY || oflag & O_RDWR);
     364                assert(!(oflag & O_APPEND));
     365               
     366                // _vfs_resize
     367                (void) ftruncate(ret, 0);
     368        }
     369
     370        return ret;
    361371}
    362372
     
    670680int stat(const char *path, struct stat *stat)
    671681{
    672         sysarg_t rc;
    673         sysarg_t rc_orig;
    674         aid_t req;
    675        
    676682        size_t pa_size;
    677683        char *pa = vfs_absolutize(path, &pa_size);
    678         if (pa == NULL) {
    679                 errno = ENOMEM;
    680                 return -1;
    681         }
    682        
    683         async_exch_t *exch = vfs_exchange_begin();
    684        
    685         req = async_send_0(exch, VFS_IN_STAT, NULL);
    686         rc = async_data_write_start(exch, pa, pa_size);
    687         if (rc != EOK) {
    688                 vfs_exchange_end(exch);
    689                 free(pa);
    690                 async_wait_for(req, &rc_orig);
    691                 if (rc_orig != EOK)
    692                         rc = rc_orig;
    693                 if (rc != EOK) {
    694                         errno = rc;
    695                         return -1;
    696                 }
    697         }
    698         rc = async_data_read_start(exch, stat, sizeof(struct stat));
    699         if (rc != EOK) {
    700                 vfs_exchange_end(exch);
    701                 free(pa);
    702                 async_wait_for(req, &rc_orig);
    703                 if (rc_orig != EOK)
    704                         rc = rc_orig;
    705                 if (rc != EOK) {
    706                         errno = rc;
    707                         return -1;
    708                 }
    709         }
    710         vfs_exchange_end(exch);
    711         free(pa);
    712         async_wait_for(req, &rc);
    713         if (rc != EOK) {
    714                 errno = rc;
    715                 return -1;
    716         }
    717         return 0;
     684        if (!pa) {
     685                return ENOMEM;
     686        }
     687       
     688        int fd = _vfs_walk(-1, pa, 0);
     689        if (fd < 0) {
     690                return fd;
     691        }
     692       
     693        int rc = fstat(fd, stat);
     694        close(fd);
     695        return rc;
    718696}
    719697
     
    727705{
    728706        DIR *dirp = malloc(sizeof(DIR));
    729         int fd = -1;
    730        
    731         if (dirp == NULL) {
     707        if (!dirp) {
    732708                errno = ENOMEM;
    733709                return NULL;
     
    742718        }
    743719       
    744         int rc = open_internal(abs, abs_size, L_DIRECTORY, 0, &fd);
     720        int ret = _vfs_walk(-1, abs, WALK_DIRECTORY);
    745721        free(abs);
    746722       
    747         if (rc != EOK) {
     723        if (ret < EOK) {
    748724                free(dirp);
     725                errno = ret;
     726                return NULL;
     727        }
     728       
     729        int rc = _vfs_open(ret, MODE_READ);
     730        if (rc < 0) {
     731                free(dirp);
     732                close(ret);
    749733                errno = rc;
    750734                return NULL;
    751735        }
    752736       
    753         dirp->fd = fd;
     737        dirp->fd = ret;
    754738        return dirp;
    755739}
     
    809793int mkdir(const char *path, mode_t mode)
    810794{
     795        size_t pa_size;
     796        char *pa = vfs_absolutize(path, &pa_size);
     797        if (!pa) {
     798                return ENOMEM;
     799        }
     800       
     801        int ret = _vfs_walk(-1, pa, WALK_MUST_CREATE | WALK_DIRECTORY);
     802        if (ret < 0) {
     803                return ret;
     804        }
     805       
     806        close(ret);
     807        return EOK;
     808}
     809
     810static int _vfs_unlink2(int parent, const char *path, int expect, int wflag)
     811{
    811812        sysarg_t rc;
    812813        aid_t req;
    813814       
     815        async_exch_t *exch = vfs_exchange_begin();
     816       
     817        req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL);
     818        rc = async_data_write_start(exch, path, str_size(path));
     819       
     820        vfs_exchange_end(exch);
     821       
     822        sysarg_t rc_orig;
     823        async_wait_for(req, &rc_orig);
     824       
     825        if (rc_orig != EOK) {
     826                return (int) rc_orig;
     827        }
     828        return rc;
     829}
     830
     831/** Unlink file or directory.
     832 *
     833 * @param path Path
     834 * @return EOk on success, error code on error
     835 */
     836int unlink(const char *path)
     837{
    814838        size_t pa_size;
    815839        char *pa = vfs_absolutize(path, &pa_size);
    816         if (pa == NULL) {
    817                 errno = ENOMEM;
    818                 return -1;
    819         }
    820        
    821         async_exch_t *exch = vfs_exchange_begin();
    822        
    823         req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL);
    824         rc = async_data_write_start(exch, pa, pa_size);
    825         if (rc != EOK) {
    826                 vfs_exchange_end(exch);
    827                 free(pa);
    828                
    829                 sysarg_t rc_orig;
    830                 async_wait_for(req, &rc_orig);
    831                
    832                 if (rc_orig != EOK)
    833                         rc = rc_orig;
    834                
    835                 if (rc != EOK) {
    836                         errno = rc;
    837                         return -1;
    838                 }
    839                
    840                 return 0;
    841         }
    842        
    843         vfs_exchange_end(exch);
    844         free(pa);
    845         async_wait_for(req, &rc);
    846        
    847         if (rc != EOK) {
    848                 errno = rc;
    849                 return -1;
    850         }
    851        
    852         return 0;
    853 }
    854 
    855 /** Unlink a file or directory.
    856  *
    857  * @param path Path to file or empty directory
    858  * @param lflag L_xxx flag (L_NONE, L_FILE or L_DIRECTORY)
    859  * @return EOK on success, non-zero error code on error
    860  */
    861 static int _unlink(const char *path, int lflag)
    862 {
    863         sysarg_t rc;
    864         aid_t req;
    865        
     840        if (!pa) {
     841                return ENOMEM;
     842        }
     843       
     844        return _vfs_unlink2(-1, pa, -1, 0);
     845}
     846
     847/** Remove empty directory.
     848 *
     849 * @param path Path
     850 * @return 0 on success. On error returns -1 and sets errno.
     851 */
     852int rmdir(const char *path)
     853{
    866854        size_t pa_size;
    867855        char *pa = vfs_absolutize(path, &pa_size);
    868         if (pa == NULL)
     856        if (!pa) {
    869857                return ENOMEM;
    870        
    871         async_exch_t *exch = vfs_exchange_begin();
    872        
    873         req = async_send_1(exch, VFS_IN_UNLINK, lflag, NULL);
    874         rc = async_data_write_start(exch, pa, pa_size);
    875         if (rc != EOK) {
    876                 vfs_exchange_end(exch);
    877                 free(pa);
    878 
    879                 sysarg_t rc_orig;
    880                 async_wait_for(req, &rc_orig);
    881 
    882                 if (rc_orig == EOK)
    883                         return (int) rc;
    884                 else
    885                         return (int) rc_orig;
    886         }
    887         vfs_exchange_end(exch);
    888         free(pa);
    889         async_wait_for(req, &rc);
    890         return rc;
    891 }
    892 
    893 /** Unlink file or directory.
    894  *
    895  * @param path Path
    896  * @return EOk on success, error code on error
    897  */
    898 int unlink(const char *path)
    899 {
    900         int rc;
    901 
    902         rc = _unlink(path, L_NONE);
    903         if (rc != EOK) {
    904                 errno = rc;
    905                 return -1;
    906         }
    907 
    908         return 0;
    909 }
    910 
    911 /** Remove empty directory.
    912  *
    913  * @param path Path
    914  * @return 0 on success. On error returns -1 and sets errno.
    915  */
    916 int rmdir(const char *path)
    917 {
    918         int rc;
    919 
    920         rc = _unlink(path, L_DIRECTORY);
    921         if (rc != EOK) {
    922                 errno = rc;
    923                 return -1;
    924         }
    925 
    926         return 0;
     858        }
     859       
     860        return _vfs_unlink2(-1, pa, -1, WALK_DIRECTORY);
    927861}
    928862
     
    957891        async_exch_t *exch = vfs_exchange_begin();
    958892       
    959         req = async_send_0(exch, VFS_IN_RENAME, NULL);
     893        req = async_send_1(exch, VFS_IN_RENAME, -1, NULL);
    960894        rc = async_data_write_start(exch, olda, olda_size);
    961895        if (rc != EOK) {
     
    1018952        size_t abs_size;
    1019953        char *abs = vfs_absolutize(path, &abs_size);
    1020         int fd = -1;
    1021        
    1022         if (abs == NULL) {
    1023                 errno = ENOMEM;
    1024                 return -1;
    1025         }
    1026        
    1027         int rc = open_internal(abs, abs_size, L_DIRECTORY, O_DESC, &fd);
    1028        
    1029         if (rc != EOK) {
     954        if (!abs)
     955                return ENOMEM;
     956       
     957        int fd = _vfs_walk(-1, abs, WALK_DIRECTORY);
     958        if (fd < 0) {
    1030959                free(abs);
    1031                 errno = rc;
     960                errno = fd;
    1032961                return -1;
    1033962        }
Note: See TracChangeset for help on using the changeset viewer.