Varie correzioni, completata revisione capitolo sull'I/O su file
[gapil.git] / sources / fork_test.c
1 /* ForkTest.c
2  * 
3  * Copyright (C) 2001 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /****************************************************************
20  *
21  * Program ForkTest.c: 
22  * Program to test process creation
23  *
24  * Author: Simone Piccardi
25  * Sep. 2001
26  *
27  * Usage: forktest -h give all info's
28  *
29  ****************************************************************/
30 /* 
31  * Include needed headers
32  */
33 #include <errno.h>       /* error definitions and routines */ 
34 #include <stdlib.h>      /* C standard library */
35 #include <unistd.h>      /* unix standard library */
36 #include <stdio.h>       /* standard I/O library */
37 #include <string.h>      /* C strings library */
38
39 #include "Gapil.h"
40 #include "macros.h"
41
42 /* Help printing routine */
43 void usage(void);
44
45 int main(int argc, char *argv[])
46 {
47 /* 
48  * Variables definition  
49  */
50     int nchild, i;
51     pid_t pid;
52     int wait_child  = 0;
53     int wait_parent = 0;
54     int wait_end    = 0;
55     /*
56      * Input section: decode command line parameters 
57      * Use getopt function
58      */
59     opterr = 0;  /* don't want writing to stderr */
60     while ( (i = getopt(argc, argv, "hsp:c:e:")) != -1) {
61         switch (i) {
62         /* 
63          * Handling options 
64          */ 
65         case 'h':   /* help option */
66             printf("Wrong -h option use\n");
67             usage();
68             return -1;
69             break;
70         case 'c':   /* take wait time for childen */
71             wait_child = strtol(optarg, NULL, 10);    /* convert input */
72             break;
73         case 'p':   /* take wait time for childen */
74             wait_parent = strtol(optarg, NULL, 10);   /* convert input */
75             break;
76         case 'e':   /* take wait before parent exit */
77             wait_end = strtol(optarg, NULL, 10);      /* convert input */
78             break;
79         case 's':
80             Signal(SIGCHLD, HandSigCHLD);
81             break;
82         case '?':   /* unrecognized options */
83             printf("Unrecognized options -%c\n",optopt);
84             usage();
85         default:    /* should not reached */
86             usage();
87         }
88     }
89     /* ***********************************************************
90      * 
91      *           Options processing completed
92      *
93      *                Main code beginning
94      * 
95      * ***********************************************************/
96     /* There must be remaing parameters */
97     if (optind == argc) {
98         usage();
99     }
100     nchild = atoi(argv[optind]);
101     printf("Process %d: forking %d child\n", getpid(), nchild);
102     /* loop to fork children */
103     for (i=0; i<nchild; i++) {
104         if ( (pid = fork()) < 0) { 
105             /* on error exit */ 
106             printf("Error on %d child creation, %s\n", i+1, strerror(errno));
107             exit(-1); 
108         }
109         if (pid == 0) {   /* child */
110             printf("Child %d successfully executing\n", ++i);
111             if (wait_child) sleep(wait_child);
112             printf("Child %d, parent %d, exiting\n", i, getppid());
113             exit(0);
114         } else {          /* parent */
115             printf("Spawned %d child, pid %d \n", i+1, pid);
116             if (wait_parent) sleep(wait_parent);
117             printf("Go to next child \n");
118         }
119     }
120     /* normal exit */
121     if (wait_end) sleep(wait_end);
122     return 0;
123 }
124 /*
125  * routine to print usage info and exit
126  */
127 void usage(void) {
128     printf("Program forktest: fork a given number of child \n");
129     printf("Usage:\n");
130     printf("  forktest [-h] [-p sec] [-c sec] [-e sec] child to fork \n");
131     printf("  -h           print this help\n");
132     printf("  -s           install signal handler\n");
133     printf("  -p sec       wait sec seconds before next fork\n");
134     printf("  -c sec       wait sec seconds before child termination\n");
135     printf("  -e sec       wait sec seconds before parent return\n");
136     
137     exit(1);
138 }