Subversion Repositories HelenOS

Rev

Rev 2753 | Rev 2761 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2753 Rev 2755
Line 30... Line 30...
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <vfs.h>
35
#include <vfs/vfs.h>
-
 
36
#include <vfs/canonify.h>
36
#include <stdlib.h>
37
#include <stdlib.h>
37
#include <unistd.h>
38
#include <unistd.h>
38
#include <dirent.h>
39
#include <dirent.h>
39
#include <fcntl.h>
40
#include <fcntl.h>
40
#include <sys/stat.h>
41
#include <sys/stat.h>
Line 47... Line 48...
47
#include <errno.h>
48
#include <errno.h>
48
#include <string.h>
49
#include <string.h>
49
#include "../../srv/vfs/vfs.h"
50
#include "../../srv/vfs/vfs.h"
50
 
51
 
51
int vfs_phone = -1;
52
int vfs_phone = -1;
52
atomic_t vfs_phone_futex = FUTEX_INITIALIZER;
53
futex_t vfs_phone_futex = FUTEX_INITIALIZER;
-
 
54
 
-
 
55
futex_t cwd_futex = FUTEX_INITIALIZER;
-
 
56
DIR *cwd_dir = NULL;
-
 
57
char *cwd_path = NULL;
-
 
58
size_t cwd_len = 0;
-
 
59
 
-
 
60
static char *absolutize(const char *path)
-
 
61
{
-
 
62
    char *ncwd_path;
-
 
63
 
-
 
64
    futex_down(&cwd_futex);
-
 
65
    size_t len = strlen(path);
-
 
66
    if (*path != '/') {
-
 
67
        if (!cwd_path) {
-
 
68
            futex_up(&cwd_futex);
-
 
69
            return NULL;
-
 
70
        }
-
 
71
        ncwd_path = malloc(len + cwd_len + 1);
-
 
72
        if (!ncwd_path) {
-
 
73
            futex_up(&cwd_futex);
-
 
74
            return NULL;
-
 
75
        }
-
 
76
        strcpy(ncwd_path, cwd_path);
-
 
77
        ncwd_path[cwd_len] = '/';
-
 
78
        ncwd_path[cwd_len + 1] = '\0';
-
 
79
    } else {
-
 
80
        ncwd_path = malloc(len + 1);
-
 
81
        if (!ncwd_path) {
-
 
82
            futex_up(&cwd_futex);
-
 
83
            return NULL;
-
 
84
        }
-
 
85
        ncwd_path[0] = '\0';
-
 
86
    }
-
 
87
    strcat(ncwd_path, path);
-
 
88
    futex_up(&cwd_futex);
-
 
89
    return ncwd_path;
-
 
90
}
53
 
91
 
54
static int vfs_connect(void)
92
static int vfs_connect(void)
55
{
93
{
56
    if (vfs_phone < 0)
94
    if (vfs_phone < 0)
57
        vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
95
        vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0);
Line 64... Line 102...
64
    ipcarg_t rc;
102
    ipcarg_t rc;
65
    aid_t req;
103
    aid_t req;
66
 
104
 
67
    int dev_handle = 0; /* TODO */
105
    int dev_handle = 0; /* TODO */
68
 
106
 
-
 
107
    char *mpa = absolutize(mp);
-
 
108
    if (!mpa)
-
 
109
        return ENOMEM;
-
 
110
    size_t mpc_len;
-
 
111
    char *mpc = canonify(mpa, &mpc_len);
-
 
112
    if (!mpc) {
-
 
113
        free(mpa);
-
 
114
        return EINVAL;
-
 
115
    }
-
 
116
 
69
    futex_down(&vfs_phone_futex);
117
    futex_down(&vfs_phone_futex);
70
    async_serialize_start();
118
    async_serialize_start();
71
    if (vfs_phone < 0) {
119
    if (vfs_phone < 0) {
72
        res = vfs_connect();
120
        res = vfs_connect();
73
        if (res < 0) {
121
        if (res < 0) {
74
            async_serialize_end();
122
            async_serialize_end();
75
            futex_up(&vfs_phone_futex);
123
            futex_up(&vfs_phone_futex);
-
 
124
            free(mpa);
76
            return res;
125
            return res;
77
        }
126
        }
78
    }
127
    }
79
    req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL);
128
    req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL);
80
    rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name));
129
    rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name));
81
    if (rc != EOK) {
130
    if (rc != EOK) {
82
        async_wait_for(req, NULL);
131
        async_wait_for(req, NULL);
83
        async_serialize_end();
132
        async_serialize_end();
84
        futex_up(&vfs_phone_futex);
133
        futex_up(&vfs_phone_futex);
-
 
134
        free(mpa);
85
        return (int) rc;
135
        return (int) rc;
86
    }
136
    }
87
    rc = ipc_data_write_start(vfs_phone, (void *)mp, strlen(mp));
137
    rc = ipc_data_write_start(vfs_phone, (void *)mpc, mpc_len);
88
    if (rc != EOK) {
138
    if (rc != EOK) {
89
        async_wait_for(req, NULL);
139
        async_wait_for(req, NULL);
90
        async_serialize_end();
140
        async_serialize_end();
91
        futex_up(&vfs_phone_futex);
141
        futex_up(&vfs_phone_futex);
-
 
142
        free(mpa);
92
        return (int) rc;
143
        return (int) rc;
93
    }
144
    }
94
    async_wait_for(req, &rc);
145
    async_wait_for(req, &rc);
95
    async_serialize_end();
146
    async_serialize_end();
96
    futex_up(&vfs_phone_futex);
147
    futex_up(&vfs_phone_futex);
-
 
148
    free(mpa);
97
    return (int) rc;
149
    return (int) rc;
98
}
150
}
99
 
151
 
100
static int _open(const char *path, int lflag, int oflag, ...)
152
static int _open(const char *path, int lflag, int oflag, ...)
101
{
153
{
102
    int res;
154
    int res;
103
    ipcarg_t rc;
155
    ipcarg_t rc;
104
    ipc_call_t answer;
156
    ipc_call_t answer;
105
    aid_t req;
157
    aid_t req;
106
   
158
   
-
 
159
    char *pa = absolutize(path);
-
 
160
    if (!pa)
-
 
161
        return ENOMEM;
-
 
162
    size_t pc_len;
-
 
163
    char *pc = canonify(pa, &pc_len);
-
 
164
    if (!pc) {
-
 
165
        free(pa);
-
 
166
        return EINVAL;
-
 
167
    }
-
 
168
   
107
    futex_down(&vfs_phone_futex);
169
    futex_down(&vfs_phone_futex);
108
    async_serialize_start();
170
    async_serialize_start();
109
    if (vfs_phone < 0) {
171
    if (vfs_phone < 0) {
110
        res = vfs_connect();
172
        res = vfs_connect();
111
        if (res < 0) {
173
        if (res < 0) {
112
            async_serialize_end();
174
            async_serialize_end();
113
            futex_up(&vfs_phone_futex);
175
            futex_up(&vfs_phone_futex);
-
 
176
            free(pa);
114
            return res;
177
            return res;
115
        }
178
        }
116
    }
179
    }
117
    req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
180
    req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
118
    rc = ipc_data_write_start(vfs_phone, path, strlen(path));
181
    rc = ipc_data_write_start(vfs_phone, pc, pc_len);
119
    if (rc != EOK) {
182
    if (rc != EOK) {
120
        async_wait_for(req, NULL);
183
        async_wait_for(req, NULL);
121
        async_serialize_end();
184
        async_serialize_end();
122
        futex_up(&vfs_phone_futex);
185
        futex_up(&vfs_phone_futex);
-
 
186
        free(pa);
123
        return (int) rc;
187
        return (int) rc;
124
    }
188
    }
125
    async_wait_for(req, &rc);
189
    async_wait_for(req, &rc);
126
    async_serialize_end();
190
    async_serialize_end();
127
    futex_up(&vfs_phone_futex);
191
    futex_up(&vfs_phone_futex);
-
 
192
    free(pa);
128
    return (int) IPC_GET_ARG1(answer);
193
    return (int) IPC_GET_ARG1(answer);
129
}
194
}
130
 
195
 
131
int open(const char *path, int oflag, ...)
196
int open(const char *path, int oflag, ...)
132
{
197
{
Line 312... Line 377...
312
{
377
{
313
    int res;
378
    int res;
314
    ipcarg_t rc;
379
    ipcarg_t rc;
315
    aid_t req;
380
    aid_t req;
316
   
381
   
-
 
382
    char *pa = absolutize(path);
-
 
383
    if (!pa)
-
 
384
        return ENOMEM;
-
 
385
    size_t pc_len;
-
 
386
    char *pc = canonify(pa, &pc_len);
-
 
387
    if (!pc) {
-
 
388
        free(pa);
-
 
389
        return EINVAL;
-
 
390
    }
-
 
391
 
317
    futex_down(&vfs_phone_futex);
392
    futex_down(&vfs_phone_futex);
318
    async_serialize_start();
393
    async_serialize_start();
319
    if (vfs_phone < 0) {
394
    if (vfs_phone < 0) {
320
        res = vfs_connect();
395
        res = vfs_connect();
321
        if (res < 0) {
396
        if (res < 0) {
322
            async_serialize_end();
397
            async_serialize_end();
323
            futex_up(&vfs_phone_futex);
398
            futex_up(&vfs_phone_futex);
-
 
399
            free(pa);
324
            return res;
400
            return res;
325
        }
401
        }
326
    }
402
    }
327
    req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
403
    req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
328
    rc = ipc_data_write_start(vfs_phone, path, strlen(path));
404
    rc = ipc_data_write_start(vfs_phone, pc, pc_len);
329
    if (rc != EOK) {
405
    if (rc != EOK) {
330
        async_wait_for(req, NULL);
406
        async_wait_for(req, NULL);
331
        async_serialize_end();
407
        async_serialize_end();
332
        futex_up(&vfs_phone_futex);
408
        futex_up(&vfs_phone_futex);
-
 
409
        free(pa);
333
        return (int) rc;
410
        return (int) rc;
334
    }
411
    }
335
    async_wait_for(req, &rc);
412
    async_wait_for(req, &rc);
336
    async_serialize_end();
413
    async_serialize_end();
337
    futex_up(&vfs_phone_futex);
414
    futex_up(&vfs_phone_futex);
-
 
415
    free(pa);
338
    return EOK;
416
    return EOK;
339
}
417
}
340
 
418
 
341
static int _unlink(const char *path, int lflag)
419
static int _unlink(const char *path, int lflag)
342
{
420
{
343
    int res;
421
    int res;
344
    ipcarg_t rc;
422
    ipcarg_t rc;
345
    aid_t req;
423
    aid_t req;
346
   
424
   
-
 
425
    char *pa = absolutize(path);
-
 
426
    if (!pa)
-
 
427
        return ENOMEM;
-
 
428
    size_t pc_len;
-
 
429
    char *pc = canonify(pa, &pc_len);
-
 
430
    if (!pc) {
-
 
431
        free(pa);
-
 
432
        return EINVAL;
-
 
433
    }
347
    futex_down(&vfs_phone_futex);
434
    futex_down(&vfs_phone_futex);
348
    async_serialize_start();
435
    async_serialize_start();
349
    if (vfs_phone < 0) {
436
    if (vfs_phone < 0) {
350
        res = vfs_connect();
437
        res = vfs_connect();
351
        if (res < 0) {
438
        if (res < 0) {
352
            async_serialize_end();
439
            async_serialize_end();
353
            futex_up(&vfs_phone_futex);
440
            futex_up(&vfs_phone_futex);
-
 
441
            free(pa);
354
            return res;
442
            return res;
355
        }
443
        }
356
    }
444
    }
357
    req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
445
    req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
358
    rc = ipc_data_write_start(vfs_phone, path, strlen(path));
446
    rc = ipc_data_write_start(vfs_phone, pc, pc_len);
359
    if (rc != EOK) {
447
    if (rc != EOK) {
360
        async_wait_for(req, NULL);
448
        async_wait_for(req, NULL);
361
        async_serialize_end();
449
        async_serialize_end();
362
        futex_up(&vfs_phone_futex);
450
        futex_up(&vfs_phone_futex);
-
 
451
        free(pa);
363
        return (int) rc;
452
        return (int) rc;
364
    }
453
    }
365
    async_wait_for(req, &rc);
454
    async_wait_for(req, &rc);
366
    async_serialize_end();
455
    async_serialize_end();
367
    futex_up(&vfs_phone_futex);
456
    futex_up(&vfs_phone_futex);
-
 
457
    free(pa);
368
    return EOK;
458
    return EOK;
369
}
459
}
370
 
460
 
371
int unlink(const char *path)
461
int unlink(const char *path)
372
{
462
{
Line 376... Line 466...
376
int rmdir(const char *path)
466
int rmdir(const char *path)
377
{
467
{
378
    return _unlink(path, L_DIRECTORY);
468
    return _unlink(path, L_DIRECTORY);
379
}
469
}
380
 
470
 
-
 
471
int chdir(const char *path)
-
 
472
{
-
 
473
    char *pa = absolutize(path);
-
 
474
    if (!pa)
-
 
475
        return ENOMEM;
-
 
476
    size_t pc_len;
-
 
477
    char *pc = canonify(pa, &pc_len);
-
 
478
    if (!pc) {
-
 
479
        free(pa);
-
 
480
        return ENOENT;
-
 
481
    }
-
 
482
 
-
 
483
    DIR *d = opendir(pc);
-
 
484
    if (!d) {
-
 
485
        free(pa);
-
 
486
        return ENOENT;
-
 
487
    }
-
 
488
 
-
 
489
    futex_down(&cwd_futex);
-
 
490
    if (cwd_dir) {
-
 
491
        closedir(cwd_dir);
-
 
492
        cwd_dir = NULL;
-
 
493
        free(cwd_path);
-
 
494
        cwd_path = NULL;
-
 
495
        cwd_len = 0;
-
 
496
    }
-
 
497
    cwd_dir = d;
-
 
498
    cwd_path = pc;
-
 
499
    cwd_len = pc_len;
-
 
500
    futex_up(&cwd_futex);
-
 
501
}
-
 
502
 
-
 
503
char *getcwd(char *buf, size_t size)
-
 
504
{
-
 
505
    if (!size)
-
 
506
        return NULL;
-
 
507
    futex_down(&cwd_futex);
-
 
508
    if (size < cwd_len + 1) {
-
 
509
        futex_up(&cwd_futex);
-
 
510
        return NULL;
-
 
511
    }
-
 
512
    strcpy(buf, cwd_path);
-
 
513
    futex_up(&cwd_futex);
-
 
514
    return buf;
-
 
515
}
-
 
516
 
381
/** @}
517
/** @}
382
 */
518
 */