Initial Commit

This commit is contained in:
2026-10-09 12:20:25 +02:00
commit 165592feea
3 changed files with 153 additions and 0 deletions

135
src/msh.c Normal file
View File

@@ -0,0 +1,135 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/utsname.h>
#include <errno.h>
#define ESC \x1B
const int LINESIZE = 512;
int cd(int argc, char** argv) {
if (argc != 1) {
fprintf(stderr, "Usage: cd <directory>\n");
return 1;
}
return chdir(argv[0]);
}
void pretty_path_home(char** path) {
char* home = secure_getenv("HOME");
int home_len = strlen(home);
if (strncmp(home, *path, home_len) == 0) {
(*path)[home_len-1] = '~';
*path = *path + (home_len - 1);
}
}
int main(int argc, char** argv) {
char* tokens[LINESIZE] = {};
char** args;
char line[LINESIZE] = {};
char* tokenwork;
char* token;
char* newline;
int ntokens = 0;
int i;
int result;
int pid;
int laststatus = 0;
int wstatus;
char pwd[LINESIZE] = {};
char* pwd_disp;
char* user;
char* host;
struct utsname uts = {};
user = secure_getenv("USER");
result = uname(&uts);
if (result != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
return errno;
}
host = uts.nodename;
while(1) {
getcwd(pwd, LINESIZE - 1);
pwd_disp = pwd;
pretty_path_home(&pwd_disp);
if (laststatus != 0) {
fprintf(stdout, "❌");
}
fprintf(stdout, "%s@%s %s$ ", user, host, pwd_disp);
char* fgets_res = fgets(line, LINESIZE, stdin);
if (fgets_res == NULL) {
printf("^D\n");
return 0;
}
newline = strrchr(line, '\n');
if (newline != NULL) {
newline[0] = 0;
}
for (tokenwork = line, i = 0; ; tokenwork = NULL, i++) {
token = strtok(tokenwork, " \t");
if (token == NULL) {
break;
}
tokens[i] = token;
}
ntokens = i;
tokens[ntokens] = NULL;
args = &tokens[1];
if (ntokens == 0) {
continue;
}
// Shell builtins
if (strcmp("exit", tokens[0]) == 0) {
printf("Goodbye!\n");
return 0;
}
if (strcmp("cd", tokens[0]) == 0) {
laststatus = cd(ntokens - 1, args);
continue;
}
// Execute command
pid = fork();
if(pid == 0) {
return execvpe(tokens[0], tokens, NULL);
} else {
waitpid(pid, &wstatus, 0);
laststatus = WEXITSTATUS(wstatus);
}
}
}