Created
January 18, 2016 17:17
-
-
Save haxwithaxe/4f2c6c03f746ff9dd355 to your computer and use it in GitHub Desktop.
Hello world unix shell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* hellosh | |
* based on http://stephen-brennan.com/2015/01/16/write-a-shell-in-c/ (first hit on google for "how to write a shell") | |
* compile: gcc -o hellosh hellosh.c | |
*/ | |
#include <sys/wait.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#define SHELL_NAME "hellosh" | |
#define DELIMITER " \t\r\n\a" | |
#define BUFFER_SIZE 64 | |
char *read_line() { | |
char *line = NULL; | |
ssize_t buffer_size = BUFFER_SIZE; | |
getline(&line, &buffer_size, stdin); | |
return line; | |
} | |
char **split(char *string, char *delimiter) { | |
ssize_t buffer_size = BUFFER_SIZE; | |
char *saveptr; | |
char *token = strtok_r(string, delimiter, &saveptr); | |
char **tokens = malloc(BUFFER_SIZE * sizeof(char*)); | |
int i = 0; | |
while (token != NULL) { | |
tokens[i] = token; | |
i++; | |
if (i >= buffer_size) { | |
buffer_size += BUFFER_SIZE; | |
tokens = realloc(tokens, buffer_size * sizeof(char*)); | |
if (!tokens) { | |
fprintf(stderr, "allocation error\n"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
token = strtok_r(NULL, delimiter, &saveptr); | |
} | |
tokens[i] = NULL; | |
return tokens; | |
} | |
int launch(char **command) { | |
pid_t pid; | |
pid_t wpid; | |
int status; | |
pid = fork(); | |
if (pid == 0) { | |
// If failed | |
if (execvp(command[0], command) == -1) { | |
perror(SHELL_NAME); | |
} | |
exit(EXIT_FAILURE); | |
} else if (pid < 0) { | |
// If successful | |
do { | |
wpid = waitpid(pid, &status, WUNTRACED); | |
} while (!WIFEXITED(status) && !WIFSIGNALED(status)); | |
} | |
} | |
int execute(char **command) { | |
if (command[0] == NULL) { | |
return 1; | |
} | |
return launch(command); | |
} | |
void loop() { | |
char *line; | |
char **args; | |
int status; | |
do { | |
printf("> "); | |
line = read_line(); | |
args = split(line, DELIMITER); | |
status = execute(args); | |
free(line); | |
free(args); | |
} while (status); | |
} | |
int main(int argc, char **argv) { | |
loop(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment