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

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

rename library directories (the common "lib" prefix is already in the upper directory)

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