back to scratko.xyz
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscratko <m@scratko.xyz>2024-06-05 18:06:48 +0300
committerscratko <m@scratko.xyz>2024-06-05 18:13:57 +0300
commit8bcfbe6a15f6195c3501b9bde633081da67179d1 (patch)
treef744ac4fde3140d1d4f2e775cdd6f482625d590f
parentc9d02770f42339b6cc741191cee87e77b914b00b (diff)
downloadshell-IV.tar.gz
shell-IV.tar.bz2
shell-IV.zip
Signal handlershell-IV
Moving zombie process cleanup to the signal handler.
-rw-r--r--shell.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/shell.c b/shell.c
index 9ce5a32..d3b96b3 100644
--- a/shell.c
+++ b/shell.c
@@ -7,6 +7,8 @@
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
enum modes { word_separation, whole_word };
enum {
@@ -53,6 +55,20 @@ static void print_error()
fprintf(stderr, "Error: unmatched quotes\n");
}
+/* remove background zombie processes */
+static void handler(int signal)
+{
+ int save_errno = errno;
+ int pid;
+
+ if(signal == SIGCHLD) {
+ do {
+ pid = wait4(-1, NULL, WNOHANG, NULL);
+ } while(pid > 0);
+ }
+ errno = save_errno;
+}
+
static void init_params(struct param_type *params, enum modes *current_mode)
{
params->is_word = 0;
@@ -294,16 +310,7 @@ static int start_escape_sequence(int ch, struct param_type params)
static int excessive_words(int ch, const struct param_type *params)
{
int next_ch;
-#if 0
- if(filename_waiting(params))
- return
- (params->tokens == '<' && params->streams.input_stream != NULL) ||
- (params->tokens == '>' && params->streams.output_stream !=NULL) ||
- (params->tokens == append &&
- params->streams.output_stream_to_append != NULL);
- else
- return 0;
-#endif
+
if(filename_waiting(params)) {
if(ch == new_line)
return 0;
@@ -320,23 +327,6 @@ static int excessive_words(int ch, const struct param_type *params)
return 0;
}
-#if 0
-static void print_word(char *word)
-{
- putchar('[');
- while(*word) {
- putchar(*word);
- ++word;
- }
- printf("]\n");
-}
-
-static void print_line(const struct queue *word_chain)
-{
- queue_processing(word_chain, print_word);
-}
-#endif
-
static char** create_cmdline(const struct queue *word_chain,
int word_counter)
{
@@ -382,14 +372,6 @@ static void clean_up_memory(struct queue *word_chain, char **cmdline,
clear_filename(params);
}
-static void clean_up_zombie_process()
-{
- int pid;
- do {
- pid = wait4(-1, NULL, WNOHANG, NULL);
- } while(pid > 0);
-}
-
static void open_files(const struct param_type *params, int *input_fd,
int *output_fd)
{
@@ -427,11 +409,13 @@ static void run_external_program(struct queue *word_chain,
struct param_type *params)
{
int pid, wait_pid, result, input_fd, output_fd;
+ input_fd = 0;
+ output_fd = 0;
+
if(word_chain->first == NULL) {
fprintf(stderr, "empty command\n");
return;
}
-
if(is_stream_redirection_set(params))
open_files(params, &input_fd, &output_fd);
@@ -451,7 +435,16 @@ static void run_external_program(struct queue *word_chain,
perror("fork error");
exit(1);
}
- /* child process */
+ if(params->tokens == '&')
+ /* zombie process termination on signal */
+ signal(SIGCHLD, handler);
+ else
+ /* the parent process will wait for the process to complete;
+ default signal disposition
+ */
+ signal(SIGCHLD, SIG_DFL);
+
+ /* child process */
if(pid == 0) {
if(is_stream_redirection_set(params))
change_streams(input_fd, output_fd);
@@ -460,18 +453,19 @@ static void run_external_program(struct queue *word_chain,
perror(cmdline[0]);
exit(1);
}
- /* parent process */
+ /* parent process */
close_files(input_fd, output_fd);
clean_up_memory(word_chain, cmdline, params);
- /* waiting for forground process */
- if(params->tokens != '&') {
+ /* waiting for forground process by pid*/
+ if(params->tokens != '&')
do {
wait_pid = wait(&result);
} while(wait_pid != pid);
- } else
- clean_up_zombie_process();
+
+ /* return of background process zombie cleanup */
+ signal(SIGCHLD, handler);
}
}
@@ -521,9 +515,9 @@ static int is_empty_word(int ch, struct param_type params)
}
static void word_separation_processing(int ch, struct param_type *params,
- enum modes *current_mode,
- struct queue *word_chain,
- struct dynamic_array *tmp_word)
+ enum modes *current_mode,
+ struct queue *word_chain,
+ struct dynamic_array *tmp_word)
{
/* could be a marker for the beginning of a blank word */
params->stored_symbol = ch;
@@ -636,7 +630,6 @@ int main()
init_params(&params, &current_mode);
show_invitation();
while((ch = getchar()) != EOF) {
- clean_up_zombie_process();
if(ch == new_line)
command_processing(&params, &current_mode, &word_chain,
&tmp_word, ch);