Intial commit

This commit is contained in:
Kamil Sowiński 2018-07-09 22:03:45 +02:00
commit 70ab6da52b
2 changed files with 204 additions and 0 deletions

2
Makefile Executable file
View File

@ -0,0 +1,2 @@
myshell: main.c
gcc -o myshell main.c -I .

202
main.c Executable file
View File

@ -0,0 +1,202 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <wait.h>
// Removes new line from string
char *remove_nl(char *p) {
char *nl = strchr( p, '\n' );
if (nl)
*nl = 0;
memset(nl, 0, sizeof nl);
return p;
}
// Checks for env variables in string and set them if found
int set_evar(char *evar) {
char *end_evar;
char *value;
char *key;
key = strtok_r(evar, "=", &end_evar);
value = strtok_r(NULL, "=", &end_evar);
setenv(key, value, 1);
memset(evar, 0, sizeof evar);
memset(end_evar, 0, sizeof end_evar);
memset(key, 0, sizeof key);
memset(value, 0, sizeof value);
return 0;
}
// Displays basic shell prompt
int display_prompt() {
char hostname[1024];
char cwd[1024];
char *username_p;
gethostname(hostname, 1024);
username_p = getenv("USER");
getcwd(cwd, 1024);
printf("[%s@%s %s] $ ", hostname, username_p, cwd);
// Flush memory
memset(hostname, 0, sizeof hostname);
memset(cwd, 0, sizeof cwd);
return 0;
}
// Commands
int my_exit(char *param_list[64]) {
if (param_list[0] != NULL) {
exit( (int)strtol(param_list[0], NULL, 0) );
} else {
exit(0);
}
}
int my_cd(char *param_list[64]) {
if (param_list[0] != NULL) {
if (chdir(param_list[0]) == -1) {
printf("cd: %s: %s\n", param_list[0], strerror(errno));
return 1;
}
}
return 0;
}
int my_kill(char *param_list[64]) {
if (param_list[0] != NULL) {
int process_pid = (int)strtol(param_list[0], NULL, 0);
if (process_pid > 0) {
if (kill(process_pid, SIGKILL) == -1) {
printf("kill: %s\n", strerror(errno));
memset(&process_pid, 0, sizeof process_pid);
return 1;
} else {
printf("kill: Killing process %d", process_pid);
memset(&process_pid, 0, sizeof process_pid);
return 0;
}
} else {
printf("kill: Invalid PID: %s\n" , param_list[0]);
memset(&process_pid, 0, sizeof process_pid);
return 1;
}
} else {
printf("Please specify PID\n");
return 1;
}
}
// Allows you to run subshell
int my_myshell() {
pid_t child_pid;
child_pid = fork();
if (child_pid != 0) {
waitpid(child_pid, NULL, 0); //Wait for child
}
}
int main() {
char input[1024];
char *input_p;
char *param_p;
char *command_p;
char *param_list[64];
char evar[256];
pid_t child_pid;
while (1) {
evar[0] = '\0';
display_prompt();
fgets(input, 1024, stdin);
input_p = input;
input_p = remove_nl(input_p);
command_p = strtok(input_p, " ");
if (command_p != NULL) {
if (strchr(command_p, '=') != NULL) {
strcpy(evar, command_p);
command_p = strtok(NULL, " ");
}
if (!command_p || !command_p[0]) {
if (evar[0] != '\0') {
set_evar(evar);
}
} else {
param_p = strtok(NULL, " ");
int i = 0;
do {
param_list[i] = param_p;
param_p = strtok(NULL, " ");
i=i+1;
} while(param_p != NULL);
memset(&i, 0, sizeof i);
if (strcmp(command_p, "exit") == 0) {
my_exit(param_list);
} else if (strcmp(command_p, "cd") == 0) {
my_cd(param_list);
} else if (strcmp(command_p, "kill") == 0) {
my_kill(param_list);
} else if (strcmp(command_p, "myshell") == 0) {
my_myshell();
} else if (strcmp(command_p, "help") == 0) {
printf(" MyShell is Bash-like shell written in C\n");
printf(" Available commands: cd, kill, myshell, help, version, exit\n");
} else if (strcmp(command_p, "version") == 0) {
printf(" Version: 0.0.1\n Author: Kamil Sowińśki\n");
} else {
child_pid = fork();
if (child_pid == 0) {
char *args[66];
int i = 1;
int param_list_s = sizeof(param_list) / sizeof(param_list[0]);
if (evar[0] != '\0') {
set_evar(evar);
}
args[0] = command_p;
while (i < param_list_s) {
args[i] = param_list[i - 1];
i++;
}
args[i] = NULL;
memset(&i, 0, sizeof i);
if (execvp(command_p, args) == -1) {
printf("%s: command not found\n", command_p);
exit(1);
}
memset(args, 0, sizeof args);
} else {
waitpid(child_pid, NULL, 0); //Wait for child
}
memset(command_p, 0, sizeof command_p);
}
}
}
// Fush memory
memset(param_list, 0, sizeof param_list);
memset(input, 0, sizeof input);
memset(input_p, 0, sizeof input_p);
}
}