本篇只涉及到sys_lseek一个函数,该函数的功能是重新定位file结构中的fd_pos属性,修改文件的读写指针,fd_pos指向的是下一个可读或可写的位置。
int32_t sys_lseek(int32_t fd, int32_t offset, uint8_t whence)
enum whence {
SEEK_SET = 1,
SEEK_CUR,
SEEK_END
};
其中fd是pcb中的文件描述符(即pcb中fd_table数组的某个下标值),whence包含了SEEK_SET、SEEK_CUR、SEEK_END,offset为偏移字节数。
SEEK_SET:新的读写位置相对于文件开头再增加offset个偏移量
SEEK_CUR:新的读写位置相对于当前位置增加offset个偏移量(注意,这里的当前位置指向的已经是下一个可读或可写的位置了,而不是已经读取或写入的最后一个字节)
SEEK_END:新的读写位置是相对于文件尺寸再增加offset个偏移量,这里的offset必须为负值
下面上代码:
int32_t sys_lseek(int32_t fd, int32_t offset, uint8_t whence) {
if(fd < 0) {
printk("sys_lseek: fd error\n");
return -1;
}
ASSERT(whence > 0 && whence < 4);
/* 通过fd找到file */
uint32_t _fd = fd_local2global(fd);
struct file* pf = &file_table[_fd];
int32_t file_size = (int32_t) pf->fd_inode->i_size;
/* 根据whence改变fd_pos */
int32_t new_pos = 0;
switch (whence) {
case SEEK_SET:
new_pos = offset;
break;
case SEEK_CUR:
new_pos = pf->fd_pos + offset;
break;
case SEEK_END:
new_pos = ((int32_t) pf->fd_inode->i_size) + offset;
break;
}
if(new_pos < 0 || new_pos > (file_size - 1)) {
return -1;
}
pf->fd_pos = new_pos;
return new_pos;
}
#include "print.h"
#include "init.h"
#include "debug.h"
#include "memory.h"
#include "thread.h"
#include "interrupt.h"
#include "console.h"
#include "process.h"
#include "syscall.h"
#include "syscall-init.h"
#include "stdio.h"
#include "fs.h"
int main(void) {
put_str("I am kernel\n");
init_all();
intr_enable();
uint32_t fd = sys_open("/file1", O_RDWR);
printf("open /file1,fd:%d\n", fd);
char buf[64] = {0};
int read_bytes = sys_read(fd, buf, 18);
printf("1_ read %d bytes:\n%s\n", read_bytes, buf);
memset(buf, 0, 64);
read_bytes = sys_read(fd, buf, 6);
printf("2_ read %d bytes:\n%s", read_bytes, buf);
memset(buf, 0, 64);
read_bytes = sys_read(fd, buf, 6);
printf("3_ read %d bytes:\n%s", read_bytes, buf);
printf("___________________ SEEK SET 0 ___________________\n");
sys_lseek(fd, 0, SEEK_SET);
memset(buf, 0, 64);
read_bytes = sys_read(fd, buf, 24);
printf("4_ read %d bytes:\n%s", read_bytes, buf);
sys_close(fd);
while (1);
return 0;
}
这篇比较简单,就不多赘述,非常轻松的搞定了这一节,接着该写文件删除的代码了。