skip to Main Content

I was trying to create a child process using fork but it is repeatedly returning -1, I tried to found the causes and I came to this:

Fork() will fail and no child process will be created if:
[EAGAIN]           The system-imposed limit on the total number of pro-
                   cesses under execution would be exceeded.  This limit
                   is configuration-dependent.

[EAGAIN]           The system-imposed limit MAXUPRC (<sys/param.h>) on the
                   total number of processes under execution by a single
                   user would be exceeded.

[ENOMEM]           There is insufficient swap space for the new process. 

Now I don’t know how to check the first and third point but on looking at point MAXUPRC – I looked into sys/param.h:

//<sys/param.h>
#define MAXUPRC     CHILD_MAX   /* max simultaneous processes */

CHILD_MAX has been mentioned here (unistd.h):

//<unistd.h> - DEFINED IN MY SYSTEM
#define _SC_CHILD_MAX            2 

CHILD_MAX – _SC_CHILD_MAX
The maximum number of simultaneous processes per user ID.
Must not be less than _POSIX_CHILD_MAX (25).

Now I can’t establish if keeping _SC_CHILD_MAX less than 25 is the reason or do I have to look into 1st and 3rd causes (they are hard to check as the system is Z/OS with limited access and I don’t have much idea about it).

perror(""); isn’t printing anything and errno is printing 655360.

  #include<stdio.h>
  #include<errno.h>
  #include<unistd.h>
  #include<stdlib.h>

   int main()
   {
       long int prc_id;

       prc_id=fork();

       if(prc_id ==0)
          calling_child();        
       else if(prc_id <0)
       {
           printf("errno - %dn",errno); 
           printf("failed %dn",prc_id);
           exit(0);
       }

      return 0;
 }

This above code runs fine and creates a child process on my own laptop (centos) but in dev environment I guess there are some restrictions.

calling_child is never called as the prc_id returned is -1 (not even first print statement is printed on entering the function).

2

Answers


  1. If you’ve been playing with fork(2) you may well have used up your limit of processes available to your process, see ulimit for your shell:

    $ help ulimit | grep process
    Ulimit provides control over the resources available to processes
        -d      the maximum size of a process's data segment
        -l      the maximum size a process may lock into memory
        -u      the maximum number of user processes
    

    If so, logging out and logging back in again will solve the problem.

    Login or Signup to reply.
  2. I copied your sample program to my z/OS system running z/OS Version 2.3, with a minor enhancement since you left out the calling_child function (UPDATED to add the sysconf() value for SC_MAX_CHILD):

      #include<stdio.h>
      #include<errno.h>
      #include<unistd.h>
      #include<stdlib.h>
    
       int main()
       {
           long int prc_id;
           printf("SC_CHILD_MAX = %dn", sysconf(_SC_CHILD_MAX));
    
           prc_id=fork();
    
           if(prc_id ==0)
              calling_child();        
           else if(prc_id <0)
           {
               printf("errno - %dn",errno); 
               printf("failed %dn",prc_id);
               exit(0);
           }
    
          return 0;
         } 
    
       static void calling_child(void)
       {
          printf("Hello from PID %xn", getpid());
          return;
       }
    

    I put the code in a file called test2.c and built it with this shell command: c99 -o test2 -g test2.c

    It compiles cleanly and I was able to run it with no problems. It produces this output:

    SC_CHILD_MAX = 32767
    Hello from PID 40100b2
    

    Most likely your build or execution environment isn’t configured properly. It absolutely works fine on my pretty basic system, and I didn’t have to do anything unusual at all to get it running.

    A few small hints…

    How are you getting into the z/OS UNIX shell? If you’re logging onto TSO then running the ISPF shell or the OMVS command, you might prefer simply SSH’ing into your z/OS system. I usually find this is the cleanest batch environment.

    Second thing is that you probably want to double-check your C/C++ environment. There are some good debugging features built into the IBM XLC compiler – try man C99 (or whatever dialect you use) and have a read.

    Third thing is that IBM includes the dbx debugger in z/OS, so if you really get stuck, just try running your executable under dbx and you can step through your program line at a time.

    As for those ERRNOs and so on, don’t forget to also look at the __errno2() values – they usually have a very specific reason code that goes along with the more generic errors. For example, your z/OS security administrator can certainly do things to limit your use of z/OS UNIX functions – that would be revealed in the __errno2() values pretty clearly.

    Stick with it though – if you know UNIX or Linux, all the skills you have from using the shell to coding pretty much transfer 100% to z/OS if you put in a little time to learning the basics.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search