Subversion Repositories HelenOS

Rev

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

Rev 4345 Rev 4348
Line 55... Line 55...
55
futex_t vfs_phone_futex = FUTEX_INITIALIZER;
55
futex_t vfs_phone_futex = FUTEX_INITIALIZER;
56
 
56
 
57
futex_t cwd_futex = FUTEX_INITIALIZER;
57
futex_t cwd_futex = FUTEX_INITIALIZER;
58
DIR *cwd_dir = NULL;
58
DIR *cwd_dir = NULL;
59
char *cwd_path = NULL;
59
char *cwd_path = NULL;
60
size_t cwd_len = 0;
60
size_t cwd_size = 0;
61
 
61
 
62
char *absolutize(const char *path, size_t *retlen)
62
char *absolutize(const char *path, size_t *retlen)
63
{
63
{
64
    char *ncwd_path;
64
    char *ncwd_path;
65
    char *ncwd_path_nc;
65
    char *ncwd_path_nc;
66
 
66
 
67
    futex_down(&cwd_futex);
67
    futex_down(&cwd_futex);
68
    size_t len = strlen(path);
68
    size_t size = str_size(path);
69
    if (*path != '/') {
69
    if (*path != '/') {
70
        if (!cwd_path) {
70
        if (!cwd_path) {
71
            futex_up(&cwd_futex);
71
            futex_up(&cwd_futex);
72
            return NULL;
72
            return NULL;
73
        }
73
        }
74
        ncwd_path_nc = malloc(cwd_len + 1 + len + 1);
74
        ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
75
        if (!ncwd_path_nc) {
75
        if (!ncwd_path_nc) {
76
            futex_up(&cwd_futex);
76
            futex_up(&cwd_futex);
77
            return NULL;
77
            return NULL;
78
        }
78
        }
79
        strcpy(ncwd_path_nc, cwd_path);
79
        str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path);
80
        ncwd_path_nc[cwd_len] = '/';
80
        ncwd_path_nc[cwd_size] = '/';
81
        ncwd_path_nc[cwd_len + 1] = '\0';
81
        ncwd_path_nc[cwd_size + 1] = '\0';
82
    } else {
82
    } else {
83
        ncwd_path_nc = malloc(len + 1);
83
        ncwd_path_nc = malloc(size + 1);
84
        if (!ncwd_path_nc) {
84
        if (!ncwd_path_nc) {
85
            futex_up(&cwd_futex);
85
            futex_up(&cwd_futex);
86
            return NULL;
86
            return NULL;
87
        }
87
        }
88
        ncwd_path_nc[0] = '\0';
88
        ncwd_path_nc[0] = '\0';
89
    }
89
    }
90
    strcat(ncwd_path_nc, path);
90
    str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path);
91
    ncwd_path = canonify(ncwd_path_nc, retlen);
91
    ncwd_path = canonify(ncwd_path_nc, retlen);
92
    if (!ncwd_path) {
92
    if (!ncwd_path) {
93
        futex_up(&cwd_futex);
93
        futex_up(&cwd_futex);
94
        free(ncwd_path_nc);
94
        free(ncwd_path_nc);
95
        return NULL;
95
        return NULL;
Line 97... Line 97...
97
    /*
97
    /*
98
     * We need to clone ncwd_path because canonify() works in-place and thus
98
     * We need to clone ncwd_path because canonify() works in-place and thus
99
     * the address in ncwd_path need not be the same as ncwd_path_nc, even
99
     * the address in ncwd_path need not be the same as ncwd_path_nc, even
100
     * though they both point into the same dynamically allocated buffer.
100
     * though they both point into the same dynamically allocated buffer.
101
     */
101
     */
102
    ncwd_path = strdup(ncwd_path);
102
    ncwd_path = str_dup(ncwd_path);
103
    free(ncwd_path_nc);
103
    free(ncwd_path_nc);
104
    if (!ncwd_path) {
104
    if (!ncwd_path) {
105
        futex_up(&cwd_futex);
105
        futex_up(&cwd_futex);
106
        return NULL;
106
        return NULL;
107
    }
107
    }
Line 130... Line 130...
130
   
130
   
131
    ipc_call_t answer;
131
    ipc_call_t answer;
132
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
132
    aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0,
133
        &answer);
133
        &answer);
134
   
134
   
135
    ipcarg_t retval = ipc_data_write_start(phone, name, strlen(name) + 1);
135
    ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);
136
   
136
   
137
    if (retval != EOK) {
137
    if (retval != EOK) {
138
        async_wait_for(req, NULL);
138
        async_wait_for(req, NULL);
139
        ipc_hangup(phone);
139
        ipc_hangup(phone);
140
        return retval;
140
        return retval;
Line 153... Line 153...
153
    ipc_hangup(phone);
153
    ipc_hangup(phone);
154
    return retval;
154
    return retval;
155
}
155
}
156
 
156
 
157
int mount(const char *fs_name, const char *mp, const char *dev,
157
int mount(const char *fs_name, const char *mp, const char *dev,
158
    const unsigned int flags)
158
    const char *opts, const unsigned int flags)
159
{
159
{
160
    int res;
160
    int res;
161
    ipcarg_t rc;
161
    ipcarg_t rc;
162
    aid_t req;
162
    aid_t req;
163
    dev_handle_t dev_handle;
163
    dev_handle_t dev_handle;
164
   
164
   
165
    res = device_get_handle(dev, &dev_handle, flags);
165
    res = device_get_handle(dev, &dev_handle, flags);
166
    if (res != EOK)
166
    if (res != EOK)
167
        return res;
167
        return res;
168
   
168
   
169
    size_t mpa_len;
169
    size_t mpa_size;
170
    char *mpa = absolutize(mp, &mpa_len);
170
    char *mpa = absolutize(mp, &mpa_size);
171
    if (!mpa)
171
    if (!mpa)
172
        return ENOMEM;
172
        return ENOMEM;
173
   
173
   
174
    futex_down(&vfs_phone_futex);
174
    futex_down(&vfs_phone_futex);
175
    async_serialize_start();
175
    async_serialize_start();
176
    vfs_connect();
176
    vfs_connect();
177
   
177
   
178
    req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL);
178
    req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL);
179
    rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_len);
179
    rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);
180
    if (rc != EOK) {
180
    if (rc != EOK) {
181
        async_wait_for(req, NULL);
181
        async_wait_for(req, NULL);
182
        async_serialize_end();
182
        async_serialize_end();
183
        futex_up(&vfs_phone_futex);
183
        futex_up(&vfs_phone_futex);
184
        free(mpa);
184
        free(mpa);
185
        return (int) rc;
185
        return (int) rc;
186
    }
186
    }
187
   
187
   
-
 
188
    rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));
-
 
189
    if (rc != EOK) {
-
 
190
        async_wait_for(req, NULL);
-
 
191
        async_serialize_end();
-
 
192
        futex_up(&vfs_phone_futex);
-
 
193
        free(mpa);
-
 
194
        return (int) rc;
-
 
195
    }
-
 
196
 
188
    rc = ipc_data_write_start(vfs_phone, (void *) fs_name, strlen(fs_name));
197
    rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
-
 
198
    if (rc != EOK) {
-
 
199
        async_wait_for(req, NULL);
-
 
200
        async_serialize_end();
-
 
201
        futex_up(&vfs_phone_futex);
-
 
202
        free(mpa);
-
 
203
        return (int) rc;
-
 
204
    }
-
 
205
 
-
 
206
    /* Ask VFS whether it likes fs_name. */
-
 
207
    rc = async_req_0_0(vfs_phone, IPC_M_PING);
189
    if (rc != EOK) {
208
    if (rc != EOK) {
190
        async_wait_for(req, NULL);
209
        async_wait_for(req, NULL);
191
        async_serialize_end();
210
        async_serialize_end();
192
        futex_up(&vfs_phone_futex);
211
        futex_up(&vfs_phone_futex);
193
        free(mpa);
212
        free(mpa);
Line 206... Line 225...
206
{
225
{
207
    ipcarg_t rc;
226
    ipcarg_t rc;
208
    ipc_call_t answer;
227
    ipc_call_t answer;
209
    aid_t req;
228
    aid_t req;
210
   
229
   
211
    size_t pa_len;
230
    size_t pa_size;
212
    char *pa = absolutize(path, &pa_len);
231
    char *pa = absolutize(path, &pa_size);
213
    if (!pa)
232
    if (!pa)
214
        return ENOMEM;
233
        return ENOMEM;
215
   
234
   
216
    futex_down(&vfs_phone_futex);
235
    futex_down(&vfs_phone_futex);
217
    async_serialize_start();
236
    async_serialize_start();
218
    vfs_connect();
237
    vfs_connect();
219
   
238
   
220
    req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
239
    req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer);
221
    rc = ipc_data_write_start(vfs_phone, pa, pa_len);
240
    rc = ipc_data_write_start(vfs_phone, pa, pa_size);
222
    if (rc != EOK) {
241
    if (rc != EOK) {
223
        async_wait_for(req, NULL);
242
        async_wait_for(req, NULL);
224
        async_serialize_end();
243
        async_serialize_end();
225
        futex_up(&vfs_phone_futex);
244
        futex_up(&vfs_phone_futex);
226
        free(pa);
245
        free(pa);
Line 382... Line 401...
382
int mkdir(const char *path, mode_t mode)
401
int mkdir(const char *path, mode_t mode)
383
{
402
{
384
    ipcarg_t rc;
403
    ipcarg_t rc;
385
    aid_t req;
404
    aid_t req;
386
   
405
   
387
    size_t pa_len;
406
    size_t pa_size;
388
    char *pa = absolutize(path, &pa_len);
407
    char *pa = absolutize(path, &pa_size);
389
    if (!pa)
408
    if (!pa)
390
        return ENOMEM;
409
        return ENOMEM;
391
   
410
   
392
    futex_down(&vfs_phone_futex);
411
    futex_down(&vfs_phone_futex);
393
    async_serialize_start();
412
    async_serialize_start();
394
    vfs_connect();
413
    vfs_connect();
395
   
414
   
396
    req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
415
    req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL);
397
    rc = ipc_data_write_start(vfs_phone, pa, pa_len);
416
    rc = ipc_data_write_start(vfs_phone, pa, pa_size);
398
    if (rc != EOK) {
417
    if (rc != EOK) {
399
        async_wait_for(req, NULL);
418
        async_wait_for(req, NULL);
400
        async_serialize_end();
419
        async_serialize_end();
401
        futex_up(&vfs_phone_futex);
420
        futex_up(&vfs_phone_futex);
402
        free(pa);
421
        free(pa);
Line 412... Line 431...
412
static int _unlink(const char *path, int lflag)
431
static int _unlink(const char *path, int lflag)
413
{
432
{
414
    ipcarg_t rc;
433
    ipcarg_t rc;
415
    aid_t req;
434
    aid_t req;
416
   
435
   
417
    size_t pa_len;
436
    size_t pa_size;
418
    char *pa = absolutize(path, &pa_len);
437
    char *pa = absolutize(path, &pa_size);
419
    if (!pa)
438
    if (!pa)
420
        return ENOMEM;
439
        return ENOMEM;
421
 
440
 
422
    futex_down(&vfs_phone_futex);
441
    futex_down(&vfs_phone_futex);
423
    async_serialize_start();
442
    async_serialize_start();
424
    vfs_connect();
443
    vfs_connect();
425
   
444
   
426
    req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
445
    req = async_send_0(vfs_phone, VFS_UNLINK, NULL);
427
    rc = ipc_data_write_start(vfs_phone, pa, pa_len);
446
    rc = ipc_data_write_start(vfs_phone, pa, pa_size);
428
    if (rc != EOK) {
447
    if (rc != EOK) {
429
        async_wait_for(req, NULL);
448
        async_wait_for(req, NULL);
430
        async_serialize_end();
449
        async_serialize_end();
431
        futex_up(&vfs_phone_futex);
450
        futex_up(&vfs_phone_futex);
432
        free(pa);
451
        free(pa);
Line 452... Line 471...
452
int rename(const char *old, const char *new)
471
int rename(const char *old, const char *new)
453
{
472
{
454
    ipcarg_t rc;
473
    ipcarg_t rc;
455
    aid_t req;
474
    aid_t req;
456
   
475
   
457
    size_t olda_len;
476
    size_t olda_size;
458
    char *olda = absolutize(old, &olda_len);
477
    char *olda = absolutize(old, &olda_size);
459
    if (!olda)
478
    if (!olda)
460
        return ENOMEM;
479
        return ENOMEM;
461
 
480
 
462
    size_t newa_len;
481
    size_t newa_size;
463
    char *newa = absolutize(new, &newa_len);
482
    char *newa = absolutize(new, &newa_size);
464
    if (!newa) {
483
    if (!newa) {
465
        free(olda);
484
        free(olda);
466
        return ENOMEM;
485
        return ENOMEM;
467
    }
486
    }
468
 
487
 
469
    futex_down(&vfs_phone_futex);
488
    futex_down(&vfs_phone_futex);
470
    async_serialize_start();
489
    async_serialize_start();
471
    vfs_connect();
490
    vfs_connect();
472
   
491
   
473
    req = async_send_0(vfs_phone, VFS_RENAME, NULL);
492
    req = async_send_0(vfs_phone, VFS_RENAME, NULL);
474
    rc = ipc_data_write_start(vfs_phone, olda, olda_len);
493
    rc = ipc_data_write_start(vfs_phone, olda, olda_size);
475
    if (rc != EOK) {
494
    if (rc != EOK) {
476
        async_wait_for(req, NULL);
495
        async_wait_for(req, NULL);
477
        async_serialize_end();
496
        async_serialize_end();
478
        futex_up(&vfs_phone_futex);
497
        futex_up(&vfs_phone_futex);
479
        free(olda);
498
        free(olda);
480
        free(newa);
499
        free(newa);
481
        return (int) rc;
500
        return (int) rc;
482
    }
501
    }
483
    rc = ipc_data_write_start(vfs_phone, newa, newa_len);
502
    rc = ipc_data_write_start(vfs_phone, newa, newa_size);
484
    if (rc != EOK) {
503
    if (rc != EOK) {
485
        async_wait_for(req, NULL);
504
        async_wait_for(req, NULL);
486
        async_serialize_end();
505
        async_serialize_end();
487
        futex_up(&vfs_phone_futex);
506
        futex_up(&vfs_phone_futex);
488
        free(olda);
507
        free(olda);
Line 497... Line 516...
497
    return rc;
516
    return rc;
498
}
517
}
499
 
518
 
500
int chdir(const char *path)
519
int chdir(const char *path)
501
{
520
{
502
    size_t pa_len;
521
    size_t pa_size;
503
    char *pa = absolutize(path, &pa_len);
522
    char *pa = absolutize(path, &pa_size);
504
    if (!pa)
523
    if (!pa)
505
        return ENOMEM;
524
        return ENOMEM;
506
 
525
 
507
    DIR *d = opendir(pa);
526
    DIR *d = opendir(pa);
508
    if (!d) {
527
    if (!d) {
Line 514... Line 533...
514
    if (cwd_dir) {
533
    if (cwd_dir) {
515
        closedir(cwd_dir);
534
        closedir(cwd_dir);
516
        cwd_dir = NULL;
535
        cwd_dir = NULL;
517
        free(cwd_path);
536
        free(cwd_path);
518
        cwd_path = NULL;
537
        cwd_path = NULL;
519
        cwd_len = 0;
538
        cwd_size = 0;
520
    }
539
    }
521
    cwd_dir = d;
540
    cwd_dir = d;
522
    cwd_path = pa;
541
    cwd_path = pa;
523
    cwd_len = pa_len;
542
    cwd_size = pa_size;
524
    futex_up(&cwd_futex);
543
    futex_up(&cwd_futex);
525
    return EOK;
544
    return EOK;
526
}
545
}
527
 
546
 
528
char *getcwd(char *buf, size_t size)
547
char *getcwd(char *buf, size_t size)
529
{
548
{
530
    if (!size)
549
    if (!size)
531
        return NULL;
550
        return NULL;
532
    futex_down(&cwd_futex);
551
    futex_down(&cwd_futex);
533
    if (size < cwd_len + 1) {
552
    if (size < cwd_size + 1) {
534
        futex_up(&cwd_futex);
553
        futex_up(&cwd_futex);
535
        return NULL;
554
        return NULL;
536
    }
555
    }
537
    strcpy(buf, cwd_path);
556
    str_cpy(buf, size, cwd_path);
538
    futex_up(&cwd_futex);
557
    futex_up(&cwd_futex);
539
    return buf;
558
    return buf;
540
}
559
}
541
 
560
 
542
/** @}
561
/** @}