int sys_sched_getscheduler(struct thread *td, struct sched_getscheduler_args *uap) { int e, policy; struct thread *targettd; struct proc *targetp; if (uap->pid == 0) { targetp = td->td_proc; targettd = td; PROC_LOCK(targetp); } else { targetp = pfind(uap->pid); if (targetp == NULL) return (ESRCH); targettd = FIRST_THREAD_IN_PROC(targetp); } e = p_cansee(td, targetp); if (e == 0) { e = ksched_getscheduler(ksched, targettd, &policy); td->td_retval[0] = policy; } PROC_UNLOCK(targetp); return (e); }
int sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap) { int e; struct sched_param sched_param; struct thread *targettd; struct proc *targetp; if (uap->pid == 0) { targetp = td->td_proc; targettd = td; PROC_LOCK(targetp); } else { targetp = pfind(uap->pid); if (targetp == NULL) { return (ESRCH); } targettd = FIRST_THREAD_IN_PROC(targetp); } e = p_cansee(td, targetp); if (e == 0) { e = ksched_getparam(ksched, targettd, &sched_param); } PROC_UNLOCK(targetp); if (e == 0) e = copyout(&sched_param, uap->param, sizeof(sched_param)); return (e); }
/* * Close a file or directory */ static int pfs_close(struct vop_close_args *va) { struct vnode *vn = va->a_vp; struct pfs_vdata *pvd = vn->v_data; struct pfs_node *pn = pvd->pvd_pn; struct proc *proc; int error; PFS_TRACE(("%s", pn->pn_name)); pfs_assert_not_owned(pn); /* * Do nothing unless this is the last close and the node has a * last-close handler. */ if (vrefcnt(vn) > 1 || pn->pn_close == NULL) PFS_RETURN (0); if (pvd->pvd_pid != NO_PID) { proc = pfind(pvd->pvd_pid); } else { proc = NULL; } error = pn_close(va->a_td, proc, pn); if (proc != NULL) PROC_UNLOCK(proc); PFS_RETURN (error); }
/* * set things up for doing i/o on * the pfsnode (vp). (vp) is locked * on entry, and should be left locked * on exit. * * for procfs we don't need to do anything * in particular for i/o. all that is done * is to support exclusive open on process * memory images. */ int procfs_open(void *v) { struct vop_open_args *ap = v; struct pfsnode *pfs = VTOPFS(ap->a_vp); struct proc *p1 = ap->a_p; /* tracer */ struct proc *p2; /* traced */ int error; if ((p2 = pfind(pfs->pfs_pid)) == 0) return (ENOENT); /* was ESRCH, jsp */ switch (pfs->pfs_type) { case Pmem: if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) return (EBUSY); if ((error = process_checkioperm(p1, p2)) != 0) return (error); if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); return (0); default: break; } return (0); }
/* * close the pfsnode (vp) after doing i/o. * (vp) is not locked on entry or exit. * * nothing to do for procfs other than undo * any exclusive open flag (see _open above). */ static int linprocfs_close(struct vop_close_args *ap) { struct pfsnode *pfs = VTOPFS(ap->a_vp); struct proc *p; switch (pfs->pfs_type) { case Pmem: if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL)) pfs->pfs_flags &= ~(FWRITE|O_EXCL); /* * If this is the last close, then it checks to see if * the target process has PF_LINGER set in p_pfsflags, * if this is *not* the case, then the process' stop flags * are cleared, and the process is woken up. This is * to help prevent the case where a process has been * told to stop on an event, but then the requesting process * has gone away or forgotten about it. */ p = NULL; if ((ap->a_vp->v_opencount < 2) && (p = pfind(pfs->pfs_pid)) && !(p->p_pfsflags & PF_LINGER)) { p->p_stops = 0; p->p_step = 0; wakeup(&p->p_step); } if (p) PRELE(p); break; default: break; } return (vop_stdclose(ap)); }
/* * find a symtab path entry in the given path. * p is expected to be a link of NMNAMEs. * It is supposed to return a sup value of the last found class. */ static struct symtab * pfind(NODE *p, struct symtab *sp) { char *n; if (cppdebug)printf("pfind: op %d searching %s\n", p->n_op, p->n_op == NAME ? (char *)p->n_sp:(char *)p->n_right->n_sp); if (p->n_op == NAME) { n = (char *)p->n_sp; if ((sp = sfind(n, sp)) == NULL) return NULL; if (cppdebug)printf("pfind: NAME class %d name %s\n", sp->sclass, sp->sname); while (!CLORNS(sp)) { if ((sp = sfind(n, sp->snext)) == NULL) return NULL; } if (cppdebug)printf("pfind: FOUND %s\n", sp->sname); sp = sp->sup; } else { n = (char *)p->n_right->n_sp; if ((sp = sfind(n, sp)) == NULL) return NULL; if (cppdebug)printf("pfind: NMLIST class %d name %s\n", sp->sclass, sp->sname); while (!CLORNS(sp)) { if ((sp = sfind(n, sp->snext)) == NULL) return NULL; } sp = pfind(p->n_left, sp->sup); } return sp; }
/* * Get an arbitrary pid's process group id */ int sys_getpgid(struct getpgid_args *uap) { struct proc *p = curproc; struct proc *pt; int error; error = 0; if (uap->pid == 0) { pt = p; PHOLD(pt); } else { pt = pfind(uap->pid); if (pt == NULL) error = ESRCH; } if (error == 0) { lwkt_gettoken_shared(&pt->p_token); uap->sysmsg_result = pt->p_pgrp->pg_id; lwkt_reltoken(&pt->p_token); } if (pt) PRELE(pt); return (error); }
int sys_sched_setparam(struct thread *td, struct sched_setparam_args *uap) { struct thread *targettd; struct proc *targetp; int e; struct sched_param sched_param; e = copyin(uap->param, &sched_param, sizeof(sched_param)); if (e) return (e); if (uap->pid == 0) { targetp = td->td_proc; targettd = td; PROC_LOCK(targetp); } else { targetp = pfind(uap->pid); if (targetp == NULL) return (ESRCH); targettd = FIRST_THREAD_IN_PROC(targetp); } e = p_cansched(td, targetp); if (e == 0) { e = ksched_setparam(ksched, targettd, (const struct sched_param *)&sched_param); } PROC_UNLOCK(targetp); return (e); }
int kern_sched_rr_get_interval(struct thread *td, pid_t pid, struct timespec *ts) { int e; struct thread *targettd; struct proc *targetp; if (pid == 0) { targettd = td; targetp = td->td_proc; PROC_LOCK(targetp); } else { targetp = pfind(pid); if (targetp == NULL) return (ESRCH); targettd = FIRST_THREAD_IN_PROC(targetp); } e = p_cansee(td, targetp); if (e == 0) e = ksched_rr_get_interval(ksched, targettd, ts); PROC_UNLOCK(targetp); return (e); }
/* * set process group (setpgid/old setpgrp) * * caller does setpgid(targpid, targpgid) * * pid must be caller or child of caller (ESRCH) * if a child * pid must be in same session (EPERM) * pid can't have done an exec (EACCES) * if pgid != pid * there must exist some pid in same session having pgid (EPERM) * pid must not be session leader (EPERM) */ int sys_setpgid(struct setpgid_args *uap) { struct proc *curp = curproc; struct proc *targp; /* target process */ struct pgrp *pgrp = NULL; /* target pgrp */ int error; if (uap->pgid < 0) return (EINVAL); if (uap->pid != 0 && uap->pid != curp->p_pid) { if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { if (targp) PRELE(targp); error = ESRCH; targp = NULL; goto done; } lwkt_gettoken(&targp->p_token); /* targp now referenced and its token is held */ if (targp->p_pgrp == NULL || targp->p_session != curp->p_session) { error = EPERM; goto done; } if (targp->p_flags & P_EXEC) { error = EACCES; goto done; } } else { targp = curp; PHOLD(targp); lwkt_gettoken(&targp->p_token); } if (SESS_LEADER(targp)) { error = EPERM; goto done; } if (uap->pgid == 0) { uap->pgid = targp->p_pid; } else if (uap->pgid != targp->p_pid) { if ((pgrp = pgfind(uap->pgid)) == NULL || pgrp->pg_session != curp->p_session) { error = EPERM; goto done; } } error = enterpgrp(targp, uap->pgid, 0); done: if (pgrp) pgrel(pgrp); if (targp) { lwkt_reltoken(&targp->p_token); PRELE(targp); } return (error); }
/* * Read a symbolic link */ static int pfs_readlink(struct vop_readlink_args *va) { struct vnode *vn = va->a_vp; struct pfs_vdata *pvd = vn->v_data; struct pfs_node *pn = pvd->pvd_pn; struct uio *uio = va->a_uio; struct proc *proc = NULL; struct thread *td = curthread; char buf[PATH_MAX]; struct sbuf sb; int error, locked; PFS_TRACE(("%s", pn->pn_name)); pfs_assert_not_owned(pn); if (vn->v_type != VLNK) PFS_RETURN (EINVAL); KASSERT_PN_IS_LINK(pn); if (pn->pn_fill == NULL) PFS_RETURN (EIO); if (pvd->pvd_pid != NO_PID) { if ((proc = pfind(pvd->pvd_pid)) == NULL) PFS_RETURN (EIO); if (proc->p_flag & P_WEXIT) { PROC_UNLOCK(proc); PFS_RETURN (EIO); } _PHOLD(proc); PROC_UNLOCK(proc); } vhold(vn); locked = VOP_ISLOCKED(vn, td); VOP_UNLOCK(vn, 0, td); /* sbuf_new() can't fail with a static buffer */ sbuf_new(&sb, buf, sizeof buf, 0); error = pn_fill(td, proc, pn, &sb, NULL); if (proc != NULL) PRELE(proc); vn_lock(vn, locked | LK_RETRY, td); vdrop(vn); if (error) { sbuf_delete(&sb); PFS_RETURN (error); } sbuf_finish(&sb); error = uiomove_frombuf(sbuf_data(&sb), sbuf_len(&sb), uio); sbuf_delete(&sb); PFS_RETURN (error); }
void osi_StopListener(void) { struct proc *p; soclose(rx_socket); p = pfind(rxk_ListenerPid); if (p) psignal(p, SIGUSR1); }
/* * _inactive is called when the pfsnode * is vrele'd and the reference count goes * to zero. (vp) will be on the vnode free * list, so to get it back vget() must be * used. * * for procfs, check if the process is still * alive and if it isn't then just throw away * the vnode by calling vgone(). this may * be overkill and a waste of time since the * chances are that the process will still be * there and pfind is not free. * * (vp) is not locked on entry or exit. */ int procfs_inactive(void *v) { struct vop_inactive_args *ap = v; struct vnode *vp = ap->a_vp; struct pfsnode *pfs = VTOPFS(vp); if (pfind(pfs->pfs_pid) == NULL && !(vp->v_flag & VXLOCK)) vgone(vp); return (0); }
int main(int argc, char **argv) { int i; char *fullpath; for (i=1; i<argc; i++) { fullpath = pfind(argv[i]); if (fullpath == NULL) printf("Unable to find %s in $PATH.\n", argv[i]); else printf("Found %s @ %s.\n", argv[i], fullpath); } }
getpriority() { register struct a { int which; int who; } *uap = (struct a *)u.u_ap; register struct proc *p; int low = PRIO_MAX + 1; switch (uap->which) { case PRIO_PROCESS: if (uap->who == 0) p = u.u_procp; else p = pfind(uap->who); if (p == 0) break; low = p->p_nice; break; case PRIO_PGRP: if (uap->who == 0) uap->who = u.u_procp->p_pgrp; for (p = allproc; p != NULL; p = p->p_nxt) { if (p->p_pgrp == uap->who && p->p_nice < low) low = p->p_nice; } break; case PRIO_USER: if (uap->who == 0) uap->who = u.u_uid; for (p = allproc; p != NULL; p = p->p_nxt) { if (p->p_uid == uap->who && p->p_nice < low) low = p->p_nice; } break; default: u.u_error = EINVAL; return; } if (low == PRIO_MAX + 1) { u.u_error = ESRCH; return; } u.u_r.r_val1 = low; }
/* * Checks for current use of a pid, either as a pid or pgid. */ int pidtaken(pid_t pid) { struct proc *p; if (pfind(pid) != NULL) return (1); if (pgfind(pid) != NULL) return (1); LIST_FOREACH(p, &zombproc, p_list) if (p->p_pid == pid || p->p_pgid == pid) return (1); return (0); }
setpriority() { register struct a { int which; int who; int prio; } *uap = (struct a *)u.u_ap; register struct proc *p; int found = 0; switch (uap->which) { case PRIO_PROCESS: if (uap->who == 0) p = u.u_procp; else p = pfind(uap->who); if (p == 0) break; donice(p, uap->prio); found++; break; case PRIO_PGRP: if (uap->who == 0) uap->who = u.u_procp->p_pgrp; for (p = allproc; p != NULL; p = p->p_nxt) if (p->p_pgrp == uap->who) { donice(p, uap->prio); found++; } break; case PRIO_USER: if (uap->who == 0) uap->who = u.u_uid; for (p = allproc; p != NULL; p = p->p_nxt) if (p->p_uid == uap->who) { donice(p, uap->prio); found++; } break; default: u.u_error = EINVAL; return; } if (found == 0) u.u_error = ESRCH; }
void osi_StopListener(void) { struct proc *p; /* * Have to drop global lock to safely do this. * soclose() is currently protected by Giant, * but pfind and psignal are MPSAFE. */ int haveGlock = ISAFS_GLOCK(); if (haveGlock) AFS_GUNLOCK(); soshutdown(rx_socket, 2); #ifndef AFS_FBSD70_ENV soclose(rx_socket); #endif p = pfind(rxk_ListenerPid); afs_warn("osi_StopListener: rxk_ListenerPid %lx\n", p); if (p) psignal(p, SIGUSR1); #ifdef AFS_FBSD50_ENV PROC_UNLOCK(p); #endif #ifdef AFS_FBSD70_ENV { /* Avoid destroying socket until osi_NetReceive has * had a chance to clean up */ int tries; struct mtx s_mtx; MUTEX_INIT(&s_mtx, "rx_shutdown_mutex", MUTEX_DEFAULT, 0); MUTEX_ENTER(&s_mtx); tries = 3; while ((tries > 0) && (!so_is_disconn(rx_socket))) { msleep(&osi_StopListener, &s_mtx, PSOCK | PCATCH, "rx_shutdown_timedwait", 1 * hz); --tries; } if (so_is_disconn(rx_socket)) soclose(rx_socket); MUTEX_EXIT(&s_mtx); MUTEX_DESTROY(&s_mtx); } #endif if (haveGlock) AFS_GLOCK(); }
/* * ptrace() * Cause a process to begin talking to us as a debugging slave */ int ptrace(pid_t pid, port_name name) { struct proc *myproc, *p; uint x; extern struct proc *pfind(); /* * If pid == 0 && name == 0, this we return whether we're * being ptrace()'ed. */ myproc = curthread->t_proc; if (!pid && !name) { return(myproc->p_dbg.pd_name != 0); } /* * Find the process. Bomb if he doesn't exist, or is * already being debugged. */ p = pfind(pid); if (!p) { return(err(ESRCH)); } if (p->p_dbg.pd_name) { v_sema(&p->p_sema); return(err(EBUSY)); } /* * See if we have the rights to do this */ x = perm_calc(myproc->p_ids, PROCPERMS, &p->p_prot); if (!(x & P_DEBUG)) { return(err(EPERM)); } /* * Stuff his fields with our request for him to call us. * Then let him go. */ p->p_dbg.pd_port = -1; p->p_dbg.pd_name = name; p->p_dbg.pd_flags = PD_ALWAYS|PD_EVENT|PD_EXIT; v_sema(&p->p_sema); return(0); }
void osi_StopListener(void) { struct proc *p; #if defined(KERNEL_FUNNEL) thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); #endif soclose(rx_socket); #if defined(KERNEL_FUNNEL) thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); #endif #ifndef AFS_DARWIN80_ENV p = pfind(rxk_ListenerPid); if (p) psignal(p, SIGUSR1); #endif }
void debugger_writemem_callback(struct allocation_t* ref) { struct message_t* message = __get(ref); if (!message) return; if (message->header.request != 1) goto cleanup; if (message->socket < 0) goto cleanup; if (!message->payload) goto cleanup; struct debugger_writemem_t* request = (struct debugger_writemem_t*)message->payload; if (request->process_id < 0) goto cleanup; if (request->address == 0) goto cleanup; if (request->dataLength == 0) goto cleanup; struct proc* (*pfind)(pid_t) = kdlsym(pfind); struct proc* process = pfind(request->process_id); if (process == 0) goto cleanup; void(*_mtx_unlock_flags)(struct mtx *m, int opts, const char *file, int line) = kdlsym(_mtx_unlock_flags); int result = proc_rw_mem(process, (void*)request->address, request->dataLength, request->data, &request->dataLength, 1); // You need to unlock the process, or the kernel will assert and hang PROC_UNLOCK(process); WriteLog(LL_Debug, "proc_rw_mem returned %d", result); cleanup: __dec(ref); }
/* * Reference to a struct as a :: name. */ NODE * cxxrstruct(int soru, NODE *attr, NODE *t, char *n) { struct symtab *ns, *sp; ns = pfind(t, spole->sup); if (ns == NULL) goto undecl; tfree(t); sp = sfind(n, ns); while (sp != NULL) { if (sp->sclass == soru) return mkty(sp->stype, 0, sp->sap); sp = sfind(n, sp->snext); } undecl: uerror("%s undeclared", n); return mkty(INT, 0, 0); }
//2. Define syscall(struct thread *td, struct syscall_args *arg){...} static int setSocialInfo(struct thread *td, struct setSocialInfo_args *arg) { //setSocialInfo logic: //if PID exists, set social_info to such process //if PID does not exists, return error code (-1) struct proc *process2; process2 = pfind(arg->pid); if(process2 == NULL){ td->td_retval[0] = -1; return 0; } else{ process2->social_info = arg->social_info; //set process's social_info with arg's social_info PROC_UNLOCK(process2); return 0; } }
//2. Define syscall(struct thread *td, struct syscall_args *arg){...} static int getProcessTickets(struct thread *td, struct getProcessTickets_args *arg) { //getProcessTickets logic here //if PID exists, get tickets from such process //if PID does not exists, return error code (-1) struct proc *process1; int procTickets; process1 = pfind(arg->pid); if(process1 == NULL){ td->td_retval[0] = -1; return 0; } else{ procTickets = process1->tickets; td->td_retval[0] = procTickets; PROC_UNLOCK(process1); return 0; } }
/* * sys-trace system call. */ ptrace() { register struct proc *p; register struct a { int req; int pid; int *addr; int data; } *uap; uap = (struct a *)u.u_ap; if (uap->req <= 0) { u.u_procp->p_flag |= STRC; return; } p = pfind(uap->pid); if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid || !(p->p_flag & STRC)) { u.u_error = ESRCH; return; } while (ipc.ip_lock) sleep((caddr_t)&ipc, IPCPRI); ipc.ip_lock = p->p_pid; ipc.ip_data = uap->data; ipc.ip_addr = uap->addr; ipc.ip_req = uap->req; p->p_flag &= ~SWTED; while (ipc.ip_req > 0) { if (p->p_stat==SSTOP) setrun(p); sleep((caddr_t)&ipc, IPCPRI); } u.u_r.r_val1 = ipc.ip_data; if (ipc.ip_req < 0) u.u_error = EIO; ipc.ip_lock = 0; wakeup((caddr_t)&ipc); }
/* * sys-trace system call. */ void ptrace() { register struct proc *p; register struct a { int req; int pid; int *addr; int data; } *uap; uap = (struct a *)u.u_arg; if (uap->req <= 0) { u.u_procp->p_flag |= P_TRACED; return; } p = pfind(uap->pid); if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid || !(p->p_flag & P_TRACED)) { u.u_error = ESRCH; return; } while (ipc.ip_lock) sleep((caddr_t)&ipc, PZERO); ipc.ip_lock = p->p_pid; ipc.ip_data = uap->data; ipc.ip_addr = uap->addr; ipc.ip_req = uap->req; p->p_flag &= ~P_WAITED; setrun(p); while (ipc.ip_req > 0) sleep((caddr_t)&ipc, PZERO); u.u_rval = ipc.ip_data; if (ipc.ip_req < 0) u.u_error = EIO; ipc.ip_lock = 0; wakeup((caddr_t)&ipc); }
/* * Get an arbitrary pid's session id. */ int sys_getsid(struct getsid_args *uap) { struct proc *p = curproc; struct proc *pt; int error; error = 0; if (uap->pid == 0) { pt = p; PHOLD(pt); } else { pt = pfind(uap->pid); if (pt == NULL) error = ESRCH; } if (error == 0) uap->sysmsg_result = pt->p_session->s_sid; if (pt) PRELE(pt); return (error); }
//2. Define syscall(struct thread *td, struct syscall_args *arg){...} static int setProcessTickets(struct thread *td, struct setProcessTickets_args *arg) { /* setProcessTickets logic: if PID exists, set tickets to such process if PID does not exists, return error code (-1) */ struct proc *process0; process0 = pfind(arg->pid); if(process0 == NULL){ td->td_retval[0] = -1; return 0; } else{ process0->tickets = arg->tickets; //set process1's tickets with arg's tickets td->td_retval[0] = process0->tickets; PROC_UNLOCK(process0); return 0; } }
//2. Define syscall(struct thread *td, struct syscall_args *arg){...} static u_int64_t getSocialInfo(struct thread *td, struct getSocialInfo_args *arg) { //getSocialInfo logic: //if PID exists, get social_info from such process //if PID does not exists, return error code (-1) struct proc *process0; u_int64_t social_info; process0 = pfind(arg->pid); if(process0 == NULL){ td->td_retval[0] = -1; return 0; } else{ social_info = process0->social_info; //get process's social_info td->td_retval[0] = social_info; //will just truncate PROC_UNLOCK(process0); return 0; } }
/* * Fork a kernel thread. Any process can request this to be done. * The VM space and limits, etc. will be shared with proc0. */ int kthread_create(void (*func)(void *), void *arg, struct proc **newpp, const char *fmt, ...) { struct proc *p2; register_t rv[2]; int error; va_list ap; /* * First, create the new process. Share the memory, file * descriptors and don't leave the exit status around for the * parent to wait for. */ error = fork1(&proc0, 0, FORK_SHAREVM|FORK_NOZOMBIE|FORK_SIGHAND, NULL, 0, func, arg, rv); if (error) return (error); p2 = pfind(rv[0]); /* * Mark it as a system process and not a candidate for * swapping. */ p2->p_flag |= P_INMEM | P_SYSTEM; /* XXX */ /* Name it as specified. */ va_start(ap, fmt); vsnprintf(p2->p_comm, sizeof p2->p_comm, fmt, ap); va_end(ap); /* All done! */ if (newpp != NULL) *newpp = p2; return (0); }