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