32,7 → 32,8 |
/** @file |
*/ |
|
#include <vfs.h> |
#include <vfs/vfs.h> |
#include <vfs/canonify.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <dirent.h> |
49,8 → 50,45 |
#include "../../srv/vfs/vfs.h" |
|
int vfs_phone = -1; |
atomic_t vfs_phone_futex = FUTEX_INITIALIZER; |
futex_t vfs_phone_futex = FUTEX_INITIALIZER; |
|
futex_t cwd_futex = FUTEX_INITIALIZER; |
DIR *cwd_dir = NULL; |
char *cwd_path = NULL; |
size_t cwd_len = 0; |
|
static char *absolutize(const char *path) |
{ |
char *ncwd_path; |
|
futex_down(&cwd_futex); |
size_t len = strlen(path); |
if (*path != '/') { |
if (!cwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path = malloc(len + cwd_len + 1); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
strcpy(ncwd_path, cwd_path); |
ncwd_path[cwd_len] = '/'; |
ncwd_path[cwd_len + 1] = '\0'; |
} else { |
ncwd_path = malloc(len + 1); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path[0] = '\0'; |
} |
strcat(ncwd_path, path); |
futex_up(&cwd_futex); |
return ncwd_path; |
} |
|
static int vfs_connect(void) |
{ |
if (vfs_phone < 0) |
66,6 → 104,16 |
|
int dev_handle = 0; /* TODO */ |
|
char *mpa = absolutize(mp); |
if (!mpa) |
return ENOMEM; |
size_t mpc_len; |
char *mpc = canonify(mpa, &mpc_len); |
if (!mpc) { |
free(mpa); |
return EINVAL; |
} |
|
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
if (vfs_phone < 0) { |
73,6 → 121,7 |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return res; |
} |
} |
82,18 → 131,21 |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, (void *)mp, strlen(mp)); |
rc = ipc_data_write_start(vfs_phone, (void *)mpc, mpc_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
|
104,6 → 156,16 |
ipc_call_t answer; |
aid_t req; |
|
char *pa = absolutize(path); |
if (!pa) |
return ENOMEM; |
size_t pc_len; |
char *pc = canonify(pa, &pc_len); |
if (!pc) { |
free(pa); |
return EINVAL; |
} |
|
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
if (vfs_phone < 0) { |
111,20 → 173,23 |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer); |
rc = ipc_data_write_start(vfs_phone, path, strlen(path)); |
rc = ipc_data_write_start(vfs_phone, pc, pc_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return (int) IPC_GET_ARG1(answer); |
} |
|
314,6 → 379,16 |
ipcarg_t rc; |
aid_t req; |
|
char *pa = absolutize(path); |
if (!pa) |
return ENOMEM; |
size_t pc_len; |
char *pc = canonify(pa, &pc_len); |
if (!pc) { |
free(pa); |
return EINVAL; |
} |
|
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
if (vfs_phone < 0) { |
321,20 → 396,23 |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL); |
rc = ipc_data_write_start(vfs_phone, path, strlen(path)); |
rc = ipc_data_write_start(vfs_phone, pc, pc_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return EOK; |
} |
|
344,6 → 422,15 |
ipcarg_t rc; |
aid_t req; |
|
char *pa = absolutize(path); |
if (!pa) |
return ENOMEM; |
size_t pc_len; |
char *pc = canonify(pa, &pc_len); |
if (!pc) { |
free(pa); |
return EINVAL; |
} |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
if (vfs_phone < 0) { |
351,20 → 438,23 |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_0(vfs_phone, VFS_UNLINK, NULL); |
rc = ipc_data_write_start(vfs_phone, path, strlen(path)); |
rc = ipc_data_write_start(vfs_phone, pc, pc_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return EOK; |
} |
|
378,5 → 468,51 |
return _unlink(path, L_DIRECTORY); |
} |
|
int chdir(const char *path) |
{ |
char *pa = absolutize(path); |
if (!pa) |
return ENOMEM; |
size_t pc_len; |
char *pc = canonify(pa, &pc_len); |
if (!pc) { |
free(pa); |
return ENOENT; |
} |
|
DIR *d = opendir(pc); |
if (!d) { |
free(pa); |
return ENOENT; |
} |
|
futex_down(&cwd_futex); |
if (cwd_dir) { |
closedir(cwd_dir); |
cwd_dir = NULL; |
free(cwd_path); |
cwd_path = NULL; |
cwd_len = 0; |
} |
cwd_dir = d; |
cwd_path = pc; |
cwd_len = pc_len; |
futex_up(&cwd_futex); |
} |
|
char *getcwd(char *buf, size_t size) |
{ |
if (!size) |
return NULL; |
futex_down(&cwd_futex); |
if (size < cwd_len + 1) { |
futex_up(&cwd_futex); |
return NULL; |
} |
strcpy(buf, cwd_path); |
futex_up(&cwd_futex); |
return buf; |
} |
|
/** @} |
*/ |