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);
- }