source: mainline/uspace/lib/libc/generic/vfs/vfs.c@ 1b31a9f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1b31a9f was 21f32ee1, checked in by Jakub Jermar <jakub@…>, 15 years ago

Add dummy unmount() implementation to libc.

  • Property mode set to 100644
File size: 14.8 KB
RevLine 
[2f02aa17]1/*
[222e57c]2 * Copyright (c) 2008 Jakub Jermar
[2f02aa17]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 */
[19b28b0]34
[5fec355]35#include <vfs/vfs.h>
36#include <vfs/canonify.h>
[d0dc74ae]37#include <stdlib.h>
[449c246]38#include <unistd.h>
[d0dc74ae]39#include <dirent.h>
[449c246]40#include <fcntl.h>
[923c39e]41#include <stdio.h>
[852b801]42#include <sys/stat.h>
[72bde81]43#include <sys/types.h>
[2f02aa17]44#include <ipc/ipc.h>
45#include <ipc/services.h>
46#include <async.h>
47#include <atomic.h>
48#include <futex.h>
49#include <errno.h>
50#include <string.h>
[1090b8c]51#include <devmap.h>
[2595dab]52#include <ipc/vfs.h>
53#include <ipc/devmap.h>
[2f02aa17]54
[2595dab]55static int vfs_phone = -1;
56static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
57static futex_t cwd_futex = FUTEX_INITIALIZER;
[5fec355]58
[2b88074b]59static int cwd_fd = -1;
60static char *cwd_path = NULL;
61static size_t cwd_size = 0;
[5fec355]62
[17b2aac]63char *absolutize(const char *path, size_t *retlen)
[5fec355]64{
65 char *ncwd_path;
[34a74ab]66 char *ncwd_path_nc;
[5fec355]67
68 futex_down(&cwd_futex);
[9eb3623]69 size_t size = str_size(path);
[5fec355]70 if (*path != '/') {
71 if (!cwd_path) {
72 futex_up(&cwd_futex);
73 return NULL;
74 }
[9eb3623]75 ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
[34a74ab]76 if (!ncwd_path_nc) {
[5fec355]77 futex_up(&cwd_futex);
78 return NULL;
79 }
[6eb2e96]80 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
[9eb3623]81 ncwd_path_nc[cwd_size] = '/';
82 ncwd_path_nc[cwd_size + 1] = '\0';
[5fec355]83 } else {
[9eb3623]84 ncwd_path_nc = malloc(size + 1);
[34a74ab]85 if (!ncwd_path_nc) {
[5fec355]86 futex_up(&cwd_futex);
87 return NULL;
88 }
[34a74ab]89 ncwd_path_nc[0] = '\0';
[5fec355]90 }
[4482bc7]91 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
[34a74ab]92 ncwd_path = canonify(ncwd_path_nc, retlen);
93 if (!ncwd_path) {
94 futex_up(&cwd_futex);
95 free(ncwd_path_nc);
96 return NULL;
97 }
98 /*
99 * We need to clone ncwd_path because canonify() works in-place and thus
100 * the address in ncwd_path need not be the same as ncwd_path_nc, even
101 * though they both point into the same dynamically allocated buffer.
102 */
[095003a8]103 ncwd_path = str_dup(ncwd_path);
[34a74ab]104 free(ncwd_path_nc);
105 if (!ncwd_path) {
[923c39e]106 futex_up(&cwd_futex);
107 return NULL;
108 }
[5fec355]109 futex_up(&cwd_futex);
110 return ncwd_path;
111}
[2f02aa17]112
[19b28b0]113static void vfs_connect(void)
[2f02aa17]114{
[19b28b0]115 while (vfs_phone < 0)
116 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
[2f02aa17]117}
118
[1313ee9]119int mount(const char *fs_name, const char *mp, const char *fqdn,
[1090b8c]120 const char *opts, unsigned int flags)
[2f02aa17]121{
122 int res;
123 ipcarg_t rc;
[3734106]124 ipcarg_t rc_orig;
[2f02aa17]125 aid_t req;
[82405266]126 dev_handle_t dev_handle;
127
[1313ee9]128 res = devmap_device_get_handle(fqdn, &dev_handle, flags);
[82405266]129 if (res != EOK)
130 return res;
131
[9eb3623]132 size_t mpa_size;
133 char *mpa = absolutize(mp, &mpa_size);
[5fec355]134 if (!mpa)
135 return ENOMEM;
[19b28b0]136
[2f02aa17]137 futex_down(&vfs_phone_futex);
138 async_serialize_start();
[19b28b0]139 vfs_connect();
140
[4198f9c3]141 req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
[0da4e41]142 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
[12fc042]143 if (rc != EOK) {
[3734106]144 async_wait_for(req, &rc_orig);
[12fc042]145 async_serialize_end();
146 futex_up(&vfs_phone_futex);
147 free(mpa);
[3734106]148 if (rc_orig == EOK)
149 return (int) rc;
150 else
151 return (int) rc_orig;
[12fc042]152 }
[19b28b0]153
[0da4e41]154 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
[594303b]155 if (rc != EOK) {
[3734106]156 async_wait_for(req, &rc_orig);
[594303b]157 async_serialize_end();
158 futex_up(&vfs_phone_futex);
159 free(mpa);
[3734106]160 if (rc_orig == EOK)
161 return (int) rc;
162 else
163 return (int) rc_orig;
[594303b]164 }
165
[0da4e41]166 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
[2f02aa17]167 if (rc != EOK) {
[3734106]168 async_wait_for(req, &rc_orig);
[2f02aa17]169 async_serialize_end();
170 futex_up(&vfs_phone_futex);
[5fec355]171 free(mpa);
[3734106]172 if (rc_orig == EOK)
173 return (int) rc;
174 else
175 return (int) rc_orig;
[2f02aa17]176 }
[c08c355]177
178 /* Ask VFS whether it likes fs_name. */
179 rc = async_req_0_0(vfs_phone, IPC_M_PING);
180 if (rc != EOK) {
[3734106]181 async_wait_for(req, &rc_orig);
[c08c355]182 async_serialize_end();
183 futex_up(&vfs_phone_futex);
184 free(mpa);
[3734106]185 if (rc_orig == EOK)
186 return (int) rc;
187 else
188 return (int) rc_orig;
[c08c355]189 }
[19b28b0]190
[2f02aa17]191 async_wait_for(req, &rc);
192 async_serialize_end();
193 futex_up(&vfs_phone_futex);
[5fec355]194 free(mpa);
[19b28b0]195
[2f02aa17]196 return (int) rc;
197}
198
[21f32ee1]199int unmount(const char *mp)
200{
201 return ENOTSUP;
202}
203
[2b88074b]204static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
[2f02aa17]205{
206 futex_down(&vfs_phone_futex);
207 async_serialize_start();
[19b28b0]208 vfs_connect();
209
[2b88074b]210 ipc_call_t answer;
211 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
212 ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
213
[2f02aa17]214 if (rc != EOK) {
[3734106]215 ipcarg_t rc_orig;
216 async_wait_for(req, &rc_orig);
[2b88074b]217
[2f02aa17]218 async_serialize_end();
219 futex_up(&vfs_phone_futex);
[2b88074b]220
[3734106]221 if (rc_orig == EOK)
222 return (int) rc;
223 else
224 return (int) rc_orig;
[2f02aa17]225 }
[2b88074b]226
[2f02aa17]227 async_wait_for(req, &rc);
228 async_serialize_end();
229 futex_up(&vfs_phone_futex);
[2595dab]230
[57b4f46]231 if (rc != EOK)
232 return (int) rc;
[2595dab]233
[2f02aa17]234 return (int) IPC_GET_ARG1(answer);
235}
236
[ae78b530]237int open(const char *path, int oflag, ...)
238{
[2b88074b]239 size_t abs_size;
240 char *abs = absolutize(path, &abs_size);
241 if (!abs)
242 return ENOMEM;
243
244 int ret = open_internal(abs, abs_size, L_FILE, oflag);
245 free(abs);
246
247 return ret;
[ae78b530]248}
249
[99272a3]250int open_node(fdi_node_t *node, int oflag)
[2595dab]251{
252 futex_down(&vfs_phone_futex);
253 async_serialize_start();
254 vfs_connect();
255
256 ipc_call_t answer;
[4198f9c3]257 aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
[2595dab]258 node->dev_handle, node->index, oflag, &answer);
259
260 ipcarg_t rc;
261 async_wait_for(req, &rc);
262 async_serialize_end();
263 futex_up(&vfs_phone_futex);
264
265 if (rc != EOK)
[3734106]266 return (int) rc;
[2595dab]267
268 return (int) IPC_GET_ARG1(answer);
269}
270
[72bde81]271int close(int fildes)
272{
[e704503]273 ipcarg_t rc;
[19b28b0]274
[e704503]275 futex_down(&vfs_phone_futex);
276 async_serialize_start();
[19b28b0]277 vfs_connect();
278
[4198f9c3]279 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
[19b28b0]280
[e704503]281 async_serialize_end();
282 futex_up(&vfs_phone_futex);
283
284 return (int)rc;
[72bde81]285}
286
[2f02aa17]287ssize_t read(int fildes, void *buf, size_t nbyte)
288{
289 ipcarg_t rc;
290 ipc_call_t answer;
291 aid_t req;
292
293 futex_down(&vfs_phone_futex);
294 async_serialize_start();
[19b28b0]295 vfs_connect();
296
[4198f9c3]297 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
[0da4e41]298 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]299 if (rc != EOK) {
[3734106]300 ipcarg_t rc_orig;
301
302 async_wait_for(req, &rc_orig);
[2f02aa17]303 async_serialize_end();
304 futex_up(&vfs_phone_futex);
[3734106]305 if (rc_orig == EOK)
306 return (ssize_t) rc;
307 else
308 return (ssize_t) rc_orig;
[2f02aa17]309 }
310 async_wait_for(req, &rc);
311 async_serialize_end();
312 futex_up(&vfs_phone_futex);
[f7017572]313 if (rc == EOK)
314 return (ssize_t) IPC_GET_ARG1(answer);
315 else
[25becee8]316 return rc;
[2f02aa17]317}
318
[449c246]319ssize_t write(int fildes, const void *buf, size_t nbyte)
320{
321 ipcarg_t rc;
322 ipc_call_t answer;
323 aid_t req;
324
325 futex_down(&vfs_phone_futex);
326 async_serialize_start();
[19b28b0]327 vfs_connect();
328
[4198f9c3]329 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
[0da4e41]330 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]331 if (rc != EOK) {
[3734106]332 ipcarg_t rc_orig;
333
334 async_wait_for(req, &rc_orig);
[449c246]335 async_serialize_end();
336 futex_up(&vfs_phone_futex);
[3734106]337 if (rc_orig == EOK)
338 return (ssize_t) rc;
339 else
340 return (ssize_t) rc_orig;
[449c246]341 }
342 async_wait_for(req, &rc);
343 async_serialize_end();
344 futex_up(&vfs_phone_futex);
[f7017572]345 if (rc == EOK)
346 return (ssize_t) IPC_GET_ARG1(answer);
347 else
348 return -1;
[449c246]349}
[222e57c]350
[2595dab]351int fsync(int fildes)
352{
353 futex_down(&vfs_phone_futex);
354 async_serialize_start();
355 vfs_connect();
356
[4198f9c3]357 ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
[2595dab]358
359 async_serialize_end();
360 futex_up(&vfs_phone_futex);
361
362 return (int) rc;
363}
364
[222e57c]365off_t lseek(int fildes, off_t offset, int whence)
366{
367 ipcarg_t rc;
368
369 futex_down(&vfs_phone_futex);
370 async_serialize_start();
[19b28b0]371 vfs_connect();
372
[c61d34b]373 ipcarg_t newoffs;
[4198f9c3]374 rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
[c61d34b]375 &newoffs);
[222e57c]376
377 async_serialize_end();
378 futex_up(&vfs_phone_futex);
379
380 if (rc != EOK)
381 return (off_t) -1;
382
[c61d34b]383 return (off_t) newoffs;
[222e57c]384}
385
[0ee4322]386int ftruncate(int fildes, off_t length)
387{
388 ipcarg_t rc;
389
390 futex_down(&vfs_phone_futex);
391 async_serialize_start();
[19b28b0]392 vfs_connect();
393
[4198f9c3]394 rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
[0ee4322]395 async_serialize_end();
396 futex_up(&vfs_phone_futex);
397 return (int) rc;
398}
399
[852b801]400int fstat(int fildes, struct stat *stat)
401{
402 ipcarg_t rc;
403 aid_t req;
404
405 futex_down(&vfs_phone_futex);
406 async_serialize_start();
407 vfs_connect();
408
409 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
[0da4e41]410 rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
[852b801]411 if (rc != EOK) {
[3734106]412 ipcarg_t rc_orig;
413
414 async_wait_for(req, &rc_orig);
[852b801]415 async_serialize_end();
416 futex_up(&vfs_phone_futex);
[3734106]417 if (rc_orig == EOK)
418 return (ssize_t) rc;
419 else
420 return (ssize_t) rc_orig;
[852b801]421 }
422 async_wait_for(req, &rc);
423 async_serialize_end();
424 futex_up(&vfs_phone_futex);
425
426 return rc;
427}
428
[415c7e0d]429int stat(const char *path, struct stat *stat)
430{
431 ipcarg_t rc;
[3734106]432 ipcarg_t rc_orig;
[415c7e0d]433 aid_t req;
434
435 size_t pa_size;
436 char *pa = absolutize(path, &pa_size);
437 if (!pa)
438 return ENOMEM;
439
440 futex_down(&vfs_phone_futex);
441 async_serialize_start();
442 vfs_connect();
443
444 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
[0da4e41]445 rc = async_data_write_start(vfs_phone, pa, pa_size);
[415c7e0d]446 if (rc != EOK) {
[3734106]447 async_wait_for(req, &rc_orig);
[415c7e0d]448 async_serialize_end();
449 futex_up(&vfs_phone_futex);
450 free(pa);
[3734106]451 if (rc_orig == EOK)
452 return (int) rc;
453 else
454 return (int) rc_orig;
[415c7e0d]455 }
[0da4e41]456 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
[415c7e0d]457 if (rc != EOK) {
[3734106]458 async_wait_for(req, &rc_orig);
[415c7e0d]459 async_serialize_end();
460 futex_up(&vfs_phone_futex);
461 free(pa);
[3734106]462 if (rc_orig == EOK)
463 return (int) rc;
464 else
465 return (int) rc_orig;
[415c7e0d]466 }
467 async_wait_for(req, &rc);
468 async_serialize_end();
469 futex_up(&vfs_phone_futex);
470 free(pa);
471 return rc;
472}
473
[d0dc74ae]474DIR *opendir(const char *dirname)
475{
476 DIR *dirp = malloc(sizeof(DIR));
477 if (!dirp)
478 return NULL;
[2b88074b]479
480 size_t abs_size;
481 char *abs = absolutize(dirname, &abs_size);
482 if (!abs) {
483 free(dirp);
484 return ENOMEM;
485 }
486
487 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
488 free(abs);
489
490 if (ret < 0) {
[d0dc74ae]491 free(dirp);
492 return NULL;
493 }
[2b88074b]494
495 dirp->fd = ret;
[d0dc74ae]496 return dirp;
497}
498
499struct dirent *readdir(DIR *dirp)
500{
[5973fd0]501 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
502 if (len <= 0)
503 return NULL;
504 return &dirp->res;
[d0dc74ae]505}
506
507void rewinddir(DIR *dirp)
508{
[5973fd0]509 (void) lseek(dirp->fd, 0, SEEK_SET);
[d0dc74ae]510}
511
512int closedir(DIR *dirp)
513{
514 (void) close(dirp->fd);
515 free(dirp);
516 return 0;
517}
518
[72bde81]519int mkdir(const char *path, mode_t mode)
[d0dc74ae]520{
[72bde81]521 ipcarg_t rc;
522 aid_t req;
523
[9eb3623]524 size_t pa_size;
525 char *pa = absolutize(path, &pa_size);
[5fec355]526 if (!pa)
527 return ENOMEM;
[19b28b0]528
[72bde81]529 futex_down(&vfs_phone_futex);
530 async_serialize_start();
[19b28b0]531 vfs_connect();
532
[4198f9c3]533 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
[0da4e41]534 rc = async_data_write_start(vfs_phone, pa, pa_size);
[72bde81]535 if (rc != EOK) {
[3734106]536 ipcarg_t rc_orig;
537
538 async_wait_for(req, &rc_orig);
[72bde81]539 async_serialize_end();
540 futex_up(&vfs_phone_futex);
[5fec355]541 free(pa);
[3734106]542 if (rc_orig == EOK)
543 return (int) rc;
544 else
545 return (int) rc_orig;
[72bde81]546 }
547 async_wait_for(req, &rc);
548 async_serialize_end();
549 futex_up(&vfs_phone_futex);
[5fec355]550 free(pa);
[2595dab]551 return rc;
[d0dc74ae]552}
553
[f15cf1a6]554static int _unlink(const char *path, int lflag)
555{
556 ipcarg_t rc;
557 aid_t req;
558
[9eb3623]559 size_t pa_size;
560 char *pa = absolutize(path, &pa_size);
[5fec355]561 if (!pa)
562 return ENOMEM;
[923c39e]563
[f15cf1a6]564 futex_down(&vfs_phone_futex);
565 async_serialize_start();
[19b28b0]566 vfs_connect();
567
[4198f9c3]568 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
[0da4e41]569 rc = async_data_write_start(vfs_phone, pa, pa_size);
[f15cf1a6]570 if (rc != EOK) {
[3734106]571 ipcarg_t rc_orig;
572
573 async_wait_for(req, &rc_orig);
[f15cf1a6]574 async_serialize_end();
575 futex_up(&vfs_phone_futex);
[5fec355]576 free(pa);
[3734106]577 if (rc_orig == EOK)
578 return (int) rc;
579 else
580 return (int) rc_orig;
[f15cf1a6]581 }
582 async_wait_for(req, &rc);
583 async_serialize_end();
584 futex_up(&vfs_phone_futex);
[5fec355]585 free(pa);
[2595dab]586 return rc;
[f15cf1a6]587}
588
589int unlink(const char *path)
590{
591 return _unlink(path, L_NONE);
592}
593
594int rmdir(const char *path)
595{
596 return _unlink(path, L_DIRECTORY);
597}
598
[a8e9ab8d]599int rename(const char *old, const char *new)
600{
601 ipcarg_t rc;
[3734106]602 ipcarg_t rc_orig;
[a8e9ab8d]603 aid_t req;
604
[9eb3623]605 size_t olda_size;
606 char *olda = absolutize(old, &olda_size);
[a8e9ab8d]607 if (!olda)
608 return ENOMEM;
[923c39e]609
[9eb3623]610 size_t newa_size;
611 char *newa = absolutize(new, &newa_size);
[a8e9ab8d]612 if (!newa) {
613 free(olda);
614 return ENOMEM;
615 }
616
617 futex_down(&vfs_phone_futex);
618 async_serialize_start();
[19b28b0]619 vfs_connect();
620
[4198f9c3]621 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
[0da4e41]622 rc = async_data_write_start(vfs_phone, olda, olda_size);
[a8e9ab8d]623 if (rc != EOK) {
[3734106]624 async_wait_for(req, &rc_orig);
[a8e9ab8d]625 async_serialize_end();
626 futex_up(&vfs_phone_futex);
627 free(olda);
628 free(newa);
[3734106]629 if (rc_orig == EOK)
630 return (int) rc;
631 else
632 return (int) rc_orig;
[a8e9ab8d]633 }
[0da4e41]634 rc = async_data_write_start(vfs_phone, newa, newa_size);
[a8e9ab8d]635 if (rc != EOK) {
[3734106]636 async_wait_for(req, &rc_orig);
[a8e9ab8d]637 async_serialize_end();
638 futex_up(&vfs_phone_futex);
639 free(olda);
640 free(newa);
[3734106]641 if (rc_orig == EOK)
642 return (int) rc;
643 else
644 return (int) rc_orig;
[a8e9ab8d]645 }
646 async_wait_for(req, &rc);
647 async_serialize_end();
648 futex_up(&vfs_phone_futex);
649 free(olda);
650 free(newa);
651 return rc;
652}
653
[5fec355]654int chdir(const char *path)
655{
[2b88074b]656 size_t abs_size;
657 char *abs = absolutize(path, &abs_size);
658 if (!abs)
[5fec355]659 return ENOMEM;
[2b88074b]660
661 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
662
663 if (fd < 0) {
664 free(abs);
[5fec355]665 return ENOENT;
666 }
[2b88074b]667
[5fec355]668 futex_down(&cwd_futex);
[2b88074b]669
670 if (cwd_fd >= 0)
671 close(cwd_fd);
672
673
674 if (cwd_path)
675 free(cwd_path);
676
677 cwd_fd = fd;
678 cwd_path = abs;
679 cwd_size = abs_size;
680
[5fec355]681 futex_up(&cwd_futex);
[0dd0f71f]682 return EOK;
[5fec355]683}
684
685char *getcwd(char *buf, size_t size)
686{
[2b88074b]687 if (size == 0)
[5fec355]688 return NULL;
[2b88074b]689
[5fec355]690 futex_down(&cwd_futex);
[2b88074b]691
692 if ((cwd_size == 0) || (size < cwd_size + 1)) {
[5fec355]693 futex_up(&cwd_futex);
694 return NULL;
695 }
[2b88074b]696
[6eb2e96]697 str_cpy(buf, size, cwd_path);
[5fec355]698 futex_up(&cwd_futex);
[2b88074b]699
[5fec355]700 return buf;
701}
702
[852b801]703int fd_phone(int fildes)
704{
705 struct stat stat;
706 int rc;
707
708 rc = fstat(fildes, &stat);
709
[1313ee9]710 if (!stat.device)
[852b801]711 return -1;
712
[1313ee9]713 return devmap_device_connect(stat.device, 0);
[852b801]714}
715
716int fd_node(int fildes, fdi_node_t *node)
717{
718 struct stat stat;
719 int rc;
720
721 rc = fstat(fildes, &stat);
722
723 if (rc == EOK) {
724 node->fs_handle = stat.fs_handle;
725 node->dev_handle = stat.dev_handle;
726 node->index = stat.index;
727 }
728
729 return rc;
730}
731
[2b88074b]732int dup2(int oldfd, int newfd)
733{
734 futex_down(&vfs_phone_futex);
735 async_serialize_start();
736 vfs_connect();
737
738 ipcarg_t ret;
739 ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
740
741 async_serialize_end();
742 futex_up(&vfs_phone_futex);
743
744 if (rc == EOK)
745 return (int) ret;
746
747 return (int) rc;
748}
749
[2f02aa17]750/** @}
751 */
Note: See TracBrowser for help on using the repository browser.