Changeset 1dff985 in mainline for uspace/lib/c/generic/vfs/vfs.c
- Timestamp:
- 2017-03-03T21:32:38Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/vfs/vfs.c
r5b46ec8 r1dff985 93 93 } 94 94 95 int _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 118 int _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 95 127 char *vfs_absolutize(const char *path, size_t *retlen) 96 128 { … … 229 261 } 230 262 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 else244 return (int) rc_orig;245 }246 247 263 vfs_exchange_end(exch); 248 264 free(mpa); … … 289 305 } 290 306 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; 307 static 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; 330 318 } 331 319 … … 341 329 int open(const char *path, int oflag, ...) 342 330 { 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 343 338 size_t abs_size; 344 339 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; 361 371 } 362 372 … … 670 680 int stat(const char *path, struct stat *stat) 671 681 { 672 sysarg_t rc;673 sysarg_t rc_orig;674 aid_t req;675 676 682 size_t pa_size; 677 683 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; 718 696 } 719 697 … … 727 705 { 728 706 DIR *dirp = malloc(sizeof(DIR)); 729 int fd = -1; 730 731 if (dirp == NULL) { 707 if (!dirp) { 732 708 errno = ENOMEM; 733 709 return NULL; … … 742 718 } 743 719 744 int r c = open_internal(abs, abs_size, L_DIRECTORY, 0, &fd);720 int ret = _vfs_walk(-1, abs, WALK_DIRECTORY); 745 721 free(abs); 746 722 747 if (r c !=EOK) {723 if (ret < EOK) { 748 724 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); 749 733 errno = rc; 750 734 return NULL; 751 735 } 752 736 753 dirp->fd = fd;737 dirp->fd = ret; 754 738 return dirp; 755 739 } … … 809 793 int mkdir(const char *path, mode_t mode) 810 794 { 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 810 static int _vfs_unlink2(int parent, const char *path, int expect, int wflag) 811 { 811 812 sysarg_t rc; 812 813 aid_t req; 813 814 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 */ 836 int unlink(const char *path) 837 { 814 838 size_t pa_size; 815 839 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 */ 852 int rmdir(const char *path) 853 { 866 854 size_t pa_size; 867 855 char *pa = vfs_absolutize(path, &pa_size); 868 if ( pa == NULL)856 if (!pa) { 869 857 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); 927 861 } 928 862 … … 957 891 async_exch_t *exch = vfs_exchange_begin(); 958 892 959 req = async_send_ 0(exch, VFS_IN_RENAME, NULL);893 req = async_send_1(exch, VFS_IN_RENAME, -1, NULL); 960 894 rc = async_data_write_start(exch, olda, olda_size); 961 895 if (rc != EOK) { … … 1018 952 size_t abs_size; 1019 953 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) { 1030 959 free(abs); 1031 errno = rc;960 errno = fd; 1032 961 return -1; 1033 962 }
Note:
See TracChangeset
for help on using the changeset viewer.