#define __LIBRARY__ #include #include #include #include #include #include #include #include #include #include #define BUF_MAX 4096 #define DIRBUF 8192 #define NAME_MAX 14 struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[NAME_MAX+1]; }; /*参数count指定该缓冲区的大小*/ int sys_getdents(unsigned int fd,struct linux_dirent *dirp,unsigned int count) { if(!count)return -1;/*count is zero*/ if(fd>=NR_OPEN)return -EINVAL;/*fd is over range*/ struct file *file; struct m_inode * inode; int ret; struct buffer_head *hd; struct dir_entry *de; struct dirent * temp; char * buf; int desize,ldsize,i,ldi; file=current->filp[fd]; if(!file)return ENOTDIR;/*the file is not exist or not file*/ ldsize = sizeof(struct dirent); desize = sizeof(struct dir_entry); inode = file ->f_inode; temp = (struct dirent *)malloc(ldsize);/* //the inter veriable */ buf = (char*)malloc(ldsize); /*get the inode's bread*/ hd = bread(inode->i_dev , inode->i_zone[0]); ldi=0; ret=0; for (;reti_size;ret += desize){ if (ldi >= count-ldsize) break; /* full */ de = (struct dir_entry *)(hd->b_data + ret);/* de is set to the current dir_entry */ if (!de -> inode )/* to skip if there is no data in de */ continue; /*To write, copying current dirent, */ temp->d_ino = de->inode; temp->d_off = 0; temp->d_reclen = ldsize; strcpy(temp->d_name,de->name); /* by put_fs_byte to write back data to the usr */ memcpy(buf, temp, ldsize); for (i=0;i < ldsize;i++){ put_fs_byte(*(buf+i), ((char*)dirp)+i+ldi); } /* memcpy(temp, buf, ldsize); */ ldi += ldsize; } return ldi; } int sys_sleep(unsigned int seconds) { sys_signal(SIGALRM,SIG_IGN); sys_alarm(seconds); if(sys_pause()!=-1) { /* printk("sleep\n");*/ return 0; } /*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; }