|
|
#define __LIBRARY__
|
|
|
#include <unistd.h>
|
|
|
#include <string.h>
|
|
|
#include <errno.h>
|
|
|
#include <sys/types.h>
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
#include <linux/sched.h>
|
|
|
#include <asm/segment.h>
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
#define BUF_MAX 128
|
|
|
#define DIRBUF 8192
|
|
|
#define NAME_MAX 14
|
|
|
|
|
|
struct dirent { /* Ŀ¼<C4BF><C2BC>ṹ<EFBFBD><E1B9B9> */
|
|
|
long d_ino; /* i<>ڵ<EFBFBD> */
|
|
|
off_t d_off; /* λ<><CEBB> */
|
|
|
unsigned short d_reclen; /* <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
char d_name[NAME_MAX + 1]; /* <20>ļ<EFBFBD><C4BC><EFBFBD> */
|
|
|
};
|
|
|
|
|
|
int sys_getdents(unsigned int fd, struct dirent* dirp, unsigned int count) {
|
|
|
struct file* file;
|
|
|
struct m_inode* inode;
|
|
|
struct buffer_head* head;
|
|
|
struct dir_entry* de_tmp;
|
|
|
struct dirent* self_tmp; /* ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD>ʱָ<CAB1><D6B8> */
|
|
|
char* buf;
|
|
|
int dir_size, dire_size, read_bytes, addr_off, i;
|
|
|
|
|
|
dir_size = sizeof(struct dirent); /* <20><>ǰĿ¼<C4BF>ṹ<EFBFBD><E1B9B9>Ĵ<EFBFBD>С */
|
|
|
dire_size = sizeof(struct dir_entry); /* Ŀ¼<C4BF><C2BC>ṹ<EFBFBD><E1B9B9>Ĵ<EFBFBD>С */
|
|
|
|
|
|
self_tmp = (struct dirent*)malloc(dir_size); /* <20>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ʼ<EFBFBD>ռ<EFBFBD> */
|
|
|
buf = (char*)malloc(dir_size);
|
|
|
|
|
|
file = current->filp[fd]; /* <20><>ȡ<EFBFBD><C8A1>ǰĿ¼<C4BF><C2BC><EFBFBD><EFBFBD>Ϣ */
|
|
|
inode = file->f_inode;
|
|
|
head = bread(inode->i_dev, inode->i_zone[0]);
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dirpΪ<70><CEAA><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>read_bytes<65>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD> */
|
|
|
read_bytes = 0;
|
|
|
for (addr_off = 0; addr_off < inode->i_size; addr_off += dire_size) { /* <20>ӵ<EFBFBD>ǰĿ¼<C4BF><C2BC><EFBFBD><EFBFBD>ڿ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ȡÿһ<C3BF><D2BB>Ŀ¼<C4BF><C2BC>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
if (read_bytes >= count - dir_size) /* <20><><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>˳<EFBFBD>ѭ<EFBFBD><D1AD> */
|
|
|
break;
|
|
|
de_tmp = (struct dir_entry*)(head->b_data + addr_off); /* de_tmpָ<70><D6B8>Ŀ¼<C4BF><EFBFBD><EEBBBA><EFBFBD><EFBFBD><EFBFBD>Ľṹ<C4BD><E1B9B9> */
|
|
|
if (!de_tmp->inode) /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><EFBFBD><EEA3AC><EFBFBD><EFBFBD> */
|
|
|
continue;
|
|
|
self_tmp->d_ino = de_tmp->inode; /* Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>deָ<65><D6B8>Ľṹ<C4BD><E1B9B9><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱָ<CAB1><D6B8>self_tmpָ<70><D6B8>Ľṹ<C4BD><E1B9B9><EFBFBD><EFBFBD> */
|
|
|
self_tmp->d_off = 0;
|
|
|
self_tmp->d_reclen = dir_size;
|
|
|
strcpy(self_tmp->d_name, de_tmp->name);
|
|
|
memcpy(buf, self_tmp, dir_size); /* <20>Ѹն<D1B8><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>buf<75><66><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD> */
|
|
|
for (i = 0; i < dir_size; i++) /* <20><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽڵؿ<DAB5><D8BF><EFBFBD><EFBFBD><EFBFBD>dirp<72><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ */
|
|
|
put_fs_byte(*(buf + i), ((char*)dirp) + i + read_bytes);
|
|
|
read_bytes += dir_size;
|
|
|
}
|
|
|
return read_bytes;
|
|
|
}
|
|
|
|
|
|
int sys_sleep(unsigned int seconds) {
|
|
|
|
|
|
sys_signal(SIGALRM, SIG_IGN); /* <20>źŴ<C5BA><C5B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪSIG_IGN<47><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD>ź<EFBFBD> */
|
|
|
sys_alarm(seconds); /* seconds<64><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źţ<C5BA><C5A3><EFBFBD><EFBFBD>ѽ<EFBFBD><D1BD><EFBFBD> */
|
|
|
|
|
|
if (sys_pause() != -1) /* <20>ٴν<D9B4><CEBD><EFBFBD>˯<EFBFBD><CBAF> */
|
|
|
return 0;
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
int sys_pipe2() {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
typedef struct
|
|
|
{
|
|
|
int dd_fd; /* <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
int dd_loc; /* <20><><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB> */
|
|
|
int dd_size; /* <20><>Ч<EFBFBD><D0A7><EFBFBD>ݴ<EFBFBD>С */
|
|
|
char* dd_buf; /* -> directory block */
|
|
|
} DIR; /* Ŀ¼<C4BF><C2BC> */
|
|
|
|
|
|
struct direct {
|
|
|
ino_t d_ino;
|
|
|
char d_name[NAME_MAX];
|
|
|
};
|
|
|
|
|
|
static struct dirent result;
|
|
|
|
|
|
_syscall3(int, read, int, fildes, char*, buf, off_t, count)
|
|
|
_syscall2(int, fstat, int, fildes, struct stat*, stat_buf)
|
|
|
_syscall2(int, stat, const char*, filename, struct stat*, stat_buf)
|
|
|
_syscall1(int, chdir, const char*, filename)
|
|
|
|
|
|
struct dirent* readdir(DIR* dir) /* <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>dirĿ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
{ /* <20><>ȡ<EFBFBD><C8A1>Ŀ¼<C4BF><C2BC>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>ptrָ<72><D6B8><EFBFBD>Ŀ¼<C4BF>ṹ<EFBFBD><E1B9B9><EFBFBD>У<EFBFBD>ֻ<EFBFBD><D6BB>i<EFBFBD>ڵ<EFBFBD><DAB5>Ŀ¼<C4BF><C2BC> */
|
|
|
struct direct* ptr; /* <20><>ȡ<EFBFBD><C8A1>ǰĿ¼<C4BF><C2BC>ͬʱ<CDAC><CAB1>ȡ<EFBFBD><C8A1><EFBFBD>¸<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>result<6C><74> */
|
|
|
/* <20><><EFBFBD><EFBFBD>ĩβ<C4A9><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NULL */
|
|
|
if (!dir) {
|
|
|
errno = EBADF;
|
|
|
return NULL;
|
|
|
}
|
|
|
if (!dir->dd_buf)
|
|
|
if (!(dir->dd_buf = malloc(DIRBUF)))
|
|
|
return NULL;
|
|
|
else
|
|
|
dir->dd_size = dir->dd_loc = 0;
|
|
|
while (1) {
|
|
|
if (dir->dd_size <= dir->dd_loc) {
|
|
|
dir->dd_loc = 0;
|
|
|
dir->dd_size = read(dir->dd_fd, dir->dd_buf, DIRBUF);
|
|
|
}
|
|
|
if (dir->dd_size <= 0)
|
|
|
return NULL;
|
|
|
ptr = (struct direct*)(dir->dd_loc + dir->dd_buf);
|
|
|
dir->dd_loc += sizeof(*ptr);
|
|
|
if (!ptr->d_ino)
|
|
|
continue;
|
|
|
result.d_ino = ptr->d_ino;
|
|
|
strncpy(result.d_name, ptr->d_name, NAME_MAX);
|
|
|
result.d_name[NAME_MAX] = 0;
|
|
|
result.d_reclen = strlen(result.d_name);
|
|
|
return &result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int closedir(DIR* dir) /* <20>رղ<D8B1><D5B2><EFBFBD>dir<69><72>ָ<EFBFBD><D6B8><EFBFBD>Ŀ¼<C4BF><C2BC> */
|
|
|
{
|
|
|
int fd;
|
|
|
|
|
|
if (!dir) {
|
|
|
errno = EBADF;
|
|
|
return -1;
|
|
|
}
|
|
|
fd = dir->dd_fd;
|
|
|
free(dir->dd_buf);
|
|
|
free(dir);
|
|
|
return close(fd);
|
|
|
}
|
|
|
|
|
|
DIR* opendir(const char* dirname) /* <20><EFBFBD><F2BFAAB2><EFBFBD>dirnameָ<65><D6B8><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DIR<49><52>̬<EFBFBD><CCAC>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>NULL */
|
|
|
{
|
|
|
int fd;
|
|
|
struct stat stat_buf;
|
|
|
DIR* ptr;
|
|
|
|
|
|
if ((fd = open(dirname, O_RDONLY)) < 0) /* ִ<><D6B4>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>read<61><64><EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
return NULL;
|
|
|
if (fstat(fd, &stat_buf) < 0 || /* ִ<><D6B4>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD>fstat<61><74>ͨ<EFBFBD><CDA8><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD>״̬<D7B4><CCAC>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD>stat_buf */
|
|
|
!S_ISDIR(stat_buf.st_mode) ||
|
|
|
!(ptr = malloc(sizeof(*ptr)))) {
|
|
|
close(fd);
|
|
|
return NULL;
|
|
|
}
|
|
|
memset(ptr, 0, sizeof(*ptr));
|
|
|
ptr->dd_fd = fd;
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
char* sys_getcwd(char* buf, size_t size) {
|
|
|
char through_name[BUF_MAX], cwd[BUF_MAX];
|
|
|
DIR* pre_fstream;
|
|
|
struct dirent* through_stream;
|
|
|
struct stat current_direct_state, through_state, pre_direct_state;
|
|
|
dev_t current_direct_dev;
|
|
|
ino_t current_direct_inum;
|
|
|
|
|
|
while (1) {
|
|
|
if (stat(".", ¤t_direct_state == 0)) { /* <20><>ȡ<EFBFBD><C8A1>ǰĿ¼<C4BF><C2BC><EFBFBD>ļ<EFBFBD>״̬<D7B4><CCAC>Ϣ */
|
|
|
current_direct_dev = current_direct_state.st_dev;
|
|
|
current_direct_inum = current_direct_state.st_ino;
|
|
|
}
|
|
|
|
|
|
pre_fstream = opendir(".."); /* <20><>ȡ<EFBFBD><C8A1>ǰĿ¼<C4BF>ĸ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD> */
|
|
|
stat("..", &pre_direct_state); /* <20><>ȡ<EFBFBD><C8A1>ǰĿ¼<C4BF>ĸ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>Ϣ */
|
|
|
if (pre_direct_state.st_dev == current_direct_dev && pre_direct_state.st_ino == current_direct_inum)
|
|
|
break; /* <20><><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF>͵<EFBFBD>ǰĿ¼<C4BF><C2BC>ͬ<EFBFBD><CDAC>˵<EFBFBD><CBB5><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>˸<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>ʱ<EFBFBD>˳<EFBFBD>ѭ<EFBFBD><D1AD> */
|
|
|
|
|
|
while ((through_stream = readdir(pre_fstream)) != NULL) { /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF>µ<EFBFBD>Ŀ¼<C4BF><EFBFBD><EEA3AC><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5> */
|
|
|
memcpy(through_name, through_stream->d_name, BUF_MAX); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>stat<61><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>״̬<D7B4><CCAC>Ϣ */
|
|
|
stat(through_name, &through_state); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>״̬<D7B4><CCAC>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5> */
|
|
|
|
|
|
if (current_direct_dev == through_state.st_dev && current_direct_inum == through_state.st_ino) {
|
|
|
memset(cwd, 0, sizeof(cwd)); /* ƥ<>䵽<EFBFBD>˵<EFBFBD>ǰĿ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>cwd<77><64> */
|
|
|
strcat(cwd, "/");
|
|
|
strcat(cwd, through_stream->d_name);
|
|
|
strcat(cwd, buf); /* buf<75><66>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD>cwd<77><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>ǰѭ<C7B0><D1AD><EFBFBD><EFBFBD>cwd */
|
|
|
strncpy(buf, cwd, BUF_MAX); /* <20><>cwd<77><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>buf */
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
closedir(pre_fstream);
|
|
|
chdir(".."); /* <20>ı䵱ǰĿ¼Ϊ<C2BC>丸Ŀ¼ */
|
|
|
}
|
|
|
return buf;
|
|
|
} |