chroot.c (1449B)
- // utils-std: Collection of commonly available Unix tools
 - // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
 - // SPDX-License-Identifier: MPL-2.0
 - #define _DEFAULT_SOURCE // chroot isn't POSIX
 - #include <assert.h> // assert
 - #include <errno.h> // errno
 - #include <limits.h> // PATH_MAX
 - #include <stdbool.h> // false
 - #include <stdio.h> // fprintf, perror
 - #include <stdlib.h> // getenv
 - #include <string.h> // strlen
 - #include <unistd.h> // chroot, execl, execv
 - int
 - main(int argc, char *argv[])
 - {
 - if(argc < 2)
 - {
 - fprintf(stderr, "chroot: error: Needs arguments\n");
 - fprintf(stderr, "Usage: chroot <newroot> [command [args ...]]\n");
 - return 125;
 - }
 - if(chroot(argv[1]) < 0)
 - {
 - perror("chroot: error: Failed to chroot");
 - return 125;
 - }
 - if(chdir("/") < 0)
 - {
 - perror("chroot: error: Failed to change directory");
 - return 125;
 - }
 - int ret = 0;
 - errno = 0;
 - if(argc == 2)
 - {
 - const char *shell = getenv("SHELL");
 - if(shell == NULL) shell = "/bin/sh";
 - if(strnlen(shell, PATH_MAX) >= PATH_MAX)
 - {
 - fprintf(stderr,
 - "chroot: warning: $SHELL is longer than {PATH_MAX}(= %d), using '/bin/sh'\n",
 - PATH_MAX);
 - shell = "/bin/sh";
 - }
 - ret = execlp(shell, shell, "-i", (char *)0);
 - }
 - else
 - {
 - argv += 2;
 - ret = execvp(argv[0], argv);
 - }
 - if(ret != 0)
 - {
 - perror("chroot: error: Execution failed");
 - if(errno == ENOENT) return 127;
 - return 126;
 - }
 - assert(false);
 - }