Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2754 → Rev 2755

/trunk/uspace/lib/libc/generic/vfs/vfs.c
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;
}
 
/** @}
*/