Reputation: 13728
Title may be a little confusing, so let me explain. I am trying to write a simple shell to practice my programming. I have got the get a command, fork, exec loop working. However, when I press CTRL-C
while child process is still executing, my shell terminates, instead of child process (but child process would keep running). Here is the main function:
int main()
{
dynarray *args; /* pointer to a dynamic array */
int bytes_read;
size_t nbytes = 0;
char *command;
pid_t pid;
printf("Enter command: ");
while ((bytes_read = getline(&command, &nbytes, stdin)) != -1) {
if (bytes_read == -1) {
perror("getline");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0) { /* child process */
args = newdynarray();
char *arg = strtok(command, " \n");
while (arg != NULL) {
addstring(args, arg);
arg = strtok(NULL, " \n");
}
if (args->nval == 0) {
freedynarray(args);
continue;
}
addstring(args, NULL);
char *fullpath = find_executable(args->strings[0]);
if (fullpath == NULL) {
fprintf(stderr, "Couldn't find executable: %s\n", command);
exit(EXIT_FAILURE);
}
if (execv(fullpath, args->strings) == -1) {
perror("execv");
exit(EXIT_FAILURE);
}
} else {
int status;
waitpid(pid, &status, 0);
}
printf("Enter command: ");
}
return 0;
}
I didn't include other parts, because I don't think they are relevant. How can I make my child process catch all the input from stdin until it terminates?
Upvotes: 0
Views: 2283
Reputation: 39797
How can I make my child process catch all the input from stdin until it terminates?
Signals generated from stdin keys (such as control C) will be sent to the last process to use stdin, so there's nothing you can do unless you can force your child to use the path.
Instead, you need to create a signal handler in your shell process to catch SIGINT (and others), and resend the signal (using the kill()
function) to the process you want to receive it.
Upvotes: 0
Reputation: 476930
You can register a signal handler for SIGINT
in your parent process, and therein use kill(2)
to send a signal to the child process, whose PID you should store somewhere.
Upvotes: 1