Last active
August 29, 2015 14:01
-
-
Save ahmpro/682ffdc869ba8e68f58e to your computer and use it in GitHub Desktop.
terminal emulator - lab 3 on "Operating Systems" in MAI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -Wall -std=gnu99 zhell.c -o zhell | |
clean: | |
rm zhell |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* File: zhell.c (14.03.2014) | |
* thx for source code shell dwhitney67 (http://ubuntuforums.org/showthread.php?t=931794&p=5869326#post5869326) | |
* Copyright 2014 L1S & ahmpro | |
*/ | |
#include <stdio.h> | |
#include <signal.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/wait.h> | |
#include <sys/types.h> | |
#include <malloc.h> | |
#include <setjmp.h> | |
pid_t child_pid, back_pid = 0; | |
pid_t child_active_pid; | |
void ctrl_c(int sig) { | |
switch(sig) { | |
case SIGINT: | |
if (child_active_pid > 0) { | |
kill(child_active_pid, SIGTERM); | |
child_active_pid = 0; | |
} | |
break; | |
default: | |
break; | |
//exit(0); | |
} | |
} | |
int main() | |
{ | |
int status = 0; | |
char cmd[512] = {0}; | |
char **argv = malloc(10 * sizeof(char*)); | |
int argc; | |
char *arg; | |
int is_bgr = 0; | |
struct sigaction sa; | |
memset(&sa, 0, sizeof(sa)); | |
sa.sa_handler = ctrl_c; | |
sigset_t set; | |
sigemptyset(&set); | |
sigaddset(&set, SIGINT); | |
sa.sa_mask = set; | |
sigaction(SIGINT, &sa, 0); | |
while (1) { | |
for (int i = 0; i < argc; ++i) { | |
free(argv[i]); | |
} | |
free(argv); | |
is_bgr = 0; | |
child_active_pid = 0; | |
argc = 0; | |
argv = malloc(10 * sizeof(char*)); | |
printf("zhell (%s) > ",getenv("PWD")); | |
if (fgets(cmd, sizeof(cmd), stdin ) == NULL) { | |
printf("\n"); | |
continue; | |
} | |
cmd[strlen(cmd)-1] = '\0'; | |
if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { | |
break; | |
} | |
if (!strcmp(cmd, "kill")) { | |
back_pid = 0; | |
} | |
arg = strtok(cmd, " "); | |
while (arg != 0 && argc < 9) { | |
argv[argc++] = strdup(arg); | |
arg = strtok(NULL, " "); | |
} | |
argv[argc] = 0; | |
if (argc > 0) { | |
char *last_arg = argv[argc-1]; | |
if (!strcmp(last_arg, "&")) { | |
printf("1\n"); | |
is_bgr = 1; | |
argc--; | |
argv[argc] = 0; | |
} else if (last_arg[strlen(last_arg)-1] == '&') { | |
last_arg[strlen(last_arg)-1] = 0; | |
is_bgr = 1; | |
} | |
} else { | |
continue; | |
} | |
child_pid = fork(); | |
if (child_pid < 0) { | |
perror("Fork failed"); | |
break; | |
} else if (child_pid > 0) { | |
if (is_bgr) { | |
back_pid = child_pid; | |
child_active_pid = 0; | |
waitpid(-1, &status, WNOWAIT); | |
} else { | |
child_active_pid = child_pid; | |
waitpid(-1, &status, 0); | |
child_active_pid = 0; | |
//printf("Exit status of PID%d was %d\n", (int)child_pid, status); | |
} | |
continue; | |
} else if (child_pid == 0) { | |
// execute shell command | |
if (argc>0) { | |
setpgid(0, 0); | |
execvp(argv[0], argv); | |
} | |
exit(0); | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment