BuildSystem: Cleanup userspace directory layout
userspace programs are now in userspace/programs userspace tests are now in userspace/tests This makes listing userspace projects much cleaner. Libraries were already separated to their own directory, so other programs should also.
This commit is contained in:
9
userspace/programs/init/CMakeLists.txt
Normal file
9
userspace/programs/init/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(init ${SOURCES})
|
||||
banan_include_headers(init ban)
|
||||
banan_link_library(init libc)
|
||||
|
||||
install(TARGETS init OPTIONAL)
|
||||
138
userspace/programs/init/main.cpp
Normal file
138
userspace/programs/init/main.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <BAN/String.h>
|
||||
#include <BAN/Optional.h>
|
||||
#include <BAN/Vector.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/banan-os.h>
|
||||
#include <termios.h>
|
||||
|
||||
void initialize_stdio()
|
||||
{
|
||||
const char* tty = "/dev/tty";
|
||||
if (open(tty, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
|
||||
if (open(tty, O_WRONLY) != 1) _exit(1);
|
||||
if (open(tty, O_WRONLY) != 2) _exit(1);
|
||||
if (open("/dev/debug", O_WRONLY) != 3) _exit(1);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
initialize_stdio();
|
||||
|
||||
if (signal(SIGINT, [](int) {}) == SIG_ERR)
|
||||
perror("signal");
|
||||
|
||||
if (load_keymap("/usr/share/keymaps/us.keymap") == -1)
|
||||
perror("load_keymap");
|
||||
|
||||
if (fork() == 0)
|
||||
{
|
||||
execl("/bin/dhcp-client", "dhcp-client", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fork() == 0)
|
||||
{
|
||||
execl("/bin/resolver", "resolver", NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
|
||||
termios termios;
|
||||
tcgetattr(STDIN_FILENO, &termios);
|
||||
|
||||
while (true)
|
||||
{
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &termios);
|
||||
|
||||
char name_buffer[128];
|
||||
|
||||
while (!first)
|
||||
{
|
||||
printf("username: ");
|
||||
fflush(stdout);
|
||||
|
||||
ssize_t nread = read(STDIN_FILENO, name_buffer, sizeof(name_buffer) - 1);
|
||||
if (nread == -1)
|
||||
{
|
||||
perror("read");
|
||||
return 1;
|
||||
}
|
||||
if (nread <= 1 || name_buffer[nread - 1] != '\n')
|
||||
continue;
|
||||
name_buffer[nread - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
strcpy(name_buffer, "user");
|
||||
first = false;
|
||||
}
|
||||
|
||||
auto* pwd = getpwnam(name_buffer);
|
||||
if (pwd == nullptr)
|
||||
continue;
|
||||
|
||||
if (chown("/dev/tty", pwd->pw_uid, pwd->pw_gid) == -1)
|
||||
{
|
||||
perror("chown");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chmod("/dev/tty", 0600) == -1)
|
||||
{
|
||||
perror("chmod");
|
||||
continue;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
pid_t pgrp = setpgrp();
|
||||
if (tcsetpgrp(0, pgrp) == -1)
|
||||
{
|
||||
perror("tcsetpgrp");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Welcome back %s!\n", pwd->pw_name);
|
||||
|
||||
if (setgid(pwd->pw_gid) == -1)
|
||||
perror("setgid");
|
||||
if (setuid(pwd->pw_uid) == -1)
|
||||
perror("setuid");
|
||||
|
||||
setenv("PATH", "/bin:/usr/bin", 0);
|
||||
|
||||
setenv("HOME", pwd->pw_dir, 1);
|
||||
chdir(pwd->pw_dir);
|
||||
|
||||
execl(pwd->pw_shell, pwd->pw_shell, nullptr);
|
||||
perror("execl");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
endpwent();
|
||||
|
||||
if (pid == -1)
|
||||
{
|
||||
perror("fork");
|
||||
break;
|
||||
}
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
if (tcsetpgrp(0, getpgrp()) == -1)
|
||||
perror("tcsetpgrp");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user