]> andersk Git - moira.git/blame - gdb/gdb_ops.c
Don't coredump on bad input streams (sanity check lengths of received
[moira.git] / gdb / gdb_ops.c
CommitLineData
5580185e 1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static char *rcsid_gdb_ops_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_ops.c
33/*
34/* GDB - Asynchronous Operations and Their Synchronous
35/* Counterparts
36/*
37/* Author: Noah Mendelsohn
38/* Copyright: 1986 MIT Project Athena
0a5ff702 39/* For copying and distribution information, please see
40/* the file <mit-copyright.h>.
5580185e 41/*
42/* These routines provide a suite of asynchronous operations
43/* on connections.
44/*
45/************************************************************************/
46
0a5ff702 47#include <mit-copyright.h>
5580185e 48#include <stdio.h>
49#include "gdb.h"
50#include <netinet/in.h>
51#include <sys/ioctl.h>
52#ifdef vax
53extern u_long htonl();
54#endif vax
55\f
56/************************************************************************/
57/*
58/* send_object (send_object)
59/*
60/* Synchronous form of start_sending_object. Returns either
61/* OP_CANCELLED, or OP_RESULT(op).
62/*
63/************************************************************************/
64
65int
66send_object(con, objp, type)
67CONNECTION con;
68char *objp;
69int type;
70{
71 register OPERATION op;
72 register int retval;
73
74
75 op = create_operation();
76 start_sending_object(op, con, objp, type);
77 (void) complete_operation(op);
78 if (OP_STATUS(op) == OP_COMPLETE)
79 retval = OP_RESULT(op);
80 else
81 retval = OP_STATUS(op);
82 delete_operation(op);
83 return retval;
84}
85\f
86/************************************************************************/
87/*
88/* start_send_object (g_snobj)
89/*
90/* Start the asynchronous transmission of a gdb object.
91/* Note that this routine must be passed the address of the object,
92/* not the object itself.
93/*
94/* The following three routines work together, and may be considered
95/* as a single entity implementing the operation. The first merely
96/* saves away its arguments and queues the operation on the designated
97/* connection. These stay there until they percolate to the head of
98/* the queue. The second is the initialization routine, which is
99/* called by the connection maintenance logic when the operation
100/* first reaches the head of the queue. This routine encodes
101/* the supplied data for transmission, and then sends it. If the
102/* transmission executes synchronously, then the third routine is
103/* called immediately to clean up. If not, the third routine is
104/* marked as the 'continuation' routine, which will cause its
105/* invocation when the transmission completes.
106/*
107/* The data is preceded by its length expressed as a long in
108/* network byte order.
109/*
110/************************************************************************/
111
112struct obj_data {
113 char *objp; /* address of the object to */
114 /* be sent */
115 int type; /* type code for the object */
116 /* to be sent*/
117 char *flattened; /* address of first byte */
118 /* of flattened data */
119 int len; /* length of the flattened */
120 /* data */
121};
122
123int g_isnobj();
124int g_csnobj();
125
126int
127start_sending_object(op, con, objp, type)
128OPERATION op;
129CONNECTION con;
130char *objp;
131int type;
132{
133 struct obj_data *arg;
134
135 /*
136 * Make sure the supplied connection is a legal one
137 */
138 GDB_CHECK_CON(con, "start_sending_object")
139 GDB_CHECK_OP(op, "start_sending_object")
140
141 arg = (struct obj_data *)db_alloc(sizeof(struct obj_data));
142
143 arg->objp = objp;
144 arg->type = type;
145 initialize_operation(op, g_isnobj, (char *)arg, (int (*)())NULL);
146 (void) queue_operation(con, CON_OUTPUT, op);
147}
148
149 /*----------------------------------------------------------*/
150 /*
151 /* g_isnobj
152 /*
153 /* Init routine for sending an object. This routine is
154 /* called by the connection management logic when the send
155 /* request percolates to the top of the queue. This routine
156 /* reformats the data into an appropriate form for transmission.
157 /* The format used is a length, represented as a long in
158 /* network byte order, followed by the data itself. The
159 /* continuation routine below is called, either synchronously
160 /* or asynchronously, once the transmission is complete.
161 /*
162 /*----------------------------------------------------------*/
163
164int
165g_isnobj(op, hcon, arg)
166OPERATION op;
167HALF_CONNECTION hcon;
168struct obj_data *arg;
169{
170 /*
171 * Find out the encoded length of the data
172 */
173 arg->len = FCN_PROPERTY(arg->type, CODED_LENGTH_PROPERTY)
174 (arg->objp, hcon);
175
176 /*
177 * Allocate space and flatten (encode) the data
178 */
179 arg->flattened = db_alloc(arg->len+sizeof(long));
180 *(u_long *)arg->flattened = htonl((u_long)arg->len);
181
182 FCN_PROPERTY(arg->type, ENCODE_PROPERTY)
183 (arg->objp, hcon, arg->flattened+sizeof(long));
184
185 /*
186 * Set up continuation routine in case it's needed after the return
187 */
188 op->fcn.cont = g_csnobj;
189
190 /*
191 * Start sending the data, maybe even complete
192 */
193 if (gdb_send_data(hcon, arg->flattened, arg->len + sizeof(long)) ==
194 OP_COMPLETE) {
195 return g_csnobj(op, hcon, arg) ;/* this return is a little */
196 /* subtle. As continuation */
197 /* routines call each other */
198 /* synchronously, the last */
199 /* one determines whether we */
200 /* completed or are still */
201 /* running. That status */
202 /* percolates back through */
203 /* the entire call chain. */
204 } else {
205 return OP_RUNNING;
206 }
207}
208
209
210
211
212
213
214 /*----------------------------------------------------------*/
215 /*
216 /* g_csnobj
217 /*
218 /* Continuation routine for sending an object. Since there is
219 /* only one transmission, started by the init routine, this is
220 /* called when that transmission is done, and it does all the
221 /* associated clean up.
222 /*
223 /*----------------------------------------------------------*/
224
225int
226g_csnobj(op, hcon, arg)
227OPERATION op;
228HALF_CONNECTION hcon;
229struct obj_data *arg;
230{
231 op->result = OP_SUCCESS;
232 db_free((char *)arg->flattened, arg->len + sizeof(long));
233 /* free the sent data */
234 db_free((char *)arg, sizeof(struct obj_data)); /* free the state structure */
235 return OP_COMPLETE;
236}
237
238\f
239/************************************************************************/
240/*
241/* receive_object (receive_object)
242/*
243/* Synchronous form of start_receiving_object. Returns either
244/* OP_CANCELLED, or OP_RESULT(op).
245/*
246/************************************************************************/
247
248int
249receive_object(con, objp, type)
250CONNECTION con;
251char *objp;
252int type;
253{
254 register OPERATION op;
255 register int retval;
256
257 op = create_operation();
258 start_receiving_object(op, con, objp, type);
259 (void) complete_operation(op);
260 if (OP_STATUS(op) == OP_COMPLETE)
261 retval = OP_RESULT(op);
262 else
263 retval = OP_STATUS(op);
264 delete_operation(op);
265 return retval;
266}
267\f
268/************************************************************************/
269/*
270/* start_receiving_object (g_rcobj)
271/*
272/* Start the asynchronous receipt of a gdb object. Note that this
273/* routine must be passed the address of the object, not the object
274/* itself. In the case of structured objects, this routine may
275/* allocate the necessary storage. The work to build the object is
276/* done by the object's decode routine.
277/*
278/* The following three routines work together, and may be considered
279/* as a single entity implementing the operation. The first merely
280/* saves away its arguments and queues the operation on the designated
281/* connection. These stay there until they percolate to the head of
282/* the queue. The second is the initialization routine, which is
283/* called by the connection maintenance logic when the operation
284/* first reaches the head of the queue. This routine initiates a read
285/* for the length of the object, and sets up a continuation routine
286/* to read the object itself. When the object itself has been read, it
287/* is decoded and the operation completes.
288/*
289/* The data is preceded by its length expressed as a long in
290/* network byte order.
291/*
292/* preempt_and_start_receiving_object (g_prcobj)
293/*
294/* Similar to above, but may be called only from an active operation
295/* (i.e. an init or continue routine) on an inbound half connection.
296/* The receive effectively pre-empts the old operation, which wil
297/* continue after the receive is done.
298/*
299/*
300/************************************************************************/
301
302struct robj_data {
303 char *objp; /* address of the object to */
304 /* be received */
305 int type; /* type code for the object */
306 /* to be received */
307 char *flattened; /* address of first byte */
308 /* of flattened data */
309 int len; /* length of the flattened */
310 /* data */
311};
312
313int g_ircobj();
314int g_c1rcobj();
315int g_c2rcobj();
316
317 /*----------------------------------------------------------*/
318 /*
319 /* start_receiving_object
320 /*
321 /*----------------------------------------------------------*/
322
323int
324start_receiving_object(op, con, objp, type)
325OPERATION op;
326CONNECTION con;
327char *objp;
328int type;
329{
330 struct robj_data *arg;
331
332 /*
333 * Make sure the supplied connection is a legal one
334 */
335 GDB_CHECK_CON(con, "start_receiving_object")
336 GDB_CHECK_OP(op, "start_receiving_object")
337
338 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
339
340 arg->objp = objp;
341 arg->type = type;
342 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
343 (void) queue_operation(con, CON_INPUT, op);
344}
345
346 /*----------------------------------------------------------*/
347 /*
348 /* preempt_and_start_receiving_object
349 /*
350 /*----------------------------------------------------------*/
351
352int
353preempt_and_start_receiving_object(op, oldop, objp, type)
354OPERATION op;
355OPERATION oldop;
356char *objp;
357int type;
358{
359 struct robj_data *arg;
360
361 /*
362 * Make sure the supplied connection is a legal one
363 */
364 GDB_CHECK_OP(op, "preempt_and_start_receiving_object")
365 GDB_CHECK_OP(oldop, "preempt_and_start_receiving_object")
366
367 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
368
369 arg->objp = objp;
370 arg->type = type;
371 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
372 (void) g_preempt_me(oldop, op);
373}
374
375 /*----------------------------------------------------------*/
376 /*
377 /* g_ircobj
378 /*
379 /* Initialization routine for receiving an object.
380 /* Called when the receive operation percolates to the
381 /* top of the queue. First, we must receive the single
382 /* 'long' which carries the length of the rest of the data.
383 /* We do that now, either synchronously or asynchronously.
384 /*
385 /*----------------------------------------------------------*/
386
387int
388g_ircobj(op, hcon, arg)
389OPERATION op;
390HALF_CONNECTION hcon;
391struct robj_data *arg;
392{
393 op->fcn.cont = g_c1rcobj;
394 if(gdb_receive_data(hcon, (char *)&(arg->len), sizeof(long)) == OP_COMPLETE) {
395 return g_c1rcobj(op, hcon, arg);/* this return is a little */
396 /* subtle. As continuation */
397 /* routines call each other */
398 /* synchronously, the last */
399 /* one determines whether we */
400 /* completed or are still */
401 /* running. That status */
402 /* percolates back through */
403 /* the entire call chain. */
404 } else {
405 return OP_RUNNING;
406 }
407}
408
409 /*----------------------------------------------------------*/
410 /*
411 /* g_c1rcobj
412 /*
413 /* At this point, we have received the length. Now, allocate
414 /* the space for the rest of the data, and start receiving
415 /* it.
416 /*
417 /*----------------------------------------------------------*/
418
419int
420g_c1rcobj(op, hcon, arg)
421OPERATION op;
422HALF_CONNECTION hcon;
423struct robj_data *arg;
424{
425#ifdef vax
426 extern u_long ntohl();
427#endif vax
428
429 /*
430 * Now we know the length of the encoded data, convert the length
431 * to local byte order, and allocate the space for the receive.
432 */
433 arg->len = (int) ntohl((u_long)arg->len);
b1fb7b0c 434 if (arg->len > 65536)
435 return OP_CANCELLED;
5580185e 436
437 arg->flattened = db_alloc(arg->len);
b1fb7b0c 438 if (arg->flattened == NULL)
439 return OP_CANCELLED;
5580185e 440 /*
441 * Now start receiving the encoded object itself. If it all comes in
442 * synchronously, then just go on to the c2 routine to decode it and
443 * finish up. Else return OP_RUNNING, so the rest of the system
444 * can get some work done while we wait.
445 */
446 op->fcn.cont = g_c2rcobj;
447 if(gdb_receive_data(hcon, arg->flattened, arg->len ) == OP_COMPLETE) {
448 return g_c2rcobj(op, hcon, arg);
449 } else {
450 return OP_RUNNING;
451 }
452}
453
454 /*----------------------------------------------------------*/
455 /*
456 /* g_c2rcobj
457 /*
458 /* At this point, all the data has been received. Decode
459 /* it into the place provided by the caller, free all
460 /* temporarily allocated memory, and return.
461 /*
462 /*----------------------------------------------------------*/
463
464int
465g_c2rcobj(op, hcon, arg)
466OPERATION op;
467HALF_CONNECTION hcon;
468struct robj_data *arg;
469{
470 /*
471 * Decode the received data into local representation.
472 */
473 FCN_PROPERTY(arg->type, DECODE_PROPERTY)
474 (arg->objp, hcon, arg->flattened);
475 op->result = OP_SUCCESS;
476 db_free(arg->flattened, arg->len); /* free the received data */
477 db_free((char *)arg, sizeof(struct robj_data)); /* free the state structure */
478 return OP_COMPLETE;
479}
480\f
481/************************************************************************/
482/*
483/* complete_operation(complete_operation)
484/*
485/* Wait for a given operation to complete, allowing everything
486/* to progress in the meantime. Returns the last known status
487/* of the operation, which in general will be OP_COMPLETE unless
488/* errors were encountered (and this version of the code doesn't
489/* do error handing right anyway!)
490/*
491/* We do this by (1) calling gdb_progress to assure that all
492/* possible progress has been made, which is always a good thing
493/* to do when we get the chance and (2) looping on calls to
494/* con_select, which will make all possible future progress,
495/* but without burning cycles unnecessarily in the process.
496/*
497/************************************************************************/
498
499int
500complete_operation(op)
501OPERATION op;
502{
503 (void) gdb_progress();
504
505 while(op->status != OP_COMPLETE && op->status != OP_CANCELLED)
506 (void) con_select(0, (fd_set *)NULL, (fd_set *)NULL,
507 (fd_set *)NULL, (struct timeval *)NULL);
508
509 return op->status;
510
511}
512
513\f
514/************************************************************************/
515/*
516/* cancel_operation(cancel_operation)
517/*
518/* Attempts to cancel an operation.
519/*
520/************************************************************************/
521
522int
523cancel_operation(op)
524OPERATION op;
525{
526 register HALF_CONNECTION hcon = op->halfcon;
527
528 if (op->status != OP_RUNNING && op->status != OP_QUEUED)
529 return op->status;
530
531 if (hcon == NULL)
532 GDB_GIVEUP("cancel_operation: operation is queued but half connection is unknown")
533
534 /*
535 * If we're at the head of the queue and running, then we have to
536 * call the cancelation routine for this particular operation so
537 * it can clean up.
538 */
539 if (op->prev == (OPERATION)hcon) {
540 if (op->status == OP_RUNNING && op->cancel != NULL)
541 (*op->cancel)(op->halfcon, op->arg);
542 }
543
544 /*
545 * Looks safe, now cancel it.
546 */
547 op->next->prev = op->prev; /* de-q it */
548 op->prev->next = op->next; /* " " " */
549 op->status = OP_CANCELLED;
550 op->halfcon = NULL;
551
552 return OP_CANCELLED;
553}
554\f
555/************************************************************************/
556/*
557/* start_listening
558/*
559/* Start the asynchronous acquisition of a connection. This
560/* results in the queuing of a GDB "OPERATION" to do the
561/* requested listening.
562/*
563/************************************************************************/
564
565struct lis_data {
566 char *otherside; /* data returned from an */
567 /* accept */
568 int *otherlen; /* length of the otherside */
569 /* field */
570 int *fdp; /* ptr to the fd of the */
571 /* newly accepted */
572 /* connection */
573};
574
575int g_ilis();
576int g_clis();
577
b1fb7b0c 578void
5580185e 579gdb_start_listening(op, con, otherside, lenp, fdp)
580OPERATION op;
581CONNECTION con;
582char *otherside;
583int *lenp;
584int *fdp;
585{
586 struct lis_data *arg;
587
588 GDB_INIT_CHECK
589
590 /*
591 * Make sure the supplied connection is a legal one
592 */
593 GDB_CHECK_CON(con, "start_listening")
594 GDB_CHECK_OP(op, "start_listening")
595
596 arg = (struct lis_data *)db_alloc(sizeof(struct lis_data));
597
598 arg->otherside = otherside;
599 arg->otherlen = lenp;
600 arg->fdp = fdp;
601 initialize_operation(op, g_ilis, (char *)arg, (int (*)())NULL);
602 (void) queue_operation(con, CON_INPUT, op);
603}
604
605 /*----------------------------------------------------------*/
606 /*
607 /* g_ilis
608 /*
609 /* Init routine for doing a listen.
610 /*
611 /*----------------------------------------------------------*/
612
613int
614g_ilis(op, hcon, arg)
615OPERATION op;
616HALF_CONNECTION hcon;
617struct lis_data *arg;
618{
619 int rc;
620
621 /*
622 * Set up continuation routine in case it's needed after the return
623 */
624 op->fcn.cont = g_clis;
625
626 /*
627 * Try doing the listen now, and then decide whether to go
628 * right on to the continuation routine or to let things hang
629 * for the moment.
630 */
631 rc = gdb_start_a_listen(hcon, arg->otherside, arg->otherlen, arg->fdp);
632 if (rc==OP_COMPLETE) {
633 return g_clis(op, hcon, arg); /* this return is a little */
634 /* subtle. As continuation */
635 /* routines call each other */
636 /* synchronously, the last */
637 /* one determines whether we */
638 /* completed or are still */
639 /* running. That status */
640 /* percolates back through */
641 /* the entire call chain. */
642 } else {
643 return OP_RUNNING;
644 }
645}
646
647
648
649 /*----------------------------------------------------------*/
650 /*
651 /* g_clis
652 /*
653 /* Continuation routine for accepting a connection.
654 /*
655 /* At this point, the fd has been accepted and all
656 /* the necessary information given back to the caller.
657 /*
658 /*----------------------------------------------------------*/
659
660int
661g_clis(op, hcon, arg)
662OPERATION op;
663HALF_CONNECTION hcon;
664struct lis_data *arg;
665{
666 op->result = OP_SUCCESS;
667 db_free((char *)arg, sizeof(struct lis_data));
668 /* free the state structure */
669 return OP_COMPLETE;
670}
671
672\f
673/************************************************************************/
674/*
675/* start_accepting_client
676/*
677/* Start the asynchronous acquisition of a client. This queueable
678/* operation first tries to accept a connection. On this connection,
679/* it reads a startup string from the client, and then completes.
680/*
681/* The return values from this are not quite what you might expect.
682/* In general, the operation will show complete, rather than cancelled,
683/* if it gets as far as creating the new connection at all. If
684/* subsequent activities result in errors from system calls, then
685/* this operation will complete with a status of OP_COMPLETE and a
686/* result of OP_CANCELLED. In this case, the applications IS given
687/* a connection descriptor for the new connection, and that descriptor
688/* has an errno value indicating why the failure occurred. The
689/* caller must then sever this connection to free the descriptor.
690/*
691/************************************************************************/
692
693struct acc_data {
694 char *otherside; /* data returned from an */
695 /* accept */
696 int *otherlen; /* length of the otherside */
697 /* field */
698 OPERATION listenop; /* used to listen for */
699 /* the fd */
700 OPERATION receiveop; /* used when receiving */
701 /* tuple from the client */
702 CONNECTION con; /* the connection we're */
703 /* trying to create */
704 CONNECTION *conp; /* this is where the caller */
705 /* wants the connection */
706 /* returned */
707 TUPLE *tuplep; /* pointer to tuple we */
708 /* are going to receive */
709 /* from new client */
710};
711
712int g_iacc();
713int g_i2acc();
714
b1fb7b0c 715void
5580185e 716start_accepting_client(listencon, op, conp, otherside, lenp, tuplep)
717CONNECTION listencon;
718OPERATION op;
719CONNECTION *conp;
720char *otherside;
721int *lenp;
722TUPLE *tuplep;
723{
724 struct acc_data *arg;
725
726 GDB_INIT_CHECK
727
728 /*
729 * Make sure the supplied connection and operation are legal
730 */
731 GDB_CHECK_CON(listencon, "start_accepting_client")
732 GDB_CHECK_OP(op, "start_accepting_client")
733
734 arg = (struct acc_data *)db_alloc(sizeof(struct acc_data));
735
736 arg->otherside = otherside;
737 arg->otherlen = lenp;
738 arg->conp = conp;
739 *conp = NULL; /* in case we fail */
740 arg->listenop = create_operation();
741 arg->receiveop = create_operation();
742 arg->con = g_make_con();
743 arg->tuplep = tuplep;
744 *tuplep = NULL; /* in case we fail */
745
746 /*
747 * Queue an operation ahead of us which will accept an fd and
748 * put it in arg->con->in. As a byproduct, pick up the from
749 * information that we return to the caller.
750 */
751 gdb_start_listening(arg->listenop, listencon,
752 arg->otherside,
753 arg->otherlen, &(arg->con->in.fd));
754
755 /*
756 * Now queue us behind it. By the time we run our init routine,
757 * a connection should have been acquired.
758 */
759 initialize_operation(op, g_iacc, (char *)arg, (int (*)())NULL);
760 (void) queue_operation(listencon, CON_INPUT, op);
761}
762
763 /*----------------------------------------------------------*/
764 /*
765 /* g_iacc
766 /*
767 /* Init routine for accepting a connection. By the
768 /* time this runs, the listen has been done, the
769 /* 'from' data put in position for the caller, and
770 /* the fd plugged into the connection descriptor.
771 /* If all went well, fill out the connection descriptor
772 /* and then requeue us on that to do the receive of
773 /* the requested tuple.
774 /*
775 /*----------------------------------------------------------*/
776
777int
778g_iacc(op, hcon, arg)
779OPERATION op;
780HALF_CONNECTION hcon;
781struct acc_data *arg;
782{
783 register CONNECTION con = arg->con;
784
785 /*
786 * Set up 2nd init routine for after we re-queue ourselves
787 */
788 op->fcn.cont = g_i2acc;
789 /*
790 * See whether we successfully accepted a connection. If
791 * not, we just cancel ourselves. If so, fill out the
792 * connection descriptor and related data structures properly,
793 * then requeue ourselves on the new connection.
794 */
795 if (OP_STATUS(arg->listenop) != OP_COMPLETE ||
796 OP_RESULT(arg->listenop) != OP_SUCCESS ||
797 con->in.fd <=0) {
798 (void) sever_connection(con);
799 g_clnup_accept(arg);
800 op->result = OP_CANCELLED;
801 return OP_CANCELLED;
802 }
803
804 /*
805 * OK, we got an fd, but the connection and related structures
806 * aren't really set up straight, and the fd must be put
807 * into non-blocking mode. There really should be a common
808 * routine for this, since some of the logic exists in 2
809 * or 3 places.
810 */
811 con->status = CON_STARTING;
812 con->out.fd = con->in.fd;
813 g_ver_iprotocol(con); /* make sure we're at */
814 /* same level of protocol */
815 if (con->status == CON_UP) {
816 /*
817 * We've successfully started the connection, now mark
818 * it for non-blocking I/O. Also, update the high water
819 * mark of fd's controlled by our system.
820 */
821 int nb = 1;
822 if(ioctl(con->in.fd, FIONBIO, (char *)&nb)== (-1)) {
823 g_stop_with_errno(con);
824 *arg->conp = con; /* give failed con to */
825 /* caller so he can find */
826 /* errno */
827 gdb_perror("gdb: ioctl for non-block failed");
828 g_clnup_accept(arg);
829 op->result = OP_CANCELLED; /* we didn't really, but */
830 /* we want caller to look */
831 /* at the connection so he */
832 /* can find errno*/
833 return OP_COMPLETE;
834 }
835 if (con->in.fd +1 > gdb_mfd)
836 gdb_mfd = con->in.fd + 1;
837 /*
838 * Allocate a buffer, if necessary, and reset buffer pointers
839 * so first request will result in a long read into the buffer
840 */
841 g_allocate_connection_buffers(con);
842
843 } else {
844 *arg->conp = con; /* give failed con to */
845 /* caller so he can find */
846 /* errno */
847 g_clnup_accept(arg);
848 op->result = OP_CANCELLED;
849 return OP_COMPLETE;
850 }
851
852 /*
853 * Before we requeue ourselves on the new connection, queue
854 * up a receive for the expected tuple. Then we'll be
855 * sure that it's there by the time we run.
856 */
857 start_receiving_object(arg->receiveop, con, (char *)(arg->tuplep),
858 TUPLE_T);
859 /*
860 * Requeue ourselves behind the receive operation.
861 */
862
863 (void) requeue_operation(con, CON_INPUT, op);
864 return OP_REQUEUED;
865}
866
867
868
869 /*----------------------------------------------------------*/
870 /*
871 /* g_i2acc
872 /*
873 /* Second init routine for accepting a connection.
874 /* This one is run after the operation is requeued on
875 /* the new connection. By the time we run here, the
876 /* attempt to receive the tuple has already been made.
877 /* We just check on status and clean-up.
878 /*
879 /*----------------------------------------------------------*/
880
881int
882g_i2acc(op, hcon, arg)
883OPERATION op;
884HALF_CONNECTION hcon;
885struct acc_data *arg;
886{
887 int rc;
888
889 rc = OP_STATUS(arg->receiveop); /* if it completes, then */
890 /* so do we! */
891 *arg->conp = arg->con; /* give caller the new con */
892 if (rc != OP_COMPLETE)
893 (void) g_stop_connection(arg->con);
894 /*
895 * Release all transient data structures.
896 */
897 g_clnup_accept(arg);
898
899 return OP_COMPLETE;
900}
901
902 /*----------------------------------------------------------*/
903 /*
904 /* g_clnup_accept
905 /*
906 /* Free all data structures used by start_accepting_client.
907 /*
908 /*----------------------------------------------------------*/
909
910int
911g_clnup_accept(arg)
912struct acc_data *arg;
913{
914 delete_operation(arg->listenop);
915 delete_operation(arg->receiveop);
916 db_free((char *)arg, sizeof(struct acc_data));
917}
This page took 0.165184 seconds and 5 git commands to generate.