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

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

Finish the libc implementation of unmount().

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