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