Changes in uspace/lib/c/generic/vfs/vfs.c [6afc9d7:4636a60] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/vfs/vfs.c
r6afc9d7 r4636a60 43 43 #include <stdio.h> 44 44 #include <sys/stat.h> 45 #include <sys/statfs.h>46 45 #include <sys/types.h> 47 46 #include <ipc/services.h> … … 75 74 76 75 while (vfs_sess == NULL) 77 vfs_sess = service_connect_blocking( SERVICE_VFS, INTERFACE_VFS,78 0 );76 vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS, 77 0, 0); 79 78 80 79 fibril_mutex_unlock(&vfs_mutex); … … 93 92 } 94 93 95 char *vfs_absolutize(const char *path, size_t *retlen) 94 int _vfs_walk(int parent, const char *path, int flags) 95 { 96 async_exch_t *exch = vfs_exchange_begin(); 97 98 ipc_call_t answer; 99 aid_t req = async_send_2(exch, VFS_IN_WALK, parent, flags, &answer); 100 sysarg_t rc = async_data_write_start(exch, path, str_size(path)); 101 vfs_exchange_end(exch); 102 103 sysarg_t rc_orig; 104 async_wait_for(req, &rc_orig); 105 106 if (rc_orig != EOK) { 107 return (int) rc_orig; 108 } 109 110 if (rc != EOK) { 111 return (int) rc; 112 } 113 114 return (int) IPC_GET_ARG1(answer); 115 } 116 117 int _vfs_open(int fildes, int mode) 118 { 119 async_exch_t *exch = vfs_exchange_begin(); 120 sysarg_t rc = async_req_2_0(exch, VFS_IN_OPEN2, fildes, mode); 121 vfs_exchange_end(exch); 122 123 return (int) rc; 124 } 125 126 char *absolutize(const char *path, size_t *retlen) 96 127 { 97 128 char *ncwd_path; … … 101 132 size_t size = str_size(path); 102 133 if (*path != '/') { 103 if ( cwd_path == NULL) {134 if (!cwd_path) { 104 135 fibril_mutex_unlock(&cwd_mutex); 105 136 return NULL; 106 137 } 107 138 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 108 if ( ncwd_path_nc == NULL) {139 if (!ncwd_path_nc) { 109 140 fibril_mutex_unlock(&cwd_mutex); 110 141 return NULL; … … 115 146 } else { 116 147 ncwd_path_nc = malloc(size + 1); 117 if ( ncwd_path_nc == NULL) {148 if (!ncwd_path_nc) { 118 149 fibril_mutex_unlock(&cwd_mutex); 119 150 return NULL; … … 123 154 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); 124 155 ncwd_path = canonify(ncwd_path_nc, retlen); 125 if ( ncwd_path == NULL) {156 if (!ncwd_path) { 126 157 fibril_mutex_unlock(&cwd_mutex); 127 158 free(ncwd_path_nc); … … 135 166 ncwd_path = str_dup(ncwd_path); 136 167 free(ncwd_path_nc); 137 if ( ncwd_path == NULL) {168 if (!ncwd_path) { 138 169 fibril_mutex_unlock(&cwd_mutex); 139 170 return NULL; … … 143 174 } 144 175 145 int vfs_mount(const char *fs_name, const char *mp, const char *fqsn,176 int mount(const char *fs_name, const char *mp, const char *fqsn, 146 177 const char *opts, unsigned int flags, unsigned int instance) 147 178 { … … 171 202 172 203 size_t mpa_size; 173 char *mpa = vfs_absolutize(mp, &mpa_size);174 if ( mpa == NULL) {204 char *mpa = absolutize(mp, &mpa_size); 205 if (!mpa) { 175 206 if (null_id != -1) 176 207 loc_null_destroy(null_id); … … 229 260 } 230 261 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 262 vfs_exchange_end(exch); 248 263 free(mpa); … … 255 270 } 256 271 257 int vfs_unmount(const char *mp)272 int unmount(const char *mp) 258 273 { 259 274 sysarg_t rc; … … 263 278 char *mpa; 264 279 265 mpa = vfs_absolutize(mp, &mpa_size);266 if ( mpa == NULL)280 mpa = absolutize(mp, &mpa_size); 281 if (!mpa) 267 282 return ENOMEM; 268 283 … … 289 304 } 290 305 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; 330 } 331 332 /** Open file. 333 * 334 * @param path File path 335 * @param oflag O_xxx flags 336 * @param mode File mode (only with O_CREAT) 337 * 338 * @return Nonnegative file descriptor on success. On error -1 is returned 339 * and errno is set. 340 */ 306 static int walk_flags(int oflags) 307 { 308 int flags = 0; 309 if (oflags & O_CREAT) { 310 if (oflags & O_EXCL) { 311 flags |= WALK_MUST_CREATE; 312 } else { 313 flags |= WALK_MAY_CREATE; 314 } 315 } 316 return flags; 317 } 318 341 319 int open(const char *path, int oflag, ...) 342 320 { 321 // FIXME: Some applications call this incorrectly. 322 if ((oflag & (O_RDONLY|O_WRONLY|O_RDWR)) == 0) { 323 oflag |= O_RDWR; 324 } 325 326 assert((((oflag & O_RDONLY) != 0) + ((oflag & O_WRONLY) != 0) + ((oflag & O_RDWR) != 0)) == 1); 327 343 328 size_t abs_size; 344 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; 361 } 362 363 /** Close file. 364 * 365 * @param fildes File descriptor 366 * @return Zero on success. On error -1 is returned and errno is set. 367 */ 329 char *abs = absolutize(path, &abs_size); 330 if (!abs) { 331 return ENOMEM; 332 } 333 334 int ret = _vfs_walk(-1, abs, walk_flags(oflag) | WALK_REGULAR); 335 if (ret < 0) { 336 return ret; 337 } 338 339 int mode = 340 ((oflag & O_RDWR) ? MODE_READ|MODE_WRITE : 0) | 341 ((oflag & O_RDONLY) ? MODE_READ : 0) | 342 ((oflag & O_WRONLY) ? MODE_WRITE : 0) | 343 ((oflag & O_APPEND) ? MODE_APPEND : 0); 344 345 int rc = _vfs_open(ret, mode); 346 if (rc < 0) { 347 // _vfs_put(ret); 348 close(ret); 349 return rc; 350 } 351 352 if (oflag & O_TRUNC) { 353 assert(oflag & O_WRONLY || oflag & O_RDWR); 354 assert(!(oflag & O_APPEND)); 355 356 // _vfs_resize 357 (void) ftruncate(ret, 0); 358 } 359 360 return ret; 361 } 362 368 363 int close(int fildes) 369 364 { … … 374 369 vfs_exchange_end(exch); 375 370 376 if (rc != EOK) { 377 errno = rc; 378 return -1; 379 } 380 381 return 0; 382 } 383 384 /** Read bytes from file. 385 * 386 * Read up to @a nbyte bytes from file. The actual number of bytes read 387 * may be lower, but greater than zero if there are any bytes available. 388 * If there are no bytes available for reading, then the function will 389 * return success with zero bytes read. 390 * 391 * @param fildes File descriptor 392 * @param buf Buffer 393 * @param nbyte Maximum number of bytes to read 394 * @param nread Place to store actual number of bytes read (0 or more) 395 * 396 * @return EOK on success, non-zero error code on error. 397 */ 398 static int _read_short(int fildes, void *buf, size_t nbyte, ssize_t *nread) 371 return (int) rc; 372 } 373 374 // TODO: Versioning for read. 375 376 ssize_t read(int fildes, void *buf, size_t nbyte) 399 377 { 400 378 sysarg_t rc; … … 402 380 aid_t req; 403 381 404 if (nbyte > DATA_XFER_LIMIT)405 nbyte = DATA_XFER_LIMIT;406 407 382 async_exch_t *exch = vfs_exchange_begin(); 408 383 409 384 req = async_send_1(exch, VFS_IN_READ, fildes, &answer); 410 rc = async_data_read_start(exch, (void *) 385 rc = async_data_read_start(exch, (void *)buf, nbyte); 411 386 if (rc != EOK) { 412 387 vfs_exchange_end(exch); 413 388 414 389 sysarg_t rc_orig; 415 390 async_wait_for(req, &rc_orig); 416 391 417 392 if (rc_orig == EOK) 418 return rc;393 return (ssize_t) rc; 419 394 else 420 return rc_orig; 421 } 422 395 return (ssize_t) rc_orig; 396 } 423 397 vfs_exchange_end(exch); 424 398 async_wait_for(req, &rc); 425 426 if (rc != EOK) 399 if (rc == EOK) 400 return (ssize_t) IPC_GET_ARG1(answer); 401 else 427 402 return rc; 428 429 *nread = (ssize_t) IPC_GET_ARG1(answer); 430 return EOK; 431 } 432 433 /** Write bytes to file. 434 * 435 * Write up to @a nbyte bytes from file. The actual number of bytes written 436 * may be lower, but greater than zero. 437 * 438 * @param fildes File descriptor 439 * @param buf Buffer 440 * @param nbyte Maximum number of bytes to write 441 * @param nread Place to store actual number of bytes written (0 or more) 442 * 443 * @return EOK on success, non-zero error code on error. 444 */ 445 static int _write_short(int fildes, const void *buf, size_t nbyte, 446 ssize_t *nwritten) 403 } 404 405 ssize_t write(int fildes, const void *buf, size_t nbyte) 447 406 { 448 407 sysarg_t rc; … … 450 409 aid_t req; 451 410 452 if (nbyte > DATA_XFER_LIMIT)453 nbyte = DATA_XFER_LIMIT;454 455 411 async_exch_t *exch = vfs_exchange_begin(); 456 412 457 413 req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer); 458 rc = async_data_write_start(exch, (void *) 414 rc = async_data_write_start(exch, (void *)buf, nbyte); 459 415 if (rc != EOK) { 460 416 vfs_exchange_end(exch); 461 417 462 418 sysarg_t rc_orig; 463 419 async_wait_for(req, &rc_orig); 464 420 465 421 if (rc_orig == EOK) 466 return rc;422 return (ssize_t) rc; 467 423 else 468 return rc_orig; 469 } 470 424 return (ssize_t) rc_orig; 425 } 471 426 vfs_exchange_end(exch); 472 427 async_wait_for(req, &rc); 473 474 if (rc != EOK) 475 return rc; 476 477 *nwritten = (ssize_t) IPC_GET_ARG1(answer); 478 return EOK; 479 } 480 481 /** Read data. 482 * 483 * Read up to @a nbytes bytes from file if available. This function always reads 484 * all the available bytes up to @a nbytes. 428 if (rc == EOK) 429 return (ssize_t) IPC_GET_ARG1(answer); 430 else 431 return -1; 432 } 433 434 /** Read entire buffer. 435 * 436 * In face of short reads this function continues reading until either 437 * the entire buffer is read or no more data is available (at end of file). 485 438 * 486 439 * @param fildes File descriptor … … 488 441 * @param nbytes Number of bytes to read 489 442 * 490 * @return On success, nonnegative number of bytes read.491 * On failure, -1 and sets errno.443 * @return On success, positive number of bytes read. 444 * On failure, negative error code from read(). 492 445 */ 493 ssize_t read (int fildes, void *buf, size_t nbyte)446 ssize_t read_all(int fildes, void *buf, size_t nbyte) 494 447 { 495 448 ssize_t cnt = 0; 496 449 size_t nread = 0; 497 450 uint8_t *bp = (uint8_t *) buf; 498 int rc; 499 451 500 452 do { 501 453 bp += cnt; 502 454 nread += cnt; 503 rc = _read_short(fildes, bp, nbyte - nread, &cnt); 504 } while (rc == EOK && cnt > 0 && (nbyte - nread - cnt) > 0); 505 506 if (rc != EOK) { 507 errno = rc; 508 return -1; 509 } 510 455 cnt = read(fildes, bp, nbyte - nread); 456 } while (cnt > 0 && (nbyte - nread - cnt) > 0); 457 458 if (cnt < 0) 459 return cnt; 460 511 461 return nread + cnt; 512 462 } 513 463 514 /** Write data.464 /** Write entire buffer. 515 465 * 516 466 * This function fails if it cannot write exactly @a len bytes to the file. … … 520 470 * @param nbytes Number of bytes to write 521 471 * 522 * @return On success, nonnegative number of bytes written.523 * On failure, -1 and sets errno.472 * @return EOK on error, return value from write() if writing 473 * failed. 524 474 */ 525 ssize_t write (int fildes, const void *buf, size_t nbyte)475 ssize_t write_all(int fildes, const void *buf, size_t nbyte) 526 476 { 527 477 ssize_t cnt = 0; 528 478 ssize_t nwritten = 0; 529 479 const uint8_t *bp = (uint8_t *) buf; 530 int rc;531 480 532 481 do { 533 482 bp += cnt; 534 483 nwritten += cnt; 535 rc = _write_short(fildes, bp, nbyte - nwritten, &cnt); 536 } while (rc == EOK && ((ssize_t )nbyte - nwritten - cnt) > 0); 537 538 if (rc != EOK) { 539 errno = rc; 540 return -1; 541 } 484 cnt = write(fildes, bp, nbyte - nwritten); 485 } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0); 486 487 if (cnt < 0) 488 return cnt; 489 490 if ((ssize_t)nbyte - nwritten - cnt > 0) 491 return EIO; 542 492 543 493 return nbyte; 544 494 } 545 495 546 /** Synchronize file.547 *548 * @param fildes File descriptor549 * @return 0 on success. On error returns -1 and sets errno.550 */551 496 int fsync(int fildes) 552 497 { … … 555 500 vfs_exchange_end(exch); 556 501 557 if (rc != EOK) { 558 errno = rc; 559 return -1; 560 } 561 562 return 0; 563 } 564 565 /** Seek to a position. 566 * 567 * @param fildes File descriptor 568 * @param offset Offset 569 * @param whence SEEK_SET, SEEK_CUR or SEEK_END 570 * 571 * @return On success the nonnegative offset from start of file. On error 572 * returns (off64_t)-1 and sets errno. 573 */ 502 return (int) rc; 503 } 504 574 505 off64_t lseek(int fildes, off64_t offset, int whence) 575 506 { … … 584 515 vfs_exchange_end(exch); 585 516 586 if (rc != EOK) { 587 errno = rc; 517 if (rc != EOK) 588 518 return (off64_t) -1; 589 }590 519 591 520 return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi); 592 521 } 593 522 594 /** Truncate file to a specified length.595 *596 * Truncate file so that its size is exactly @a length597 *598 * @param fildes File descriptor599 * @param length Length600 *601 * @return 0 on success, -1 on error and sets errno.602 */603 523 int ftruncate(int fildes, aoff64_t length) 604 524 { … … 610 530 vfs_exchange_end(exch); 611 531 612 if (rc != EOK) { 613 errno = rc; 614 return -1; 615 } 616 617 return 0; 618 } 619 620 /** Get file status. 621 * 622 * @param fildes File descriptor 623 * @param stat Place to store file information 624 * 625 * @return 0 on success, -1 on error and sets errno. 626 */ 532 return (int) rc; 533 } 534 627 535 int fstat(int fildes, struct stat *stat) 628 536 { … … 636 544 if (rc != EOK) { 637 545 vfs_exchange_end(exch); 638 546 639 547 sysarg_t rc_orig; 640 548 async_wait_for(req, &rc_orig); 641 642 if (rc_orig != EOK) 643 rc = rc_orig; 644 if (rc != EOK) { 645 errno = rc; 646 return -1; 647 } 648 649 return 0; 650 } 651 549 550 if (rc_orig == EOK) 551 return (ssize_t) rc; 552 else 553 return (ssize_t) rc_orig; 554 } 652 555 vfs_exchange_end(exch); 653 556 async_wait_for(req, &rc); 654 655 if (rc != EOK) { 557 558 return rc; 559 } 560 561 int stat(const char *path, struct stat *stat) 562 { 563 size_t pa_size; 564 char *pa = absolutize(path, &pa_size); 565 if (!pa) { 566 return ENOMEM; 567 } 568 569 int fd = _vfs_walk(-1, pa, 0); 570 if (fd < 0) { 571 return fd; 572 } 573 574 int rc = fstat(fd, stat); 575 close(fd); 576 return rc; 577 } 578 579 DIR *opendir(const char *dirname) 580 { 581 DIR *dirp = malloc(sizeof(DIR)); 582 if (!dirp) { 583 errno = ENOMEM; 584 return NULL; 585 } 586 587 size_t abs_size; 588 char *abs = absolutize(dirname, &abs_size); 589 if (!abs) { 590 free(dirp); 591 errno = ENOMEM; 592 return NULL; 593 } 594 595 int ret = _vfs_walk(-1, abs, WALK_DIRECTORY); 596 free(abs); 597 598 if (ret < 0) { 599 free(dirp); 600 errno = ret; 601 return NULL; 602 } 603 604 int rc = _vfs_open(ret, MODE_READ); 605 if (rc < 0) { 606 free(dirp); 607 close(ret); 656 608 errno = rc; 657 return -1; 658 } 659 609 return NULL; 610 } 611 612 dirp->fd = ret; 613 return dirp; 614 } 615 616 struct dirent *readdir(DIR *dirp) 617 { 618 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1); 619 if (len <= 0) 620 return NULL; 621 return &dirp->res; 622 } 623 624 void rewinddir(DIR *dirp) 625 { 626 (void) lseek(dirp->fd, 0, SEEK_SET); 627 } 628 629 int closedir(DIR *dirp) 630 { 631 (void) close(dirp->fd); 632 free(dirp); 660 633 return 0; 661 634 } 662 635 663 /** Get file status. 664 * 665 * @param path Path to file 666 * @param stat Place to store file information 667 * 668 * @return 0 on success, -1 on error and sets errno. 669 */ 670 int stat(const char *path, struct stat *stat) 636 int mkdir(const char *path, mode_t mode) 637 { 638 size_t pa_size; 639 char *pa = absolutize(path, &pa_size); 640 if (!pa) { 641 return ENOMEM; 642 } 643 644 int ret = _vfs_walk(-1, pa, WALK_MUST_CREATE | WALK_DIRECTORY); 645 if (ret < 0) { 646 return ret; 647 } 648 649 close(ret); 650 return EOK; 651 } 652 653 static int _vfs_unlink2(int parent, const char *path, int expect, int wflag) 654 { 655 sysarg_t rc; 656 aid_t req; 657 658 async_exch_t *exch = vfs_exchange_begin(); 659 660 req = async_send_3(exch, VFS_IN_UNLINK2, parent, expect, wflag, NULL); 661 rc = async_data_write_start(exch, path, str_size(path)); 662 663 vfs_exchange_end(exch); 664 665 sysarg_t rc_orig; 666 async_wait_for(req, &rc_orig); 667 668 if (rc_orig != EOK) { 669 return (int) rc_orig; 670 } 671 return rc; 672 } 673 674 int unlink(const char *path) 675 { 676 size_t pa_size; 677 char *pa = absolutize(path, &pa_size); 678 if (!pa) { 679 return ENOMEM; 680 } 681 682 return _vfs_unlink2(-1, pa, -1, 0); 683 } 684 685 int rmdir(const char *path) 686 { 687 size_t pa_size; 688 char *pa = absolutize(path, &pa_size); 689 if (!pa) { 690 return ENOMEM; 691 } 692 693 return _vfs_unlink2(-1, pa, -1, WALK_DIRECTORY); 694 } 695 696 int rename(const char *old, const char *new) 671 697 { 672 698 sysarg_t rc; … … 674 700 aid_t req; 675 701 676 size_t pa_size; 677 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; 718 } 719 720 /** Open directory. 721 * 722 * @param dirname Directory pathname 723 * 724 * @return Non-NULL pointer on success. On error returns @c NULL and sets errno. 725 */ 726 DIR *opendir(const char *dirname) 727 { 728 DIR *dirp = malloc(sizeof(DIR)); 729 int fd = -1; 730 731 if (dirp == NULL) { 732 errno = ENOMEM; 733 return NULL; 734 } 735 736 size_t abs_size; 737 char *abs = vfs_absolutize(dirname, &abs_size); 738 if (abs == NULL) { 739 free(dirp); 740 errno = ENOMEM; 741 return NULL; 742 } 743 744 int rc = open_internal(abs, abs_size, L_DIRECTORY, 0, &fd); 745 free(abs); 746 747 if (rc != EOK) { 748 free(dirp); 749 errno = rc; 750 return NULL; 751 } 752 753 dirp->fd = fd; 754 return dirp; 755 } 756 757 /** Read directory entry. 758 * 759 * @param dirp Open directory 760 * @return Non-NULL pointer to directory entry on success. On error returns 761 * @c NULL and sets errno. 762 */ 763 struct dirent *readdir(DIR *dirp) 764 { 765 int rc; 766 ssize_t len; 767 768 rc = _read_short(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1, &len); 769 if (rc != EOK) { 770 errno = rc; 771 return NULL; 772 } 773 774 (void) len; 775 return &dirp->res; 776 } 777 778 /** Rewind directory position to the beginning. 779 * 780 * @param dirp Open directory 781 */ 782 void rewinddir(DIR *dirp) 783 { 784 (void) lseek(dirp->fd, 0, SEEK_SET); 785 } 786 787 /** Close directory. 788 * 789 * @param dirp Open directory 790 * @return 0 on success. On error returns -1 and sets errno. 791 */ 792 int closedir(DIR *dirp) 793 { 794 int rc; 795 796 rc = close(dirp->fd); 797 free(dirp); 798 799 /* On error errno was set by close() */ 800 return rc; 801 } 802 803 /** Create directory. 804 * 805 * @param path Path 806 * @param mode File mode 807 * @return 0 on success. On error returns -1 and sets errno. 808 */ 809 int mkdir(const char *path, mode_t mode) 810 { 811 sysarg_t rc; 812 aid_t req; 813 814 size_t pa_size; 815 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 866 size_t pa_size; 867 char *pa = vfs_absolutize(path, &pa_size); 868 if (pa == NULL) 702 size_t olda_size; 703 char *olda = absolutize(old, &olda_size); 704 if (!olda) 869 705 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 else885 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 Path896 * @return EOk on success, error code on error897 */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 Path914 * @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;927 }928 929 /** Rename directory entry.930 *931 * @param old Old name932 * @param new New name933 *934 * @return 0 on success. On error returns -1 and sets errno.935 */936 int rename(const char *old, const char *new)937 {938 sysarg_t rc;939 sysarg_t rc_orig;940 aid_t req;941 942 size_t olda_size;943 char *olda = vfs_absolutize(old, &olda_size);944 if (olda == NULL) {945 errno = ENOMEM;946 return -1;947 }948 706 949 707 size_t newa_size; 950 char *newa = vfs_absolutize(new, &newa_size);951 if ( newa == NULL) {708 char *newa = absolutize(new, &newa_size); 709 if (!newa) { 952 710 free(olda); 953 errno = ENOMEM; 954 return -1; 955 } 956 957 async_exch_t *exch = vfs_exchange_begin(); 958 959 req = async_send_0(exch, VFS_IN_RENAME, NULL); 711 return ENOMEM; 712 } 713 714 async_exch_t *exch = vfs_exchange_begin(); 715 716 req = async_send_1(exch, VFS_IN_RENAME, -1, NULL); 960 717 rc = async_data_write_start(exch, olda, olda_size); 961 718 if (rc != EOK) { … … 964 721 free(newa); 965 722 async_wait_for(req, &rc_orig); 966 if (rc_orig != EOK) 967 rc = rc_orig; 968 if (rc != EOK) { 969 errno = rc; 970 return -1; 971 } 972 return 0; 723 if (rc_orig == EOK) 724 return (int) rc; 725 else 726 return (int) rc_orig; 973 727 } 974 728 rc = async_data_write_start(exch, newa, newa_size); … … 978 732 free(newa); 979 733 async_wait_for(req, &rc_orig); 980 if (rc_orig != EOK) 981 rc = rc_orig; 982 if (rc != EOK) { 983 errno = rc; 984 return -1; 985 } 986 return 0; 734 if (rc_orig == EOK) 735 return (int) rc; 736 else 737 return (int) rc_orig; 987 738 } 988 739 vfs_exchange_end(exch); … … 990 741 free(newa); 991 742 async_wait_for(req, &rc); 992 993 if (rc != EOK) { 994 errno = rc; 995 return -1; 996 } 997 998 return 0; 999 } 1000 1001 /** Remove directory entry. 1002 * 1003 * @param path Path 1004 * @return 0 on success. On error returns -1 and sets errno. 1005 */ 1006 int remove(const char *path) 1007 { 1008 return unlink(path); 1009 } 1010 1011 /** Change working directory. 1012 * 1013 * @param path Path 1014 * @return 0 on success. On error returns -1 and sets errno. 1015 */ 743 return rc; 744 } 745 1016 746 int chdir(const char *path) 1017 747 { 1018 748 size_t abs_size; 1019 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) { 749 char *abs = absolutize(path, &abs_size); 750 if (!abs) 751 return ENOMEM; 752 753 int fd = _vfs_walk(-1, abs, WALK_DIRECTORY); 754 if (fd < 0) { 1030 755 free(abs); 1031 errno = rc; 1032 return -1; 756 return ENOENT; 1033 757 } 1034 758 … … 1037 761 if (cwd_fd >= 0) 1038 762 close(cwd_fd); 763 1039 764 1040 765 if (cwd_path) … … 1046 771 1047 772 fibril_mutex_unlock(&cwd_mutex); 1048 return 0; 1049 } 1050 1051 /** Get current working directory path. 1052 * 1053 * @param buf Buffer 1054 * @param size Size of @a buf 1055 * @return On success returns @a buf. On failure returns @c NULL and sets errno. 1056 */ 773 return EOK; 774 } 775 1057 776 char *getcwd(char *buf, size_t size) 1058 777 { 1059 if (size == 0) { 1060 errno = EINVAL; 1061 return NULL; 1062 } 778 if (size == 0) 779 return NULL; 1063 780 1064 781 fibril_mutex_lock(&cwd_mutex); … … 1066 783 if ((cwd_size == 0) || (size < cwd_size + 1)) { 1067 784 fibril_mutex_unlock(&cwd_mutex); 1068 errno = ERANGE;1069 785 return NULL; 1070 786 } … … 1076 792 } 1077 793 1078 /** Open session to service represented by a special file. 1079 * 1080 * Given that the file referred to by @a fildes represents a service, 1081 * open a session to that service. 1082 * 1083 * @param fildes File descriptor 1084 * @param iface Interface to connect to (XXX Should be automatic) 1085 * @return On success returns session pointer. On error returns @c NULL. 1086 */ 1087 async_sess_t *vfs_fd_session(int fildes, iface_t iface) 794 async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes) 1088 795 { 1089 796 struct stat stat; 1090 797 int rc = fstat(fildes, &stat); 1091 if (rc != 0) 1092 return NULL; 1093 1094 if (stat.service == 0) 1095 return NULL; 1096 1097 return loc_service_connect(stat.service, iface, 0); 1098 } 1099 1100 /** Duplicate open file. 1101 * 1102 * Duplicate open file under a new file descriptor. 1103 * 1104 * @param oldfd Old file descriptor 1105 * @param newfd New file descriptor 1106 * @return 0 on success. On error -1 is returned and errno is set 1107 */ 798 if (rc != 0) { 799 errno = rc; 800 return NULL; 801 } 802 803 if (!stat.service) { 804 errno = ENOENT; 805 return NULL; 806 } 807 808 return loc_service_connect(mgmt, stat.service, 0); 809 } 810 1108 811 int dup2(int oldfd, int newfd) 1109 812 { … … 1116 819 1117 820 if (rc == EOK) 1118 rc = ret; 1119 1120 if (rc != EOK) { 1121 errno = rc; 1122 return -1; 1123 } 1124 1125 return 0; 1126 } 1127 1128 int vfs_fd_wait(void) 821 return (int) ret; 822 823 return (int) rc; 824 } 825 826 int fd_wait(void) 1129 827 { 1130 828 async_exch_t *exch = vfs_exchange_begin(); … … 1141 839 } 1142 840 1143 int vfs_get_mtab_list(list_t *mtab_list)841 int get_mtab_list(list_t *mtab_list) 1144 842 { 1145 843 sysarg_t rc; … … 1161 859 1162 860 mtab_ent = malloc(sizeof(mtab_ent_t)); 1163 if ( mtab_ent == NULL) {861 if (!mtab_ent) { 1164 862 rc = ENOMEM; 1165 863 goto exit; … … 1202 900 } 1203 901 1204 /** Get filesystem statistics.1205 *1206 * @param path Mount point path1207 * @param st Buffer for storing information1208 * @return 0 on success. On error -1 is returned and errno is set.1209 */1210 int statfs(const char *path, struct statfs *st)1211 {1212 sysarg_t rc, rc_orig;1213 aid_t req;1214 size_t pa_size;1215 1216 char *pa = vfs_absolutize(path, &pa_size);1217 if (pa == NULL) {1218 errno = ENOMEM;1219 return -1;1220 }1221 1222 async_exch_t *exch = vfs_exchange_begin();1223 1224 req = async_send_0(exch, VFS_IN_STATFS, NULL);1225 rc = async_data_write_start(exch, pa, pa_size);1226 if (rc != EOK)1227 goto exit;1228 1229 rc = async_data_read_start(exch, (void *) st, sizeof(*st));1230 1231 exit:1232 vfs_exchange_end(exch);1233 free(pa);1234 async_wait_for(req, &rc_orig);1235 rc = (rc_orig != EOK ? rc_orig : rc);1236 1237 if (rc != EOK) {1238 errno = rc;1239 return -1;1240 }1241 1242 return 0;1243 }1244 1245 902 /** @} 1246 903 */
Note:
See TracChangeset
for help on using the changeset viewer.