1 module symmetry.linux.process;
2 import symmetry.sildoc;
3 
4 version(Posix):
5 
6 
7 extern(C) @nogc nothrow
8 {
9     import std.conv : to;
10 	int clone(int function(void*), void* child_stack, int flags, void* arg, ...);
11 	int unshare(int flags) @trusted;
12 
13 	enum CLONE_VM = 		0x100;
14 	enum CLONE_FS = 		0x200;
15 	enum CLONE_FILES = 		0x400;
16 	enum CLONE_SIGHAND = 	0x800;
17 	enum CLONE_PTRACE  = "00002000".to!int(16);
18 	enum CLONE_VFORK   = "00004000".to!int(16);
19 	enum CLONE_PARENT  = "00008000".to!int(16);
20 	enum CLONE_THREAD  = "00010000".to!int(16);
21 	enum CLONE_NEWNS   = "00020000".to!int(16);
22 	enum CLONE_SYSVSEM = "00040000".to!int(16);
23 	enum CLONE_SETTLS  = "00080000".to!int(16);
24 	enum CLONE_PARENT_SETTID  = "00100000".to!int(16);
25 	enum CLONE_CHILD_CLEARTID = "00200000".to!int(16);
26 	enum CLONE_DETACHED       = "00400000".to!int(16);
27 	enum CLONE_UNTRACED       = "00800000".to!int(16);
28 	enum CLONE_CHILD_SETTID   = "01000000".to!int(16);
29 	enum CLONE_NEWCGROUP      = "02000000".to!int(16);
30 	enum CLONE_NEWUTS         = "04000000".to!int(16);
31 	enum CLONE_NEWIPC         = "08000000".to!int(16);
32 	enum CLONE_NEWUSER        = "10000000".to!int(16);
33 	enum CLONE_NEWPID         = "20000000".to!int(16);
34 	enum CLONE_NEWNET         = "40000000".to!int(16);
35 	enum CLONE_IO             = "80000000".to!uint(16);
36 }
37 
38 
39 enum CloneFlag
40 {
41 	none = 0,
42 
43 	@SILdoc("set if open files shared between processes")
44 	files = CLONE_FILES,
45 
46 	@SILdoc("set if file system info shared between processes")
47 	fs = CLONE_FS,
48 
49 	@SILdoc("set if signal handlers and blocked signals shared")
50 	sigHand = CLONE_SIGHAND,
51 
52 	@SILdoc("set if VM shared between processes")
53 	vm = CLONE_VM,
54 
55 	@SILdoc("set if we want to let tracing continue on the child too")
56 	ptrace = CLONE_PTRACE,
57 
58 	@SILdoc("set if the parent wants the child to wake it up on mm_release")
59   	vfork = CLONE_VFORK,
60 
61 	@SILdoc("set if we want to have the same parent as the cloner")
62 	parent = CLONE_PARENT,
63 
64 	@SILdoc("Same thread group?")
65 	thread = CLONE_THREAD,
66 
67 	@SILdoc("New mount namespace group")
68 	newMountNamespace = CLONE_NEWNS,
69 
70 	@SILdoc("share system V SEM_UNDO semantics")
71 	sysVSemantics = CLONE_SYSVSEM,
72 
73 	@SILdoc("create a new TLS for the child")
74 	setTLS = CLONE_SETTLS,
75 
76 	@SILdoc("set the TID in the parent")
77 	parentSetTID = CLONE_PARENT_SETTID,
78 
79 	@SILdoc("clear the TID in the child")
80 	childClearTID = CLONE_CHILD_CLEARTID,
81 	
82 	@SILdoc("Unused, ignored")
83 	detached = CLONE_DETACHED,
84 
85 	@SILdoc("set if the tracing process can't force CLONE_PTRACE on this clone")
86 	untraced = CLONE_UNTRACED,
87 
88 	@SILdoc("set the TID in the child")
89 	childSetTID = CLONE_CHILD_SETTID,
90 
91 	@SILdoc("New cgroup namespace")
92 	newCGroup = CLONE_NEWCGROUP,
93 
94 	@SILdoc("New utsname namespace")
95 	newUTS = CLONE_NEWUTS,
96 
97 	@SILdoc("New ipc namespace")
98 	newIPC = CLONE_NEWIPC,
99 
100 	@SILdoc("New user namespace")
101 	newUser = CLONE_NEWUSER,
102 
103 	@SILdoc("New pid namespace")
104 	newPid = CLONE_NEWPID,
105 
106 	@SILdoc("New network namespace")
107 	newNet = CLONE_NEWNET,
108 
109 	@SILdoc("Clone io context")
110 	io = CLONE_IO,
111 }
112 
113 CloneFlag[] cloneFlagsFromPosix(int flags)
114 {
115 	import std.traits : EnumMembers;
116 	CloneFlag[] ret;
117 	static foreach(M;EnumMembers!CloneFlag)
118 	{
119 		if (flags & M)
120 			ret ~= M;
121 	}
122 	return ret;
123 }
124 
125 string[] cloneFlags()
126 {
127     import std.traits : EnumMembers;
128     import std.conv : to;
129     import std.array: Appender;
130     Appender!(string[]) ret;
131     static foreach(E;EnumMembers!CloneFlag)
132         ret.put(E.to!string);
133     return ret.data;
134 }
135 
136 CloneFlag cloneFlag(string flagName)
137 {
138     import std.traits : EnumMembers;
139     import std.conv : to;
140     static foreach(E;EnumMembers!CloneFlag)
141     {
142         if (E.to!string == flagName)
143             return E;
144     }
145     throw new Exception ("unknown clone flag: " ~flagName);
146 }
147 
148 int posixCloneFlags(CloneFlag[] cloneFlags)
149 {
150 	import std.conv : to;
151 	int i;
152 	foreach(flag;cloneFlags)
153 	{
154 		i |= flag.to!int;
155 	}
156 	return i;
157 }
158 
159