Intial commit
This commit is contained in:
commit
70ab6da52b
202
main.c
Executable file
202
main.c
Executable 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user