Compare commits
No commits in common. "60b9863f087d073e2b35396cc2d46ba9f25d4aec" and "4048652b5bd62cab32c68c30de85a64db6e98039" have entirely different histories.
60b9863f08
...
4048652b5b
3 changed files with 3 additions and 129 deletions
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# arsh
|
||||||
|
|
||||||
|
Simple shell for Unix-like systems written in C
|
||||||
12
README.org
12
README.org
|
|
@ -1,12 +0,0 @@
|
||||||
#+title: arsh - ARchaic SHell
|
|
||||||
#+options: toc:nil
|
|
||||||
Simple shell for Unix-like systems written in C, that has a funny name (for germans).
|
|
||||||
* Features
|
|
||||||
- Can run one command at a given time (no | , &&, ||, functions, etc)
|
|
||||||
- ~cd~ builtin command
|
|
||||||
- ~exit~ builtin command
|
|
||||||
* Build
|
|
||||||
To build it, you need ~readline~ library. Then use
|
|
||||||
#+begin_src shell
|
|
||||||
gcc main.c -O3 -lreadline -o arsh
|
|
||||||
#+end_src
|
|
||||||
117
main.c
117
main.c
|
|
@ -1,117 +0,0 @@
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <readline/readline.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
static sigjmp_buf restart_jmp_buf;
|
|
||||||
static const int restart_value = 69;
|
|
||||||
static volatile sig_atomic_t jump_active = 0;
|
|
||||||
|
|
||||||
void sigint_handler(int signo)
|
|
||||||
{
|
|
||||||
if(!jump_active)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
siglongjmp(restart_jmp_buf, restart_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
char** split_input(char* input)
|
|
||||||
{
|
|
||||||
const size_t alloc_size = ((strlen(input) + 1) / 2) + 1;
|
|
||||||
char** command = malloc(alloc_size * sizeof(char*));
|
|
||||||
if (command == NULL)
|
|
||||||
{
|
|
||||||
perror("malloc failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
const char* separator = " ";
|
|
||||||
char* parsed;
|
|
||||||
uint32_t index = 0;
|
|
||||||
parsed = strtok(input, separator);
|
|
||||||
while (parsed != NULL)
|
|
||||||
{
|
|
||||||
command[index] = parsed;
|
|
||||||
index++;
|
|
||||||
parsed = strtok(NULL, separator);
|
|
||||||
}
|
|
||||||
command[index] = NULL;
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cd(char* path)
|
|
||||||
{
|
|
||||||
return chdir(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
struct sigaction s;
|
|
||||||
s.sa_handler = sigint_handler;
|
|
||||||
sigemptyset(&s.sa_mask);
|
|
||||||
s.sa_flags = SA_RESTART;
|
|
||||||
struct sigaction s_old;
|
|
||||||
sigaction(SIGINT, &s, &s_old);
|
|
||||||
|
|
||||||
int stat_loc;
|
|
||||||
|
|
||||||
if(sigsetjmp(restart_jmp_buf, 1) == restart_value)
|
|
||||||
{
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
jump_active = 1;
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
char* input = readline("arsh> ");
|
|
||||||
if(input == NULL) //CTRL + D
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
char** command = split_input(input);
|
|
||||||
|
|
||||||
if(strcmp(command[0], "cd") == 0)
|
|
||||||
{
|
|
||||||
if (cd(command[1]) < 0)
|
|
||||||
{
|
|
||||||
perror(command[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue; //skip fork()
|
|
||||||
}
|
|
||||||
if(strcmp(command[0], "exit") == 0)
|
|
||||||
{
|
|
||||||
int32_t status_code = command[1] != NULL ? atoi(command[1]) : 0;
|
|
||||||
exit(status_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t child_pid = fork();
|
|
||||||
if (child_pid < 0)
|
|
||||||
{
|
|
||||||
perror("Fork failed");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (child_pid == 0)
|
|
||||||
{
|
|
||||||
sigaction(SIGINT, &s_old, NULL);
|
|
||||||
//never returns if call is successful
|
|
||||||
if(execvp(command[0], command) < 0)
|
|
||||||
{
|
|
||||||
perror(command[0]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
waitpid(child_pid, &stat_loc, WUNTRACED);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(input);
|
|
||||||
free(command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue