source: mainline/uspace/lib/c/generic/vfs/vfs.c@ 64d2b10

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

libc: do not intermix low-level IPC methods with async framework methods

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