Annotation of prex-old/usr/server/proc/pid.c, Revision 1.1.1.1.2.1
1.1 nbrk 1: /*
2: * Copyright (c) 2005-2007, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * pid.c - service for process id.
32: */
33:
34: #include <prex/prex.h>
35: #include <server/proc.h>
36: #include <server/stdmsg.h>
37: #include <sys/list.h>
38:
39: #include <unistd.h>
40: #include <errno.h>
41: #include <stdlib.h>
42:
43: #include "proc.h"
44:
45: /*
46: * PID previously allocated.
47: *
48: * Note: The following pids are reserved by default.
49: * pid = 0: Process server
50: * pid = 1: Init process
51: */
52: static pid_t last_pid = 1;
53:
54: /*
55: * Assign new pid.
56: * Returns pid on sucess, or 0 on failure.
57: */
58: pid_t
59: pid_assign(void)
60: {
61: pid_t pid;
62:
63: pid = last_pid + 1;
64: if (pid >= PID_MAX)
65: pid = 1;
66: while (pid != last_pid) {
1.1.1.1.2.1! nbrk 67: if (proc_find(pid) == NULL)
1.1 nbrk 68: break;
69: if (++pid >= PID_MAX)
70: pid = 1;
71: }
72: if (pid == last_pid)
73: return 0;
74: last_pid = pid;
75: return pid;
76: }
77:
78: /*
1.1.1.1.2.1! nbrk 79: * getpid - get the process ID.
1.1 nbrk 80: */
81: int
82: proc_getpid(struct msg *msg)
83: {
84:
85: if (curproc == NULL)
86: return ESRCH;
87:
1.1.1.1.2.1! nbrk 88: msg->data[0] = (int)curproc->p_pid;
1.1 nbrk 89: return 0;
90: }
91:
92: /*
1.1.1.1.2.1! nbrk 93: * getppid - get the parent process ID.
1.1 nbrk 94: */
95: int
96: proc_getppid(struct msg *msg)
97: {
98:
99: if (curproc == NULL)
100: return ESRCH;
101:
1.1.1.1.2.1! nbrk 102: msg->data[0] = (int)curproc->p_parent->p_pid;
1.1 nbrk 103: return 0;
104: }
105:
106: /*
1.1.1.1.2.1! nbrk 107: * getpgid - get the process group ID for a process.
! 108: *
! 109: * If the specified pid is equal to 0, it returns the process
! 110: * group ID of the calling process.
1.1 nbrk 111: */
112: int
113: proc_getpgid(struct msg *msg)
114: {
115: pid_t pid;
116: struct proc *p;
117:
1.1.1.1.2.1! nbrk 118: if (curproc == NULL)
1.1 nbrk 119: return ESRCH;
120:
1.1.1.1.2.1! nbrk 121: pid = (pid_t)msg->data[0];
! 122: if (pid == 0)
! 123: p = curproc;
! 124: else {
! 125: if ((p = proc_find(pid)) == NULL)
! 126: return ESRCH;
! 127: }
! 128: msg->data[0] = (int)p->p_pgrp->pg_pgid;
! 129: DPRINTF(("proc: getpgid pgid=%d\n", msg->data[0]));
1.1 nbrk 130: return 0;
131: }
132:
133: /*
1.1.1.1.2.1! nbrk 134: * setpgid - set process group ID for job control.
! 135: *
! 136: * If the specified pid is equal to 0, it the process ID of
! 137: * the calling process is used. Also, if pgid is 0, the process
! 138: * ID of the indicated process is used.
1.1 nbrk 139: */
140: int
141: proc_setpgid(struct msg *msg)
142: {
143: pid_t pid, pgid;
144: struct proc *p;
145: struct pgrp *pgrp;
146:
1.1.1.1.2.1! nbrk 147: DPRINTF(("proc: setpgid pid=%d pgid=%d\n", msg->data[0],
! 148: msg->data[1]));
! 149:
! 150: if (curproc == NULL)
! 151: return ESRCH;
! 152:
1.1 nbrk 153: pid = (pid_t)msg->data[0];
1.1.1.1.2.1! nbrk 154: if (pid == 0)
! 155: p = curproc;
! 156: else {
! 157: if ((p = proc_find(pid)) == NULL)
! 158: return ESRCH;
! 159: }
1.1 nbrk 160: pgid = (pid_t)msg->data[1];
161: if (pgid < 0)
162: return EINVAL;
1.1.1.1.2.1! nbrk 163: if (pgid == 0)
! 164: pgid = p->p_pid;
! 165: if (p->p_pgrp->pg_pgid == pgid) /* already leader */
1.1 nbrk 166: return 0;
167:
1.1.1.1.2.1! nbrk 168: if ((pgrp = pgrp_find(pgid)) == NULL) {
1.1 nbrk 169: /*
1.1.1.1.2.1! nbrk 170: * Create a new process group.
1.1 nbrk 171: */
1.1.1.1.2.1! nbrk 172: if ((pgrp = malloc(sizeof(struct pgrp))) == NULL)
1.1 nbrk 173: return ENOMEM;
1.1.1.1.2.1! nbrk 174: list_init(&pgrp->pg_members);
! 175: pgrp->pg_pgid = pgid;
1.1 nbrk 176: pgrp_add(pgrp);
1.1.1.1.2.1! nbrk 177: } else {
1.1 nbrk 178: /*
1.1.1.1.2.1! nbrk 179: * Join an existing process group.
! 180: * Remove from the old process group.
1.1 nbrk 181: */
1.1.1.1.2.1! nbrk 182: list_remove(&p->p_pgrp_link);
1.1 nbrk 183: }
1.1.1.1.2.1! nbrk 184: list_insert(&pgrp->pg_members, &p->p_pgrp_link);
! 185: p->p_pgrp = pgrp;
! 186: return 0;
! 187: }
! 188:
! 189: /*
! 190: * getsid - get the process group ID of a session leader.
! 191: */
! 192: int
! 193: proc_getsid(struct msg *msg)
! 194: {
! 195: pid_t pid;
! 196: struct proc *p, *leader;
! 197:
! 198: if (curproc == NULL)
! 199: return ESRCH;
! 200:
! 201: pid = (pid_t)msg->data[0];
! 202: if (pid == 0)
! 203: p = curproc;
! 204: else {
! 205: if ((p = proc_find(pid)) == NULL)
! 206: return ESRCH;
! 207: }
! 208: leader = p->p_pgrp->pg_session->s_leader;
! 209: msg->data[0] = (int)leader->p_pid;
! 210: DPRINTF(("proc: getsid sid=%d\n", msg->data[0]));
! 211: return 0;
! 212: }
! 213:
! 214: /*
! 215: * setsid - create session and set process group ID.
! 216: */
! 217: int
! 218: proc_setsid(struct msg *msg)
! 219: {
! 220: struct proc *p;
! 221: struct pgrp *pgrp;
! 222: struct session *sess;
! 223:
! 224: if (curproc == NULL)
! 225: return ESRCH;
! 226: p = curproc;
! 227: if (p->p_pid == p->p_pgrp->pg_pgid) /* already leader */
! 228: return EPERM;
! 229:
! 230: if ((sess = malloc(sizeof(struct session))) == NULL)
! 231: return ENOMEM;
! 232:
! 233: /*
! 234: * Create a new process group.
! 235: */
! 236: if ((pgrp = malloc(sizeof(struct pgrp))) == NULL) {
! 237: free(sess);
! 238: return ENOMEM;
! 239: }
! 240: list_init(&pgrp->pg_members);
! 241: pgrp->pg_pgid = p->p_pid;
! 242: pgrp_add(pgrp);
! 243: list_remove(&p->p_pgrp_link);
! 244: list_insert(&pgrp->pg_members, &p->p_pgrp_link);
! 245: p->p_pgrp = pgrp;
! 246:
! 247: /*
! 248: * Create a new session.
! 249: */
! 250: sess->s_refcnt = 1;
! 251: sess->s_leader = p;
! 252: sess->s_ttyhold = 0;
! 253: pgrp->pg_session = sess;
! 254:
! 255: msg->data[0] = (int)p->p_pid;
! 256: DPRINTF(("proc: setsid sid=%d\n", msg->data[0]));
1.1 nbrk 257: return 0;
258: }
CVSweb