fix fs_read and cat
This commit is contained in:
parent
2f24ceac0d
commit
d51c050af3
@ -7,6 +7,7 @@
|
||||
#include <ipc.h>
|
||||
#include <string.h>
|
||||
#include <proc.h>
|
||||
#include "malloc.h"
|
||||
|
||||
#define SERVER_READY_FLAG(vaddr) (*(int *)(vaddr))
|
||||
#define SERVER_EXIT_FLAG(vaddr) (*(int *)((u64)vaddr+ 4))
|
||||
@ -14,6 +15,7 @@
|
||||
extern ipc_struct_t *tmpfs_ipc_struct;
|
||||
static ipc_struct_t ipc_struct;
|
||||
static int tmpfs_scan_pmo_cap;
|
||||
static int tmpfs_read_pmo_cap;
|
||||
|
||||
/* fs_server_cap in current process; can be copied to others */
|
||||
int fs_server_cap;
|
||||
@ -83,21 +85,51 @@ int do_top()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转为绝对路径
|
||||
*/
|
||||
void path_to_absolute(char *path) {
|
||||
char pathbuf[BUFLEN];
|
||||
strcpy(pathbuf + 1, path);
|
||||
pathbuf[0] = '/';
|
||||
strcpy(path, pathbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 路径连接
|
||||
*/
|
||||
void path_append(char *path, char *sub) {
|
||||
size_t path_len = strlen(path);
|
||||
// path 末尾应该有 '/'
|
||||
if (path[path_len - 1] == '/') {
|
||||
path += path_len;
|
||||
} else {
|
||||
path[path_len] = '/';
|
||||
path += path_len + 1;
|
||||
}
|
||||
// sub 之前没有 '/'
|
||||
while (*sub == '/') sub++;
|
||||
// 连接路径
|
||||
strcpy(path, sub);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录
|
||||
*/
|
||||
int fs_scan(char *path)
|
||||
{
|
||||
// TODO: your code here
|
||||
int count = 4096/2;
|
||||
char str[256];
|
||||
struct fs_request fr;
|
||||
int ret;
|
||||
|
||||
// 拼接请求
|
||||
fr.req = FS_REQ_SCAN;
|
||||
fr.buff = (char *) TMPFS_SCAN_BUF_VADDR;
|
||||
strcpy(fr.path + 1, path);
|
||||
fr.path[0] = '/';
|
||||
strcpy(fr.path, path);
|
||||
fr.offset = 0;
|
||||
fr.count = count;
|
||||
|
||||
// 发送
|
||||
printf("Send ls: %s\n", path);
|
||||
ipc_msg_t *ipc_msg = ipc_create_msg(tmpfs_ipc_struct, sizeof(fr), 1);
|
||||
ipc_set_msg_data(ipc_msg, (void *)&fr, 0, sizeof(fr));
|
||||
@ -108,16 +140,98 @@ int fs_scan(char *path)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得文件大小
|
||||
*/
|
||||
int fs_get_size(char *path)
|
||||
{
|
||||
struct fs_request fr;
|
||||
int ret;
|
||||
|
||||
// 拼接请求
|
||||
fr.req = FS_REQ_GET_SIZE;
|
||||
strcpy(fr.path, path);
|
||||
|
||||
// 发送
|
||||
ipc_msg_t *ipc_msg = ipc_create_msg(tmpfs_ipc_struct, sizeof(fr), 1);
|
||||
ipc_set_msg_data(ipc_msg, (void *)&fr, 0, sizeof(fr));
|
||||
ipc_set_msg_cap(ipc_msg, 0, tmpfs_scan_pmo_cap);
|
||||
ret = ipc_call(tmpfs_ipc_struct, ipc_msg);
|
||||
ipc_destroy_msg(ipc_msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_read(char *path, off_t offset, ssize_t count) {
|
||||
struct fs_request fr;
|
||||
int ret;
|
||||
|
||||
fail_cond(count > PAGE_SIZE,
|
||||
"read size should smaller than %d, now %d", PAGE_SIZE, count);
|
||||
|
||||
// 拼接请求
|
||||
fr.req = FS_REQ_READ;
|
||||
fr.buff = (char *) TMPFS_READ_BUF_VADDR;
|
||||
strcpy(fr.path, path);
|
||||
fr.offset = offset;
|
||||
fr.count = count;
|
||||
|
||||
// 发送
|
||||
ipc_msg_t *ipc_msg = ipc_create_msg(tmpfs_ipc_struct, sizeof(fr), 1);
|
||||
ipc_set_msg_data(ipc_msg, (void *)&fr, 0, sizeof(fr));
|
||||
ipc_set_msg_cap(ipc_msg, 0, tmpfs_read_pmo_cap);
|
||||
ret = ipc_call(tmpfs_ipc_struct, ipc_msg);
|
||||
ipc_destroy_msg(ipc_msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读入文件并返回长度
|
||||
*/
|
||||
int fs_read_all(char *path, void **ret_buf)
|
||||
{
|
||||
// 获得文件长度
|
||||
int size = fs_get_size(path);
|
||||
if (size < 0) {
|
||||
return size;
|
||||
}
|
||||
|
||||
// 申请缓冲
|
||||
unsigned char *buf = malloc(size);
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
*ret_buf = buf;
|
||||
|
||||
// 读入文件
|
||||
// FIXME: 读取 1 页以上会遇到 warning: vmr overlap
|
||||
int pos = 0;
|
||||
while (size - pos > 0) {
|
||||
int cur = fs_read(path, pos, PAGE_SIZE - 1);
|
||||
if (cur < 0) {
|
||||
return cur;
|
||||
}
|
||||
memcpy(buf, (const void *) TMPFS_READ_BUF_VADDR, cur);
|
||||
pos += cur;
|
||||
buf += cur;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int do_ls(char *cmdline)
|
||||
{
|
||||
char pathbuf[BUFLEN];
|
||||
char fpathbuf[BUFLEN];
|
||||
int ret;
|
||||
|
||||
pathbuf[0] = '\0';
|
||||
cmdline += 2;
|
||||
while (*cmdline == ' ')
|
||||
cmdline++;
|
||||
strcat(pathbuf, cmdline);
|
||||
// 路径格式化
|
||||
strcat(pathbuf, cmdline);
|
||||
path_to_absolute(pathbuf);
|
||||
// 请求 fs
|
||||
ret = fs_scan(pathbuf);
|
||||
if (ret >= 0) {
|
||||
char *print_ptr;
|
||||
@ -126,7 +240,17 @@ int do_ls(char *cmdline)
|
||||
|
||||
for (int i = 0; i < ret; i++) {
|
||||
dirat = (struct dirent *) print_ptr;
|
||||
printf(" %s\n", dirat->d_name);
|
||||
// 文件类型
|
||||
char type = 'f';
|
||||
if (dirat->d_type == 2) {
|
||||
type = 'd'; // 目录
|
||||
}
|
||||
// 文件大小
|
||||
strcpy(fpathbuf, pathbuf);
|
||||
path_append(fpathbuf, dirat->d_name);
|
||||
int size = fs_get_size(fpathbuf);
|
||||
// 输出
|
||||
printf("%c %10d %s\n", type, size, dirat->d_name);
|
||||
print_ptr += dirat->d_reclen;
|
||||
}
|
||||
} else {
|
||||
@ -143,9 +267,22 @@ int do_cat(char *cmdline)
|
||||
cmdline += 3;
|
||||
while (*cmdline == ' ')
|
||||
cmdline++;
|
||||
strcat(pathbuf, cmdline);
|
||||
// fs_scan(pathbuf);
|
||||
printf("apple banana This is a test file.\n");
|
||||
// 路径格式化
|
||||
strcat(pathbuf, cmdline);
|
||||
path_to_absolute(pathbuf);
|
||||
// 读入文件
|
||||
char *buf;
|
||||
int ret = fs_read_all(pathbuf, (void **) &buf);
|
||||
if (ret < 0) {
|
||||
printf("cannot cat file, code %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
// 打印
|
||||
for (int i = 0; i < ret; i++) {
|
||||
usys_putc(buf[i]);
|
||||
}
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -296,5 +433,15 @@ void boot_fs(void)
|
||||
TMPFS_SCAN_BUF_VADDR, VM_READ | VM_WRITE);
|
||||
fail_cond(ret < 0, "usys_map_pmo ret %d\n", ret);
|
||||
|
||||
// 创建读文件 pmo
|
||||
tmpfs_read_pmo_cap = usys_create_pmo(PAGE_SIZE, PMO_DATA);
|
||||
fail_cond(tmpfs_read_pmo_cap < 0, "usys create_ret ret %d\n",
|
||||
tmpfs_read_pmo_cap);
|
||||
|
||||
ret = usys_map_pmo(SELF_CAP,
|
||||
tmpfs_read_pmo_cap,
|
||||
TMPFS_READ_BUF_VADDR, VM_READ | VM_WRITE);
|
||||
fail_cond(ret < 0, "usys_map_pmo ret %d\n", ret);
|
||||
|
||||
printf("fs is UP.\n");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user