📄 dir.c
字号:
#include "fs.h"
s_int g_curdir_ino=0;
char g_curdir_name[256]="";
/* char * get_last_name(char *path)
path must be absolute directory(start with '/') or
relative directory(start not with '/')
return the working path's inode number
*/
char * get_last_name(char *path)
{
s_int i;
for(i=strlen(path)-1;i>=0 && path[i]!='/';i--);
if(i>=0) return path+i+1;
else return path;
}
/* s_int get_working_dir_ino(char *path)
path must be absolute directory(start with '/') or
relative directory(start not with '/')
return the working path's inode number
*/
s_int get_working_dir_ino(char *path)
{
s_int i;
char p[256];
/* #ifdef DEBUG_MODE
printf("get_working_dir_ino: path[%s]",path);
#endif /**/
for(i=strlen(path)-1;i>=0 && path[i]!='/';i--);
/* #ifdef DEBUG_MODE
printf("last '/' is at [%d]'th char\n",i);
#endif /**/
if(i>0)
{
strncpy(p,path,i);
p[i]='\0';
path+=i+1;
/* #ifdef DEBUG_MODE
printf("p[%s],path[%s]\n",p,path);
#endif /* */
i=namei(p);
if(i<0)
{
#ifdef DEBUG_MODE
printf("get_working_dir_ino: path not found.\n",i);
#endif
return -1; /* path not found */
}
}
else if(i<0)
{
i=g_curdir_ino; /* create dir at the current directory */
}
/* if i==0 path start with a '/' and only 1 name ,so working dir is root */
/* #ifdef DEBUG_MODE
printf("[%d]\n",i);
#endif /**/
return i;
}
/* 目录搜索函数 */
/* fname must be absolute directory(start with '/') or
relative directory(start not with '/')
*/
s_int namei(char *fname)
{
s_int i,*jp;
s_int dirino;
dir_rec *dirs;
inode *ip;
char tname[32];
/* #ifdef DEBUG_MODE
printf("namei():[%s]\n",fname);
#endif /**/
/* . is current directory
if(fname[0]=='.')return g_curdir_ino;*/
/* search from root or from the current directory
and skip the root slash character if from root */
dirino= (fname[0]=='/')?(++fname,0): g_curdir_ino;
Loop:
if(*fname)
{
/* get a name from the fname */
for(i=0;i<30 && fname[i];i++)
{
if(fname[i]=='/')break;
tname[i]=fname[i];
}
tname[i]='\0';
if(fname[i]&&fname[i]!='/')return -2; /* path error, not found */
if(fname[i]=='/')fname++;
fname+=i;
ip=iget(dirino);
/* #ifdef DEBUG_MODE
printf("namei: dirino=[%d][%s]\n",dirino,fname);
#endif /**/
if(ip==NULL)
{
panic("namei:iget(dirino)==NULL");
}
for(jp=&ip->adr[0];jp<&ip->adr[8] && *jp;jp++)
{
dirs=(dir_rec *)bread(*jp);
for(i=0;i<512/32;i++)
if(!strncmp(dirs[i].name,tname,30))
{
dirino=dirs[i].ino; /* found the name, go for the next part */
goto Loop;
}
}
#ifdef DEBUG_MODE
printf("namei: path not found.\n");
#endif
return -1; /* path not found */
}
return dirino;
}
/* 访问控制函数 */
s_int access()
{
return 0;
}
/* 列目录函数 */
/* path must be absolute directory(start with '/') or
relative directory(start not with '/')
*/
s_int dir(char *path)
{
s_int i,j;
inode *ip,*ip2;
dir_rec *dp;
if(!strcmp(path,"."))i=g_curdir_ino;
else i=namei(path);
ip=iget(i);
if((ip->mode & IFMT)!=IFDIR)
{
iput(ip);
return -1;
}
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] && dp[j].name[0]!='.')
{
ip2=iget(dp[j].ino);
switch(ip2->mode&IFMT)
{
case IFDIR:printf("/");break;
case IFCHR:break;
}
printf("%s\t",dp[j].name);
}
}
}
iput(ip);
return 0;
}
/* 创建子目录函数 */
/* path must be absolute directory(start with '/') or
relative directory(start not with '/')
*/
s_int mkdir(char *path)
{
s_int i,j;
s_long size;
inode *ip,*ip2;
dir_rec *dp;
i=get_working_dir_ino(path);
if(i==-1)return -1;
ip=iget(i);
if((ip->mode & IFMT) !=IFDIR)
{
iput(ip);
#ifdef DEBUG_MODE
printf("mkdir :path not found\n",i);
#endif
return -1; /* 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);
printf("mkdir: directory file no more spaces, mkdir failed.\n");
return -2; /* directory file no more spaces, mkdir failed */
}
ip->adr[i]=balloc();
if(ip->adr[i]==0)panic("mkdir: 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:
ip2=ialloc();
if(ip2==NULL)panic("mkdir: ialloc return NULL, must be inode empty.");
dp[j].ino=ip2->number; /* link to sub dir */
strcpy(dp[j].name,get_last_name(path));
ip2->adr[0]=balloc();
if(ip2->adr[0]==0)panic("mkdir: balloc return 0, must be block empty.");
dp=(dir_rec *)bread(ip2->adr[0]);
memset(dp,0,512);
dp[0].ino=ip->number; /* link to father dir */
ip->lastr++;
iput(ip);
strcpy(dp[0].name,"..");
strcpy(dp[1].name,".");
dp[1].ino=ip2->number; /* link to self */
ip2->mode&=~IFMT;
ip2->mode|=IFDIR;
ip2->lastr=0;
ip2->size1=512;
ip2->size0=0;
iput(ip2);
return 0;
}
/* 改变当前子目录函数
path must be absolute directory(start with '/') or
relative directory(start not with '/')
*/
s_int chdir(char *path)
{
s_int i;
i=namei(path);
/* #ifdef DEBUG_MODE
printf("chdir(): path[%s] i=%d\n",path,i);
#endif /**/
if(i<0)return i; /* path error , not found */
g_curdir_ino=i;
if(i)
{
if(!strcmp(path,".."))
{
g_curdir_name[get_last_name(g_curdir_name)-g_curdir_name-1]=0;
}
else if(path[0]=='/')
{
strcpy(g_curdir_name,path);
}
else
{
i=strlen(g_curdir_name);
if(g_curdir_name[i-1]!='/')
{
g_curdir_name[i]='/';
i++;
}
strcpy(g_curdir_name+i,path);
}
}
else strcpy(g_curdir_name,"/");
return 0;
}
/*删除子目录函数
path must be absolute directory(start with '/') or
relative directory(start not with '/')
*/
s_int rmdir(char *path)
{
s_int i,j;
s_long size;
inode *ip,*ip2;
dir_rec *dp;
char *name=get_last_name(path);
if(!strcmp(name,".."))return 0; /* '..' is not a normal path */
i=get_working_dir_ino(path);
if(i==-1)return -1;
ip=iget(i);
if((ip->mode & IFMT) !=IFDIR)
{
iput(ip);
#ifdef DEBUG_MODE
printf("rmdir : working path not found\n",i);
#endif
return -1; /* 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(!strcmp(dp[j].name,name))goto Del_record;
}
}
iput(ip);
#ifdef DEBUG_MODE
printf("rmdir: rm path not found.\n");
#endif
return -2; /* rm path not found. */
Del_record:
ip2=iget(dp[j].ino);
if(ip2==NULL)return -3; /* dir's inode error */
if((ip2->mode&IFMT)!=IFDIR)return -2; /* rm path not found, it is not a path */
if(ip2->lastr>0)return -4; /* rm path not empty */
ip->lastr--;
iput(ip);
for(i=0;i<8&&ip2->adr[i];i++)
if(ip2->adr[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 + -