int main(void) { put_str("I am kernel\n"); init_all(); /******** 测试代码 ********/ printf("/dir1 content before delete /dir1/subdir1:\n"); struct dir* dir = sys_opendir("/dir1/"); char* type = NULL; struct dir_entry* dir_e = NULL; while((dir_e = sys_readdir(dir))) { if (dir_e->f_type == FT_REGULAR) { type = "regular"; } else { type = "directory"; } printf(" %s %s\n", type, dir_e->filename); } printf("try to delete nonempty directory /dir1/subdir1\n"); if (sys_rmdir("/dir1/subdir1") == -1) { printf("sys_rmdir: /dir1/subdir1 delete fail!\n"); } printf("try to delete /dir1/subdir1/file2\n"); if (sys_rmdir("/dir1/subdir1/file2") == -1) { printf("sys_rmdir: /dir1/subdir1/file2 delete fail!\n"); } if (sys_unlink("/dir1/subdir1/file2") == 0 ) { printf("sys_unlink: /dir1/subdir1/file2 delete done\n"); } printf("try to delete directory /dir1/subdir1 again\n"); if (sys_rmdir("/dir1/subdir1") == 0) { printf("/dir1/subdir1 delete done!\n"); } printf("/dir1 content after delete /dir1/subdir1:\n"); sys_rewinddir(dir); while((dir_e = sys_readdir(dir))) { if (dir_e->f_type == FT_REGULAR) { type = "regular"; } else { type = "directory"; } printf(" %s %s\n", type, dir_e->filename); } /******** 测试代码 ********/ while(1); return 0; }
/* * get the name of the newest ticket cache for the uid user. * pam_krb5 defines a non default ticket cache for each user */ static char * get_ticket_cache( uid_t uid ) { char *ticket_file = NULL; SMB_STRUCT_DIR *tcdir; /* directory where ticket caches are stored */ SMB_STRUCT_DIRENT *dirent; /* directory entry */ char *filename = NULL; /* holds file names on the tmp directory */ SMB_STRUCT_STAT buf; char user_cache_prefix[CC_MAX_FILE_LEN]; char file_path[CC_MAX_FILE_PATH_LEN]; time_t t = 0; snprintf(user_cache_prefix, CC_MAX_FILE_LEN, "%s%d", CC_PREFIX, uid ); tcdir = sys_opendir( TICKET_CC_DIR ); if ( tcdir == NULL ) return NULL; while ( (dirent = sys_readdir( tcdir ) ) ) { filename = dirent->d_name; snprintf(file_path, CC_MAX_FILE_PATH_LEN,"%s/%s", TICKET_CC_DIR, filename); if (sys_stat(file_path, &buf) == 0 ) { if ( ( buf.st_uid == uid ) && ( S_ISREG(buf.st_mode) ) ) { /* * check the user id of the file to prevent denial of * service attacks by creating fake ticket caches for the * user */ if ( strstr( filename, user_cache_prefix ) ) { if ( buf.st_mtime > t ) { /* * a newer ticket cache found */ free(ticket_file); ticket_file=SMB_STRDUP(file_path); t = buf.st_mtime; } } } } } sys_closedir(tcdir); if ( ticket_file == NULL ) { /* no ticket cache found */ fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid); return NULL; } return ticket_file; }
SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp) { SMB_STRUCT_DIRENT *result; START_PROFILE(syscall_readdir); result = sys_readdir(dirp); END_PROFILE(syscall_readdir); return result; }
int prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data), void *data) { char *name = NULL; DIR *d = NULL; struct dirent *de = NULL; struct dirent scratch[2] = { { 0, }, }; pid_t pid = -1; pid_t ppid = -1; int ret = 0; d = sys_opendir(PROC); if (!d) return -1; for (;;) { errno = 0; de = sys_readdir(d, scratch); if (!de || errno != 0) break; if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) { ppid = pidinfo(pid, &name); switch (ppid) { case -1: continue; case -2: break; } ret = proch(pid, ppid, name, data); GF_FREE(name); if (ret) break; } } sys_closedir(d); if (!de && errno) { fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno)); ret = -1; } return ret; }
SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp) { static SMB_STRUCT_WDIRENT retval; SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp); if(!dirval) return NULL; /* * The only POSIX defined member of this struct is d_name. */ unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name)); return &retval; }
/* * read a directory */ struct dirent * readdir(void * dir) { struct dir * pdir; struct file * fp; if(!dir) return NULL; pdir = (struct dir *)dir; if((fp = get_fp(pdir->fd)) == NULL) return NULL; if(sys_readdir(fp, &pdir->entry) == 0) return &pdir->entry; return NULL; }
static int change_mode_r(const char *path, mode_t mode) { int ret = 0; struct infinity_dirent dent; int fd = open(path, O_RDONLY); char buf[256]; int d = 0; while(sys_readdir(fd, d++, &dent) == 0) { if(path[0] == '/' && path[1] == 0) sprintf(buf, "/%s", dent.d_name); else sprintf(buf, "%s/%s", path, dent.d_name); if(dent.d_type == 0x02) ret = change_mode_r(buf, mode); int res = sys_chmod(buf, mode); if(res != 0) { printf("chmod: can not access %s : %s\n", buf, get_errmsg(res)); ret = res; } } return ret; }
static void atalk_rrmdir(TALLOC_CTX *ctx, char *path) { char *dpath; SMB_STRUCT_DIRENT *dent = 0; SMB_STRUCT_DIR *dir; if (!path) return; dir = sys_opendir(path); if (!dir) return; while (NULL != (dent = sys_readdir(dir))) { if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; if (!(dpath = talloc_asprintf(ctx, "%s/%s", path, dent->d_name))) continue; atalk_unlink_file(dpath); } sys_closedir(dir); }
static void syscall_handler (struct intr_frame *f ) { /* VALUE */ int syscall_num; int arg[5]; void *esp = f->esp; /* VALUE */ check_address(esp); syscall_num = *(int *)esp; switch(syscall_num) { case SYS_HALT: halt(); break; case SYS_EXIT: get_argument(esp,arg,1); exit(arg[0]); break; case SYS_EXEC: get_argument(esp,arg,1); check_address((void *)arg[0]); f->eax = exec((const char *)arg[0]); break; case SYS_WAIT: get_argument(esp,arg,1); f->eax = wait(arg[0]); break; case SYS_CREATE: get_argument(esp,arg,2); check_address((void *)arg[0]); f->eax = create((const char *)arg[0],(unsigned)arg[1]); break; case SYS_REMOVE: get_argument(esp,arg,1); check_address((void *)arg[0]); f->eax=remove((const char *)arg[0]); break; case SYS_OPEN: get_argument(esp,arg,1); check_address((void *)arg[0]); f->eax = open((const char *)arg[0]); break; case SYS_FILESIZE: get_argument(esp,arg,1); f->eax = filesize(arg[0]); break; case SYS_READ: get_argument(esp,arg,3); check_address((void *)arg[1]); f->eax = read(arg[0],(void *)arg[1],(unsigned)arg[2]); break; case SYS_WRITE: get_argument(esp,arg,3); check_address((void *)arg[1]); f->eax = write(arg[0],(void *)arg[1],(unsigned)arg[2]); break; case SYS_SEEK: get_argument(esp,arg,2); seek(arg[0],(unsigned)arg[1]); break; case SYS_TELL: get_argument(esp,arg,1); f->eax = tell(arg[0]); break; case SYS_CLOSE: get_argument(esp,arg,1); close(arg[0]); break; case SYS_ISDIR: get_argument(esp,arg,1); sys_isdir(arg[0]); break; case SYS_MKDIR: get_argument(esp, arg, 1); check_address((void *)arg[0]); f->eax = sys_mkdir((const char *)arg[0]); break; case SYS_READDIR: get_argument(esp, arg, 2); check_address((char *)arg[1]); f->eax = sys_readdir(arg[0], (char *)arg[1]); break; case SYS_CHDIR: get_argument(esp, arg, 1); check_address((void *)arg[0]); f->eax = sys_chdir((const char *)arg[0]); break; } }
static void syscall_handler (struct intr_frame *f) { int syscall_number; ASSERT( sizeof(syscall_number) == 4 ); // assuming x86 // The system call number is in the 32-bit word at the caller's stack pointer. memread_user(f->esp, &syscall_number, sizeof(syscall_number)); _DEBUG_PRINTF ("[DEBUG] system call, number = %d!\n", syscall_number); // Store the esp, which is needed in the page fault handler. // refer to exception.c:page_fault() (see manual 4.3.3) thread_current()->current_esp = f->esp; // Dispatch w.r.t system call number // SYS_*** constants are defined in syscall-nr.h switch (syscall_number) { case SYS_HALT: // 0 { sys_halt(); NOT_REACHED(); break; } case SYS_EXIT: // 1 { int exitcode; memread_user(f->esp + 4, &exitcode, sizeof(exitcode)); sys_exit(exitcode); NOT_REACHED(); break; } case SYS_EXEC: // 2 { void* cmdline; memread_user(f->esp + 4, &cmdline, sizeof(cmdline)); int return_code = sys_exec((const char*) cmdline); f->eax = (uint32_t) return_code; break; } case SYS_WAIT: // 3 { pid_t pid; memread_user(f->esp + 4, &pid, sizeof(pid_t)); int ret = sys_wait(pid); f->eax = (uint32_t) ret; break; } case SYS_CREATE: // 4 { const char* filename; unsigned initial_size; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); memread_user(f->esp + 8, &initial_size, sizeof(initial_size)); return_code = sys_create(filename, initial_size); f->eax = return_code; break; } case SYS_REMOVE: // 5 { const char* filename; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_remove(filename); f->eax = return_code; break; } case SYS_OPEN: // 6 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_open(filename); f->eax = return_code; break; } case SYS_FILESIZE: // 7 { int fd, return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_filesize(fd); f->eax = return_code; break; } case SYS_READ: // 8 { int fd, return_code; void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_read(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_WRITE: // 9 { int fd, return_code; const void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_write(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_SEEK: // 10 { int fd; unsigned position; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &position, sizeof(position)); sys_seek(fd, position); break; } case SYS_TELL: // 11 { int fd; unsigned return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_tell(fd); f->eax = (uint32_t) return_code; break; } case SYS_CLOSE: // 12 { int fd; memread_user(f->esp + 4, &fd, sizeof(fd)); sys_close(fd); break; } #ifdef VM case SYS_MMAP: // 13 { int fd; void *addr; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &addr, sizeof(addr)); mmapid_t ret = sys_mmap (fd, addr); f->eax = ret; break; } case SYS_MUNMAP: // 14 { mmapid_t mid; memread_user(f->esp + 4, &mid, sizeof(mid)); sys_munmap(mid); break; } #endif #ifdef FILESYS case SYS_CHDIR: // 15 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_chdir(filename); f->eax = return_code; break; } case SYS_MKDIR: // 16 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_mkdir(filename); f->eax = return_code; break; } case SYS_READDIR: // 17 { int fd; char *name; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &name, sizeof(name)); return_code = sys_readdir(fd, name); f->eax = return_code; break; } case SYS_ISDIR: // 18 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_isdir(fd); f->eax = return_code; break; } case SYS_INUMBER: // 19 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_inumber(fd); f->eax = return_code; break; } #endif /* unhandled case */ default: printf("[ERROR] system call %d is unimplemented!\n", syscall_number); // ensure that waiting (parent) process should wake up and terminate. sys_exit(-1); break; } }
int runner_start (runner_t *runner) { int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}}; int xpi[2]; int ret = 0; int errno_priv = 0; int i = 0; sigset_t set; if (runner->runerr) { errno = runner->runerr; return -1; } GF_ASSERT (runner->argv[0]); /* set up a channel to child to communicate back * possible execve(2) failures */ ret = pipe(xpi); if (ret != -1) ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC); for (i = 0; i < 3; i++) { if (runner->chfd[i] != -2) continue; ret = pipe (pi[i]); if (ret != -1) { runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w"); if (!runner->chio[i]) ret = -1; } } if (ret != -1) runner->chpid = fork (); switch (runner->chpid) { case -1: errno_priv = errno; sys_close (xpi[0]); sys_close (xpi[1]); for (i = 0; i < 3; i++) { sys_close (pi[i][0]); sys_close (pi[i][1]); } errno = errno_priv; return -1; case 0: for (i = 0; i < 3; i++) sys_close (pi[i][i ? 0 : 1]); sys_close (xpi[0]); ret = 0; for (i = 0; i < 3; i++) { if (ret == -1) break; switch (runner->chfd[i]) { case -1: /* no redir */ break; case -2: /* redir to pipe */ ret = dup2 (pi[i][i ? 1 : 0], i); break; default: /* redir to file */ ret = dup2 (runner->chfd[i], i); } } if (ret != -1 ) { #ifdef GF_LINUX_HOST_OS DIR *d = NULL; struct dirent *de = NULL; char *e = NULL; d = sys_opendir ("/proc/self/fd"); if (d) { while ((de = sys_readdir (d))) { i = strtoul (de->d_name, &e, 10); if (*e == '\0' && i > 2 && i != dirfd (d) && i != xpi[1]) sys_close (i); } sys_closedir (d); } else ret = -1; #else /* !GF_LINUX_HOST_OS */ struct rlimit rl; ret = getrlimit (RLIMIT_NOFILE, &rl); GF_ASSERT (ret == 0); for (i = 3; i < rl.rlim_cur; i++) { if (i != xpi[1]) sys_close (i); } #endif /* !GF_LINUX_HOST_OS */ } if (ret != -1) { /* save child from inheriting our singal handling */ sigemptyset (&set); sigprocmask (SIG_SETMASK, &set, NULL); execvp (runner->argv[0], runner->argv); } ret = sys_write (xpi[1], &errno, sizeof (errno)); _exit (1); } errno_priv = errno; for (i = 0; i < 3; i++) sys_close (pi[i][i ? 1 : 0]); sys_close (xpi[1]); if (ret == -1) { for (i = 0; i < 3; i++) { if (runner->chio[i]) { fclose (runner->chio[i]); runner->chio[i] = NULL; } } } else { ret = sys_read (xpi[0], (char *)&errno_priv, sizeof (errno_priv)); sys_close (xpi[0]); if (ret <= 0) return 0; GF_ASSERT (ret == sizeof (errno_priv)); } errno = errno_priv; return -1; }
/** * Retrieve one direntry and optional stat buffer from our readdir cache. * * Increment the internal resume cookie, and refresh the cache from the * kernel if necessary. * * @param[in] handle vfs handle given in most VFS calls * @param[in] dirp system DIR handle to retrieve direntries from * @param[in/out] sbuf optional stat buffer to fill, this can be NULL * * @return dirent structure, NULL if at the end of the directory, NULL on error */ SMB_STRUCT_DIRENT * onefs_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, SMB_STRUCT_STAT *sbuf) { struct rdp_dir_state *dsp = NULL; SMB_STRUCT_DIRENT *ret_direntp; bool same_as_last; int ret = -1; /* Set stat invalid in-case we error out */ if (sbuf) SET_STAT_INVALID(*sbuf); /* Fallback to default system routines if readdirplus is disabled */ if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, PARM_USE_READDIRPLUS, PARM_USE_READDIRPLUS_DEFAULT)) { return sys_readdir(dirp); } /* Retrieve state based off DIR handle */ ret = rdp_retrieve_dir_state(dirp, &dsp, &same_as_last); if (ret) { DEBUG(1, ("Could not retrieve dir_state struct for " "SMB_STRUCT_DIR pointer.\n")); ret_direntp = NULL; goto end; } /* DIR is the same, current buffer and cursors are valid. * Grab the next direntry from our cache. */ if (same_as_last) { if ((dsp->direntries_cursor >= rdp_direntries + RDP_DIRENTRIES_SIZE) || (dsp->stat_cursor == dsp->stat_count)) { /* Cache is empty, refill from kernel */ ret = rdp_fill_cache(dsp); if (ret <= 0) { ret_direntp = NULL; goto end; } } } else { /* DIR is different from last call, reset all buffers and * cursors, and refill the global cache from the new DIR */ ret = rdp_fill_cache(dsp); if (ret <= 0) { ret_direntp = NULL; goto end; } DEBUG(8, ("Switched global rdp cache to new DIR entry.\n")); } /* Return next entry from cache */ ret_direntp = ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor); dsp->direntries_cursor += ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor)->d_reclen; if (sbuf) { *sbuf = rdp_stats[dsp->stat_cursor]; /* readdirplus() sets st_ino field to 0, if it was * unable to retrieve stat information for that * particular directory entry. */ if (sbuf->st_ino == 0) SET_STAT_INVALID(*sbuf); } DEBUG(9, ("Read from DIR %p, direntry: \"%s\", location: %ld, " "resume cookie: 0x%llx, cache cursor: %zu, cache count: %zu\n", dsp->dirp, ret_direntp->d_name, dsp->location, dsp->resume_cookie, dsp->stat_cursor, dsp->stat_count)); dsp->resume_cookie = rdp_cookies[dsp->stat_cursor]; dsp->stat_cursor++; dsp->location++; /* FALLTHROUGH */ end: /* Set rdp_last_dirp at the end of every VFS call where the cache was * reloaded */ rdp_last_dirp = dirp; return ret_direntp; }
int readdir(unsigned int fd, struct dirent *dirp, unsigned int count) { return sys_readdir(fd, dirp, count); }
/** * @API * gf_changelog_scan() - scan and generate a list of change entries * * calling this api multiple times (without calling gf_changlog_done()) * would result new changelogs(s) being refreshed in the tracker file. * This call also acts as a cancellation point for the consumer. */ ssize_t gf_changelog_scan () { int tracker_fd = 0; size_t off = 0; xlator_t *this = NULL; size_t nr_entries = 0; gf_changelog_journal_t *jnl = NULL; struct dirent *entry = NULL; struct dirent scratch[2] = {{0,},}; char buffer[PATH_MAX] = {0,}; this = THIS; if (!this) goto out; jnl = (gf_changelog_journal_t *) GF_CHANGELOG_GET_API_PTR (this); if (!jnl) goto out; if (JNL_IS_API_DISCONNECTED (jnl)) { errno = ENOTCONN; goto out; } errno = EINVAL; tracker_fd = jnl->jnl_fd; if (gf_ftruncate (tracker_fd, 0)) goto out; rewinddir (jnl->jnl_dir); for (;;) { errno = 0; entry = sys_readdir (jnl->jnl_dir, scratch); if (!entry || errno != 0) break; if (!strcmp (basename (entry->d_name), ".") || !strcmp (basename (entry->d_name), "..")) continue; nr_entries++; GF_CHANGELOG_FILL_BUFFER (jnl->jnl_processing_dir, buffer, off, strlen (jnl->jnl_processing_dir)); GF_CHANGELOG_FILL_BUFFER (entry->d_name, buffer, off, strlen (entry->d_name)); GF_CHANGELOG_FILL_BUFFER ("\n", buffer, off, 1); if (gf_changelog_write (tracker_fd, buffer, off) != off) { gf_msg (this->name, GF_LOG_ERROR, 0, CHANGELOG_LIB_MSG_WRITE_FAILED, "error writing changelog filename" " to tracker file"); break; } off = 0; } if (!entry) { if (gf_lseek (tracker_fd, 0, SEEK_SET) != -1) return nr_entries; } out: return -1; }