Changeset 2b88074b in mainline
- Timestamp:
- 2009-10-29T22:06:46Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2e983c7
- Parents:
- 14ecd6c
- Location:
- uspace
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/getvc/getvc.c
r14ecd6c r2b88074b 36 36 37 37 #include <sys/types.h> 38 #include <fcntl.h> 38 39 #include <unistd.h> 39 40 #include <stdio.h> … … 46 47 } 47 48 48 static void closeall(void)49 static void reopen(FILE **stream, int fd, const char *path, int flags, const char *mode) 49 50 { 50 fclose(stdin); 51 fclose(stdout); 52 fclose(stderr); 51 if (fclose(*stream)) 52 return; 53 53 54 close(0); 55 close(1); 56 close(2); 54 *stream = NULL; 55 56 int oldfd = open(path, flags); 57 if (oldfd < 0) 58 return; 59 60 if (oldfd != fd) { 61 if (dup2(oldfd, fd) != fd) 62 return; 63 64 if (close(oldfd)) 65 return; 66 } 67 68 *stream = fdopen(fd, mode); 57 69 } 58 70 … … 74 86 int main(int argc, char *argv[]) 75 87 { 76 task_exit_t texit;77 int retval;78 79 88 if (argc < 3) { 80 89 usage(); … … 82 91 } 83 92 84 closeall(); 93 reopen(&stdin, 0, argv[1], O_RDONLY, "r"); 94 reopen(&stdout, 1, argv[1], O_WRONLY, "w"); 95 reopen(&stderr, 2, argv[1], O_WRONLY, "w"); 85 96 86 stdin = fopen(argv[1], "r");87 stdout = fopen(argv[1], "w");88 stderr = fopen(argv[1], "w");89 90 97 /* 91 * FIXME: f open() should actually detect that we are opening a console98 * FIXME: fdopen() should actually detect that we are opening a console 92 99 * and it should set line-buffering mode automatically. 93 100 */ 94 101 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); 95 102 96 if ((stdin == NULL) 97 || (stdout == NULL) 98 || (stderr == NULL)) 103 if (stdin == NULL) 99 104 return -2; 105 106 if (stdout == NULL) 107 return -3; 108 109 if (stderr == NULL) 110 return -4; 100 111 101 112 version_print(argv[1]); 102 113 task_id_t id = spawn(argv[2]); 114 115 task_exit_t texit; 116 int retval; 103 117 task_wait(id, &texit, &retval); 104 118 -
uspace/lib/libc/generic/vfs/vfs.c
r14ecd6c r2b88074b 57 57 static futex_t cwd_futex = FUTEX_INITIALIZER; 58 58 59 DIR *cwd_dir = NULL;60 char *cwd_path = NULL;61 s ize_t cwd_size = 0;59 static int cwd_fd = -1; 60 static char *cwd_path = NULL; 61 static size_t cwd_size = 0; 62 62 63 63 char *absolutize(const char *path, size_t *retlen) … … 197 197 } 198 198 199 static int _open(const char *path, int lflag, int oflag, ...) 200 { 201 ipcarg_t rc; 199 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 200 { 201 futex_down(&vfs_phone_futex); 202 async_serialize_start(); 203 vfs_connect(); 204 202 205 ipc_call_t answer; 203 aid_t req; 204 205 size_t pa_size; 206 char *pa = absolutize(path, &pa_size); 207 if (!pa) 208 return ENOMEM; 209 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 = async_data_write_start(vfs_phone, pa, pa_size); 206 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 207 ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size); 208 216 209 if (rc != EOK) { 217 210 ipcarg_t rc_orig; 218 219 async_wait_for(req, &rc_orig);220 async_serialize_end(); 221 futex_up(&vfs_phone_futex); 222 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);231 f ree(pa);211 async_wait_for(req, &rc_orig); 212 213 async_serialize_end(); 214 futex_up(&vfs_phone_futex); 215 216 if (rc_orig == EOK) 217 return (int) rc; 218 else 219 return (int) rc_orig; 220 } 221 222 async_wait_for(req, &rc); 223 async_serialize_end(); 224 futex_up(&vfs_phone_futex); 232 225 233 226 if (rc != EOK) … … 239 232 int open(const char *path, int oflag, ...) 240 233 { 241 return _open(path, L_FILE, oflag); 234 size_t abs_size; 235 char *abs = absolutize(path, &abs_size); 236 if (!abs) 237 return ENOMEM; 238 239 int ret = open_internal(abs, abs_size, L_FILE, oflag); 240 free(abs); 241 242 return ret; 242 243 } 243 244 … … 471 472 if (!dirp) 472 473 return NULL; 473 dirp->fd = _open(dirname, L_DIRECTORY, 0); 474 if (dirp->fd < 0) { 474 475 size_t abs_size; 476 char *abs = absolutize(dirname, &abs_size); 477 if (!abs) { 478 free(dirp); 479 return ENOMEM; 480 } 481 482 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0); 483 free(abs); 484 485 if (ret < 0) { 475 486 free(dirp); 476 487 return NULL; 477 488 } 489 490 dirp->fd = ret; 478 491 return dirp; 479 492 } … … 636 649 int chdir(const char *path) 637 650 { 638 size_t pa_size; 639 char *pa = absolutize(path, &pa_size); 640 if (!pa) 641 return ENOMEM; 642 643 DIR *d = opendir(pa); 644 if (!d) { 645 free(pa); 651 size_t abs_size; 652 char *abs = absolutize(path, &abs_size); 653 if (!abs) 654 return ENOMEM; 655 656 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC); 657 658 if (fd < 0) { 659 free(abs); 646 660 return ENOENT; 647 661 } 648 662 649 663 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; 664 665 if (cwd_fd >= 0) 666 close(cwd_fd); 667 668 669 if (cwd_path) 670 free(cwd_path); 671 672 cwd_fd = fd; 673 cwd_path = abs; 674 cwd_size = abs_size; 675 660 676 futex_up(&cwd_futex); 661 677 return EOK; … … 664 680 char *getcwd(char *buf, size_t size) 665 681 { 666 if ( !cwd_size)682 if (size == 0) 667 683 return NULL; 668 if (!size) 669 return NULL; 684 670 685 futex_down(&cwd_futex); 671 if (size < cwd_size + 1) { 686 687 if ((cwd_size == 0) || (size < cwd_size + 1)) { 672 688 futex_up(&cwd_futex); 673 689 return NULL; 674 690 } 691 675 692 str_cpy(buf, size, cwd_path); 676 693 futex_up(&cwd_futex); 694 677 695 return buf; 678 696 } … … 707 725 } 708 726 727 int dup2(int oldfd, int newfd) 728 { 729 futex_down(&vfs_phone_futex); 730 async_serialize_start(); 731 vfs_connect(); 732 733 ipcarg_t ret; 734 ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret); 735 736 async_serialize_end(); 737 futex_up(&vfs_phone_futex); 738 739 if (rc == EOK) 740 return (int) ret; 741 742 return (int) rc; 743 } 744 709 745 /** @} 710 746 */ -
uspace/lib/libc/include/fcntl.h
r14ecd6c r2b88074b 43 43 #define O_RDWR 32 44 44 #define O_WRONLY 64 45 #define O_DESC 128 45 46 46 47 extern int open(const char *, int, ...); -
uspace/lib/libc/include/ipc/vfs.h
r14ecd6c r2b88074b 73 73 VFS_IN_UNLINK, 74 74 VFS_IN_RENAME, 75 VFS_IN_STAT 75 VFS_IN_STAT, 76 VFS_IN_DUP 76 77 } vfs_in_request_t; 77 78 -
uspace/lib/libc/include/unistd.h
r14ecd6c r2b88074b 51 51 #endif 52 52 53 extern int dup2(int oldfd, int newfd); 54 53 55 extern ssize_t write(int, const void *, size_t); 54 56 extern ssize_t read(int, void *, size_t); -
uspace/srv/vfs/vfs.c
r14ecd6c r2b88074b 126 126 vfs_sync(callid, &call); 127 127 break; 128 case VFS_IN_DUP: 129 vfs_dup(callid, &call); 128 130 default: 129 131 ipc_answer_0(callid, ENOTSUP); -
uspace/srv/vfs/vfs.h
r14ecd6c r2b88074b 186 186 extern bool vfs_files_init(void); 187 187 extern vfs_file_t *vfs_file_get(int); 188 extern int vfs_fd_alloc(void); 188 extern int vfs_fd_assign(vfs_file_t *file, int fd); 189 extern int vfs_fd_alloc(bool desc); 189 190 extern int vfs_fd_free(int); 190 191 … … 200 201 extern void vfs_open_node(ipc_callid_t, ipc_call_t *); 201 202 extern void vfs_sync(ipc_callid_t, ipc_call_t *); 203 extern void vfs_dup(ipc_callid_t, ipc_call_t *); 202 204 extern void vfs_close(ipc_callid_t, ipc_call_t *); 203 205 extern void vfs_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/vfs/vfs_file.c
r14ecd6c r2b88074b 76 76 /** Allocate a file descriptor. 77 77 * 78 * @return First available file descriptor or a negative error 79 * code. 80 */ 81 int vfs_fd_alloc(void) 78 * @param desc If true, look for an available file descriptor 79 * in a descending order. 80 * 81 * @return First available file descriptor or a negative error 82 * code. 83 */ 84 int vfs_fd_alloc(bool desc) 82 85 { 83 86 if (!vfs_files_init()) … … 85 88 86 89 unsigned int i; 87 for (i = 0; i < MAX_OPEN_FILES; i++) { 90 if (desc) 91 i = MAX_OPEN_FILES; 92 else 93 i = 0; 94 95 while (true) { 88 96 if (!files[i]) { 89 97 files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t)); … … 96 104 return (int) i; 97 105 } 106 107 if (desc) { 108 if (i == 0) 109 break; 110 111 i--; 112 } else { 113 if (i == MAX_OPEN_FILES) 114 break; 115 116 i++; 117 } 98 118 } 99 119 … … 118 138 vfs_file_delref(files[fd]); 119 139 files[fd] = NULL; 140 141 return EOK; 142 } 143 144 /** Assign a file to a file descriptor. 145 * 146 * @param file File to assign. 147 * @param fd File descriptor to assign to. 148 * 149 * @return EOK on success or EINVAL if fd is an invalid or already 150 * used file descriptor. 151 * 152 */ 153 int vfs_fd_assign(vfs_file_t *file, int fd) 154 { 155 if (!vfs_files_init()) 156 return ENOMEM; 157 158 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] != NULL)) 159 return EINVAL; 160 161 files[fd] = file; 162 vfs_file_addref(files[fd]); 120 163 121 164 return EOK; -
uspace/srv/vfs/vfs_ops.c
r14ecd6c r2b88074b 543 543 * structure. 544 544 */ 545 int fd = vfs_fd_alloc( );545 int fd = vfs_fd_alloc((oflag & O_DESC) != 0); 546 546 if (fd < 0) { 547 547 vfs_node_put(node); … … 620 620 * structure. 621 621 */ 622 int fd = vfs_fd_alloc( );622 int fd = vfs_fd_alloc((oflag & O_DESC) != 0); 623 623 if (fd < 0) { 624 624 vfs_node_put(node); … … 679 679 } 680 680 681 static int vfs_close_internal(vfs_file_t *file) 682 { 683 /* 684 * Lock the open file structure so that no other thread can manipulate 685 * the same open file at a time. 686 */ 687 fibril_mutex_lock(&file->lock); 688 689 if (file->refcnt <= 1) { 690 /* Only close the file on the destination FS server 691 if there are no more file descriptors (except the 692 present one) pointing to this file. */ 693 694 int fs_phone = vfs_grab_phone(file->node->fs_handle); 695 696 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 697 aid_t msg; 698 ipc_call_t answer; 699 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle, 700 file->node->index, &answer); 701 702 /* Wait for reply from the FS server. */ 703 ipcarg_t rc; 704 async_wait_for(msg, &rc); 705 706 vfs_release_phone(fs_phone); 707 fibril_mutex_unlock(&file->lock); 708 709 return IPC_GET_ARG1(answer); 710 } 711 712 fibril_mutex_unlock(&file->lock); 713 return EOK; 714 } 715 681 716 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 682 717 { … … 690 725 } 691 726 692 /* 693 * Lock the open file structure so that no other thread can manipulate 694 * the same open file at a time. 695 */ 696 fibril_mutex_lock(&file->lock); 697 int fs_phone = vfs_grab_phone(file->node->fs_handle); 698 699 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 700 aid_t msg; 701 ipc_call_t answer; 702 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle, 703 file->node->index, &answer); 704 705 /* Wait for reply from the FS server. */ 706 ipcarg_t rc; 707 async_wait_for(msg, &rc); 708 709 vfs_release_phone(fs_phone); 710 fibril_mutex_unlock(&file->lock); 711 712 int retval = IPC_GET_ARG1(answer); 713 if (retval != EOK) 714 ipc_answer_0(rid, retval); 715 716 retval = vfs_fd_free(fd); 717 ipc_answer_0(rid, retval); 727 int ret = vfs_close_internal(file); 728 if (ret != EOK) 729 ipc_answer_0(rid, ret); 730 731 ret = vfs_fd_free(fd); 732 ipc_answer_0(rid, ret); 718 733 } 719 734 … … 1310 1325 } 1311 1326 1327 void vfs_dup(ipc_callid_t rid, ipc_call_t *request) 1328 { 1329 int oldfd = IPC_GET_ARG1(*request); 1330 int newfd = IPC_GET_ARG2(*request); 1331 1332 /* Lookup the file structure corresponding to oldfd. */ 1333 vfs_file_t *oldfile = vfs_file_get(oldfd); 1334 if (!oldfile) { 1335 ipc_answer_0(rid, EBADF); 1336 return; 1337 } 1338 1339 /* If the file descriptors are the same, do nothing. */ 1340 if (oldfd == newfd) { 1341 ipc_answer_1(rid, EOK, newfd); 1342 return; 1343 } 1344 1345 /* 1346 * Lock the open file structure so that no other thread can manipulate 1347 * the same open file at a time. 1348 */ 1349 fibril_mutex_lock(&oldfile->lock); 1350 1351 /* Lookup an open file structure possibly corresponding to newfd. */ 1352 vfs_file_t *newfile = vfs_file_get(newfd); 1353 if (newfile) { 1354 /* Close the originally opened file. */ 1355 int ret = vfs_close_internal(newfile); 1356 if (ret != EOK) { 1357 ipc_answer_0(rid, ret); 1358 return; 1359 } 1360 1361 ret = vfs_fd_free(newfd); 1362 if (ret != EOK) { 1363 ipc_answer_0(rid, ret); 1364 return; 1365 } 1366 } 1367 1368 /* Assign the old file to newfd. */ 1369 int ret = vfs_fd_assign(oldfile, newfd); 1370 fibril_mutex_unlock(&oldfile->lock); 1371 1372 if (ret != EOK) 1373 ipc_answer_0(rid, ret); 1374 else 1375 ipc_answer_1(rid, EOK, newfd); 1376 } 1377 1312 1378 /** 1313 1379 * @}
Note:
See TracChangeset
for help on using the changeset viewer.