add readdir
This commit is contained in:
parent
f108a3613f
commit
a834155cce
5 changed files with 101 additions and 41 deletions
106
fs/initrd.c
106
fs/initrd.c
|
@ -57,51 +57,86 @@ typedef struct {
|
|||
|
||||
static ssize_t initrd_read(fildes_t* file, uint8_t* buffer, size_t size)
|
||||
{
|
||||
uint32_t i, pos = 0, found = 0;
|
||||
off_t offset = 0;
|
||||
char* data = NULL;
|
||||
vfs_node_t* node = file->node;
|
||||
block_list_t* blist = &node->block_list;
|
||||
|
||||
if (file->flags & O_WRONLY)
|
||||
return -EACCES;
|
||||
if (node->type != FS_DIRECTORY) {
|
||||
/*********** The original read function ****************/
|
||||
uint32_t i, pos = 0, found = 0;
|
||||
off_t offset = 0;
|
||||
char* data = NULL;
|
||||
block_list_t* blist = &node->block_list;
|
||||
|
||||
/* init the tmp offset */
|
||||
offset = file->offset;
|
||||
if (file->flags & O_WRONLY)
|
||||
return -EACCES;
|
||||
|
||||
/* searching for the valid data block */
|
||||
if (offset) {
|
||||
pos = offset / node->block_size;
|
||||
offset = offset % node->block_size;
|
||||
}
|
||||
do {
|
||||
for(i=0; i<MAX_DATABLOCKS && !data; i++) {
|
||||
if (blist->data[i]) {
|
||||
found++;
|
||||
if (found > pos)
|
||||
data = (char*) blist->data[i];
|
||||
}
|
||||
/* init the tmp offset */
|
||||
offset = file->offset;
|
||||
|
||||
/* searching for the valid data block */
|
||||
if (offset) {
|
||||
pos = offset / node->block_size;
|
||||
offset = offset % node->block_size;
|
||||
}
|
||||
do {
|
||||
for(i=0; i<MAX_DATABLOCKS && !data; i++) {
|
||||
if (blist->data[i]) {
|
||||
found++;
|
||||
if (found > pos)
|
||||
data = (char*) blist->data[i];
|
||||
}
|
||||
}
|
||||
|
||||
blist = blist->next;
|
||||
} while(blist && !data);
|
||||
blist = blist->next;
|
||||
} while(blist && !data);
|
||||
|
||||
if (BUILTIN_EXPECT(!data, 0))
|
||||
return 0;
|
||||
if (BUILTIN_EXPECT(!data, 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If the data block is not large engough,
|
||||
* we copy only the rest of the current block.
|
||||
* The user has to restart the read operation
|
||||
* for the next block.
|
||||
*/
|
||||
if ((offset + size) >= node->block_size)
|
||||
size = node->block_size - offset;
|
||||
/*
|
||||
* If the data block is not large engough,
|
||||
* we copy only the rest of the current block.
|
||||
* The user has to restart the read operation
|
||||
* for the next block.
|
||||
*/
|
||||
if ((offset + size) >= node->block_size)
|
||||
size = node->block_size - offset;
|
||||
|
||||
memcpy(buffer, data + offset, size);
|
||||
memcpy(buffer, data + offset, size);
|
||||
|
||||
file->offset += size;
|
||||
return size;
|
||||
file->offset += size;
|
||||
return size;
|
||||
} else {
|
||||
/*********** The emulated readdir funtion *************/
|
||||
uint32_t i, j, k, count;
|
||||
uint32_t index = file->offset;
|
||||
dirent_t* dirent;
|
||||
dir_block_t* dirblock;
|
||||
block_list_t* blist = &node->block_list;
|
||||
|
||||
do {
|
||||
for(i=0,count=0; i<MAX_DATABLOCKS; i++) {
|
||||
dirblock = (dir_block_t*) blist->data[i];
|
||||
for(j=0; dirblock && j<MAX_DIRENTRIES; j++) {
|
||||
dirent = &dirblock->entries[j];
|
||||
if (dirent->vfs_node) {
|
||||
count++;
|
||||
if (count > index) {
|
||||
k=0;
|
||||
do {
|
||||
buffer[k] = dirent->name[0];
|
||||
k++;
|
||||
} while(dirent->name[k] != '\0');
|
||||
return k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blist = blist->next;
|
||||
} while(blist);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t initrd_write(fildes_t* file, uint8_t* buffer, size_t size)
|
||||
|
@ -343,6 +378,7 @@ static vfs_node_t* initrd_mkdir(vfs_node_t* node, const char* name)
|
|||
|
||||
memset(new_node, 0x00, sizeof(vfs_node_t));
|
||||
new_node->type = FS_DIRECTORY;
|
||||
new_node->read = &initrd_read;
|
||||
new_node->readdir = &initrd_readdir;
|
||||
new_node->finddir = &initrd_finddir;
|
||||
new_node->mkdir = &initrd_mkdir;
|
||||
|
|
|
@ -164,7 +164,6 @@ static int sys_read(int fd, const char* buf, size_t len)
|
|||
return read_fs(curr_task->fildes_table[fd], (uint8_t*)buf, len);
|
||||
}
|
||||
|
||||
|
||||
#if defined(CONFIG_LWIP) && LWIP_SOCKET
|
||||
static int sys_socket(int domain, int type, int protocol)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
|
||||
|
@ -46,6 +47,8 @@ int main(int argc, char** argv)
|
|||
{
|
||||
int i, testfile;
|
||||
char* teststr;
|
||||
DIR* testdir;
|
||||
dirent_t* testdirent;
|
||||
|
||||
for(i=0; environ[i]; i++)
|
||||
printf("environ[%d] = %s\n", i, environ[i]);
|
||||
|
@ -56,14 +59,22 @@ int main(int argc, char** argv)
|
|||
if (!teststr)
|
||||
return EFAULT;
|
||||
|
||||
testfile = open("/bin/test/test.txt", O_CREAT | O_EXCL, "wr");
|
||||
testfile = open("/bin/test.txt", O_CREAT | O_EXCL, "wr");
|
||||
if (testfile < 1)
|
||||
printf("error");
|
||||
write(testfile, "hello in new file '/bin/test/test.txt'", 34);
|
||||
write(testfile, "hello in new file '/bin/test.txt'", 34);
|
||||
lseek(testfile, 0, SEEK_SET);
|
||||
read(testfile, teststr, 100);
|
||||
close(testfile);
|
||||
|
||||
testdir = opendir("/bin/");
|
||||
if (testdir < 1)
|
||||
printf("error");
|
||||
testdirent = readdir(testdir);
|
||||
printf("1. Dirent: %s", testdirent->d_name);
|
||||
closedir(testdir);
|
||||
|
||||
|
||||
printf("read from new file: %s\n", teststr);
|
||||
|
||||
return errno;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
* Sean Eric Fagan, sef@Kithrup.COM
|
||||
*/
|
||||
|
||||
#include "../../../../../include/metalsvm/config.h"
|
||||
|
||||
typedef struct _dirdesc {
|
||||
int dd_fd;
|
||||
long dd_loc;
|
||||
|
@ -30,7 +32,7 @@ typedef struct dirent {
|
|||
off_t d_off;
|
||||
unsigned short d_reclen;
|
||||
/* we need better syntax for variable-sized arrays */
|
||||
char d_name[1];
|
||||
char d_name[MAX_FNAME];
|
||||
} dirent_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <_syslist.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#undef errno
|
||||
extern int errno;
|
||||
#include "warning.h"
|
||||
|
@ -47,9 +48,20 @@ dirent_t*
|
|||
_DEFUN (readdir, (dirp),
|
||||
DIR *dirp)
|
||||
{
|
||||
dirent_t* dirent;
|
||||
dirent_t* dirent = malloc(sizeof(dirent_t));
|
||||
int ret;
|
||||
/* init */
|
||||
dirent->d_ino = 0;
|
||||
dirent->d_off = 0;
|
||||
dirent->d_reclen = MAX_FNAME;
|
||||
dirent->d_name[0] = '\n';
|
||||
|
||||
read(dirp->dd_fd, dirent, 0);
|
||||
ret = read(dirp->dd_fd, dirent->d_name, MAX_FNAME);
|
||||
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dirent;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue