84 lines
1.8 KiB
C
84 lines
1.8 KiB
C
|
/* This file is part of the sample code and exercises
|
||
|
* used by the class "Advanced Programming in the UNIX
|
||
|
* Environment" taught by Jan Schaumann
|
||
|
* <jschauma@netmeister.org> at Stevens Institute of
|
||
|
* Technology.
|
||
|
*
|
||
|
* This file is in the public domain.
|
||
|
*
|
||
|
* You don't have to, but if you feel like
|
||
|
* acknowledging where you got this code, you may
|
||
|
* reference me by name, email address, or point
|
||
|
* people to the course website:
|
||
|
* https://stevens.netmeister.org/631/
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* World's 2nd simplest shell
|
||
|
* Same as simple-shell.c, but with a SIGINT signal handler.
|
||
|
* Feed EOF (^D) to exit.
|
||
|
*
|
||
|
* Also illustrates forward declaration of a function prototype.
|
||
|
*/
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/wait.h>
|
||
|
#include <errno.h>
|
||
|
#include <signal.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <sysexits.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
char *
|
||
|
getinput(char *buffer, size_t buflen) {
|
||
|
printf("$$ ");
|
||
|
return fgets(buffer, buflen, stdin);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
sig_int(int signo) {
|
||
|
printf("\nCaught SIGINT (Signal #%d)!\n$$ ", signo);
|
||
|
(void)fflush(stdout);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char **argv) {
|
||
|
char buf[BUFSIZ];
|
||
|
pid_t pid;
|
||
|
int status;
|
||
|
|
||
|
/* cast to void to silence compiler warnings */
|
||
|
(void)argc;
|
||
|
(void)argv;
|
||
|
|
||
|
if (signal(SIGINT, sig_int) == SIG_ERR) {
|
||
|
fprintf(stderr, "signal error: %s\n", strerror(errno));
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
while (getinput(buf, sizeof(buf))) {
|
||
|
buf[strlen(buf) - 1] = '\0';
|
||
|
|
||
|
if((pid=fork()) == -1) {
|
||
|
fprintf(stderr, "shell: can't fork: %s\n",
|
||
|
strerror(errno));
|
||
|
continue;
|
||
|
} else if (pid == 0) { /* child */
|
||
|
execlp(buf, buf, (char *)0);
|
||
|
fprintf(stderr, "shell: couldn't exec %s: %s\n", buf,
|
||
|
strerror(errno));
|
||
|
exit(EX_UNAVAILABLE);
|
||
|
}
|
||
|
|
||
|
/* parent waits */
|
||
|
if ((pid=waitpid(pid, &status, 0)) < 0) {
|
||
|
fprintf(stderr, "shell: waitpid error: %s\n",
|
||
|
strerror(errno));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit(EX_OK);
|
||
|
}
|