parent
7c38d2d8a4
commit
c147ba95d2
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* linux/fs/stat.c
|
||||
*
|
||||
* (C) 1991 Linus Torvalds
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/segment.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static void cp_stat(struct m_inode * inode, struct stat * statbuf)
|
||||
{
|
||||
struct stat tmp;
|
||||
int i;
|
||||
|
||||
verify_area(statbuf,sizeof (* statbuf));
|
||||
tmp.st_dev = inode->i_dev;
|
||||
tmp.st_ino = inode->i_num;
|
||||
tmp.st_mode = inode->i_mode;
|
||||
tmp.st_nlink = inode->i_nlinks;
|
||||
tmp.st_uid = inode->i_uid;
|
||||
tmp.st_gid = inode->i_gid;
|
||||
tmp.st_rdev = inode->i_zone[0];
|
||||
tmp.st_size = inode->i_size;
|
||||
tmp.st_atime = inode->i_atime;
|
||||
tmp.st_mtime = inode->i_mtime;
|
||||
tmp.st_ctime = inode->i_ctime;
|
||||
for (i=0 ; i<sizeof (tmp) ; i++)
|
||||
put_fs_byte(((char *) &tmp)[i],&((char *) statbuf)[i]);
|
||||
}
|
||||
|
||||
static void new_cp_stat(struct m_inode * inode, struct stat * statbuf)
|
||||
{
|
||||
struct stat tmp;
|
||||
int i;
|
||||
|
||||
verify_area(statbuf,sizeof (* statbuf));
|
||||
tmp.st_dev = inode->i_dev;
|
||||
tmp.st_ino = inode->i_num;
|
||||
tmp.st_mode = inode->i_mode;
|
||||
tmp.st_nlink = inode->i_nlinks;
|
||||
tmp.st_uid = inode->i_uid;
|
||||
tmp.st_gid = inode->i_gid;
|
||||
tmp.st_rdev = inode->i_zone[0];
|
||||
tmp.st_size = inode->i_size;
|
||||
tmp.st_atime = inode->i_atime;
|
||||
tmp.st_mtime = inode->i_mtime;
|
||||
tmp.st_ctime = inode->i_ctime;
|
||||
for (i=0 ; i<sizeof (tmp) ; i++)
|
||||
//put_fs_byte(((char *) &tmp)[i],&((char *) statbuf)[i]);
|
||||
((char *)statbuf)[i]=((char *) &tmp)[i];
|
||||
}
|
||||
|
||||
|
||||
int sys_stat(char * filename, struct stat * statbuf)
|
||||
{
|
||||
struct m_inode * inode;
|
||||
|
||||
if (!(inode=namei(filename)))
|
||||
return -ENOENT;
|
||||
cp_stat(inode,statbuf);
|
||||
iput(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_stat(char * filename, struct stat * statbuf)
|
||||
{
|
||||
struct m_inode * inode;
|
||||
|
||||
if (!(inode=namei(filename)))
|
||||
return -ENOENT;
|
||||
new_cp_stat(inode,statbuf);
|
||||
iput(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_lstat(char * filename, struct stat * statbuf)
|
||||
{
|
||||
return sys_stat(filename, statbuf);
|
||||
}
|
||||
|
||||
int sys_fstat(unsigned int fd, struct stat * statbuf)
|
||||
{
|
||||
struct file * f;
|
||||
struct m_inode * inode;
|
||||
|
||||
if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
|
||||
return -EBADF;
|
||||
cp_stat(inode,statbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_readlink()
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
char *sys_getcwd(char *buf,size_t size)
|
||||
{
|
||||
char path[128], cwd[128], name[16], res[128];
|
||||
int dirp;
|
||||
struct stat sb, sb_d, sb_1;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
int tmp = 0, i;
|
||||
memset(res, 0, sizeof(res));
|
||||
while(1)
|
||||
{
|
||||
//将当前目录的字符串"."存入buf中才能作为stat的参数传入使用
|
||||
put_fs_byte('.', &buf[0]);
|
||||
put_fs_byte(0, &buf[1]);
|
||||
|
||||
//获取当前目录的文件信息
|
||||
my_stat(buf, &sb);
|
||||
dev = sb.st_dev;
|
||||
ino = sb.st_ino;
|
||||
|
||||
//获取父目录的对应的目录流和父目录的文件信息,将父目录".."字符串写入buf中
|
||||
put_fs_byte('.', &buf[0]);
|
||||
put_fs_byte('.', &buf[1]);
|
||||
put_fs_byte(0, &buf[2]);
|
||||
|
||||
//获取父目录的对应的目录流
|
||||
dirp = sys_open(buf, O_RDONLY, 0);
|
||||
//获取父目录的文件信息
|
||||
my_stat(buf, &sb_1);
|
||||
|
||||
//判断当前目录是否与父目录相同,相同则找到当前路径
|
||||
if(sb_1.st_dev == dev && sb_1.st_ino == ino)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//在父目录对应的目录流读取条目
|
||||
//遍历父目录下对应的所有目录与之前获取的当前目录想匹配,匹配成功的目录项对当前目录所在的目录项,即可保存名字后继续向前寻找
|
||||
while(my_read(dirp, name, 16) > 0 && name[0])
|
||||
{
|
||||
tmp = 0;
|
||||
memset(path, 0, sizeof(path));
|
||||
path[0] = '.';path[1] = '.';path[2] = '/';
|
||||
while(name[tmp+2])
|
||||
{
|
||||
path[tmp+3] = name[tmp+2];
|
||||
tmp++;
|
||||
}
|
||||
path[tmp+3] = 0;
|
||||
for(i=0;i<size;i++)
|
||||
put_fs_byte(path[i], &buf[i]);
|
||||
|
||||
//获取当前父目录下的目录项文件信息
|
||||
my_stat(buf, &sb_d);
|
||||
if(dev == sb_d.st_dev && ino == sb_d.st_ino)
|
||||
{
|
||||
//若匹配成功,则写入文件路径
|
||||
memset(cwd, 0, sizeof(cwd));
|
||||
strcat(cwd, "/");
|
||||
strcat(cwd, name+2);
|
||||
strcat(cwd, res);
|
||||
strncpy(res, cwd, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//关闭当前打开的父目录
|
||||
sys_close(dirp);
|
||||
|
||||
//将buf重新修改为父目录对应的字符串".."
|
||||
put_fs_byte('.', &buf[0]);
|
||||
put_fs_byte('.', &buf[1]);
|
||||
put_fs_byte(0, &buf[2]);
|
||||
|
||||
//改变当前目录到上一级,继续上述遍历寻找步骤直到父目录与当前目录相一致
|
||||
sys_chdir(buf);
|
||||
}
|
||||
//将得到的路径写入buf中
|
||||
for(i=0;i<size;i++)
|
||||
put_fs_byte(res[i], &buf[i]);
|
||||
sys_close(dirp);
|
||||
sys_chdir(buf);
|
||||
return buf;
|
||||
}
|
Loading…
Reference in new issue