root / prex-0.9.0 / usr / server / proc / proc_pid.c @ 03e9c04a
History | View | Annotate | Download (5.02 KB)
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 <sys/prex.h> |
35 |
#include <ipc/proc.h> |
36 |
#include <ipc/ipc.h> |
37 |
#include <sys/list.h> |
38 |
|
39 |
#include <unistd.h> |
40 |
#include <errno.h> |
41 |
#include <stdlib.h> |
42 |
#include <string.h> |
43 |
|
44 |
#include "proc.h" |
45 |
|
46 |
/*
|
47 |
* getpid - get the process ID.
|
48 |
*/
|
49 |
pid_t |
50 |
sys_getpid(void)
|
51 |
{ |
52 |
|
53 |
ASSERT(curproc); |
54 |
return curproc->p_pid;
|
55 |
} |
56 |
|
57 |
/*
|
58 |
* getppid - get the parent process ID.
|
59 |
*/
|
60 |
pid_t |
61 |
sys_getppid(void)
|
62 |
{ |
63 |
|
64 |
ASSERT(curproc); |
65 |
return curproc->p_parent->p_pid;
|
66 |
} |
67 |
|
68 |
/*
|
69 |
* getpgid - get the process group ID for a process.
|
70 |
*
|
71 |
* If the specified pid is equal to 0, it returns the process
|
72 |
* group ID of the calling process.
|
73 |
*/
|
74 |
int
|
75 |
sys_getpgid(pid_t pid, pid_t *retval) |
76 |
{ |
77 |
struct proc *p;
|
78 |
|
79 |
ASSERT(curproc); |
80 |
|
81 |
if (pid == 0) |
82 |
p = curproc; |
83 |
else {
|
84 |
if ((p = p_find(pid)) == NULL) |
85 |
return ESRCH;
|
86 |
} |
87 |
*retval = p->p_pgrp->pg_pgid; |
88 |
return 0; |
89 |
} |
90 |
|
91 |
/*
|
92 |
* getsid - get the process group ID of a session leader.
|
93 |
*/
|
94 |
int
|
95 |
sys_getsid(pid_t pid, pid_t *retval) |
96 |
{ |
97 |
pid_t sid; |
98 |
struct proc *p, *leader;
|
99 |
|
100 |
ASSERT(curproc); |
101 |
|
102 |
if (pid == 0) |
103 |
p = curproc; |
104 |
else {
|
105 |
if ((p = p_find(pid)) == NULL) |
106 |
return ESRCH;
|
107 |
} |
108 |
leader = p->p_pgrp->pg_session->s_leader; |
109 |
sid = leader->p_pid; |
110 |
|
111 |
DPRINTF(("proc: getsid sid=%d\n", sid));
|
112 |
*retval = sid; |
113 |
return 0; |
114 |
} |
115 |
|
116 |
/*
|
117 |
* Move process to a new or existing process group.
|
118 |
*/
|
119 |
int
|
120 |
enterpgrp(struct proc *p, pid_t pgid)
|
121 |
{ |
122 |
struct pgrp *pgrp;
|
123 |
|
124 |
DPRINTF(("proc: enter pgrp pid=%d pgid=%d\n", p->p_pid, pgid));
|
125 |
if ((pgrp = pg_find(pgid)) == NULL) { |
126 |
/*
|
127 |
* Create a new process group.
|
128 |
*/
|
129 |
DPRINTF(("proc: create new pgrp\n"));
|
130 |
if ((pgrp = malloc(sizeof(struct pgrp))) == NULL) |
131 |
return ENOMEM;
|
132 |
memset(pgrp, 0, sizeof(*pgrp)); |
133 |
list_init(&pgrp->pg_members); |
134 |
pgrp->pg_pgid = pgid; |
135 |
pg_add(pgrp); |
136 |
} |
137 |
/*
|
138 |
* Remove from the old process group.
|
139 |
* And, join an existing process group.
|
140 |
*/
|
141 |
list_remove(&p->p_pgrp_link); |
142 |
list_insert(&pgrp->pg_members, &p->p_pgrp_link); |
143 |
pgrp->pg_session = curproc->p_pgrp->pg_session; |
144 |
p->p_pgrp = pgrp; |
145 |
return 0; |
146 |
} |
147 |
|
148 |
/*
|
149 |
* Remove process from process group.
|
150 |
*/
|
151 |
int
|
152 |
leavepgrp(struct proc *p)
|
153 |
{ |
154 |
struct pgrp *pgrp = p->p_pgrp;
|
155 |
|
156 |
list_remove(&p->p_pgrp_link); |
157 |
if (list_empty(&pgrp->pg_members)) {
|
158 |
|
159 |
/* XXX: do some work for session */
|
160 |
|
161 |
pg_remove(pgrp); |
162 |
free(pgrp); |
163 |
} |
164 |
p->p_pgrp = 0;
|
165 |
return (0); |
166 |
} |
167 |
|
168 |
|
169 |
/*
|
170 |
* setpgid - set process group ID for job control.
|
171 |
*
|
172 |
* If the specified pid is equal to 0, the process ID of
|
173 |
* the calling process is used. Also, if pgid is 0, the process
|
174 |
* ID of the indicated process is used.
|
175 |
*/
|
176 |
int
|
177 |
sys_setpgid(pid_t pid, pid_t pgid) |
178 |
{ |
179 |
struct proc *p;
|
180 |
|
181 |
DPRINTF(("proc: setpgid pid=%d pgid=%d\n", pid, pgid));
|
182 |
|
183 |
if (pid == 0) |
184 |
p = curproc; |
185 |
else {
|
186 |
if ((p = p_find(pid)) == NULL) |
187 |
return ESRCH;
|
188 |
} |
189 |
if (pgid < 0) |
190 |
return EINVAL;
|
191 |
if (pgid == 0) |
192 |
pgid = p->p_pid; |
193 |
if (p->p_pgrp->pg_pgid == pgid) /* already leader */ |
194 |
return 0; |
195 |
return (enterpgrp(p, pgid));
|
196 |
} |
197 |
|
198 |
/*
|
199 |
* setsid - create session and set process group ID.
|
200 |
*/
|
201 |
int
|
202 |
sys_setsid(pid_t *retval) |
203 |
{ |
204 |
struct proc *p;
|
205 |
struct pgrp *pgrp;
|
206 |
struct session *sess;
|
207 |
int error;
|
208 |
|
209 |
DPRINTF(("proc: setsid sid=%d\n", curproc->p_pid));
|
210 |
|
211 |
p = curproc; |
212 |
if (p->p_pid == p->p_pgrp->pg_pgid) /* already leader */ |
213 |
return EPERM;
|
214 |
|
215 |
if ((sess = malloc(sizeof(struct session))) == NULL) |
216 |
return ENOMEM;
|
217 |
memset(sess, 0, sizeof(*sess)); |
218 |
|
219 |
/*
|
220 |
* Create a new process group.
|
221 |
*/
|
222 |
if ((error = enterpgrp(p, p->p_pid)) != 0) { |
223 |
free(sess); |
224 |
return error;
|
225 |
} |
226 |
pgrp = p->p_pgrp; |
227 |
|
228 |
/*
|
229 |
* Create a new session.
|
230 |
*/
|
231 |
sess->s_refcnt = 1;
|
232 |
sess->s_leader = p; |
233 |
sess->s_ttyhold = 0;
|
234 |
pgrp->pg_session = sess; |
235 |
|
236 |
*retval = p->p_pid; |
237 |
return 0; |
238 |
} |