int do_sigaction(int sig, struct sigaction *sa, struct sigaction *old_sa){ if (sig<1 || sig>NSIG || sig==SIGKILL || sa==NULL) { syserr(EINVAL); return -1; } // store the old struct sigaction if (old_sa!=NULL) { if (vm_verify(old_sa, sizeof(struct sigaction))<0) { syserr(EFAULT); return -1; } *old_sa = cu->p_sigact[sig-1]; } // set the new sigaction if (vm_verify(sa, sizeof(struct sigaction))<0) { syserr(EFAULT); return -1; } cu->p_sigact[sig-1] = *sa; cu->p_sigact[sig-1].sa_mask |= (1<<(sig-1)); return 0; }
/* * The value of pid can be: (via `man waitpid`) * < -1 wait for any child process whose process group ID is equal to the absolute value of pid. * -1 wait for any child process. * 0 wait for any child process whose process group ID is equal to that of the calling process. * > 0 wait for the child whose process ID is equal to the value of pid. * * opt: * WNOHANG : return immediately if no child exited. * */ int do_waitpid(int pid, int *stat, int opt){ struct proc *p; uint nr; if (vm_verify(stat, sizeof(int)) < 0){ syserr(EFAULT); return -1; } // _repeat: for(nr=1; nr<NPROC; nr++){ if ((p=proc[nr]) && p!=cu) { if (pid < -1) { if (p->p_ppid!=cu->p_pid || p->p_pgrp!=cu->p_pid) continue; } else if (pid == -1) { if (p->p_ppid!=cu->p_pid) continue; } else if (pid == 0) { if (p->p_ppid!=cu->p_pid || p->p_pgrp!=cu->p_pgrp) continue; } else if (pid > 0) { if (p->p_ppid!=cu->p_pid || p->p_pid!=pid) continue; } // on found switch(p->p_stat){ case SZOMB: *stat = p->p_ret; pid = p->p_pid; proc[pid] = NULL; kfree(p, PAGE); return pid; default: continue; } } } _not_found: // no child has found if (opt & WNOHANG) { return 0; } sleep(cu, PWAIT); goto _repeat; }
long sys_readdir(unsigned int fd, struct dirent *dirent, unsigned int count) { struct file *file; struct inode *inode; if (vm_verify(¤t->mm, dirent, sizeof(*dirent), VM_WRITE)) return -EFAULT; if (fd >= NR_FILES || !(file = current->filp[fd]) || !(inode = file->f_inode)) return -EBADF; if (file->f_op && file->f_op->readdir) return file->f_op->readdir(inode, file, dirent, count); return -ENOTDIR; }
long sys_stat(const char *pathname, size_t name_len, struct stat *s) { int error; struct inode *inode; error = verify_user_string(pathname, name_len); if (error) return error; if (vm_verify(¤t->mm, s, sizeof(*s), VM_WRITE)) return -EFAULT; error = namei(pathname, &inode); if (error) return error; do_stat(inode, s); iput(inode); return 0; }