-
Notifications
You must be signed in to change notification settings - Fork 12
/
setsid.c
93 lines (86 loc) · 2.98 KB
/
setsid.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* Copyright (c) 2012 Jerry Kuch
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
/**
* An ersatz setsid command for those Unixes (e.g. Mac OS X) that
* don't have one. Intended to work like (or enough like) the one
* from the util-linux-ng package that I can run the RabbitMQ test
* suite post summer 2011 on a Mac OS X dev machine.
*
* Synopsis:
* setsid program [arg...]
*
* Description:
* setsid runs a program in a new session.
*
* See Also:
* setsid(2)
*
*/
int
main(int argc, char *argv[])
{
if( argc < 2 )
{
fprintf(stderr,
"usage: %s program [arg ...]\n",
(char *)argv[0]);
}
// Are we the leader of a process group (i.e. is our process id
// equal to our process group id?)?
if (getpgrp() == getpid())
{
switch(fork())
{
case 0:
// We're in the child process...
break;
case -1:
// We're in the parent process and child creation
// failed, so squawk and exit with error code...
perror("fork");
exit(1);
default:
// We're in the parent process (setsid itself), child
// creation was OK...
exit(0);
}
}
// Create a new session and make this setsid process the session
// leader for the new session; This setsid process also becomes
// the process group leader of a new process group and has no
// controlling terminal...
if (setsid() < 0)
{
perror("setsid");
exit(1);
}
// Execute the requested command with the given arguments,
// replacing our current process image (which now has its own
// happy session and group) with a new process image...
execvp(argv[1], argv + 1);
// If we got to here, squawk and exit with an error code...
perror("execvp");
exit(1);
}