]> andersk Git - moira.git/blame - gdb/gdb_fserv.c
new kerberos library with interrealm stuff;
[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
0a5ff702 38/* For copying and distribution information, please see
39/* the file <mit-copyright.h>.
5580185e 40/*
41/************************************************************************/
42
0a5ff702 43#include <mit-copyright.h>
5580185e 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
94CONNECTION
95create_forking_server(service, validate)
96char *service;
97int (*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/************************************************************************/
183int
184gdb_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
213int
214g_do_signals()
215{
216 (void) signal(SIGCHLD, gdb_reaper);
217}
This page took 0.325609 seconds and 5 git commands to generate.