⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 一个完整的SHELL实现源代码
💻 C
字号:
#include "fs.h"

file g_file[NFILE]={0};

/* 打开文件函数*/
file *open(char *fname,s_int op)
{
    file *fp;
    inode *ip;
    /* find a free file record */
    for(fp=&g_file[0];fp<&g_file[NFILE];fp++)
    {
        if(fp->flag==0)
	    break;
    }
    if(fp == &g_file[NFILE])
    {
        panic("open():g_file[NFILE] empty.");
        return NULL;
    }
    fp->count=1;
    fp->offset[0]=fp->offset[1]=0;
    fp->ino=namei(fname);
    if(fp->ino<0)
    {
    	/* file not found */
    	return NULL;
    }
    fp->flag=op;
/*    #ifdef DEBUG_MODE
    printf("open(): ino=%d\n",fp->ino);
    #endif	/**/
    ip=iget(fp->ino);
    ip->count++; /* using count ++ */
    iput(ip);
    return fp;
}

/* 创建文件函数*/
file * create(char *fname)
{
    s_int i,j;
    s_long size;
    inode *ip,*ip2;
    dir_rec *dp;
    i=get_working_dir_ino(fname);
    if(i==-1)return NULL;
    ip=iget(i);
    if((ip->mode & IFMT) !=IFDIR)
    {
        iput(ip);
        #ifdef DEBUG_MODE
        printf("create :path not found\n",i);
        #endif
        return NULL; /* path not found */
    }
    size=((s_long)ip->size0 << 16) + ip->size1;
    for(i=0;i<8 && ip->adr[i];i++)
    {
        dp=(dir_rec *)bread(ip->adr[i]);
        for(j=0;j<512/32;j++)
        {
            if(dp[j].name[0]=='\0')goto Add_record;
        }    	
    }
    if(i>=8)
    {
	 iput(ip);
        panic("create: directory file no more spaces, create failed.");
        return NULL;
    }
    ip->adr[i]=balloc();
    if(ip->adr[i]==0)panic("create: balloc return 0, must be block empty.");
    dp=(dir_rec *)bread(ip->adr[i]);
    memset(dp,0,512);
    size+=512;
    ip->size1=size & 0xffff;
    ip->size0=size>>16;
    j=0;
Add_record:
    iput(ip);
    ip2=ialloc();
    if(ip2==NULL)panic("create: ialloc return NULL, must be inode empty.");
    ip2->mode&=~IFMT;
    ip2->mode|=IFCHR;
    ip2->nlink=1;
    ip2->size0=0;
    ip2->size1=0;
    dp[j].ino=ip2->number;
    iput(ip2);
    strcpy(dp[j].name,get_last_name(fname));
    /* if created open the file and return it */
    return open(fname,FREAD|FWRITE);
}

s_int seek(file *fp,s_long offset,s_int whence)
{
	s_long off;
	if(fp==NULL)return -1;
	off=((s_long)fp->offset[1]<<16)+fp->offset[0];
	switch(whence)
	{
		case SEEK_SET:
			off=offset;
			break;
		case SEEK_CUR:
			off+=offset;
			break;
/*		case SEEK_END:
			off=size+offset;
			break;*/
	}
	fp->offset[0]=off;
	fp->offset[1]=off>>16;
	return 0;
}

/* 读文件函数*/
s_int read(file *fp,s_int size,char *buf)
{
    inode *ip;
    char *tbuf;
    s_long fsize,fpos;
    s_int bno,rest;
    ip=iget(fp->ino);
    if(ip==NULL)
    {
	#ifdef DEBUG_MODE
       printf("read: iget return NULL\n");
       #endif
    	return -2;
    }
    fsize=((s_long)ip->size0 << 16) + ip->size1;
    fpos=((s_long)fp->offset[1] << 16)+fp->offset[0];
    if(fpos>=fsize) /* end of file reached */
    {
    	iput(ip);
    	return -1;
    }
    for(bno=(fpos>>9);bno<8 && size>0;bno++)
    {
	tbuf=NULL;
	if(ip->adr[bno]==0)break;
	if(tbuf==NULL)tbuf=bread(ip->adr[bno]);
	rest=min(512-(fpos&0x1ff),size);
	tbuf+=fpos&0x1ff;
	fpos+=rest;
	size-=rest;
	while(rest--)*buf++=*tbuf++;
    }
    fp->offset[0]=(s_int)(fpos&0xffff);
    fp->offset[1]=(s_int)(fpos>>16);
    iput(ip);
    return 0;
}

/* 写文件函数*/
s_int write(file *fp,s_int size,char *buf)
{
    inode *ip;
    char *tbuf;
    s_long fsize,fpos;
    s_int bno,rest;
    ip=iget(fp->ino);
    if(ip==NULL)return -1;
    fsize=((s_long)ip->size0 << 16) + ip->size1;
    fpos=((s_long)fp->offset[1] << 16)+fp->offset[0];
    for(bno=0;bno<8 && size>0;bno++)
    {
	tbuf=NULL;
	if(ip->adr[bno]==0)   /* if file not big enough */
	{
	    ip->adr[bno]=balloc();
	    if(ip->adr[bno]==0)panic("write: balloc return 0, must be block empty.");
	    tbuf=bread(ip->adr[bno]);
	    memset(tbuf,0,512);
	}
	if(bno>=(fpos>>9))
	{
		if(tbuf==NULL)tbuf=bread(ip->adr[bno]);
		if(fpos&0x1ff)
		{
			rest=512- (fpos&0x1ff);
			if(rest>size)rest=size;
			tbuf+= (fpos&0x1ff);
		}
 		else rest=(size>512)?512: size;
		fpos+=rest;
	    	size-=rest;
		while(rest--)*tbuf++=*buf++;
	}
    }
    /* write back file rw postion */
    fp->offset[0]=(us_int)(fpos&0xffff);
    fp->offset[1]=(us_int)(fpos>>16);
    /* write back file size */
    if(fsize<fpos)fsize=fpos;
/*    #ifdef DEBUG_MODE
    printf("write: fsize=[%d]\n",fsize);
    #endif /**/
    ip->size0=(char)(fsize>>16);
    ip->size1=(us_int)(fsize&0xffff);
    fp->flag|=FCHG;
    iput(ip);
    return 0;
}

/* 关闭文件函数*/
s_int close(file *fp)
{
    inode *ip;
    fp->flag=0; /* close the file */
    ip=iget(fp->ino);
    ip->count--; /* using count -- */
    iput(ip);
    return 0;
}

/* 删除文件函数*/
s_int delete(char *fname)
{
    s_int i,j;
    s_long size;
    inode *ip,*ip2;
    dir_rec *dp;
    i=get_working_dir_ino(fname);
    if(i==-1)return -1;
    ip=iget(i);
    if((ip->mode & IFMT) !=IFDIR)
    {
        iput(ip);
        #ifdef DEBUG_MODE
        printf("delete :path not found\n",i);
        #endif
        return -1; /* path not found */
    }
    fname=get_last_name(fname);
    size=((s_long)ip->size0 << 16) + ip->size1;
    for(i=0;i<8 && ip->adr[i];i++)
    {
        dp=(dir_rec *)bread(ip->adr[i]);
        for(j=0;j<512/32;j++)
        {
            if(!strcmp(dp[j].name,fname))goto Del_record;
        }    	
    }
    iput(ip);
    #ifdef DEBUG_MODE
    printf("delete: file not found.\n");
    #endif
    return -2; /* file not found. */
Del_record:
    ip2=iget(dp[j].ino);
    if(ip2==NULL)return -3; /* file's inode error */
    if((ip2->mode&IFMT)!=IFCHR)return -2; /* file not found, it is not a file */
    ip->lastr--;
    iput(ip);
    for(i=0;i<8&&ip2->adr[i];i++)
	 bfree(ip2->adr[i]);
    ifree(ip2->number);
    iput(ip2);
    dp[j].name[0]=0;
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -