source: mainline/uspace/lib/libc/generic/vfs/vfs.c@ 81342f7

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

getcwd() should return NULL if the current working directory is not set.

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