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