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

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

Rename async_data_read/write_start_flexible() to async_data_read/write_start_generic().

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