source: mainline/uspace/lib/c/generic/vfs/vfs.c@ 007e6efa

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