📄 os.cpp
字号:
#include <stdio.h>
#include <string.h>
#define BSIZE 512 /* 512bytes/块 */
#define BLKMAX 2048 /* 共2048块 */
#define BUFFER 1048576 /* 1M*/
#define READRIG 1
#define WRITEERR 1
#define FILES 5
struct user
{ char u_name[12]; /* 用户名,登录时使用 */
char u_uid; /* 用户标识,即文件创建时的文件主 */
char u_gid; /* 同组用户标识 */
struct fcb *u_cdir; /* 现行工作目录的FCB指针 */
char u_error; /* 执行文件管理函数时返回的错误代码 */
char *u_base; /* 读/写文件时信息存储区始址 */
int u_count; /* 读/写文件的信息字节数 */
int u_offset; /* 读/写文件的相对位移量 */
char u_obuf[8]; /* 文件路径名分量暂存区(查找文件时用) */
struct fcb *u_pdir; /* 新文件父目录FCB指针(文件创建时用) */
struct ofile *u_ofile[FILES]; /* 本用户打开文件表 */
};
# define USERNO 5 /* 定义本文件系统最多可接纳五个用户 */
struct user user[USERNO],*u=new struct user;
#define NOERROR -1
#define READERR 0
#define NOTFOUND 1
struct ofile
{ char o_flag; /* 标志字 */
char o_count; /* 访问计数 */
struct fcb *o_fcbp; /* 对应打开文件fcb结构指针 */
int o_offset; /*文件当前位置*/
};
# define FILENO 10 /* 文件系统允许打开文件数量 */
struct ofile ofile[FILENO]; /* 系统打开文件表ofile */
//标志字 o-flag 表示的标志定义为:
# define FREAD 01 /* 文件“读打开”标志 */
# define FWRITE 02 /* 文件“写打开”标志 */
# define FNOPEN 00
/* openf() ─ 为打开文件建立对应的ofile结构的函数
closef() ─ 为关闭文件建立对应的ofile结构的函数
openf()主要是在创建或打开文件时,执行完查找(namei())操作, 获得文件的
fcb结构指针后,为该文件分配一 ofile结构,置读/写指针初值等。
closef() 是在关闭文件时释放 ofile结构(即将 o-count减1,若o-count=0表
示该 ofile结构空闲),并调用 iput()将关闭文件的目录结构写回文件卷内
*/
//-----------------------------------------------------
struct dir
{ unsigned short d_mode; /* 文件属性及访问权限 */
char d_uid; /* 文件主标识 */
char d_gid; /* 文件主同组用户标识 */
int d_fsize; /* 文件大小(字节) */
char d_name[8]; /* 文件名 */
unsigned short d_add[8]; /* 存放文件信息的空间地址(块号) */
};
# define DSIZE 32 /* 以上目录结构占用32字节 */
struct fcb
{
char f_count;
char f_flag;
int f_blkno;
char f_number;
unsigned short f_mode;
char f_uid;
char f_gid;
int f_fsize;
char f_name[8];
int f_add[8];
};
# define FCBMAX 16
struct fcb fcb[FCBMAX],file_fcb[FILENO]; /* 系统 fcb[] 结构 */
struct fcb *fp;
# define FLOCK 01 /* fcb访问互斥标志 */
# define FUPD 02 /* 本fcb代表的文件已修改 */
# define FCHG 04 /* 本fcb结构中某些信息已被修改 */
# define IFMT 0070000 /* 文件类型屏蔽字 */
# define IFDIR 0010000 /* 子目录文件 */
# define EMPTY 11000 /* 删除的文件目录 */
# define IFREG 0020000 /* 普通文件 */
# define IREAD 0400 /* 文件主“读”权限 */
# define IWRITE 0200 /* 文件主“写”权限 */
# define IEXEC 0100 /* 文件主“执行”权限 */
# define GREAD 040 /* 同组用户“读”权限 */
# define GWRITE 020 /* 同组用户“写”权限 */
# define GEXEC 010 /* 同组用户“执行”权限 */
# define OREAD 04 /* 其它用户“读”权限 */
# define OWRITE 02 /* 其它用户“写”权限 */
# define OEXEC 01 /* 其它用户“执行”权限 */
# define HOST 0
#define GROUPS 1
#define OTHERS 2
FILE *vp;
char buffer[2048/8];
int block,blk_offset;
struct dir *dir_struct=new struct dir;
char filebuffer[BSIZE*8];
//------------------------------------------------------
//第一层
/*(1) 块管理层(或称文件卷管理层),设下列主要函数:
balloc() ─ 块分配函数
brelse() ─ 块释放函数
bread() ─ 读一块函数
bwrite() ─ 写一块函数*/
//--------------------------------------------------------
#define STRLENGTH 100
char cur_dir[STRLENGTH];
#define CD 0
#define DIR 1
#define MD 1
#define RD 1
#define CD2 2
#define CD1 3
void printcdir(int oprtype,char *name)
{
int i,j,t=0;
if(oprtype==0)
{
for(i=0;i<STRLENGTH;i++)
if(cur_dir[i]!='>')continue;
else
if(*name!='\0')
{
if(t==0)
{
t=1;
cur_dir[i]='\\';
}
else
{
cur_dir[i]=*name;
name++;
}
}
else
{
for(j=0;j<=i;j++)
printf("%c",cur_dir[j]);
return;
}
}
if(oprtype==1)
{
for(j=0;j<STRLENGTH;j++)
if(cur_dir[j]!='>')
printf("%c",cur_dir[j]);
else break;
printf("%c",cur_dir[j]);
return;
}
if(oprtype==2)
{
for(j=0;j<STRLENGTH;j++)
{
if(cur_dir[j]=='\\')
{
cur_dir[j]=':';
t=1;
}
if (cur_dir[j]=='>') break;
if(t==1) cur_dir[j]='>';
}
for(j=0;j<STRLENGTH;j++)
if(cur_dir[j]!='>')
printf("%c",cur_dir[j]);
else break;
printf("%c",cur_dir[j]);
return;
}
if(oprtype==3)
{
for(j=0;j<STRLENGTH;j++)
if(cur_dir[j]=='>')
break;
int k=j;
for(;j>5;j--)
if(cur_dir[j]=='\\')
break;
for(j;j<=k;j++)
cur_dir[j]='>';
for(j=0;j<STRLENGTH;j++)
if(cur_dir[j]!='>')
printf("%c",cur_dir[j]);
else break;
printf("%c",cur_dir[j]);
return;
}
}
//--------------------------------------------------------
void iget();
void init()
{
int i, *k=new int;
char p[12]="dengyu", pass[4]="f";
if((vp=fopen("buffer","rb+"))==NULL)
{
vp=fopen("buffer","wb+");//初始化超级块
fputc(128,vp);
for(i=1;i<BUFFER;i++)
fputc(0,vp);
fclose(vp);
vp=fopen("buffer","rb+");
unsigned short *attribution=new unsigned short;
*attribution=IFDIR;
fseek(vp,DSIZE*15,0);
fwrite(attribution,sizeof(unsigned short),1,vp);
char name[8]="ROOTDIR";
fseek(vp,DSIZE*15+8,0);
fwrite(name,8,1,vp);
fseek(vp,DSIZE*8,0);
fwrite(p,12,1,vp);
fwrite(pass,4,1,vp);
fclose(vp);
vp=fopen("buffer","rb+");
}
//user load
do
{
char name[12];
char password[4];
printf("LOGIN:");
gets(name);
if(strcmp(name,p))
{
printf("user wrong\n\n");
continue;
}
printf("password:");
gets(password);
if(strcmp(password,pass))
{
printf("password wrong\n\n");
continue;
}
break;
}
while (1);
//read out useful block
fread(buffer,2048/8,1,vp);
//init cur_dir[100]="FILE:>"
cur_dir[0]='F';cur_dir[1]='I';cur_dir[2]='L';cur_dir[3]='E';
cur_dir[4]=':';
for(i=5;i<100;i++)
cur_dir[i]='>';
//init struct fcb
for(i=0;i<FCBMAX;i++)
{
fcb[i].f_mode=0;
file_fcb[i].f_mode=0;
}
fp=fcb;
//init struct user
u->u_uid=HOST;
u->u_gid=HOST;
fseek(vp,DSIZE*15,0);//vp 指向根目录
block=0;blk_offset=15;
iget();// printf("%d ",u->u_cdir->f_add[0]);
u->u_base=NULL;
u->u_count=0;
u->u_error=NOERROR;
for(int j=0;j<5;j++)
u->u_ofile[j]=NULL;
for(i=0;i<BSIZE*8;i++)
filebuffer[i]=0;
//init struct ofile*/
for(i=0;i<FILENO;i++)
{
ofile[i].o_count=0;
ofile[i].o_flag=0;
ofile[i].o_fcbp=NULL;
ofile[i].o_offset=0;
}
}
void bread(int bno,char *buf) /* 待读出块的块号, 读出块信息缓冲区指针 */
{
int nbyte;
fseek(vp,bno*BSIZE,0); /* 将读/写指针移到文件卷指定块的边界处 */
nbyte=fread(buf,BSIZE,1,vp); /* 读出一块信息 */
if(nbyte!=BSIZE)
u->u_error=READERR; /* u为当前用户的 user 结构指针 */
}
void bwrite(int bno,char *buf)
{
int nbyte;
fseek(vp,bno*BSIZE,0);
nbyte=fwrite(buf,BSIZE,1,vp);
if(nbyte!=BSIZE)
u->u_error=WRITEERR;
}
int balloc()
{
FILE *f=vp;
int i,j,k,t=1;
for(i=0;i<BLKMAX/8;i++)
{
if(buffer[i]!=-1)
{
for(j=1;j<BLKMAX/8;j*=2)
{
if (buffer[i]==(buffer[i]&(buffer[i]+j)))
{
buffer[i]+=j;
for(k=1;k<=8;k++)
{
if(t==j) break;
t*=2;
}
vp=f;
return i*8+8-k; //分配的块号
}
}
}
}
if(i==BLKMAX/8)
vp=f;
return 0;//没有块分配
}
void brelse(int blk)
{
char zero[BSIZE+1];
int bitno,bit_offset,xor=1,i;
bitno=blk/8;
bit_offset=blk%8;
for(i=1;i<8-bit_offset;i++)
xor*=2;
if(buffer[bitno]==(buffer[bitno]|xor))
{
buffer[bitno]-=xor;
for(i=0;i<BSIZE;i++)
zero[i]=0;
zero[i]='\0';
bwrite(blk,zero);
}
}
//-----------------------------------------------------
//第二层
/* namei() ─ 文件查找函数
iget() ─ 取目录结构函数(从文件中读出一指定的目录结构,建立相应fcb)
iput() ─ 存目录结构函数(将一指定fcb结构写回文件卷的目录结构位置内)
readi() ─ 对指定fcb代表的文件读函数
writei() ─ 对指定fcb代表的文件写函数
readi()、writei() 二函数的功能是根据 u-offset、u-count 和 u-base三个
参数,对指定文件 (由 fcb结构指针 fp指定) 进行读/写。实现时,必须先将位移
u-offset 转化为对应的块号 (即: fp->f-add[u-offset/BSIZE])和块内位移(即:
u-offset%BSIZE),然后再调用笫一层的 bread()或 bwrite()实现真正的读/写;
如 u-count较大(大于 BSIZE-u-offset%BSIZE),必须分多次读/写。*/
//-------------------------------------------------------------
void cdirstruct()
{
int i;
for(i=0;i<8;i++)
dir_struct->d_add[i]=u->u_cdir->f_add[i];
for(i=0;i<8;i++)
dir_struct->d_name[i]=u->u_cdir->f_name[i];
dir_struct->d_fsize=u->u_cdir->f_fsize;
dir_struct->d_gid=u->u_cdir->f_gid;
dir_struct->d_mode=u->u_cdir->f_mode;
dir_struct->d_uid=u->u_cdir->f_uid;
}
#define BLKZERO 0
void search(char *fname)
{
int i,j,k;
for(i=0;i<8;i++)
{
for(j=0;j<16;j++)
{
fseek(vp,u->u_cdir->f_add[i]*BSIZE+DSIZE*j,0);
fread(dir_struct,DSIZE,1,vp);
if(dir_struct->d_mode!=IFDIR)
continue;
if(!strcmp(dir_struct->d_name,fname))
{
u->u_cdir->f_mode=IFDIR;
u->u_cdir->f_blkno=u->u_cdir->f_add[i];
u->u_cdir->f_number=j;
for(k=0;k<8;k++)
u->u_cdir->f_add[k]=dir_struct->d_add[k];
u->u_error=NOERROR;
return;
}
}
}
if (i==8) u->u_error=NOTFOUND;
}
void namei(char *route)
{
FILE *f=vp;
int i,oprtype=DIR;
char *name=new char;
fp->f_mode=u->u_cdir->f_mode;
fp->f_blkno=u->u_cdir->f_blkno;
fp->f_number=u->u_cdir->f_number;
for(i=0;i<8;i++)
fp->f_add[i]=u->u_cdir->f_add[i];
u->u_cdir=fp;
if(*route=='/'||*route=='\\')
{
while(*route!='\0')
{
route++;
for(i=0;i<9;i++)
{
if(*route=='/')break;
if(*route=='\0')break;
if(*route=='\\') break;
name[i]=*route;
route++;
}
name[i]='\0';
search(name);
if(u->u_error==NOTFOUND)//没找到
{
fp--;
u->u_cdir=fp;
fp++;
fp->f_mode=0;
return;
}
}
return;
}
if(*route!='/'&&*route!='\\')
{
for(i=0;i<8;i++)
u->u_cdir->f_add[i]=fcb->f_add[i];
while(*route!='\0')
{
for(i=0;i<9;i++)
{
if(*route=='/'||*route=='\\')
{
route++;
break;
}
if(*route=='\0') break;
name[i]=*route;
route++;
}
name[i]='\0';
search(name);
if(u->u_error==NOTFOUND)//没找到
{
fp--;
u->u_cdir=fp;
fp++;
fp->f_mode=0;
return;
}
}
}
}
void iget()//need block and blk_offset
{
int i;
fread(dir_struct,DSIZE,1,vp);
fp->f_count++;
fp->f_flag=ofile->o_flag;
fp->f_blkno=block;
fp->f_number=blk_offset;
fp->f_mode=dir_struct->d_mode;
fp->f_uid=dir_struct->d_uid;
fp->f_gid=dir_struct->d_gid;
fp->f_fsize=dir_struct->d_fsize;
for(i=0;i<8;i++)
fp->f_name[i]=dir_struct->d_name[i];
for(i=0;i<8;i++)
fp->f_add[i]=dir_struct->d_add[i];
u->u_cdir=fp;
fp++;
}
void iput()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -