source: mainline/uspace/lib/libc/generic/vfs/vfs.c@ 28be7fa

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 28be7fa was 28be7fa, checked in by Martin Decky <martin@…>, 15 years ago

cstyle changes, no change in functionality

  • Property mode set to 100644
File size: 16.2 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{
[210e50a]122 int null_id = -1;
123 char null[DEVMAP_NAME_MAXLEN];
124
125 if (str_cmp(fqdn, "") == 0) {
126 /* No device specified, create a fresh
127 null/%d device instead */
128 null_id = devmap_null_create();
129
130 if (null_id == -1)
131 return ENOMEM;
132
133 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);
134 fqdn = null;
135 }
[82405266]136
[28be7fa]137 dev_handle_t dev_handle;
138 int res = devmap_device_get_handle(fqdn, &dev_handle, flags);
[210e50a]139 if (res != EOK) {
140 if (null_id != -1)
141 devmap_null_destroy(null_id);
142
[82405266]143 return res;
[210e50a]144 }
[82405266]145
[9eb3623]146 size_t mpa_size;
147 char *mpa = absolutize(mp, &mpa_size);
[210e50a]148 if (!mpa) {
149 if (null_id != -1)
150 devmap_null_destroy(null_id);
151
[5fec355]152 return ENOMEM;
[210e50a]153 }
[19b28b0]154
[2f02aa17]155 futex_down(&vfs_phone_futex);
156 async_serialize_start();
[19b28b0]157 vfs_connect();
158
[28be7fa]159 ipcarg_t rc_orig;
160 aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL);
161 ipcarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
[12fc042]162 if (rc != EOK) {
[3734106]163 async_wait_for(req, &rc_orig);
[12fc042]164 async_serialize_end();
165 futex_up(&vfs_phone_futex);
166 free(mpa);
[210e50a]167
168 if (null_id != -1)
169 devmap_null_destroy(null_id);
170
[3734106]171 if (rc_orig == EOK)
172 return (int) rc;
173 else
174 return (int) rc_orig;
[12fc042]175 }
[19b28b0]176
[0da4e41]177 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
[594303b]178 if (rc != EOK) {
[3734106]179 async_wait_for(req, &rc_orig);
[594303b]180 async_serialize_end();
181 futex_up(&vfs_phone_futex);
182 free(mpa);
[210e50a]183
184 if (null_id != -1)
185 devmap_null_destroy(null_id);
186
[3734106]187 if (rc_orig == EOK)
188 return (int) rc;
189 else
190 return (int) rc_orig;
[594303b]191 }
[210e50a]192
[0da4e41]193 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
[2f02aa17]194 if (rc != EOK) {
[3734106]195 async_wait_for(req, &rc_orig);
[2f02aa17]196 async_serialize_end();
197 futex_up(&vfs_phone_futex);
[5fec355]198 free(mpa);
[210e50a]199
200 if (null_id != -1)
201 devmap_null_destroy(null_id);
202
[3734106]203 if (rc_orig == EOK)
204 return (int) rc;
205 else
206 return (int) rc_orig;
[2f02aa17]207 }
[210e50a]208
[c08c355]209 /* Ask VFS whether it likes fs_name. */
210 rc = async_req_0_0(vfs_phone, IPC_M_PING);
211 if (rc != EOK) {
[3734106]212 async_wait_for(req, &rc_orig);
[c08c355]213 async_serialize_end();
214 futex_up(&vfs_phone_futex);
215 free(mpa);
[210e50a]216
217 if (null_id != -1)
218 devmap_null_destroy(null_id);
219
[3734106]220 if (rc_orig == EOK)
221 return (int) rc;
222 else
223 return (int) rc_orig;
[c08c355]224 }
[19b28b0]225
[2f02aa17]226 async_wait_for(req, &rc);
227 async_serialize_end();
228 futex_up(&vfs_phone_futex);
[5fec355]229 free(mpa);
[19b28b0]230
[210e50a]231 if ((rc != EOK) && (null_id != -1))
232 devmap_null_destroy(null_id);
233
[2f02aa17]234 return (int) rc;
235}
236
[21f32ee1]237int unmount(const char *mp)
238{
[b9067dfa]239 ipcarg_t rc;
240 ipcarg_t rc_orig;
241 aid_t req;
242 size_t mpa_size;
243 char *mpa;
244
245 mpa = absolutize(mp, &mpa_size);
246 if (!mpa)
247 return ENOMEM;
248
249 futex_down(&vfs_phone_futex);
250 async_serialize_start();
251 vfs_connect();
252
253 req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
254 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
255 if (rc != EOK) {
256 async_wait_for(req, &rc_orig);
257 async_serialize_end();
258 futex_up(&vfs_phone_futex);
259 free(mpa);
260 if (rc_orig == EOK)
261 return (int) rc;
262 else
263 return (int) rc_orig;
264 }
265
266
267 async_wait_for(req, &rc);
268 async_serialize_end();
269 futex_up(&vfs_phone_futex);
270 free(mpa);
271
272 return (int) rc;
[21f32ee1]273}
274
[2b88074b]275static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
[2f02aa17]276{
277 futex_down(&vfs_phone_futex);
278 async_serialize_start();
[19b28b0]279 vfs_connect();
280
[2b88074b]281 ipc_call_t answer;
282 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);
283 ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size);
284
[2f02aa17]285 if (rc != EOK) {
[3734106]286 ipcarg_t rc_orig;
287 async_wait_for(req, &rc_orig);
[2b88074b]288
[2f02aa17]289 async_serialize_end();
290 futex_up(&vfs_phone_futex);
[2b88074b]291
[3734106]292 if (rc_orig == EOK)
293 return (int) rc;
294 else
295 return (int) rc_orig;
[2f02aa17]296 }
[2b88074b]297
[2f02aa17]298 async_wait_for(req, &rc);
299 async_serialize_end();
300 futex_up(&vfs_phone_futex);
[2595dab]301
[57b4f46]302 if (rc != EOK)
303 return (int) rc;
[2595dab]304
[2f02aa17]305 return (int) IPC_GET_ARG1(answer);
306}
307
[ae78b530]308int open(const char *path, int oflag, ...)
309{
[2b88074b]310 size_t abs_size;
311 char *abs = absolutize(path, &abs_size);
312 if (!abs)
313 return ENOMEM;
314
315 int ret = open_internal(abs, abs_size, L_FILE, oflag);
316 free(abs);
317
318 return ret;
[ae78b530]319}
320
[99272a3]321int open_node(fdi_node_t *node, int oflag)
[2595dab]322{
323 futex_down(&vfs_phone_futex);
324 async_serialize_start();
325 vfs_connect();
326
327 ipc_call_t answer;
[4198f9c3]328 aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,
[2595dab]329 node->dev_handle, node->index, oflag, &answer);
330
331 ipcarg_t rc;
332 async_wait_for(req, &rc);
333 async_serialize_end();
334 futex_up(&vfs_phone_futex);
335
336 if (rc != EOK)
[3734106]337 return (int) rc;
[2595dab]338
339 return (int) IPC_GET_ARG1(answer);
340}
341
[72bde81]342int close(int fildes)
343{
[e704503]344 ipcarg_t rc;
[19b28b0]345
[e704503]346 futex_down(&vfs_phone_futex);
347 async_serialize_start();
[19b28b0]348 vfs_connect();
349
[4198f9c3]350 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
[19b28b0]351
[e704503]352 async_serialize_end();
353 futex_up(&vfs_phone_futex);
354
355 return (int)rc;
[72bde81]356}
357
[2f02aa17]358ssize_t read(int fildes, void *buf, size_t nbyte)
359{
360 ipcarg_t rc;
361 ipc_call_t answer;
362 aid_t req;
363
364 futex_down(&vfs_phone_futex);
365 async_serialize_start();
[19b28b0]366 vfs_connect();
367
[4198f9c3]368 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
[0da4e41]369 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]370 if (rc != EOK) {
[3734106]371 ipcarg_t rc_orig;
372
373 async_wait_for(req, &rc_orig);
[2f02aa17]374 async_serialize_end();
375 futex_up(&vfs_phone_futex);
[3734106]376 if (rc_orig == EOK)
377 return (ssize_t) rc;
378 else
379 return (ssize_t) rc_orig;
[2f02aa17]380 }
381 async_wait_for(req, &rc);
382 async_serialize_end();
383 futex_up(&vfs_phone_futex);
[f7017572]384 if (rc == EOK)
385 return (ssize_t) IPC_GET_ARG1(answer);
386 else
[25becee8]387 return rc;
[2f02aa17]388}
389
[449c246]390ssize_t write(int fildes, const void *buf, size_t nbyte)
391{
392 ipcarg_t rc;
393 ipc_call_t answer;
394 aid_t req;
395
396 futex_down(&vfs_phone_futex);
397 async_serialize_start();
[19b28b0]398 vfs_connect();
399
[4198f9c3]400 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
[0da4e41]401 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]402 if (rc != EOK) {
[3734106]403 ipcarg_t rc_orig;
404
405 async_wait_for(req, &rc_orig);
[449c246]406 async_serialize_end();
407 futex_up(&vfs_phone_futex);
[3734106]408 if (rc_orig == EOK)
409 return (ssize_t) rc;
410 else
411 return (ssize_t) rc_orig;
[449c246]412 }
413 async_wait_for(req, &rc);
414 async_serialize_end();
415 futex_up(&vfs_phone_futex);
[f7017572]416 if (rc == EOK)
417 return (ssize_t) IPC_GET_ARG1(answer);
418 else
419 return -1;
[449c246]420}
[222e57c]421
[2595dab]422int fsync(int fildes)
423{
424 futex_down(&vfs_phone_futex);
425 async_serialize_start();
426 vfs_connect();
427
[4198f9c3]428 ipcarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
[2595dab]429
430 async_serialize_end();
431 futex_up(&vfs_phone_futex);
432
433 return (int) rc;
434}
435
[222e57c]436off_t lseek(int fildes, off_t offset, int whence)
437{
438 ipcarg_t rc;
439
440 futex_down(&vfs_phone_futex);
441 async_serialize_start();
[19b28b0]442 vfs_connect();
443
[c61d34b]444 ipcarg_t newoffs;
[4198f9c3]445 rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
[c61d34b]446 &newoffs);
[222e57c]447
448 async_serialize_end();
449 futex_up(&vfs_phone_futex);
450
451 if (rc != EOK)
452 return (off_t) -1;
453
[c61d34b]454 return (off_t) newoffs;
[222e57c]455}
456
[0ee4322]457int ftruncate(int fildes, off_t length)
458{
459 ipcarg_t rc;
460
461 futex_down(&vfs_phone_futex);
462 async_serialize_start();
[19b28b0]463 vfs_connect();
464
[4198f9c3]465 rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
[0ee4322]466 async_serialize_end();
467 futex_up(&vfs_phone_futex);
468 return (int) rc;
469}
470
[852b801]471int fstat(int fildes, struct stat *stat)
472{
473 ipcarg_t rc;
474 aid_t req;
475
476 futex_down(&vfs_phone_futex);
477 async_serialize_start();
478 vfs_connect();
479
480 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
[0da4e41]481 rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
[852b801]482 if (rc != EOK) {
[3734106]483 ipcarg_t rc_orig;
484
485 async_wait_for(req, &rc_orig);
[852b801]486 async_serialize_end();
487 futex_up(&vfs_phone_futex);
[3734106]488 if (rc_orig == EOK)
489 return (ssize_t) rc;
490 else
491 return (ssize_t) rc_orig;
[852b801]492 }
493 async_wait_for(req, &rc);
494 async_serialize_end();
495 futex_up(&vfs_phone_futex);
496
497 return rc;
498}
499
[415c7e0d]500int stat(const char *path, struct stat *stat)
501{
502 ipcarg_t rc;
[3734106]503 ipcarg_t rc_orig;
[415c7e0d]504 aid_t req;
505
506 size_t pa_size;
507 char *pa = absolutize(path, &pa_size);
508 if (!pa)
509 return ENOMEM;
510
511 futex_down(&vfs_phone_futex);
512 async_serialize_start();
513 vfs_connect();
514
515 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
[0da4e41]516 rc = async_data_write_start(vfs_phone, pa, pa_size);
[415c7e0d]517 if (rc != EOK) {
[3734106]518 async_wait_for(req, &rc_orig);
[415c7e0d]519 async_serialize_end();
520 futex_up(&vfs_phone_futex);
521 free(pa);
[3734106]522 if (rc_orig == EOK)
523 return (int) rc;
524 else
525 return (int) rc_orig;
[415c7e0d]526 }
[0da4e41]527 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
[415c7e0d]528 if (rc != EOK) {
[3734106]529 async_wait_for(req, &rc_orig);
[415c7e0d]530 async_serialize_end();
531 futex_up(&vfs_phone_futex);
532 free(pa);
[3734106]533 if (rc_orig == EOK)
534 return (int) rc;
535 else
536 return (int) rc_orig;
[415c7e0d]537 }
538 async_wait_for(req, &rc);
539 async_serialize_end();
540 futex_up(&vfs_phone_futex);
541 free(pa);
542 return rc;
543}
544
[d0dc74ae]545DIR *opendir(const char *dirname)
546{
547 DIR *dirp = malloc(sizeof(DIR));
548 if (!dirp)
549 return NULL;
[2b88074b]550
551 size_t abs_size;
552 char *abs = absolutize(dirname, &abs_size);
553 if (!abs) {
554 free(dirp);
555 return ENOMEM;
556 }
557
558 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
559 free(abs);
560
561 if (ret < 0) {
[d0dc74ae]562 free(dirp);
563 return NULL;
564 }
[2b88074b]565
566 dirp->fd = ret;
[d0dc74ae]567 return dirp;
568}
569
570struct dirent *readdir(DIR *dirp)
571{
[5973fd0]572 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
573 if (len <= 0)
574 return NULL;
575 return &dirp->res;
[d0dc74ae]576}
577
578void rewinddir(DIR *dirp)
579{
[5973fd0]580 (void) lseek(dirp->fd, 0, SEEK_SET);
[d0dc74ae]581}
582
583int closedir(DIR *dirp)
584{
585 (void) close(dirp->fd);
586 free(dirp);
587 return 0;
588}
589
[72bde81]590int mkdir(const char *path, mode_t mode)
[d0dc74ae]591{
[72bde81]592 ipcarg_t rc;
593 aid_t req;
594
[9eb3623]595 size_t pa_size;
596 char *pa = absolutize(path, &pa_size);
[5fec355]597 if (!pa)
598 return ENOMEM;
[19b28b0]599
[72bde81]600 futex_down(&vfs_phone_futex);
601 async_serialize_start();
[19b28b0]602 vfs_connect();
603
[4198f9c3]604 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
[0da4e41]605 rc = async_data_write_start(vfs_phone, pa, pa_size);
[72bde81]606 if (rc != EOK) {
[3734106]607 ipcarg_t rc_orig;
608
609 async_wait_for(req, &rc_orig);
[72bde81]610 async_serialize_end();
611 futex_up(&vfs_phone_futex);
[5fec355]612 free(pa);
[3734106]613 if (rc_orig == EOK)
614 return (int) rc;
615 else
616 return (int) rc_orig;
[72bde81]617 }
618 async_wait_for(req, &rc);
619 async_serialize_end();
620 futex_up(&vfs_phone_futex);
[5fec355]621 free(pa);
[2595dab]622 return rc;
[d0dc74ae]623}
624
[f15cf1a6]625static int _unlink(const char *path, int lflag)
626{
627 ipcarg_t rc;
628 aid_t req;
629
[9eb3623]630 size_t pa_size;
631 char *pa = absolutize(path, &pa_size);
[5fec355]632 if (!pa)
633 return ENOMEM;
[923c39e]634
[f15cf1a6]635 futex_down(&vfs_phone_futex);
636 async_serialize_start();
[19b28b0]637 vfs_connect();
638
[4198f9c3]639 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
[0da4e41]640 rc = async_data_write_start(vfs_phone, pa, pa_size);
[f15cf1a6]641 if (rc != EOK) {
[3734106]642 ipcarg_t rc_orig;
643
644 async_wait_for(req, &rc_orig);
[f15cf1a6]645 async_serialize_end();
646 futex_up(&vfs_phone_futex);
[5fec355]647 free(pa);
[3734106]648 if (rc_orig == EOK)
649 return (int) rc;
650 else
651 return (int) rc_orig;
[f15cf1a6]652 }
653 async_wait_for(req, &rc);
654 async_serialize_end();
655 futex_up(&vfs_phone_futex);
[5fec355]656 free(pa);
[2595dab]657 return rc;
[f15cf1a6]658}
659
660int unlink(const char *path)
661{
662 return _unlink(path, L_NONE);
663}
664
665int rmdir(const char *path)
666{
667 return _unlink(path, L_DIRECTORY);
668}
669
[a8e9ab8d]670int rename(const char *old, const char *new)
671{
672 ipcarg_t rc;
[3734106]673 ipcarg_t rc_orig;
[a8e9ab8d]674 aid_t req;
675
[9eb3623]676 size_t olda_size;
677 char *olda = absolutize(old, &olda_size);
[a8e9ab8d]678 if (!olda)
679 return ENOMEM;
[923c39e]680
[9eb3623]681 size_t newa_size;
682 char *newa = absolutize(new, &newa_size);
[a8e9ab8d]683 if (!newa) {
684 free(olda);
685 return ENOMEM;
686 }
687
688 futex_down(&vfs_phone_futex);
689 async_serialize_start();
[19b28b0]690 vfs_connect();
691
[4198f9c3]692 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
[0da4e41]693 rc = async_data_write_start(vfs_phone, olda, olda_size);
[a8e9ab8d]694 if (rc != EOK) {
[3734106]695 async_wait_for(req, &rc_orig);
[a8e9ab8d]696 async_serialize_end();
697 futex_up(&vfs_phone_futex);
698 free(olda);
699 free(newa);
[3734106]700 if (rc_orig == EOK)
701 return (int) rc;
702 else
703 return (int) rc_orig;
[a8e9ab8d]704 }
[0da4e41]705 rc = async_data_write_start(vfs_phone, newa, newa_size);
[a8e9ab8d]706 if (rc != EOK) {
[3734106]707 async_wait_for(req, &rc_orig);
[a8e9ab8d]708 async_serialize_end();
709 futex_up(&vfs_phone_futex);
710 free(olda);
711 free(newa);
[3734106]712 if (rc_orig == EOK)
713 return (int) rc;
714 else
715 return (int) rc_orig;
[a8e9ab8d]716 }
717 async_wait_for(req, &rc);
718 async_serialize_end();
719 futex_up(&vfs_phone_futex);
720 free(olda);
721 free(newa);
722 return rc;
723}
724
[5fec355]725int chdir(const char *path)
726{
[2b88074b]727 size_t abs_size;
728 char *abs = absolutize(path, &abs_size);
729 if (!abs)
[5fec355]730 return ENOMEM;
[2b88074b]731
732 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
733
734 if (fd < 0) {
735 free(abs);
[5fec355]736 return ENOENT;
737 }
[2b88074b]738
[5fec355]739 futex_down(&cwd_futex);
[2b88074b]740
741 if (cwd_fd >= 0)
742 close(cwd_fd);
743
744
745 if (cwd_path)
746 free(cwd_path);
747
748 cwd_fd = fd;
749 cwd_path = abs;
750 cwd_size = abs_size;
751
[5fec355]752 futex_up(&cwd_futex);
[0dd0f71f]753 return EOK;
[5fec355]754}
755
756char *getcwd(char *buf, size_t size)
757{
[2b88074b]758 if (size == 0)
[5fec355]759 return NULL;
[2b88074b]760
[5fec355]761 futex_down(&cwd_futex);
[2b88074b]762
763 if ((cwd_size == 0) || (size < cwd_size + 1)) {
[5fec355]764 futex_up(&cwd_futex);
765 return NULL;
766 }
[2b88074b]767
[6eb2e96]768 str_cpy(buf, size, cwd_path);
[5fec355]769 futex_up(&cwd_futex);
[2b88074b]770
[5fec355]771 return buf;
772}
773
[852b801]774int fd_phone(int fildes)
775{
776 struct stat stat;
777 int rc;
778
779 rc = fstat(fildes, &stat);
780
[1313ee9]781 if (!stat.device)
[852b801]782 return -1;
783
[1313ee9]784 return devmap_device_connect(stat.device, 0);
[852b801]785}
786
787int fd_node(int fildes, fdi_node_t *node)
788{
789 struct stat stat;
790 int rc;
791
792 rc = fstat(fildes, &stat);
793
794 if (rc == EOK) {
795 node->fs_handle = stat.fs_handle;
796 node->dev_handle = stat.dev_handle;
797 node->index = stat.index;
798 }
799
800 return rc;
801}
802
[2b88074b]803int dup2(int oldfd, int newfd)
804{
805 futex_down(&vfs_phone_futex);
806 async_serialize_start();
807 vfs_connect();
808
809 ipcarg_t ret;
810 ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
811
812 async_serialize_end();
813 futex_up(&vfs_phone_futex);
814
815 if (rc == EOK)
816 return (int) ret;
817
818 return (int) rc;
819}
820
[2f02aa17]821/** @}
822 */
Note: See TracBrowser for help on using the repository browser.