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