3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // Copyright (C) 2007 Daniel Hokka Zakrisson
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; version 2 of the License.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <lib_internal/sys_clone.h>
35 #define ENSC_WRAPPERS_PREFIX "vspace: "
36 #define ENSC_WRAPPERS_UNISTD 1
37 #define ENSC_WRAPPERS_VSERVER 1
40 #define CMD_HELP 0x1000
41 #define CMD_VERSION 0x1001
43 int wrapper_exit_code = 255;
47 { "help", no_argument, 0, CMD_HELP },
48 { "version", no_argument, 0, CMD_VERSION },
49 { "new", no_argument, 0, 'n' },
50 { "enter", required_argument, 0, 'e' },
51 { "set", no_argument, 0, 's' },
52 { "index", required_argument, 0, 'i' },
53 { "mask", required_argument, 0, 'm' },
54 { "default", no_argument, 0, 'd' },
55 { "~default", no_argument, 0, 'd' | 0x10000 },
57 { "mount", no_argument, 0, 'M' },
58 { "~mount", no_argument, 0, 'M' | 0x10000 },
59 { "fs", no_argument, 0, 'F' },
60 { "~fs", no_argument, 0, 'F' | 0x10000 },
61 { "ipc", no_argument, 0, 'I' },
62 { "~ipc", no_argument, 0, 'I' | 0x10000 },
63 { "uts", no_argument, 0, 'U' },
64 { "~uts", no_argument, 0, 'U' | 0x10000 },
65 { "user", no_argument, 0, 'S' },
66 { "~user", no_argument, 0, 'S' | 0x10000 },
67 { "pid", no_argument, 0, 'P' },
68 { "~pid", no_argument, 0, 'P' | 0x10000 },
69 { "net", no_argument, 0, 'N' },
70 { "~net", no_argument, 0, 'N' | 0x10000 },
75 showHelp(int fd, char const *cmd, int res)
77 WRITE_MSG(fd, "Usage: ");
80 " <operation> <spaces>* [--] [<program> <args>*]\n"
82 "<operation> can be one of:\n"
83 " --new|-n ... create new spaces and execute <program> there;\n"
84 " <program> is mandatory in this case\n"
85 " --enter|-e <xid> ... enter the spaces of context <xid> and execute\n"
86 " <program> there; <program> is mandatory in this\n"
88 " --set|-s ... assign the current spaces to the current context\n"
89 " --index|-i <idx> ... work with the namespaces for <idx>\n"
91 "<spaces>* specifies the spaces to manipulate.\n"
92 "It can be any combination of:\n"
93 " --mask <mask> ... specify a mask of spaces\n"
94 " --default ... the default spaces for this kernel\n"
95 " --mount ... the mount namespace\n"
96 " --fs ... the fs_struct\n"
97 " --ipc ... the IPC namespace\n"
98 " --uts ... the uts namespace\n"
99 " --user ... the user namespace\n"
100 " --pid ... the pid namespace\n"
101 " --net ... the network namespace\n"
103 "Please report bugs to " PACKAGE_BUGREPORT "\n");
112 "vspace " VERSION " -- manages spaces\n"
113 "This program is part of " PACKAGE_STRING "\n\n"
114 "Copyright (C) 2004 Enrico Scholz\n"
115 "Copyright (C) 2007 Daniel Hokka Zakrisson\n"
116 VERSION_COPYRIGHT_DISCLAIMER);
121 newSpaces(uint_least64_t mask)
127 signal(SIGCHLD, SIG_DFL);
130 pid = sys_clone((int) mask | CLONE_VFORK|SIGCHLD, 0);
132 pid = sys_clone((int) mask | SIGCHLD, 0);
137 perror(ENSC_WRAPPERS_PREFIX "clone()");
138 exit(wrapper_exit_code);
142 vc_exitLikeProcess(pid, wrapper_exit_code);
147 enterSpaces(xid_t xid, uint_least64_t mask, uint32_t index)
149 if (vc_enter_namespace(xid, mask, index)==-1) {
150 perror(ENSC_WRAPPERS_PREFIX "vc_enter_namespace()");
151 exit(wrapper_exit_code);
156 setSpaces(xid_t xid, uint_least64_t mask, uint32_t index)
158 if (vc_set_namespace(xid, mask, index)==-1) {
159 perror(ENSC_WRAPPERS_PREFIX "vc_set_namespace()");
160 exit(wrapper_exit_code);
164 int main(int argc, char *argv[])
167 bool do_enter = false;
169 uint_least64_t mask = 0;
171 xid_t xid = VC_NOCTX;
175 int c = getopt_long(argc, argv, "+nsce:m:i:" "MFIUSPN", CMDLINE_OPTIONS, 0);
176 uint_least64_t thisbit = 0;
179 switch (c & 0xFFFF) {
180 case CMD_HELP : showHelp(1, argv[0], 0);
181 case CMD_VERSION : showVersion();
182 case 'n' : do_new = true; break;
183 case 's' : do_set = true; break;
186 xid = Evc_xidopt2xid(optarg,true);
189 unsigned long index_l;
190 if (!isNumberUnsigned(optarg, &index_l, true)) {
191 WRITE_MSG(2, "Invalid index '");
192 WRITE_STR(2, optarg);
193 WRITE_MSG(2, "'; try '--help' for more information\n");
194 return wrapper_exit_code;
196 index = (uint32_t)index_l;
200 unsigned long mask_l;
201 if (!isNumberUnsigned(optarg, &mask_l, true)) {
202 WRITE_MSG(2, "Invalid mask '");
203 WRITE_STR(2, optarg);
204 WRITE_MSG(2, "'; try '--help' for more information\n");
205 return wrapper_exit_code;
210 case 'M' : thisbit = CLONE_NEWNS; break;
211 case 'F' : thisbit = CLONE_FS; break;
212 case 'I' : thisbit = CLONE_NEWIPC; break;
213 case 'U' : thisbit = CLONE_NEWUTS; break;
214 case 'S' : thisbit = CLONE_NEWUSER; break;
215 case 'P' : thisbit = CLONE_NEWPID; break;
216 case 'N' : thisbit = CLONE_NEWNET; break;
218 thisbit = vc_get_space_default();
219 if (thisbit == (__typeof__(thisbit)) -1) {
220 thisbit = vc_get_space_mask();
221 if (thisbit == (__typeof__(thisbit)) -1)
227 WRITE_MSG(2, "Try '");
228 WRITE_STR(2, argv[0]);
229 WRITE_MSG(2, " --help' for more information.\n");
240 sum = ((do_new ? 1 : 0) + (do_enter ? 1 : 0) +
244 WRITE_MSG(2, "No operation was specified; try '--help' for more information\n");
246 WRITE_MSG(2, "Can not specify multiple operations; try '--help' for more information\n");
247 else if (optind==argc && (do_new || do_enter))
248 WRITE_MSG(2, "No command specified; try '--help' for more information\n");
250 if (do_new) newSpaces(mask);
251 else if (do_set) setSpaces(VC_SAMECTX, mask, index);
252 else if (do_enter) enterSpaces(xid, mask, index);
255 EexecvpD(argv[optind], argv+optind);