You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
6.4 KiB

/*
* getcwdʵ<EFBFBD><EFBFBD>˼·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵѵ<EFBFBD><EFBFBD>дһ<EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>ls
* <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>c<EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>opendir,readdir<EFBFBD><EFBFBD>closedir<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD>Ծ<EFBFBD>ȥc<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˹<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><EFBFBD><EFBFBD>read,fstat,stat<EFBFBD><EFBFBD>chdir
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͱȽϼ<EFBFBD><EFBFBD><EFBFBD>
*/
#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> */
};
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;
/* <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ں<EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ú<EFBFBD><C3BA><EFBFBD> */
_syscall3(int, read, int, fildes, char*, buf, off_t, count) /* open<65><6E><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> */
_syscall2(int, fstat, int, fildes, struct stat*, stat_buf) /* fstat<61><74><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD>״̬<D7B4><CCAC>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>statָ<74><D6B8>Ľṹ<C4BD><E1B9B9> */
_syscall2(int, stat, const char*, filename, struct stat*, stat_buf) /* stat<61><74><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD>״̬<D7B4><CCAC>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>statָ<74><D6B8>Ľṹ<C4BD><E1B9B9> */
_syscall1(int, chdir, const char*, filename) /* chdir<69>л<EFBFBD><D0BB><EFBFBD>filename<6D><65><EFBFBD><EFBFBD>Ŀ¼ */
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>c<EFBFBD><63><EFBFBD>е<EFBFBD>ʵ<EFBFBD><CAB5> */
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;
}
/* ʵ<><CAB5>getcwd */
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(".", &current_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;
}