Baelix
Baelix

Reputation: 261

Confused on the use of exec(family) in Unix

I'm writing a program in which I use the system call fork() to create a child process, and then create a grandchild, as well as creating a pipe between the child and grandchild. I think my implementation is fairly good, however when I run the program, it simply skips right through the prompts in my code.

Essentially we have this:

-Process starts
Fork() create child
Child creates pipe
Fork() creates grandchild, pipe inherited.

TL;DR- Code skips through UI prompts, not sure if I'm entering data correctly, not sure if I'm reading data into processes correctly.

How do I read inputs down the pipe?

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>

void main(int argc, char *argv[])
{
        int p[2];
        int pid, pid2;

        pid = fork();

        if(pid == 0)
        {
                pipe(p);
                pid2 = fork();

                switch(pid2)
                {
                        case -1:
                                printf("CASE 1");
                                exit(-1);
                        case 0:
                                close(0);
                                dup(p[0]);
                                close(p[0]);
                                close(p[1]);
                                execl("./Sort/sort", 0);
                                break;
                        default:
                                close(1);
                                dup(p[1]);
                                close(p[1]);
                                close(p[0]);
                                execl("./Pre/pre", 0);
                                break;
                }
          }
          else
          {
                wait(pid);
                printf("Process Completed\n");
                exit(0);
           }
}

Child process for pre:

#include <stdio.h>

void main (int argc, char *argv[])
{
        char n1[20];
        int g1;
        FILE *ofp, *ifp;
        int track;

        ofp = fopen("output.txt", "w");

        while(track != -1)
        {
                printf("Please enter the student's grade and then name, ");
                printf("separated by a space: ");
                scanf("%3d %s", &g1, n1);

                if (g1 >= 60)
                {
                        fprintf(ofp, "%s\n", n1);
                }

                printf("Add another name?(-1 to quit, 0 to continue): ");
                scanf("%d", &track);
        }
        fclose(ofp);

        ifp = fopen("output.txt", "r");
        printf("Students that made a 60+:\n");
        while(fscanf(ifp, "%s", n1) == 1)
                printf("%s\n", n1);

        fclose(ifp);

Child process for sort:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int stringcmp(const void *a, const void *b)
{
    const char **ia = (const char **)a;
    const char **ib = (const char **)b;
    return strcmp(*ia, *ib);
}

void main(int argc, char *argv[])
{
     int i = 0;
     int num = 0;
     int j = 0;
     char name[20];

          printf("How many names would you like to enter? ");
          scanf("%d", &num);

          char **input = malloc(num * sizeof(char*));

          for (i=0; i < num; i++)
          {
                printf("Please input a name(first only): ");
                scanf("%s", name);
                input[i] = strdup(name);
          }

          qsort(input, num, sizeof(char *), stringcmp);

          printf("Names:\n");

          for(j = 0; j < num; j++)
               printf("%s\n", input[j]);


          for( i = 0; i < num; i++ ) free(input[i]);
          free(input);

Upvotes: 0

Views: 420

Answers (2)

nneonneo
nneonneo

Reputation: 179422

Observe that pre outputs prompts to stdout. That text will end up in the pipe, which is going to end up in sort's stdin.

You should fprintf all your prompts to stderr.

pre also doesn't output text in the format expected by sort; sort expects an integer n followed by n words (first names). So, that should be the only text that pre outputs on stdout; everything else needs to go to a file or stderr.

P.S. Also, use dup2(p[0], 0) instead of close(0); dup(p[0]) as it makes your intent clearer, as well as potentially avoiding threading issues (of course only relevant if you have threads, but it's worth keeping in mind).

Upvotes: 1

nonsensickle
nonsensickle

Reputation: 4528

Here's are two examples of how to do it

  1. http://www.gnu.org/software/libc/manual/html_node/Creating-a-Pipe.html
  2. http://tldp.org/LDP/lpg/node11.html

Edit: I can tell that you are trying to pipe the output of "./Pre/pre" to the input of "./Sort/sort" but I'm not sure what you mean by "Code skips through UI prompts" because for case 1: and default: you don't have any prompts. What exactly is the problem? If you want something more specific please explain more of the details in your question.

Upvotes: 0

Related Questions