add readdir

This commit is contained in:
Marian Ohligs 2011-11-09 11:56:37 +01:00
parent f108a3613f
commit a834155cce
5 changed files with 101 additions and 41 deletions

View file

@ -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;

View file

@ -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)
{

View file

@ -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;

View file

@ -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

View file

@ -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;
}