[comp.lang.c] Creating subprocesses with vfork

BRAAMS%HLSDNL5.BITNET@CUNYVM.CUNY.EDU (03/17/88)

Hi info-C guys,

    After having struggled through a lot of your messages, we now have
    a question of our own. Please answer directly via e-mail to the address
    below, because we try to unsubscribe from this list (most of your
    messages are of low interest to us, we are just simple C users).

    Here it comes. We want to create a number of subprocesses from
    within a program. We run on a VAX with VMS and have only the routine
    vfork() to create child processes. (With ULTRIX we have fork() as well
    and no problems there). Furthermore, we want to communicate with these
    processes, using mailboxes or pipes, wich are set up with pipe() and
    dup2(). With VMS we find that we can communicate with the first
    child, sometimes with the second, but never with the third.....
    We tried to locate the problem and think that vfork() doesn't create
    the propper process environment. An argument for this could be that
    vfork() doesn't work under ULTRIX as well.

    We include the sources of the parent program and one child below.

    Has anybody out there encountered the same problem? and possibly
    solved it as well?

    We would be very obliged if you could let us know.

    Regards,

        Johannes Braams & Arian Koster

        PTT Dr Neher Laboratories,      Phone:        +31 70 435172
        P.o. box 421,                   BITNET/EARN:  BRAAMS@HLSDNL50.BITNET
        2260 AK Leidschendam,                         KOSTER@HLSDNL50.BITNET
        The Netherlands.

=================================== mbox.h =====================================
#define pipe1_r 10
#define pipe1_w 11
#define pipe2_r 12
#define pipe2_w 13
#define pipe3_r 14
#define pipe3_w 15
#define pipe4_r 16
#define pipe4_w 17
#define pipe5_r 18
#define pipe5_w 19
#define pipe6_r 20
#define pipe6_w 21


=================================== mbox_parent.c ==============================
#include climsgdef
#include stdio
#include perror
#include processes
#include "mbox.h"

main() {
    int     pipe1[2];
    int     pipe2[2];
    int     pipe3[2];
    int     pipe4[2];
    int     pipe5[2];
    int     pipe6[2];
    int     mode,
            status,
            cstatus,
            len;
    char   *outbuf,
           *inbuf;
    char    name[256];

    if ((outbuf = malloc(512)) == NULL) {
        printf("Parent - Outbuf allocation failed\n");
        exit();
    }
    if ((inbuf = malloc(512)) == NULL) {
        printf("Parent - Inbuf allocation failed\n");
        exit();
    }
    if (pipe(pipe1) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    if (pipe(pipe2) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    if (pipe(pipe3) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    if (pipe(pipe4) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    if (pipe(pipe5) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    if (pipe(pipe6) == -1) {
        printf("Parent - Pipe allocation failed\n");
        exit();
    }

    printf("-------------------START DUP---------------\n");

    if (dup2(pipe4[0], pipe4_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe4[1], pipe4_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    if (dup2(pipe5[0], pipe5_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe5[1], pipe5_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    if (dup2(pipe6[0], pipe6_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe6[1], pipe6_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    if (dup2(pipe1[0], pipe1_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe1[1], pipe1_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    if (dup2(pipe2[0], pipe2_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe2[1], pipe2_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    if (dup2(pipe3[0], pipe3_r) == -1) {
        perror("Parent - Dup failed");
        exit();
    }
    if (dup2(pipe3[1], pipe3_w) == -1) {
        perror("Parent - Dup failed");
        exit();
    }

    status = vfork ();
    switch (status) {
        case 0:
            if ((status = execve("mbox_child1", 0, 0)) == -1) {
                perror("Parent - Execl failed");
                _exit();
            }
            printf("Parent - Child1 terminated\n");
            exit();
            break;
        case -1:
            printf("Parent - Child1 process failed\n");
            exit();
            break;
    }


    status = vfork ();
    switch (status) {
        case 0:
            if ((status = execl("mbox_child2", 0, 0)) == -1) {
                perror("Parent - Execl failed");
                _exit();
            }
            printf("Parent - Child2 terminated\n");
            exit();
            break;
        case -1:
            printf("Parent - Child2 process failed\n");
            exit();
            break;
    }

    status = vfork ();
    switch (status) {
        case 0:
            if ((status = execl("mbox_child3", 0, 0)) == -1) {
                perror("Parent - Execl failed");
                _exit();
            }
            printf("Parent - Child3 terminated\n");
            exit();
            break;
        case -1:
            printf("Parent - Child3 process failed\n");
            exit();
            break;
    }
    strcpy(outbuf, "This is a test of two-way pipes.\n");

    printf("Parent - Writing to child1\n");
    if (write(pipe1_w, outbuf, strlen(outbuf + 1)) == -1) {
        perror("Parent - Write failed");
        exit();
    }
    printf("Parent - Reading from child1\n");
    if ((len = read(pipe2_r, inbuf, 512)) <= 0) {
        perror("Parent - Read failed\n");
    }
    printf("Parent - Read from child1: %s\n", inbuf);
    strcpy(inbuf, "");

    strcpy(outbuf, "This is a test of two-way pipes.\n");
    printf("Parent - Writing to child2\n");
    if (write(pipe3_w, outbuf, strlen(outbuf + 1)) == -1) {
        perror("Parent - Write failed");
        exit();
    }
    printf("Parent - Reading from child2\n");
    if ((len = read(pipe4_r, inbuf, 512)) <= 0) {
        perror("Parent - Read failed\n");
    }
    printf("Parent - Read from child2: %s\n", inbuf);
    strcpy(inbuf, "");

    strcpy(outbuf, "This is a test of two-way pipes.\n");
    printf("Parent - Writing to child3\n");
    if (write(pipe5_w, outbuf, strlen(outbuf + 1)) == -1) {
        perror("Parent - Write failed");
        exit();
    }
    printf("Parent - Reading from child3\n");
    if ((len = read(pipe6_r, inbuf, 512)) <= 0) {
        perror("Parent - Read failed\n");
    }
    printf("Parent - Read from child3: %s\n", inbuf);
    strcpy(inbuf, "");
}

================================== mbox_child1.c ===============================
#include stdio
#include "mbox.h"

main() {
    int     len;
    char   *buffer;
    char    name[256];

    if ((buffer = malloc(512)) == NULL) {
        printf("Child - Buffer allocation failed\n");
        exit();
    }

    printf("Child1 - Reading from parent\n");
    if ((len = read(pipe1_r, buffer, 512)) <= 0) {
        perror("Child1 - Read failed\n");
        exit();
    } else {
        printf("Child1 - %s\n", buffer);
        printf("Child1 - Writing to parent\n");
        if (write(pipe2_w, buffer, strlen(buffer) + 1) == -1) {
            perror("Child1 - Write failed\n");
            exit();
        }
    }
}