操作系统真象还原[14章/八]-文件指针重定位

        本篇只涉及到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;
}	

         这篇比较简单,就不多赘述,非常轻松的搞定了这一节,接着该写文件删除的代码了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值