source: mainline/uspace/lib/c/generic/vfs/vfs.c@ ae0300b5

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

Use async sessions in the VFS libc client code.

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