Statistics
| Branch: | Revision:

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
}