Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2762 → Rev 2763

/trunk/uspace/lib/libfs/libfs.c
141,6 → 141,7
unsigned last = IPC_GET_ARG2(*request);
int dev_handle = IPC_GET_ARG3(*request);
int lflag = IPC_GET_ARG4(*request);
int index = IPC_GET_ARG5(*request); /* when L_LINK specified */
 
if (last < next)
last += PLB_SIZE;
180,21 → 181,34
 
/* handle miss: match amongst siblings */
if (!tmp) {
if ((next > last) && (lflag & L_CREATE)) {
/* no components left and L_CREATE specified */
if (next <= last) {
/* there are unprocessed components */
ipc_answer_0(rid, ENOENT);
return;
}
/* miss in the last component */
if (lflag & (L_CREATE | L_LINK)) {
/* request to create a new link */
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
}
void *nodep = ops->create(lflag);
}
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle,
dev_handle, index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
ops->destroy(nodep);
if (lflag & L_CREATE)
ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep), 0,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
}
} else {
201,7 → 215,12
ipc_answer_0(rid, ENOSPC);
}
return;
}
} else if (lflag & L_PARENT) {
/* return parent */
ipc_answer_5(rid, EOK, fs_handle, dev_handle,
ops->index_get(cur), ops->size_get(cur),
ops->lnkcnt_get(cur));
}
ipc_answer_0(rid, ENOENT);
return;
}
214,7 → 233,7
 
/* handle miss: excessive components */
if (!tmp && next <= last) {
if (lflag & L_CREATE) {
if (lflag & (L_CREATE | L_LINK)) {
if (!ops->is_directory(cur)) {
ipc_answer_0(rid, ENOTDIR);
return;
239,15 → 258,22
component[len] = '\0';
len = 0;
void *nodep = ops->create(lflag);
void *nodep;
if (lflag & L_CREATE)
nodep = ops->create(lflag);
else
nodep = ops->node_get(fs_handle, dev_handle,
index);
if (nodep) {
if (!ops->link(cur, nodep, component)) {
ops->destroy(nodep);
if (lflag & L_CREATE)
ops->destroy(nodep);
ipc_answer_0(rid, ENOSPC);
} else {
ipc_answer_5(rid, EOK,
fs_handle, dev_handle,
ops->index_get(nodep), 0,
ops->index_get(nodep),
ops->size_get(nodep),
ops->lnkcnt_get(nodep));
}
} else {
260,7 → 286,14
}
 
/* handle hit */
if (lflag & L_DESTROY) {
if (lflag & L_PARENT) {
cur = par;
if (!cur) {
ipc_answer_0(rid, ENOENT);
return;
}
}
if (lflag & L_UNLINK) {
unsigned old_lnkcnt = ops->lnkcnt_get(cur);
int res = ops->unlink(par, cur);
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
267,7 → 300,8
ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
return;
}
if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
(lflag & L_LINK)) {
ipc_answer_0(rid, EEXIST);
return;
}
/trunk/uspace/lib/libfs/libfs.h
43,6 → 43,7
 
typedef struct {
bool (* match)(void *, void *, const char *);
void * (* node_get)(int, int, unsigned long);
void * (* create)(int);
void (* destroy)(void *);
bool (* link)(void *, void *, const char *);
/trunk/uspace/lib/libc/include/stdio.h
67,6 → 67,8
 
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__)
 
extern int rename(const char *, const char *);
 
#endif
 
/** @}
/trunk/uspace/lib/libc/generic/vfs/vfs.c
468,6 → 468,73
return _unlink(path, L_DIRECTORY);
}
 
int rename(const char *old, const char *new)
{
int res;
ipcarg_t rc;
aid_t req;
char *olda = absolutize(old);
if (!olda)
return ENOMEM;
size_t oldc_len;
char *oldc = canonify(olda, &oldc_len);
if (!oldc) {
free(olda);
return EINVAL;
}
char *newa = absolutize(new);
if (!newa) {
free(olda);
return ENOMEM;
}
size_t newc_len;
char *newc = canonify(newa, &newc_len);
if (!newc) {
free(olda);
free(newa);
return EINVAL;
}
 
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
free(olda);
free(newa);
return res;
}
}
req = async_send_0(vfs_phone, VFS_RENAME, NULL);
rc = ipc_data_write_start(vfs_phone, oldc, oldc_len);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(olda);
free(newa);
return (int) rc;
}
rc = ipc_data_write_start(vfs_phone, newc, newc_len);
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(olda);
free(newa);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
free(olda);
free(newa);
return rc;
}
 
int chdir(const char *path)
{
char *pa = absolutize(path);