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