0

I need help with the following program, It's supposed to fork() two childs, child1 should send two random numbers, in a string separated by space, to child2 trough pipe, wait 1 sec and do it again until it receives SIGUSR1 from the parent(parent sends it after 5 secs). child2 should run 'main.exe' binary file, redirect the pipe's output to main.exe's input and redirect main.exe's output to out.txt file. The main.exe binary works just fine by itself and it's in the application folder.

It's a school homework. I've managed to send strings from the child1 to child2 using write and read functions. But part of the homework is that each time i'm redirecting outputs or inputs, i must use the dup(int a, int b) function. Also im supposed to make child1 ?accept? the SIGUSR1 using sigaction,(when it is received child 1 should print 'TERMINATED' on stderr and terminate) -> i dont know how to do that. The program completes successfully but doesn't seem to do anything, the printf part in child1 seems to not work as i intended. Any help would be greatly appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    int fd[2];
    pipe(fd);
    pid_t pid1 = fork();
    struct timespec tim1, tim5;
    tim1.tv_sec = 1;
    tim1.tv_nsec=0;
    tim5.tv_sec = 5;
    tim5.tv_nsec=0;
    if (pid1 > 0) {
        pid_t pid2 = fork();
        if (pid2 > 0) {
            close(fd[0]);
            close(fd[1]);
            nanosleep(&tim5, (struct timespec *) NULL);
            kill(pid1, SIGUSR1);
            int status;
            wait(&status);
        } else if (!pid2) {
            execl("main.exe","main", (char*) 0);
            close(fd[1]);
            char *buf;
            if((buf = malloc(23))==NULL){
                return 3;
            }            
            mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
            int file = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, mode);            
            ssize_t bytesread;
            while ((bytesread=read(fd[0], buf, 22)) > 0) {
                buf[bytesread] = '\0';
                printf("%s\n", buf);
            }
            //^redirect pipe output to the main.exe's input and then redirect main.exe's output to out.txt text file^
        } else {
            return 2;
        }
    } else if (!pid1) {
        close(fd[0]);
        int a, b;
        dup2(fd[1], STDOUT_FILENO);
        while (1) {//child 1 should write to stderr "TERMINATED" if SIGUSR1 is received, and terminate 
            a = rand();
            b = rand();
            printf("%d %d\n", a, b);
            nanosleep(&tim1, (struct timespec *) NULL);
        }
    } else {
        return 1;
    }
    return 0;
}
Petr Kroupa
  • 53
  • 3
  • 8
  • a few things to note: 1) `fork()` has three return conditions: <0 means error, ==0 means child process, >0 mean parent process. The code needs to handle all three conditions. 2) there is no return from any of the `exec...()` functions unless that function failed, So if returns do two statements: `perror( "exec.. failed" ); exit( EXIT_FAILURE ); and nothing else – user3629249 Apr 14 '17 at 18:15
  • `sleep()` is depreciated, use `nanosleep()` or similar function – user3629249 Apr 14 '17 at 18:16
  • suggest post the source code for `main.exe` – user3629249 Apr 14 '17 at 18:17
  • be sure to read/understand the system functions that your code calls. for instance, the syntax for `execl()` is: `int execl(const char *path, const char *arg, ... /* (char *) NULL */);` which means the call should look more like: `execl("main.exe", "main", NULL);` – user3629249 Apr 14 '17 at 18:20
  • only have to do this once in the child, not every time through a loop: `dup2(file, STDOUT_FILENO);` – user3629249 Apr 14 '17 at 18:22
  • when calling any of the heap allocation functions (malloc, calloc, realloc) always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Apr 14 '17 at 18:23
  • in the child, no need for all the 'fiddling' to be able to use `printf()`. Just use `fprintf( file, "%s\n", buf);` – user3629249 Apr 14 '17 at 18:25
  • in the code block `while( read(fd...` loop, what about when the number of characters read is less than 22? Suggest using: `ssize_t bytesRead; while ( (bytesRead = read(fd[0], buf, 22) ) > 0) { buf[bytesRead] = '\0'; ...` – user3629249 Apr 14 '17 at 18:28
  • inside the child process, to set a signal handler for SIGUSR1, call `sigaction()` with the appropriate parameter. Then insert the related signal handler function into the posted code. Note: there is nothing in the posted code to actually generate a SIGUSR1 signal. – user3629249 Apr 14 '17 at 18:37
  • NOTE: nothing in the posted code uses anything from the `math.h` header file, Header files that are not actually used should not be included. Such inclusion can lead to problems later on. – user3629249 Apr 14 '17 at 18:39
  • the posted code is missing the statement: `#include ` for the `signal()` function. The posted code is missing the statements: `#include ` and `#include ` for the `wait()` and `kill()` functions. Always enable all the warnings when compiling. then fix any messages raised by the compiler (don't hide the messages) (for `gcc`, at a minimum use: `-Wall -Wextra -pedantic-errors` I also use: `-Wconversion -std=gnu11` ) – user3629249 Apr 14 '17 at 18:43
  • Alright i changed the code a bit and actually even modified the question(sorry i understood the homework in a bad way). The main.exe is a binary that reads line of two integers separated by space and then prints their greatest common divider. I know i can just use fprintf in child1 but the homework says i can only use dup and dup2 for redirecting the files. If i understand the read func. properly, it only returns the number of bytes read, so if it is less than 22, the program should still carry on. Also would you be so kind and show me an example of setting the handler and sending the signal – Petr Kroupa Apr 15 '17 at 13:16
  • ...from the parent, pretty please? I read some stuff online about it but totaly dont get how to implement it in the way i'm supposed to do it in this homework. – Petr Kroupa Apr 15 '17 at 13:22

0 Answers0