mirror of
https://github.com/ish-app/ish.git
synced 2026-02-01 14:32:26 +00:00
This seems moderately successful, I was able to get logging out of the CLI build with syslog(). I may marely have been having trouble with logging on my Mac.
127 lines
3.7 KiB
C
127 lines
3.7 KiB
C
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <syslog.h>
|
|
#include "kernel/init.h"
|
|
#include "kernel/fs.h"
|
|
#include "fs/devices.h"
|
|
#include "fs/real.h"
|
|
#ifdef __APPLE__
|
|
#include <sys/resource.h>
|
|
#define IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY 1
|
|
#define IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE 1
|
|
#endif
|
|
|
|
void real_tty_reset_term(void);
|
|
|
|
static void exit_handler(struct task *task, int code) {
|
|
if (task->parent != NULL)
|
|
return;
|
|
real_tty_reset_term();
|
|
if (code & 0xff)
|
|
raise(code & 0xff);
|
|
exit(code >> 8);
|
|
}
|
|
|
|
// this function parses command line arguments and initializes global
|
|
// data structures. thanks programming discussions discord server for the name.
|
|
// https://discord.gg/9zT7NHP
|
|
static inline int xX_main_Xx(int argc, char *const argv[], const char *envp) {
|
|
#ifdef __APPLE__
|
|
// Enable case-sensitive filesystem mode on macOS, if possible.
|
|
// In order for this to succeed, either we need to be running as root, or
|
|
// be given the com.apple.private.iopol.case_sensitivity entitlement. The
|
|
// second option isn't possible so you'll need to give iSH the setuid root
|
|
// bit. In that case it's important to drop root permissions ASAP.
|
|
// https://worthdoingbadly.com/casesensitive-iossim/
|
|
int iopol_err = setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY,
|
|
IOPOL_SCOPE_PROCESS,
|
|
IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE);
|
|
if (iopol_err != 0 && errno != EPERM)
|
|
perror("could not enable case sensitivity");
|
|
setgid(getgid());
|
|
setuid(getuid());
|
|
#endif
|
|
|
|
// parse cli options
|
|
int opt;
|
|
const char *root = NULL;
|
|
const char *workdir = NULL;
|
|
const struct fs_ops *fs = &realfs;
|
|
const char *console = "/dev/tty1";
|
|
while ((opt = getopt(argc, argv, "+r:f:d:c:")) != -1) {
|
|
switch (opt) {
|
|
case 'r':
|
|
case 'f':
|
|
root = optarg;
|
|
if (opt == 'f')
|
|
fs = &fakefs;
|
|
break;
|
|
case 'd':
|
|
workdir = optarg;
|
|
break;
|
|
case 'c':
|
|
console = optarg;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
openlog(argv[0], 0, LOG_USER);
|
|
|
|
char root_realpath[MAX_PATH + 1] = "/";
|
|
if (root != NULL && realpath(root, root_realpath) == NULL) {
|
|
perror(root);
|
|
exit(1);
|
|
}
|
|
if (fs == &fakefs)
|
|
strcat(root_realpath, "/data");
|
|
int err = mount_root(fs, root_realpath);
|
|
if (err < 0)
|
|
return err;
|
|
|
|
become_first_process();
|
|
current->thread = pthread_self();
|
|
char cwd[MAX_PATH + 1];
|
|
if (root == NULL && workdir == NULL) {
|
|
getcwd(cwd, sizeof(cwd));
|
|
workdir = cwd;
|
|
}
|
|
if (workdir != NULL) {
|
|
struct fd *pwd = generic_open(workdir, O_RDONLY_, 0);
|
|
if (IS_ERR(pwd)) {
|
|
fprintf(stderr, "error opening working dir: %ld\n", PTR_ERR(pwd));
|
|
return 1;
|
|
}
|
|
fs_chdir(current->fs, pwd);
|
|
}
|
|
|
|
char argv_copy[4096];
|
|
int i = optind;
|
|
size_t p = 0;
|
|
while (i < argc) {
|
|
strcpy(&argv_copy[p], argv[i]);
|
|
p += strlen(argv[i]) + 1;
|
|
i++;
|
|
}
|
|
argv_copy[p] = '\0';
|
|
if (argv[optind] == NULL)
|
|
return _ENOENT;
|
|
err = do_execve(argv[optind], argc - optind, argv_copy, envp == NULL ? "\0" : envp);
|
|
if (err < 0)
|
|
return err;
|
|
tty_drivers[TTY_CONSOLE_MAJOR] = &real_tty_driver;
|
|
if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
|
|
err = create_stdio(console, TTY_CONSOLE_MAJOR, 1);
|
|
if (err < 0)
|
|
return err;
|
|
} else {
|
|
err = create_piped_stdio();
|
|
if (err < 0)
|
|
return err;
|
|
}
|
|
exit_hook = exit_handler;
|
|
return 0;
|
|
}
|