/* * unshare(1) - command-line interface for unshare(2) * * Copyright (C) 2009 Mikhail Gusarov * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include "nls.h" #ifndef CLONE_NEWSNS # define CLONE_NEWNS 0x00020000 #endif #ifndef CLONE_NEWUTS # define CLONE_NEWUTS 0x04000000 #endif #ifndef CLONE_NEWIPC # define CLONE_NEWIPC 0x08000000 #endif #ifndef CLONE_NEWNET # define CLONE_NEWNET 0x40000000 #endif #ifndef HAVE_UNSHARE # include static int unshare(int flags) { return syscall(SYS_unshare, flags); } #endif static void usage(int status, const char *my_program_invocation_short_name) { FILE *out = status == EXIT_SUCCESS ? stdout : stderr; fprintf(out, _("Usage: %s [options] [args...]\n"), my_program_invocation_short_name); fputs(_("Run program with some namespaces unshared from parent\n\n" " -h, --help usage information (this)\n" " -m, --mount unshare mounts namespace\n" " -u, --uts unshare UTS namespace (hostname etc)\n" " -i, --ipc unshare System V IPC namespace\n" " -n, --net unshare network namespace\n"), out); fprintf(out, _("\nFor more information see unshare(1).\n")); exit(status); } int main(int argc, char *argv[]) { struct option longopts[] = { { "help", no_argument, 0, 'h' }, { "mount", no_argument, 0, 'm' }, { "uts", no_argument, 0, 'u' }, { "ipc", no_argument, 0, 'i' }, { "net", no_argument, 0, 'n' }, }; int unshare_flags = 0; int c; setlocale(LC_MESSAGES, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while((c = getopt_long(argc, argv, "hmuin", longopts, NULL)) != -1) { switch(c) { case 'h': usage(EXIT_SUCCESS, argv[0]); case 'm': unshare_flags |= CLONE_NEWNS; break; case 'u': unshare_flags |= CLONE_NEWUTS; break; case 'i': unshare_flags |= CLONE_NEWIPC; break; case 'n': unshare_flags |= CLONE_NEWNET; break; default: usage(EXIT_FAILURE, argv[0]); } } if(optind >= argc) usage(EXIT_FAILURE, argv[0]); if(-1 == unshare(unshare_flags)) err(EXIT_FAILURE, _("unshare failed")); execvp(argv[optind], argv + optind); err(EXIT_FAILURE, _("exec %s failed"), argv[optind]); }