]> andersk Git - moira.git/blob - gdb/gdb_fserv.c
33986ecc4702bfdd0f3e1bec1a53c537ddd41863
[moira.git] / gdb / gdb_fserv.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 #ifndef lint
7 static char *rcsid_gdb_fserv_c = "$Header$";
8 #endif  lint
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /************************************************************************/
31 /*      
32 /*                         gdb_fserv.c
33 /*      
34 /*            GDB - Routines to implement forking servers.
35 /*      
36 /*      Author: Noah Mendelsohn
37 /*      Copyright: 1986 MIT Project Athena 
38 /*              For copying and distribution information, please see
39 /*              the file <mit-copyright.h>.
40 /*      
41 /************************************************************************/
42
43 #include <mit-copyright.h>
44 #include <stdio.h>
45 #include <sys/types.h>
46 #include <sys/uio.h>
47 #include <sys/socket.h>
48 #include <sys/wait.h>
49 #include <sys/signal.h>
50 #include "gdb.h"
51 #include <sys/resource.h>
52 \f
53 /************************************************************************/
54 /*      
55 /*                      create_forking_server (create_forking_server)
56 /*      
57 /*      Called by an application to turn itself into a forking model
58 /*      server.  Returns from this routine occur only in the forked
59 /*      children.  The parent lives in this routine forever, waiting
60 /*      for incoming connection requests and doing the appropriate
61 /*      forking.
62 /*      
63 /*      Children are expected to do their own cleanup, but this routine
64 /*      does do the work of reaping the resulting zombie processes.
65 /*      
66 /*      ARGUMENTS:
67 /*      ----------
68 /*      
69 /*              service-id      identifies the port to be used for
70 /*                              listening.  Same rules as for
71 /*                              create_listening_connection.
72 /*      
73 /*              validate-rtn    pointer to a function to be called to
74 /*                              validate the incoming client.  Should
75 /*                              return TRUE if client is acceptable,
76 /*                              else false.  If this is NULL, all clients
77 /*                              are accepted.
78 /*      
79 /*      GLOBAL VARIABLES
80 /*      ----------------
81 /*      
82 /*      Children created by this routine inherit the global variables
83 /*      gdb_sockaddr_of_client, which is of type sockaddr_in and 
84 /*      gdb_socklen, which is the returned length of the sockaddr.
85 /*      These are the Berkeley identifiers of the clients as accepted.
86 /*      Use of this interface is non-portable to other than Berkeley 
87 /*      systems.
88 /*      
89 /*      The client's request tuple may be found in gdb_client_tuple.
90 /*      
91 /************************************************************************/
92
93
94 CONNECTION
95 create_forking_server(service, validate)
96 char *service;
97 int (*validate)();
98 {
99
100         CONNECTION incoming;                    /* listen for incoming */
101                                                 /* children here */
102         CONNECTION client = NULL;               /* connection to client */
103                                                 /* is created here */
104         OPERATION listenop;                     /* used to asynchronously */
105                                                 /* listen for a child */
106                                                 /* connection request */
107         GDB_INIT_CHECK
108
109         /*----------------------------------------------------------*/
110         /*      
111         /*      Set up parent execution environment
112         /*      
113         /*----------------------------------------------------------*/
114
115         g_do_signals();                         /* set up signal handling */
116
117         incoming = create_listening_connection(service);
118         if (incoming == NULL)
119                 GDB_GIVEUP("create_forking_server: can't create listening connection")
120
121         /*----------------------------------------------------------*/
122         /*      
123         /*      Repeatedly listen for incoming
124         /*      
125         /*----------------------------------------------------------*/
126
127         listenop = create_operation();
128         while (TRUE) {
129                 gdb_socklen = sizeof(gdb_sockaddr_of_client);
130                 client = NULL;
131                 (void) start_accepting_client(incoming, listenop, &client, 
132                                        gdb_sockaddr_of_client, &gdb_socklen,
133                                        &gdb_client_tuple);
134                 if(complete_operation(listenop) != OP_COMPLETE ||
135                    client == NULL) 
136                         GDB_GIVEUP("create_forking_server: failed to accept client")
137                 
138
139                 /*
140                  * Call the validate routine, if it fails, 
141                  * refuse the client.
142                  */
143                 if (validate != NULL && !(*validate)()) {
144                         reset_operation(listenop);
145                         start_replying_to_client(listenop, client, 
146                                                  GDB_REFUSED, "","");
147                         (void) complete_operation(listenop); 
148                         reset_operation(listenop);
149                         (void) sever_connection(client);
150                         continue;                       
151                 }
152                 /*
153                  * Create  the child for this client
154                  */
155                 if ((gdb_Debug & GDB_NOFORK) || fork() == 0) {
156                        /*
157                         * This is the child, or we're in noforking
158                         * debug mode.
159                         */
160                         reset_operation(listenop);
161                         start_replying_to_client(listenop, client, 
162                                                  GDB_ACCEPTED, "","");
163                         if (complete_operation(listenop) != OP_COMPLETE) 
164                                 exit(8);
165                         return client;          /* return to application */
166                                                 /* program */
167                 }
168                /*
169                 * Still in the parent
170                 */
171                 (void) sever_connection(client);
172                 reset_operation(listenop);
173         }
174 }
175 \f
176 /************************************************************************/
177 /*      
178 /*                              gdb_reaper
179 /*      
180 /*      Called on SIGCHILD to reap all dead children.
181 /*      
182 /************************************************************************/
183 int
184 gdb_reaper()
185 {
186         union wait status;
187         extern char *sys_siglist[];
188        
189         while (wait3(&status, WNOHANG, (struct rusage *)0) >0) {
190 #ifdef notdef
191                 if (WIFEXITED(status)) {
192                         if (status.w_retcode)
193                                 printf("exited with code %d\n",
194                                         status.w_retcode);
195                 }
196                 if (WIFSIGNALED(status)) {
197                         printf("exited on %s signal%s\n",
198                                sys_siglist[status.w_termsig],
199                                (status.w_coredump?"; core dumped":0));
200                 }
201 #endif notdef
202         }
203 }
204 \f
205 /************************************************************************/
206 /*      
207 /*                              g_do_signals
208 /*      
209 /*      Set up signal handling for a forking server.
210 /*      
211 /************************************************************************/
212
213 int
214 g_do_signals()
215 {
216         (void) signal(SIGCHLD, gdb_reaper);
217 }
This page took 0.040219 seconds and 3 git commands to generate.