source: mainline/uspace/lib/c/generic/vfs/vfs.c@ 06e724e1

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

use the return value

  • Property mode set to 100644
File size: 15.9 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);
[0da4e41]380 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]381 if (rc != EOK) {
[a28ab12]382 vfs_exchange_end(vfs_phone);
383
[96b02eb9]384 sysarg_t rc_orig;
[3734106]385 async_wait_for(req, &rc_orig);
[a28ab12]386
[3734106]387 if (rc_orig == EOK)
388 return (ssize_t) rc;
389 else
390 return (ssize_t) rc_orig;
[2f02aa17]391 }
[a28ab12]392 vfs_exchange_end(vfs_phone);
[2f02aa17]393 async_wait_for(req, &rc);
[f7017572]394 if (rc == EOK)
395 return (ssize_t) IPC_GET_ARG1(answer);
396 else
[25becee8]397 return rc;
[2f02aa17]398}
399
[449c246]400ssize_t write(int fildes, const void *buf, size_t nbyte)
401{
[96b02eb9]402 sysarg_t rc;
[449c246]403 ipc_call_t answer;
404 aid_t req;
405
[a28ab12]406 int vfs_phone = vfs_exchange_begin();
[19b28b0]407
[4198f9c3]408 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
[0da4e41]409 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
[07e01e6]410 if (rc != EOK) {
[a28ab12]411 vfs_exchange_end(vfs_phone);
412
[96b02eb9]413 sysarg_t rc_orig;
[3734106]414 async_wait_for(req, &rc_orig);
[a28ab12]415
[3734106]416 if (rc_orig == EOK)
417 return (ssize_t) rc;
418 else
419 return (ssize_t) rc_orig;
[449c246]420 }
[a28ab12]421 vfs_exchange_end(vfs_phone);
[449c246]422 async_wait_for(req, &rc);
[f7017572]423 if (rc == EOK)
424 return (ssize_t) IPC_GET_ARG1(answer);
425 else
426 return -1;
[449c246]427}
[222e57c]428
[2595dab]429int fsync(int fildes)
430{
[a28ab12]431 int vfs_phone = vfs_exchange_begin();
[2595dab]432
[96b02eb9]433 sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
[2595dab]434
[a28ab12]435 vfs_exchange_end(vfs_phone);
[2595dab]436
437 return (int) rc;
438}
439
[ed903174]440off64_t lseek(int fildes, off64_t offset, int whence)
[222e57c]441{
[a28ab12]442 int vfs_phone = vfs_exchange_begin();
[19b28b0]443
[96b02eb9]444 sysarg_t newoff_lo;
445 sysarg_t newoff_hi;
446 sysarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
[ed903174]447 LOWER32(offset), UPPER32(offset), whence,
448 &newoff_lo, &newoff_hi);
449
[a28ab12]450 vfs_exchange_end(vfs_phone);
[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{
[96b02eb9]460 sysarg_t rc;
[0ee4322]461
[a28ab12]462 int vfs_phone = vfs_exchange_begin();
[19b28b0]463
[ed903174]464 rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
465 LOWER32(length), UPPER32(length));
[a28ab12]466 vfs_exchange_end(vfs_phone);
[ed903174]467
[0ee4322]468 return (int) rc;
469}
470
[852b801]471int fstat(int fildes, struct stat *stat)
472{
[96b02eb9]473 sysarg_t rc;
[852b801]474 aid_t req;
475
[a28ab12]476 int vfs_phone = vfs_exchange_begin();
[852b801]477
478 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
[ed903174]479 rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
[852b801]480 if (rc != EOK) {
[a28ab12]481 vfs_exchange_end(vfs_phone);
482
[96b02eb9]483 sysarg_t rc_orig;
[3734106]484 async_wait_for(req, &rc_orig);
[a28ab12]485
[3734106]486 if (rc_orig == EOK)
487 return (ssize_t) rc;
488 else
489 return (ssize_t) rc_orig;
[852b801]490 }
[a28ab12]491 vfs_exchange_end(vfs_phone);
[852b801]492 async_wait_for(req, &rc);
493
494 return rc;
495}
496
[415c7e0d]497int stat(const char *path, struct stat *stat)
498{
[96b02eb9]499 sysarg_t rc;
500 sysarg_t rc_orig;
[415c7e0d]501 aid_t req;
502
503 size_t pa_size;
504 char *pa = absolutize(path, &pa_size);
505 if (!pa)
506 return ENOMEM;
507
[a28ab12]508 int vfs_phone = vfs_exchange_begin();
[415c7e0d]509
510 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
[0da4e41]511 rc = async_data_write_start(vfs_phone, pa, pa_size);
[415c7e0d]512 if (rc != EOK) {
[a28ab12]513 vfs_exchange_end(vfs_phone);
[415c7e0d]514 free(pa);
[a28ab12]515 async_wait_for(req, &rc_orig);
[3734106]516 if (rc_orig == EOK)
517 return (int) rc;
518 else
519 return (int) rc_orig;
[415c7e0d]520 }
[0da4e41]521 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
[415c7e0d]522 if (rc != EOK) {
[a28ab12]523 vfs_exchange_end(vfs_phone);
[415c7e0d]524 free(pa);
[a28ab12]525 async_wait_for(req, &rc_orig);
[3734106]526 if (rc_orig == EOK)
527 return (int) rc;
528 else
529 return (int) rc_orig;
[415c7e0d]530 }
[a28ab12]531 vfs_exchange_end(vfs_phone);
[415c7e0d]532 free(pa);
[a28ab12]533 async_wait_for(req, &rc);
[415c7e0d]534 return rc;
535}
536
[d0dc74ae]537DIR *opendir(const char *dirname)
538{
539 DIR *dirp = malloc(sizeof(DIR));
540 if (!dirp)
541 return NULL;
[2b88074b]542
543 size_t abs_size;
544 char *abs = absolutize(dirname, &abs_size);
545 if (!abs) {
546 free(dirp);
[ed903174]547 return NULL;
[2b88074b]548 }
549
550 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0);
551 free(abs);
552
553 if (ret < 0) {
[d0dc74ae]554 free(dirp);
555 return NULL;
556 }
[2b88074b]557
558 dirp->fd = ret;
[d0dc74ae]559 return dirp;
560}
561
562struct dirent *readdir(DIR *dirp)
563{
[5973fd0]564 ssize_t len = read(dirp->fd, &dirp->res.d_name[0], NAME_MAX + 1);
565 if (len <= 0)
566 return NULL;
567 return &dirp->res;
[d0dc74ae]568}
569
570void rewinddir(DIR *dirp)
571{
[5973fd0]572 (void) lseek(dirp->fd, 0, SEEK_SET);
[d0dc74ae]573}
574
575int closedir(DIR *dirp)
576{
577 (void) close(dirp->fd);
578 free(dirp);
579 return 0;
580}
581
[72bde81]582int mkdir(const char *path, mode_t mode)
[d0dc74ae]583{
[96b02eb9]584 sysarg_t rc;
[72bde81]585 aid_t req;
586
[9eb3623]587 size_t pa_size;
588 char *pa = absolutize(path, &pa_size);
[5fec355]589 if (!pa)
590 return ENOMEM;
[19b28b0]591
[a28ab12]592 int vfs_phone = vfs_exchange_begin();
[19b28b0]593
[4198f9c3]594 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
[0da4e41]595 rc = async_data_write_start(vfs_phone, pa, pa_size);
[72bde81]596 if (rc != EOK) {
[a28ab12]597 vfs_exchange_end(vfs_phone);
598 free(pa);
599
[96b02eb9]600 sysarg_t rc_orig;
[3734106]601 async_wait_for(req, &rc_orig);
[a28ab12]602
[3734106]603 if (rc_orig == EOK)
604 return (int) rc;
605 else
606 return (int) rc_orig;
[72bde81]607 }
[a28ab12]608 vfs_exchange_end(vfs_phone);
[5fec355]609 free(pa);
[a28ab12]610 async_wait_for(req, &rc);
[2595dab]611 return rc;
[d0dc74ae]612}
613
[f15cf1a6]614static int _unlink(const char *path, int lflag)
615{
[96b02eb9]616 sysarg_t rc;
[f15cf1a6]617 aid_t req;
618
[9eb3623]619 size_t pa_size;
620 char *pa = absolutize(path, &pa_size);
[5fec355]621 if (!pa)
622 return ENOMEM;
[923c39e]623
[a28ab12]624 int vfs_phone = vfs_exchange_begin();
[19b28b0]625
[4198f9c3]626 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
[0da4e41]627 rc = async_data_write_start(vfs_phone, pa, pa_size);
[f15cf1a6]628 if (rc != EOK) {
[a28ab12]629 vfs_exchange_end(vfs_phone);
630 free(pa);
[3734106]631
[a28ab12]632 sysarg_t rc_orig;
[3734106]633 async_wait_for(req, &rc_orig);
[a28ab12]634
[3734106]635 if (rc_orig == EOK)
636 return (int) rc;
637 else
638 return (int) rc_orig;
[f15cf1a6]639 }
[a28ab12]640 vfs_exchange_end(vfs_phone);
[5fec355]641 free(pa);
[a28ab12]642 async_wait_for(req, &rc);
[2595dab]643 return rc;
[f15cf1a6]644}
645
646int unlink(const char *path)
647{
648 return _unlink(path, L_NONE);
649}
650
651int rmdir(const char *path)
652{
653 return _unlink(path, L_DIRECTORY);
654}
655
[a8e9ab8d]656int rename(const char *old, const char *new)
657{
[96b02eb9]658 sysarg_t rc;
659 sysarg_t rc_orig;
[a8e9ab8d]660 aid_t req;
661
[9eb3623]662 size_t olda_size;
663 char *olda = absolutize(old, &olda_size);
[a8e9ab8d]664 if (!olda)
665 return ENOMEM;
[923c39e]666
[9eb3623]667 size_t newa_size;
668 char *newa = absolutize(new, &newa_size);
[a8e9ab8d]669 if (!newa) {
670 free(olda);
671 return ENOMEM;
672 }
673
[a28ab12]674 int vfs_phone = vfs_exchange_begin();
[19b28b0]675
[4198f9c3]676 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
[0da4e41]677 rc = async_data_write_start(vfs_phone, olda, olda_size);
[a8e9ab8d]678 if (rc != EOK) {
[a28ab12]679 vfs_exchange_end(vfs_phone);
[a8e9ab8d]680 free(olda);
681 free(newa);
[a28ab12]682 async_wait_for(req, &rc_orig);
[3734106]683 if (rc_orig == EOK)
684 return (int) rc;
685 else
686 return (int) rc_orig;
[a8e9ab8d]687 }
[0da4e41]688 rc = async_data_write_start(vfs_phone, newa, newa_size);
[a8e9ab8d]689 if (rc != EOK) {
[a28ab12]690 vfs_exchange_end(vfs_phone);
[a8e9ab8d]691 free(olda);
692 free(newa);
[a28ab12]693 async_wait_for(req, &rc_orig);
[3734106]694 if (rc_orig == EOK)
695 return (int) rc;
696 else
697 return (int) rc_orig;
[a8e9ab8d]698 }
[a28ab12]699 vfs_exchange_end(vfs_phone);
[a8e9ab8d]700 free(olda);
701 free(newa);
[a28ab12]702 async_wait_for(req, &rc);
[a8e9ab8d]703 return rc;
704}
705
[5fec355]706int chdir(const char *path)
707{
[2b88074b]708 size_t abs_size;
709 char *abs = absolutize(path, &abs_size);
710 if (!abs)
[5fec355]711 return ENOMEM;
[2b88074b]712
713 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC);
714
715 if (fd < 0) {
716 free(abs);
[5fec355]717 return ENOENT;
718 }
[2b88074b]719
[a28ab12]720 fibril_mutex_lock(&cwd_mutex);
[2b88074b]721
722 if (cwd_fd >= 0)
723 close(cwd_fd);
724
725
726 if (cwd_path)
727 free(cwd_path);
728
729 cwd_fd = fd;
730 cwd_path = abs;
731 cwd_size = abs_size;
732
[a28ab12]733 fibril_mutex_unlock(&cwd_mutex);
[0dd0f71f]734 return EOK;
[5fec355]735}
736
737char *getcwd(char *buf, size_t size)
738{
[2b88074b]739 if (size == 0)
[5fec355]740 return NULL;
[2b88074b]741
[a28ab12]742 fibril_mutex_lock(&cwd_mutex);
[2b88074b]743
744 if ((cwd_size == 0) || (size < cwd_size + 1)) {
[a28ab12]745 fibril_mutex_unlock(&cwd_mutex);
[5fec355]746 return NULL;
747 }
[2b88074b]748
[6eb2e96]749 str_cpy(buf, size, cwd_path);
[a28ab12]750 fibril_mutex_unlock(&cwd_mutex);
[2b88074b]751
[5fec355]752 return buf;
753}
754
[852b801]755int fd_phone(int fildes)
756{
757 struct stat stat;
[8caaea7]758
759 int rc = fstat(fildes, &stat);
760 if (rc != 0)
761 return rc;
762
[1313ee9]763 if (!stat.device)
[852b801]764 return -1;
765
[1313ee9]766 return devmap_device_connect(stat.device, 0);
[852b801]767}
768
769int fd_node(int fildes, fdi_node_t *node)
770{
771 struct stat stat;
772 int rc;
773
774 rc = fstat(fildes, &stat);
775
776 if (rc == EOK) {
777 node->fs_handle = stat.fs_handle;
[991f645]778 node->devmap_handle = stat.devmap_handle;
[852b801]779 node->index = stat.index;
780 }
781
782 return rc;
783}
784
[2b88074b]785int dup2(int oldfd, int newfd)
786{
[a28ab12]787 int vfs_phone = vfs_exchange_begin();
[2b88074b]788
[96b02eb9]789 sysarg_t ret;
790 sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
[2b88074b]791
[a28ab12]792 vfs_exchange_end(vfs_phone);
[2b88074b]793
794 if (rc == EOK)
795 return (int) ret;
796
797 return (int) rc;
798}
799
[2f02aa17]800/** @}
801 */
Note: See TracBrowser for help on using the repository browser.