202 lines
5.5 KiB
C
Executable File
202 lines
5.5 KiB
C
Executable File
#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);
|
|
}
|
|
} |