diff --git a/mysystem_call.c b/mysystem_call.c index 0a26de5..eac4639 100644 --- a/mysystem_call.c +++ b/mysystem_call.c @@ -76,31 +76,166 @@ int sys_getdents(unsigned int fd,struct linux_dirent *dirp,unsigned int count) return ldi; } -int sys_execve2(const char * filename, char ** argv, char ** envp) -{ - return 0; -} -long sys_getcwd(char *buf,size_t size) -{ - return 0; -} + + + + int sys_sleep(unsigned int seconds) { sys_signal(SIGALRM,SIG_IGN); sys_alarm(seconds); if(sys_pause()!=-1) { - printk("sleep\n"); + /* printk("sleep\n");*/ return 0; } - printk("do not sleep\n"); + /*printk("do not sleep\n");*/ return -1; } - +/*just full the sys_call_table[89]*/ int sys_something() { return 0; +} + +typedef struct + { + int dd_fd; /* file descriptor */ + int dd_loc; /* offset in block */ + int dd_size; /* amount of valid data */ + char *dd_buf; /* -> directory block */ + } DIR; /* stream data from opendir() */ +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) +{ + struct direct * ptr; + + 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) +{ + 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) +{ + int fd; + struct stat stat_buf; + DIR * ptr; + + if ((fd = open(dirname,O_RDONLY))<0) + return NULL; + if (fstat(fd,&stat_buf)<0 || + !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; +} + +/*find the father inode constantly*/ +long sys_getcwd(char *buf,size_t size) +{ + char path[BUF_MAX],cwd[BUF_MAX]; + DIR *dirp; + struct dirent *dp; + struct stat sb,sb_d,sb_1; + dev_t dev; + ino_t ino; + while(1) + { + //get the dir message + if(stat(".",&sb)==-1); + /*{printk("getcwd error1\n");}*/ + dev=sb.st_dev; + ino=sb.st_ino;//the message of inode + /* + Gets the corresponding directory stream + and + file information for the parent directory + */ + if((dirp=opendir(".."))==NULL); + /*{printk("there is no ..\n");}*/ + if(stat("..",&sb_1)==-1); + /*{printk("getcwd error 2\n");}*/ + //judge the current dir is same as father dir + if(sb_1.st_dev==dev && sb_1.st_ino == ino) + break; + errno=0; + /* + Reads entries in the dir stream + corresponding to the father directory + */ + while((dp=readdir(dirp))!=NULL) + { + printk("../%s",dp->d_name); + memcpy(path,dp->d_name,BUF_MAX); + if(stat(path,&sb_d)==-1); + /*{printk("getcwd error 3\n");}*/ + /*finish the entires*/ + if(dev == sb_d.st_dev && ino == sb_d.st_ino) + { + memset(cwd, 0, sizeof(cwd)); + if(strcat(cwd, "/") == NULL) + if(strcat(cwd, dp->d_name) == NULL) + if(strcat(cwd, buf) == NULL) + if(strncpy(buf, cwd, BUF_MAX) == NULL) + break; + } + } + if(dp==NULL&&errno!=0); + /*{printk("getcwd error 4\n");}*/ + closedir(dirp); + chdir("..");//change current dir + } + return buf; } \ No newline at end of file