Annotation of prex/usr/server/proc/pid.c, Revision 1.1.1.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) {
67: if (proc_find(pid) == NULL)
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: /*
79: * getpid - get the process ID.
80: */
81: int
82: proc_getpid(struct msg *msg)
83: {
84:
85: if (curproc == NULL)
86: return ESRCH;
87:
88: msg->data[0] = (int)curproc->p_pid;
89: return 0;
90: }
91:
92: /*
93: * getppid - get the parent process ID.
94: */
95: int
96: proc_getppid(struct msg *msg)
97: {
98:
99: if (curproc == NULL)
100: return ESRCH;
101:
102: msg->data[0] = (int)curproc->p_parent->p_pid;
103: return 0;
104: }
105:
106: /*
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.
111: */
112: int
113: proc_getpgid(struct msg *msg)
114: {
115: pid_t pid;
116: struct proc *p;
117:
118: if (curproc == NULL)
119: return ESRCH;
120:
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]));
130: return 0;
131: }
132:
133: /*
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.
139: */
140: int
141: proc_setpgid(struct msg *msg)
142: {
143: pid_t pid, pgid;
144: struct proc *p;
145: struct pgrp *pgrp;
146:
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:
153: pid = (pid_t)msg->data[0];
154: if (pid == 0)
155: p = curproc;
156: else {
157: if ((p = proc_find(pid)) == NULL)
158: return ESRCH;
159: }
160: pgid = (pid_t)msg->data[1];
161: if (pgid < 0)
162: return EINVAL;
163: if (pgid == 0)
164: pgid = p->p_pid;
165: if (p->p_pgrp->pg_pgid == pgid) /* already leader */
166: return 0;
167:
168: if ((pgrp = pgrp_find(pgid)) == NULL) {
169: /*
170: * Create a new process group.
171: */
172: if ((pgrp = malloc(sizeof(struct pgrp))) == NULL)
173: return ENOMEM;
174: list_init(&pgrp->pg_members);
175: pgrp->pg_pgid = pgid;
176: pgrp_add(pgrp);
177: } else {
178: /*
179: * Join an existing process group.
180: * Remove from the old process group.
181: */
182: list_remove(&p->p_pgrp_link);
183: }
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]));
257: return 0;
258: }
CVSweb