📄 file.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 + -