Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4608224
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T00:48:52+00:00 2026-05-22T00:48:52+00:00

For some reason this code executes the parental commands immediately, terminating my semaphores and

  • 0

For some reason this code executes the parental commands immediately, terminating my semaphores and screwing up my flow control of other programs. Can anyone tell me why the waitpid() isnt working?

    //Create child processes
pid = fork();
if(pid < 0){
    fprintf(stderr, "Fork Failed.\n");
    exit(1);
    return;
}else if(pid==0){
        if(execl("/home/tropix/hw11-2","/home/tropix/hw11-2",semarg,pipe_to_p3,pipe_to_p4,(char*)0)){
            fprintf(stderr, "File Exexecution of hw11-2 failed.\n");
            exit(1);
        }
} else {
    pid = fork();
    if(pid < 0){
        fprintf(stderr, "Fork Failed.\n");
        exit(1);
        return;
    } else if(pid==0){
        if(execl("/home/tropix/hw11-3","/home/tropix/hw11-3",shmarg,semarg,pipe_from_p2,pipe_to_p5_1, (char*)0)){
            fprintf(stderr, "File Execution of hw11-3 failed.\n");
            exit(1);
        }
    } else {
        pid = fork();
        if(pid < 0){
            fprintf(stderr, "Fork Failed.\n");
            exit(1);
            return;
        } else if (pid == 0){
            if(execl("/home/tropix/hw11-4","/home/tropix/hw11-4",shmarg,semarg,pipe_from_p2_2,pipe_to_p5_2, (char*)0)){
                fprintf(stderr, "File Execution of hw11-4 failed.\n");
                exit(1);
            }
        } else {
            pid = fork();
            if(pid < 0){
                fprintf(stderr, "Fork Failed.\n");
                exit(1);
                return;
            } else if (pid == 0){
                if(execl("/home/tropix/hw11-5","/home/tropix/hw11-5",semarg,pipe_from_p3,pipe_from_p4,(char*)0)){
                    fprintf(stderr, "File Execution of hw11-5 failed.\n");
                    exit(1);
                }
            } else if (pid > 0) {
            }
        }

    }

    //Closing Pipes
    close(pipe1[1]);
    close(pipe2[1]);
    close(pipe3[1]);
    close(pipe4[1]);
    close(pipe1[0]);
    close(pipe2[0]);
    close(pipe3[0]);
    close(pipe4[0]);

    //Wait for child process completetion
    waitpid(pid,NULL,0);
    printf("Child Processes Complete.\n");

    //Terminate Semaphores
    semctl(sem_id,0,IPC_RMID);

    //Terminate Shared Memory Segement
    shmctl(shmid, IPC_RMID, NULL);



}

}

Thanks!

EDIT: Ok, I replaced waitpid with:

while (pid = waitpid(-1, NULL, 0)) {
       if (errno == ECHILD) {
          break;
       }
    }

and that got me part of the way there. It isnt executing the parental controls immediately, but it seems to never execute now. As far as the pipe issue you talked about, program 1 (this one) is supposed to terminate all IPC elements, including the pipes. If there is a better way, I would love to hear it.

Thanks @Jonathan

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T00:48:53+00:00Added an answer on May 22, 2026 at 12:48 am

    You only wait for one process to complete – not for all processes to complete. That is probably one problem. Fix with a loop on waitpid() until it returns ‘no more kids’.

    The structure of the code leaves something to be desired – it is a rabbit’s warren of nested if’s; ick!

    I worry that you are not closing enough pipes before the other commands are executed. You may be OK if the commands do not depend on detecting EOF on a pipe; otherwise, you are in for a long wait.

    You need a function like:

    #include <stdarg.h>
    
    static void err_exit(const char *format, ...)
    {
        va_list args;
        va_start(args, format);
        vfprintf(stderr, format, args);
        va_end(args);
        exit(EXIT_FAILURE);
    }
    

    This simplifies your error handling. You can also do things like automatically add the PID that is dying, or the error that triggered the exit, if you wish.

    We can also create a function to run another command:

    static pid_t run_command(const char *cmd, const char *shmarg, const char *semarg,
                             const char *fdarg1, const char *fdarg2)
    {
        pid_t pid = fork();
        if (pid < 0)
            err_exit("Failed to fork\n");
        else if (pid == 0)
        {
            execl(cmd, cmd, shmarg, semarg, fdarg1, fdarg2, (char *)0);
            err_exit("Failed to exec %s\n", cmd);
        }
        return pid;
    }
    

    With those in place, we can look to reduce your code to this…

    // Create child processes
    pid_t pid1 = run_command("/home/tropix/hw11-2", semarg, pipe_to_p3,   pipe_to_p4);
    pid_t pid2 = run_command("/home/tropix/hw11-3", shmarg, semarg, pipe_from_p2,   pipe_to_p5_1);
    pid_t pid3 = run_command("/home/tropix/hw11-4", shmarg, semarg, pipe_from_p2_2, pipe_to_p5_2);
    pid_t pid4 = run_command("/home/tropix/hw11-5", semarg, pipe_from_p3, pipe_from_p4);
    

    Hmmm…some of these have the shmarg and some don’t – is that inconsistency intentional or accidental? We’ll assume intentional, so we need two versions of ‘run_command()’:

    static pid_t run_cmd4(const char *cmd, const char *shmarg, const char *semarg,
                             const char *fdarg1, const char *fdarg2)
    {
        pid_t pid = fork();
        if (pid < 0)
            err_exit("Failed to fork\n");
        else if (pid == 0)
        {
            execl(cmd, cmd, shmarg, semarg, fdarg1, fdarg2, (char *)0);
            err_exit("Failed to exec %s\n", cmd);
        }
        return pid;
    }
    
    static pid_t run_cmd3(const char *cmd, const char *semarg,
                             const char *fdarg1, const char *fdarg2)
    {
        pid_t pid = fork();
        if (pid < 0)
            err_exit("Failed to fork\n");
        else if (pid == 0)
        {
            execl(cmd, cmd, semarg, fdarg1, fdarg2, (char *)0);
            err_exit("Failed to exec %s\n", cmd);
        }
        return pid;
    }
    

    And then:

    // Create child processes
    pid_t pid1 = run_cmd3("/home/tropix/hw11-2", semarg, pipe_to_p3,   pipe_to_p4);
    pid_t pid2 = run_cmd4("/home/tropix/hw11-3", shmarg, semarg, pipe_from_p2,   pipe_to_p5_1);
    pid_t pid3 = run_cmd4("/home/tropix/hw11-4", shmarg, semarg, pipe_from_p2_2, pipe_to_p5_2);
    pid_t pid4 = run_cmd3("/home/tropix/hw11-5", semarg, pipe_from_p3, pipe_from_p4);
    

    If it was my code, the names of the variables would be more uniform – and probably in arrays:

    // Create child processes
    pid_t pid1 = run_cmd3("/home/tropix/hw11-2",         semarg, pipearg[0], pipearg[1]);
    pid_t pid2 = run_cmd4("/home/tropix/hw11-3", shmarg, semarg, pipearg[2], pipearg[3]);
    pid_t pid3 = run_cmd4("/home/tropix/hw11-4", shmarg, semarg, pipearg[4], pipearg[5]);
    pid_t pid4 = run_cmd3("/home/tropix/hw11-5",         semarg, pipearg[6], pipearg[7]);
    

    Then, finally, you have the code:

    // Closing Pipes
    close(pipe1[1]);
    close(pipe2[1]);
    close(pipe3[1]);
    close(pipe4[1]);
    close(pipe1[0]);
    close(pipe2[0]);
    close(pipe3[0]);
    close(pipe4[0]);
    
    //Wait for child process completion
    while (waitpid(0, NULL, 0) != 0)
        ;
    
    printf("Child Processes Complete.\n");
    
    // Remove Semaphores and Shared Memory
    semctl(sem_id,0,IPC_RMID);
    shmctl(shmid, IPC_RMID, NULL);
    

    I am deeply suspicious that the run_cmdX() functions also need to close a large selection of the pipes – at least every descriptor of the pipes not intended for communication with their sub-process.

    Organizing that cleanly is trickier – but can be done with care. I’d probably create the pipes in a single array:

    if (pipe(&pipes[0]) != 0 || pipe(&pipes[2]) != 0 ||
        pipe(&pipes[4]) != 0 || pipe(&pipes[6]) != 0)
        err_exit("Failed to create a pipe\n");
    

    Then I’d create a function:

    void pipe_closer(int *pipes, int close_mask)
    {
        for (i = 0; i < 8; i++)
        {
             if ((mask & (1 << i)) != 0)
                 close(pipes[i]);
        }
    }
    

    Then it can be called to close the unneeded pipes:

    pipe_closer(pipes, 0xFF);   // Close them all - main()
    pipe_closer(pipes, 0xFC);   // All except 0, 1
    pipe_closer(pipes, 0xF3);   // All except 2, 3
    pipe_closer(pipes, 0xCF);   // All except 4, 5
    pipe_closer(pipes, 0x3F);   // All except 6, 7
    

    You just have to arrange for the right mask to be passed with each of the run_cmdN() functions, and the correct calls to be made. If the pipes array is not global, that will need to be passed too. I’d also look at how to encode the data tidily so that the calls to run_cmdN() are as regular and symmetric as possible.


    Kernighan & Plauger’s “The Elements of Programming Style” (2nd Edn, 1978; hard to find, I suspect) contains many magnificent quotes. The immediately apposite one is (bold emphasis added, italics in original):

    • [T]he subroutine call permits us to summarize the irregularities in the argument list where we can quickly see what is going on.
    • The subroutine itself summarizes the regularities of the code, so repeated patterns need not be used.

    This can be viewed as part of the DRY (Don’t Repeat Yourself) principle of programming. The err_exit() function call encapsulates three or four lines of code – a print and an exit plus the braces, depending on your preferred layout. The run_command() functions are a prime case of DRY. The proposed pipe_closer()is yet another.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

For some reason I never see this done. Is there a reason why not?
For some reason I'm not getting this. (Example model below) If I write: var
html Tidy gives this as output for some reason: <?xml version=1.0 encoding=utf-16?> <?xml version=1.0
For some reason, addAsync chaining in a flexunit test as described in this article
I know this is a dumb question. For some reason my mind is blank
Okay so im working on this php image upload system but for some reason
This is a fairly basic question, which for some reason, a proper solution escapes
This should be a really really simple thing, but for some reason it is
For some reason when I attempt to make a request to an Ajax.net web
For some reason when I create a new namespace in Visual Studio 2008 its

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.