* Write buffers should be const.

* Added sys_stat_attr().
* Added sys_open_attr_dir(). Extended the directory functions to be able
  to deal with attribute directories.
* Init the current directory, so we can use it (the support is there
  already).
* Use our open modes instead of the platform ones.
* Added O_NOTRAVERSE support to sys_open().


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2005-03-05 20:45:45 +00:00
parent e19f027e30
commit c5126c5985
2 changed files with 254 additions and 130 deletions
@@ -36,7 +36,7 @@
#include <sys/stat.h>
#define OMODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
#define OMODE_MASK (MY_O_RDONLY | MY_O_WRONLY | MY_O_RDWR)
#define SLEEP_TIME (10000.0)
#define MAX_SYM_LINKS 16
@@ -48,8 +48,9 @@
#define FD_FILE 1
#define FD_DIR 2
#define FD_WD 4
#define FD_ATTR_DIR 8
#define FD_ALL (FD_FILE | FD_DIR | FD_WD)
#define FD_ALL (FD_FILE | FD_DIR | FD_WD | FD_ATTR_DIR)
#define DEFAULT_FD_NUM (128)
#define VNNUM 256
@@ -171,6 +172,7 @@ int sys_rstat(bool kernel, int fd, const char *path,
struct my_stat *st, bool eatlink);
static fsystem * inc_file_system(const char *name);
static int dec_file_system(fsystem *fs);
static ioctx * get_cur_ioctx(void);
static int get_dir_fd(bool kernel, int fd, const char *path, char *filename,
vnode **dvn);
@@ -474,6 +476,7 @@ init_vnode_layer(void)
nspace *ns;
void *data;
extern vnode_ops rootfs; /* XXXdbg */
ioctx *io;
/*
compute vnnum based on memsize. 256 vnodes with 8MB.
@@ -565,6 +568,11 @@ init_vnode_layer(void)
ns->root = lookup_vnode(ns->nsid, vnid);
rootvn = ns->root;
// set cwd to "/"
io = get_cur_ioctx();
inc_vnode(rootvn);
io->cwd = rootvn;
#ifndef USER
#ifdef DEBUG
@@ -880,7 +888,7 @@ error1:
int
sys_closedir(bool kernel, int fd)
{
return remove_fd(kernel, fd, FD_DIR);
return remove_fd(kernel, fd, FD_DIR | FD_ATTR_DIR);
}
/*
@@ -901,15 +909,20 @@ sys_readdir(bool kernel, int fd, struct my_dirent *buf, size_t bufsize,
vnode_id vnid;
long nm;
f = get_fd(kernel, fd, FD_DIR);
f = get_fd(kernel, fd, FD_DIR | FD_ATTR_DIR);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
nm = count;
err = (*vn->ns->fs->ops.readdir)(vn->ns->data, vn->data, f->cookie,
&nm, buf, bufsize);
if (f->type == FD_DIR) {
err = (*vn->ns->fs->ops.readdir)(vn->ns->data, vn->data, f->cookie,
&nm, buf, bufsize);
} else {
err = (*vn->ns->fs->ops.read_attrdir)(vn->ns->data, vn->data, f->cookie,
&nm, buf, bufsize);
}
if (err)
goto error1;
@@ -922,23 +935,25 @@ sys_readdir(bool kernel, int fd, struct my_dirent *buf, size_t bufsize,
patch the mount points and the root.
*/
LOCK(vnlock);
nsid = vn->ns->nsid;
p = buf;
for(i=0; i<nm; i++) {
if (is_mount_vnid(nsid, p->d_ino, &vnid))
p->d_ino = vnid;
if (vn->ns->mount && !strcmp(p->d_name, "..")) {
UNLOCK(vnlock);
err = sys_rstat(kernel, fd, "..", &st, FALSE);
if (err)
goto error2;
LOCK(vnlock);
p->d_ino = st.ino;
}
p = (struct my_dirent *) ((char *) p + p->d_reclen);
}
UNLOCK(vnlock);
if (f->type == FD_DIR) {
LOCK(vnlock);
nsid = vn->ns->nsid;
p = buf;
for(i=0; i<nm; i++) {
if (is_mount_vnid(nsid, p->d_ino, &vnid))
p->d_ino = vnid;
if (vn->ns->mount && !strcmp(p->d_name, "..")) {
UNLOCK(vnlock);
err = sys_rstat(kernel, fd, "..", &st, FALSE);
if (err)
goto error2;
LOCK(vnlock);
p->d_ino = st.ino;
}
p = (struct my_dirent *) ((char *) p + p->d_reclen);
}
UNLOCK(vnlock);
}
put_fd(f);
return nm;
@@ -961,11 +976,16 @@ sys_rewinddir(bool kernel, int fd)
int err;
vnode *vn;
f = get_fd(kernel, fd, FD_DIR);
f = get_fd(kernel, fd, FD_DIR | FD_ATTR_DIR);
if (!f)
return FS_EBADF;
vn = f->vn;
err = (*vn->ns->fs->ops.rewinddir)(vn->ns->data, vn->data, f->cookie);
if (f->type == FD_DIR) {
err = (*vn->ns->fs->ops.rewinddir)(vn->ns->data, vn->data, f->cookie);
} else {
err = (*vn->ns->fs->ops.rewind_attrdir)(vn->ns->data, vn->data,
f->cookie);
}
put_fd(f);
return err;
}
@@ -990,7 +1010,7 @@ sys_open(bool kernel, int fd, const char *path, int omode, int perms,
op_open *opo;
op_free_cookie *opf;
if (omode & O_CREAT) {
if (omode & MY_O_CREAT) {
err = get_dir_fd(kernel, fd, path, filename, &dvn);
if (err)
goto errorA;
@@ -1009,7 +1029,7 @@ sys_open(bool kernel, int fd, const char *path, int omode, int perms,
dec_vnode(dvn, FALSE);
} else {
err = get_file_fd(kernel, fd, path, TRUE, &vn);
err = get_file_fd(kernel, fd, path, !(omode & MY_O_NOTRAVERSE), &vn);
if (err)
goto error1;
opo = vn->ns->fs->ops.open;
@@ -1055,7 +1075,7 @@ error3:
opf = vn->ns->fs->ops.free_cookie;
if (opf)
(*opf)(vn->ns->data, vn->data, cookie);
if (omode & O_CREAT)
if (omode & MY_O_CREAT)
goto errorC;
error2:
dec_vnode(vn, FALSE);
@@ -1170,11 +1190,11 @@ sys_lseek(bool kernel, int fd, fs_off_t pos, int whence)
goto error1;
}
switch(whence) {
case SEEK_SET:
case MY_SEEK_SET:
f->pos = pos;
break;
case SEEK_CUR:
if ((f->omode & O_APPEND) == 0)
case MY_SEEK_CUR:
if ((f->omode & MY_O_APPEND) == 0)
f->pos += pos;
else { /* we're in append mode so ask where the EOF is */
vn = f->vn;
@@ -1191,7 +1211,7 @@ sys_lseek(bool kernel, int fd, fs_off_t pos, int whence)
break;
}
break;
case SEEK_END:
case MY_SEEK_END:
vn = f->vn;
op = vn->ns->fs->ops.rstat;
if (!op) {
@@ -1245,7 +1265,7 @@ sys_read(bool kernel, int fd, void *buf, size_t len)
err = FS_EBADF;
goto error1;
}
if ((f->omode & OMODE_MASK) == O_WRONLY) {
if ((f->omode & OMODE_MASK) == MY_O_WRONLY) {
err = FS_EBADF;
goto error2;
}
@@ -1279,7 +1299,7 @@ error1:
*/
ssize_t
sys_write(bool kernel, int fd, void *buf, size_t len)
sys_write(bool kernel, int fd, const void *buf, size_t len)
{
ofile *f;
int err;
@@ -1291,7 +1311,7 @@ sys_write(bool kernel, int fd, void *buf, size_t len)
err = FS_EBADF;
goto error1;
}
if ((f->omode & OMODE_MASK) == O_RDONLY) {
if ((f->omode & OMODE_MASK) == MY_O_RDONLY) {
err = FS_EBADF;
goto error2;
}
@@ -1319,96 +1339,6 @@ error1:
}
ssize_t
sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos)
{
ofile *f;
int err;
vnode *vn;
size_t sz;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
sz = len;
err = (*vn->ns->fs->ops.read_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos);
if (err)
goto error2;
put_fd(f);
return sz;
error2:
put_fd(f);
error1:
return err;
}
ssize_t
sys_write_attr(bool kernel, int fd, const char *name,int type,void *buffer, size_t len, off_t pos)
{
ofile *f;
int err;
vnode *vn;
size_t sz;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
sz = len;
err = (*vn->ns->fs->ops.write_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos);
if (err)
goto error2;
put_fd(f);
return sz;
error2:
put_fd(f);
error1:
return err;
}
ssize_t
sys_remove_attr(bool kernel, int fd, const char *name)
{
ofile *f;
int err;
vnode *vn;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
err = (*vn->ns->fs->ops.remove_attr)(vn->ns->data, vn->data, name);
if (err)
goto error2;
put_fd(f);
return 0;
error2:
put_fd(f);
error1:
return err;
}
/*
* sys_ioctl
*/
@@ -1781,6 +1711,188 @@ add_nspace(nspace *ns, fsystem *fs, const char *fileSystem, dev_t dev, ino_t ino
}
int
sys_open_attr_dir(bool kernel, int fd, const char *path)
{
int err;
op_open_attrdir *op;
op_free_cookie *opf;
ofile *f;
int nfd;
vnode *vn;
void *cookie;
err = get_file_fd(kernel, fd, path, TRUE, &vn);
if (err)
goto error1;
op = vn->ns->fs->ops.open_attrdir;
if (!op) {
err = FS_EINVAL;
goto error2;
}
err = (*op)(vn->ns->data, vn->data, &cookie);
if (err)
goto error2;
/*
find a file descriptor
*/
f = (ofile *) calloc(sizeof(ofile), 1);
if (!f) {
err = FS_ENOMEM;
goto error3;
}
f->type = FD_ATTR_DIR;
f->vn = vn;
f->cookie = cookie;
f->rcnt = 0;
f->ocnt = 0;
nfd = new_fd(kernel, -1, f, -1, TRUE);
if (nfd < 0) {
err = FS_EMFILE;
goto error4;
}
return nfd;
error4:
free(f);
error3:
(*vn->ns->fs->ops.close_attrdir)(vn->ns->data, vn->data, cookie);
opf = vn->ns->fs->ops.free_attrdircookie;
if (opf)
(*opf)(vn->ns->data, vn->data, cookie);
error2:
dec_vnode(vn, FALSE);
error1:
return err;
}
ssize_t
sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos)
{
ofile *f;
int err;
vnode *vn;
size_t sz;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
sz = len;
err = (*vn->ns->fs->ops.read_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos);
if (err)
goto error2;
put_fd(f);
return sz;
error2:
put_fd(f);
error1:
return err;
}
ssize_t
sys_write_attr(bool kernel, int fd, const char *name,int type,
const void *buffer, size_t len, off_t pos)
{
ofile *f;
int err;
vnode *vn;
size_t sz;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
sz = len;
err = (*vn->ns->fs->ops.write_attr)(vn->ns->data, vn->data, name, type, buffer, &sz, pos);
if (err)
goto error2;
put_fd(f);
return sz;
error2:
put_fd(f);
error1:
return err;
}
ssize_t
sys_remove_attr(bool kernel, int fd, const char *name)
{
ofile *f;
int err;
vnode *vn;
f = get_fd(kernel, fd, FD_FILE);
if (!f) {
err = FS_EBADF;
goto error1;
}
vn = f->vn;
err = (*vn->ns->fs->ops.remove_attr)(vn->ns->data, vn->data, name);
if (err)
goto error2;
put_fd(f);
return 0;
error2:
put_fd(f);
error1:
return err;
}
int
sys_stat_attr(bool kernel, int fd, const char *path, const char *name,
my_attr_info *info)
{
int err;
vnode *vn;
op_stat_attr *op;
err = get_file_fd(kernel, fd, path, TRUE, &vn);
if (err)
goto error1;
op = vn->ns->fs->ops.stat_attr;
if (!op) {
err = FS_EINVAL;
goto error2;
}
err = (*op)(vn->ns->data, vn->data, name, info);
if (err)
goto error2;
dec_vnode(vn, FALSE);
return 0;
error2:
dec_vnode(vn, FALSE);
error1:
return err;
}
/*
* sys_mount
*/
@@ -2986,7 +3098,7 @@ remove_fd(bool kernel, int fd, int type)
LOCK(fds->lock);
if ((fd >= 0) && (fd < fds->num) && fds->fds[fd]) {
f = fds->fds[fd];
if (f->type == type) {
if (f->type & type) {
SETBIT(fds->alloc, fd, 0);
fds->fds[fd] = NULL;
} else
@@ -3094,6 +3206,10 @@ invoke_close(ofile *f)
case FD_DIR:
err = (*vn->ns->fs->ops.closedir)(vn->ns->data, vn->data, f->cookie);
break;
case FD_ATTR_DIR:
err = (*vn->ns->fs->ops.close_attrdir)(vn->ns->data, vn->data,
f->cookie);
break;
case FD_WD:
default:
err = 0;
@@ -3119,6 +3235,9 @@ invoke_free(ofile *f)
case FD_WD:
op = NULL;
break;
case FD_ATTR_DIR:
op = vn->ns->fs->ops.free_attrdircookie;
break;
}
if (op)
(*op)(vn->ns->data, vn->data, f->cookie);
@@ -20,7 +20,7 @@ int sys_open_entry_ref(bool kernel, nspace_id device, vnode_id parent,
int sys_close(bool kernel, int fd);
fs_off_t sys_lseek(bool kernel, int fd, fs_off_t pos, int whence);
ssize_t sys_read(bool kernel, int fd, void *buf, size_t len);
ssize_t sys_write(bool kernel, int fd, void *buf, size_t len);
ssize_t sys_write(bool kernel, int fd, const void *buf, size_t len);
int sys_unlink(bool kernel, int fd, const char *path);
int sys_link(bool kernel, int ofd, const char *oldpath, int nfd,
const char *newpath);
@@ -47,10 +47,15 @@ int sys_access(bool kernel, int fd, const char *path, int mode);
int sys_sync(void);
ssize_t sys_read_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos);
ssize_t sys_write_attr(bool kernel, int fd, const char *name, int type, void *buffer, size_t len, off_t pos);
int sys_open_attr_dir(bool kernel, int fd, const char *path);
ssize_t sys_read_attr(bool kernel, int fd, const char *name, int type,
void *buffer, size_t len, off_t pos);
ssize_t sys_write_attr(bool kernel, int fd, const char *name, int type,
const void *buffer, size_t len, off_t pos);
ssize_t sys_remove_attr(bool kernel, int fd, const char *name);
int sys_stat_attr(bool kernel, int fd, const char *path, const char *name,
my_attr_info *info);
int sys_open_query(bool kernel, int fd, const char *path, const char *query, ulong flags, port_id port, ulong token, void **cookie);
int sys_close_query(bool kernel, int fd, const char *path, void *cookie);
int sys_read_query(bool kernel, int fd, const char *path, void *cookie, struct my_dirent *dent,size_t bufferSize,long num);