diff -ur coreutils-8.5.orig/src/chroot.c coreutils-8.5/src/chroot.c --- coreutils-8.5.orig/src/chroot.c 2010-04-20 21:52:04.000000000 +0200 +++ coreutils-8.5/src/chroot.c 2011-07-07 15:29:47.000000000 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include #include "system.h" #include "error.h" @@ -37,16 +38,22 @@ # define MAXGID GID_T_MAX #endif +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif + enum { GROUPS = UCHAR_MAX + 1, - USERSPEC + USERSPEC, + HOSTNAME }; static struct option const long_opts[] = { {"groups", required_argument, NULL, GROUPS}, {"userspec", required_argument, NULL, USERSPEC}, + {"hostname", required_argument, NULL, HOSTNAME}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} @@ -132,6 +139,7 @@ fputs (_("\ --userspec=USER:GROUP specify user and group (ID or name) to use\n\ --groups=G_LIST specify supplementary groups as g1,g2,..,gN\n\ + --hostname=HOSTNAME specify a different hostname\n\ "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); @@ -151,6 +159,7 @@ int c; char const *userspec = NULL; char const *groups = NULL; + char const *hostname = NULL; initialize_main (&argc, &argv); set_program_name (argv[0]); @@ -173,6 +182,10 @@ groups = optarg; break; + case HOSTNAME: + hostname = optarg; + break; + case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -188,6 +201,18 @@ usage (EXIT_CANCELED); } + if (hostname) + { + // Use 'syscall' instead of unshare incase glibc doesn't have it. + // unshare(CLONE_NEWUTS); + if (syscall(__NR_unshare, CLONE_NEWUTS)) + error (EXIT_CANCELED, errno, _("new utsname namespace failed")); + + if (sethostname(hostname, strlen(hostname)+1)) + error (EXIT_CANCELED, errno, _("set hostname failed")); + } + + if (chroot (argv[optind]) != 0) error (EXIT_CANCELED, errno, _("cannot change root directory to %s"), argv[optind]);