|
|
#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;
|
|
|
|
|
|
_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;
|
|
|
} |