Updated the code to reflect the changes in the VFS.
Fixed some bugs in fd.c (how many more bugs can be in a small file like this? :-). Added the syscalls for sys_open_dir(), and sys_create_dir(). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@209 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ea536d2ba4
commit
3b120ea240
@ -2,6 +2,7 @@
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include <kernel.h>
|
||||
#include <lock.h>
|
||||
@ -24,6 +25,7 @@ typedef struct bus {
|
||||
static bus *bus_list;
|
||||
static mutex bus_lock;
|
||||
|
||||
|
||||
int bus_man_init(kernel_args *ka)
|
||||
{
|
||||
mutex_init(&bus_lock, "bus_lock");
|
||||
@ -37,8 +39,8 @@ static bus *find_bus(const char *path)
|
||||
{
|
||||
bus *b;
|
||||
|
||||
for(b = bus_list; b != NULL; b = b->next) {
|
||||
if(!strcmp(b->path, path))
|
||||
for (b = bus_list; b != NULL; b = b->next) {
|
||||
if (!strcmp(b->path, path))
|
||||
break;
|
||||
}
|
||||
return b;
|
||||
@ -53,15 +55,15 @@ int bus_register_bus(const char *path)
|
||||
|
||||
mutex_lock(&bus_lock);
|
||||
|
||||
if(!find_bus(path)) {
|
||||
if (!find_bus(path)) {
|
||||
b = (bus *)kmalloc(sizeof(bus));
|
||||
if(b == NULL) {
|
||||
if (b == NULL) {
|
||||
err = ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
b->path = kmalloc(strlen(path)+1);
|
||||
if(b->path == NULL) {
|
||||
if (b->path == NULL) {
|
||||
err = ENOMEM;
|
||||
kfree(b);
|
||||
goto err;
|
||||
@ -80,51 +82,58 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bus_find_device_recurse(int *n, char *base_path, int base_fd, id_list *vendor_ids, id_list *device_ids)
|
||||
static int bus_find_device_recurse(int *n, char *base_path, int max_path_len, int base_fd, id_list *vendor_ids, id_list *device_ids)
|
||||
{
|
||||
char leaf[256];
|
||||
char buffer[sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1];
|
||||
struct dirent *dirent = (struct dirent *)buffer;
|
||||
int base_path_len = strlen(base_path);
|
||||
ssize_t len;
|
||||
int fd;
|
||||
int err;
|
||||
struct stat stat;
|
||||
|
||||
while((len = sys_read(base_fd, &leaf, -1, sizeof(leaf))) > 0) {
|
||||
// reset the base_path to the original string passed in
|
||||
base_path[base_path_len] = 0;
|
||||
while ((len = sys_read_dir(base_fd, dirent, sizeof(buffer), 1)) > 0) {
|
||||
int fd;
|
||||
|
||||
strlcat(base_path, leaf, sizeof(leaf));
|
||||
fd = sys_open(base_path, STREAM_TYPE_ANY, 0);
|
||||
if(fd < 0)
|
||||
// reset the base_path to the original string passed in
|
||||
base_path[base_path_len] = '\0';
|
||||
dirent->d_name[dirent->d_reclen] = '\0';
|
||||
strlcat(base_path, dirent->d_name, max_path_len);
|
||||
|
||||
err = sys_read_stat(base_path, &stat);
|
||||
if (err < 0)
|
||||
continue;
|
||||
err = sys_rstat(base_path, &stat);
|
||||
if(err < 0) {
|
||||
|
||||
if (S_ISDIR(stat.st_mode)) {
|
||||
fd = sys_open_dir(base_path);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
strlcat(base_path, "/", max_path_len);
|
||||
err = bus_find_device_recurse(n, base_path, max_path_len, fd, vendor_ids, device_ids);
|
||||
sys_close(fd);
|
||||
continue;
|
||||
}
|
||||
if(S_ISDIR(stat.st_mode)) {
|
||||
strcat(base_path, "/"); /* XXXfreston... this is unsafe!!!! */
|
||||
err = bus_find_device_recurse(n, base_path, fd, vendor_ids, device_ids);
|
||||
sys_close(fd);
|
||||
if(err >= 0)
|
||||
if (err >= 0)
|
||||
return err;
|
||||
continue;
|
||||
} else if(S_ISREG(stat.st_mode)) {
|
||||
} else if (S_ISREG(stat.st_mode)) {
|
||||
// we opened the device
|
||||
// XXX assumes PCI
|
||||
struct pci_cfg cfg;
|
||||
uint32 i, j;
|
||||
|
||||
fd = sys_open(base_path, 0);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg));
|
||||
if(err >= 0) {
|
||||
if (err >= 0) {
|
||||
// see if the vendor & device id matches
|
||||
for(i=0; i<vendor_ids->num_ids; i++) {
|
||||
if(cfg.vendor_id == vendor_ids->id[i]) {
|
||||
for(j=0; j<device_ids->num_ids; j++) {
|
||||
if(cfg.device_id == device_ids->id[j]) {
|
||||
for (i = 0; i < vendor_ids->num_ids; i++) {
|
||||
if (cfg.vendor_id == vendor_ids->id[i]) {
|
||||
for (j = 0; j < device_ids->num_ids; j++) {
|
||||
if (cfg.device_id == device_ids->id[j]) {
|
||||
// found it
|
||||
(*n)--;
|
||||
if(*n <= 0)
|
||||
if (*n <= 0)
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
@ -145,22 +154,22 @@ int bus_find_device(int n, id_list *vendor_ids, id_list *device_ids, device *dev
|
||||
bus *b;
|
||||
int err = -1;
|
||||
|
||||
for(b = bus_list; b != NULL && err < 0; b = b->next) {
|
||||
base_fd = sys_open(b->path, STREAM_TYPE_DIR, 0);
|
||||
if(base_fd < 0)
|
||||
for (b = bus_list; b != NULL && err < 0; b = b->next) {
|
||||
base_fd = sys_open_dir(b->path);
|
||||
if (base_fd < 0)
|
||||
continue;
|
||||
|
||||
strlcpy(path, b->path, sizeof(path));
|
||||
strlcat(path, "/", sizeof(path));
|
||||
fd = bus_find_device_recurse(&n, path, base_fd, vendor_ids, device_ids);
|
||||
if(fd >= 0) {
|
||||
fd = bus_find_device_recurse(&n, path, sizeof(path), base_fd, vendor_ids, device_ids);
|
||||
if (fd >= 0) {
|
||||
// we have a device!
|
||||
// XXX assumes pci
|
||||
struct pci_cfg cfg;
|
||||
int i;
|
||||
|
||||
err = sys_ioctl(fd, PCI_GET_CFG, &cfg, sizeof(struct pci_cfg));
|
||||
if(err >= 0) {
|
||||
if (err >= 0) {
|
||||
// copy the relevant data from the pci config to the more generic config
|
||||
memset(dev, 0, sizeof(device));
|
||||
dev->vendor_id = cfg.vendor_id;
|
||||
|
@ -68,7 +68,7 @@ int con_init(kernel_args *ka)
|
||||
{
|
||||
dprintf("con_init: entry\n");
|
||||
|
||||
console_fd = sys_open("/dev/console", STREAM_TYPE_DEVICE, 0);
|
||||
console_fd = sys_open("/dev/console", 0);
|
||||
dprintf("console_fd = %d\n", console_fd);
|
||||
|
||||
return 0;
|
||||
|
@ -501,7 +501,7 @@ int elf_load_uspace(const char *path, struct proc *p, int flags, addr *entry)
|
||||
|
||||
dprintf("elf_load: entry path '%s', proc %p\n", path, p);
|
||||
|
||||
fd = sys_open(path, STREAM_TYPE_FILE, 0);
|
||||
fd = sys_open(path, 0);
|
||||
if(fd < 0)
|
||||
return fd;
|
||||
|
||||
@ -669,7 +669,7 @@ image_id elf_load_kspace(const char *path, const char *sym_prepend)
|
||||
|
||||
// dprintf("elf_load_kspace: entry path '%s'\n", path);
|
||||
|
||||
fd = sys_open(path, STREAM_TYPE_FILE, 0);
|
||||
fd = sys_open(path, 0);
|
||||
if(fd < 0)
|
||||
return fd;
|
||||
|
||||
@ -907,7 +907,7 @@ int elf_unload_kspace( const char *path )
|
||||
void *vnode;
|
||||
struct elf_image_info *image;
|
||||
|
||||
fd = sys_open(path, STREAM_TYPE_FILE, 0);
|
||||
fd = sys_open(path, 0);
|
||||
if(fd < 0)
|
||||
return fd;
|
||||
|
||||
|
@ -37,7 +37,7 @@ alloc_fd(void)
|
||||
struct file_descriptor *f;
|
||||
|
||||
f = kmalloc(sizeof(struct file_descriptor));
|
||||
if(f) {
|
||||
if (f) {
|
||||
f->vnode = NULL;
|
||||
f->cookie = NULL;
|
||||
f->ref_count = 1;
|
||||
@ -185,6 +185,26 @@ user_write(int fd, const void *buffer, off_t pos, size_t length)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_seek(int fd, off_t pos, int seek_type)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
int status;
|
||||
|
||||
descriptor = get_fd(get_current_io_context(false), fd);
|
||||
if (!descriptor)
|
||||
return EBADF;
|
||||
|
||||
if (descriptor->ops->fd_seek)
|
||||
status = descriptor->ops->fd_seek(descriptor, pos, seek_type);
|
||||
else
|
||||
status = EOPNOTSUPP;
|
||||
|
||||
put_fd(descriptor);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
user_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
@ -204,6 +224,7 @@ user_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
else
|
||||
status = EOPNOTSUPP;
|
||||
|
||||
put_fd(descriptor);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -364,6 +385,26 @@ sys_write(int fd, const void *buffer, off_t pos, size_t length)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_seek(int fd, off_t pos, int seek_type)
|
||||
{
|
||||
struct file_descriptor *descriptor;
|
||||
int status;
|
||||
|
||||
descriptor = get_fd(get_current_io_context(true), fd);
|
||||
if (!descriptor)
|
||||
return EBADF;
|
||||
|
||||
if (descriptor->ops->fd_seek)
|
||||
status = descriptor->ops->fd_seek(descriptor, pos, seek_type);
|
||||
else
|
||||
status = EOPNOTSUPP;
|
||||
|
||||
put_fd(descriptor);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sys_ioctl(int fd, ulong op, void *buffer, size_t length)
|
||||
{
|
||||
@ -396,7 +437,7 @@ sys_read_dir(int fd, struct dirent *buffer,size_t bufferSize,uint32 maxCount)
|
||||
|
||||
PRINT(("sys_read_dir(fd = %d, buffer = 0x%p, bufferSize = %ld, count = %u)\n",fd,buffer,bufferSize,maxCount));
|
||||
|
||||
descriptor = get_fd(get_current_io_context(false), fd);
|
||||
descriptor = get_fd(get_current_io_context(true), fd);
|
||||
if (descriptor == NULL)
|
||||
return EBADF;
|
||||
|
||||
@ -421,7 +462,7 @@ sys_rewind_dir(int fd)
|
||||
|
||||
PRINT(("user_rewind_dir(fd = %d)\n",fd));
|
||||
|
||||
descriptor = get_fd(get_current_io_context(false), fd);
|
||||
descriptor = get_fd(get_current_io_context(true), fd);
|
||||
if (descriptor == NULL)
|
||||
return EBADF;
|
||||
|
||||
|
@ -426,8 +426,8 @@ static int recurse_directory(const char *path, const char *match)
|
||||
int res = 0, dir;
|
||||
int bufferSize = sizeof(struct dirent) + SYS_MAX_NAME_LEN + 1;
|
||||
struct dirent *dirent;
|
||||
|
||||
if ((dir = sys_open(path, STREAM_TYPE_DIR, 0)) < 0)
|
||||
|
||||
if ((dir = sys_open_dir(path)) < 0)
|
||||
return -1;
|
||||
|
||||
dirent = kmalloc(bufferSize);
|
||||
@ -453,7 +453,7 @@ static int recurse_directory(const char *path, const char *match)
|
||||
strlcat(newpath, "/", slen);
|
||||
strlcat(newpath, dirent->d_name, slen);
|
||||
|
||||
if ((res = sys_rstat(newpath, &stat)) != B_NO_ERROR) {
|
||||
if ((res = sys_read_stat(newpath, &stat)) != B_NO_ERROR) {
|
||||
kfree(newpath);
|
||||
break;
|
||||
}
|
||||
@ -663,25 +663,25 @@ static inline int module_create_dir_iterator( module_iterator *iter, int file, c
|
||||
|
||||
static inline int module_enter_dir(module_iterator *iter, const char *path)
|
||||
{
|
||||
int file;
|
||||
int dir;
|
||||
int res;
|
||||
|
||||
file = sys_open( path, STREAM_TYPE_DIR, 0 );
|
||||
if (file < 0 ) {
|
||||
SHOW_FLOW( 3, "couldn't open directory %s (%s)\n", path, strerror( file ));
|
||||
|
||||
dir = sys_open_dir(path);
|
||||
if (dir < 0 ) {
|
||||
SHOW_FLOW(3, "couldn't open directory %s (%s)\n", path, strerror(dir));
|
||||
|
||||
// there are so many errors for "not found" that we don't bother
|
||||
// and always assume that the directory suddenly disappeared
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
res = module_create_dir_iterator(iter, file, path);
|
||||
res = module_create_dir_iterator(iter, dir, path);
|
||||
if (res != B_NO_ERROR) {
|
||||
sys_close(file);
|
||||
sys_close(dir);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
SHOW_FLOW( 3, "entered directory %s\n", path );
|
||||
|
||||
SHOW_FLOW(3, "entered directory %s\n", path);
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -779,8 +779,8 @@ static inline int module_traverse_dir(module_iterator *iter)
|
||||
|
||||
SHOW_FLOW( 3, "got %s\n", name );
|
||||
|
||||
if (strcmp( name, "." ) == 0 ||
|
||||
strcmp( name, ".." ) == 0 )
|
||||
if (strcmp(name, ".") == 0 ||
|
||||
strcmp(name, "..") == 0 )
|
||||
return B_NO_ERROR;
|
||||
|
||||
/* currently, sys_read returns an error if buffer is too small
|
||||
@ -796,7 +796,7 @@ static inline int module_traverse_dir(module_iterator *iter)
|
||||
iter->cur_header = NULL;
|
||||
iter->module_pos = 0;
|
||||
|
||||
if ((res = sys_rstat(path, &stat)) != B_NO_ERROR )
|
||||
if ((res = sys_read_stat(path, &stat)) != B_NO_ERROR)
|
||||
return res;
|
||||
|
||||
if (S_ISREG(stat.st_mode)) {
|
||||
|
@ -61,7 +61,7 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
*call_ret = user_sync();
|
||||
break;
|
||||
case SYSCALL_OPEN:
|
||||
*call_ret = user_open((const char *)arg0, (stream_type)arg1, (int)arg2);
|
||||
*call_ret = user_open((const char *)arg0, (int)arg1);
|
||||
break;
|
||||
case SYSCALL_CLOSE:
|
||||
*call_ret = user_close((int)arg0);
|
||||
@ -78,6 +78,9 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
case SYSCALL_SEEK:
|
||||
*call_ret = user_seek((int)arg0, (off_t)INT32TOINT64(arg1, arg2), (int)arg3);
|
||||
break;
|
||||
case SYSCALL_OPEN_DIR:
|
||||
*call_ret = user_open_dir((const char *)arg0);
|
||||
break;
|
||||
case SYSCALL_READ_DIR:
|
||||
*call_ret = user_read_dir((int)arg0, (struct dirent *)arg1, (size_t)arg2, (uint32)arg3);
|
||||
break;
|
||||
@ -88,7 +91,10 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
*call_ret = user_ioctl((int)arg0, (ulong)arg1, (void *)arg2, (size_t)arg3);
|
||||
break;
|
||||
case SYSCALL_CREATE:
|
||||
*call_ret = user_create((const char *)arg0, (stream_type)arg1);
|
||||
*call_ret = user_create((const char *)arg0, (int)arg1, (int)arg2);
|
||||
break;
|
||||
case SYSCALL_CREATE_DIR:
|
||||
*call_ret = user_create_dir((const char *)arg0, (int)arg1);
|
||||
break;
|
||||
case SYSCALL_UNLINK:
|
||||
*call_ret = user_unlink((const char *)arg0);
|
||||
@ -97,13 +103,13 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re
|
||||
*call_ret = user_rename((const char *)arg0, (const char *)arg1);
|
||||
break;
|
||||
case SYSCALL_RSTAT:
|
||||
*call_ret = user_rstat((const char *)arg0, (struct stat *)arg1);
|
||||
*call_ret = user_read_stat((const char *)arg0, (struct stat *)arg1);
|
||||
break;
|
||||
case SYSCALL_FSTAT:
|
||||
*call_ret = user_fstat((int)arg0, (struct stat*)arg1);
|
||||
break;
|
||||
case SYSCALL_WSTAT:
|
||||
*call_ret = user_wstat((const char *)arg0, (struct stat *)arg1, (int)arg2);
|
||||
*call_ret = user_write_stat((const char *)arg0, (struct stat *)arg1, (int)arg2);
|
||||
break;
|
||||
case SYSCALL_SYSTEM_TIME:
|
||||
*call_ret = system_time();
|
||||
|
@ -2,6 +2,7 @@
|
||||
** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
** Distributed under the terms of the NewOS License.
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <vm.h>
|
||||
#include <memheap.h>
|
||||
@ -41,12 +42,12 @@ static int vnode_has_page(struct vm_store *store, off_t offset)
|
||||
|
||||
static ssize_t vnode_read(struct vm_store *store, off_t offset, iovecs *vecs)
|
||||
{
|
||||
return vfs_readpage(STORE_DATA(store)->vn, vecs, offset);
|
||||
return vfs_read_page(STORE_DATA(store)->vn, vecs, offset);
|
||||
}
|
||||
|
||||
static ssize_t vnode_write(struct vm_store *store, off_t offset, iovecs *vecs)
|
||||
{
|
||||
return vfs_writepage(STORE_DATA(store)->vn, vecs, offset);
|
||||
return vfs_write_page(STORE_DATA(store)->vn, vecs, offset);
|
||||
}
|
||||
|
||||
/* unused
|
||||
|
@ -195,7 +195,7 @@ void vm_test()
|
||||
// char *blah;
|
||||
int fd;
|
||||
|
||||
fd = sys_open("/boot/kernel", STREAM_TYPE_FILE, 0);
|
||||
fd = sys_open("/boot/kernel", 0);
|
||||
|
||||
rid = vm_map_file(vm_get_kernel_aspace_id(), "mmap_test", &ptr, REGION_ADDR_ANY_ADDRESS,
|
||||
PAGE_SIZE, LOCK_RW|LOCK_KERNEL, REGION_NO_PRIVATE_MAP, "/boot/kernel", 0);
|
||||
|
Loading…
Reference in New Issue
Block a user