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.

145 lines
5.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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(".", &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;
}