]> andersk Git - moira.git/blame - gdb/test.c
Case-insensitive stuff.
[moira.git] / gdb / test.c
CommitLineData
5580185e 1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static char *rcsid_test_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_trans2.c
33/*
34/* GDB - Data Transport Services Routines (Part 2)
35/*
36/* Author: Noah Mendelsohn
37/* Copyright: 1986 MIT Project Athena
38/*
39/* These routines implement layer 6 of the Client Library
40/* Specification of the GDB system, as well as the facilities
41/* outlined in the GDB Protocol Specification. Part 2 of 2.
42/*
43/* Some of the routines specified are actually implemented as
44/* macros defined in gdb.h.
45/*
46/************************************************************************/
47
48#include <sys/types.h>
49#include <errno.h>
50#include <stdio.h>
51#include "gdb.h"
52
53extern int errno; /* Unix error slot */
54
55/*
56 * The following values are returned by g_con_progress
57 */
58#define NOPROGRESS 0 /* nothing happened on this */
59 /* connection--must be 0*/
60#define PROGRESS 1 /* connection has progressed */
61#define COMPLETE 2 /* an operation has */
62 /* completed on this con */
63\f
64/************************************************************************/
65/*
66/* queue_operation(queue_operation)
67/*
68/* Add an operation to the queue for a given connection, and
69/* then allows all connections to progress. Returns the last
70/* known status of the operation.
71/*
72/************************************************************************/
73
74int
75queue_operation(con, direction, op)
76CONNECTION con;
77int direction;
78OPERATION op;
79{
80 register HALF_CONNECTION hcon = (direction==CON_INPUT)?(&(con->in)):
81 (&(con->out));
82
83 GDB_CHECK_CON(con, "queue_operation")
84 /*
85 * Write message to debugging log
86 */
87 if (gdb_Debug & GDB_LOG)
88 fprintf(gdb_log, "op queued: con=0x%x dir=%s op=0x%x Q was %s empty\n",
89 con, (direction == CON_INPUT)?"INPUT":"OUTPUT",
90 op, (hcon->op_q_first == (OPERATION)hcon)?"":"not");
91 /*
92 * Make sure connection is up
93 */
94 if (con->status != CON_UP) {
95 op->status = OP_CANCELLED;
96 if (gdb_Debug & GDB_LOG)
97 fprintf(gdb_log, "\nop NOT queued\n");
98 return OP_CANCELLED;
99 }
100
101 /*
102 * Put the new operation at the end of the queue
103 */
104 op->prev = hcon->op_q_last;
105 op->next = (OPERATION)hcon;
106 hcon->op_q_last->next = op;
107 hcon->op_q_last = op;
108 /*
109 * Mark it as queued
110 */
111 op->status = OP_QUEUED;
112 op->halfcon = hcon;
113 /*
114 * Force progress on all connections
115 */
116 gdb_progress();
117
118 /*
119 * Return the last known status of the operation
120 */
121 return op->status;
122}
123/************************************************************************/
124/*
125/* requeue_operation
126/*
127/* This routine may be called from an init or continuation routine
128/* to cause the current operation to be requeued on a new connection.
129/* The init routine field ofthe operation should be properly set to
130/* indicate the routine to receive control when the operation actually
131/* runs on the new connection. The caller of this routine is
132/* responsible for returning the status OP_REQUEUED to its caller.
133/*
134/* This routine returns the status of the newly queued operation.
135/* Note, however, that even if this operation returns the status
136/* CANCELLED, the operation itself may not continue to execute
137/* on the old connection and it should return the status OP_REQUEUED,
138/* NOT OP_CANCELLED (at least in this implementation.)
139/*
140/************************************************************************/
141
142int
143requeue_operation(con, direction, op)
144CONNECTION con;
145int direction;
146OPERATION op;
147{
148 /*
149 * Make sure the connection supplied is a legal one
150 */
151 GDB_CHECK_CON(con, "requeue_operation")
152 /*
153 * Write message to debugging log
154 */
155 if (gdb_Debug & GDB_LOG)
156 fprintf(gdb_log, "op requeued: new con=0x%x dir=%s op=0x%x\n",
157 con, (direction == CON_INPUT)?"INPUT":"OUTPUT",
158 op);
159 /*
160 * Dequeue the operation from its old half connection
161 */
162 g_op_newhead(op->halfcon);
163
164 /*
165 * Now queue it on the new one
166 */
167 return queue_operation(con, direction, op);
168}
169
170/************************************************************************/
171/*
172/* g_preempt_me
173/*
174/* Sticks a new operation in ahead of the current one and runs it
175/* on the current connection. May be called only from an init or
176/* continuation routine. The old operation must have completely
177/* prepared the descriptor for the new operation, i.e. it should
178/* be in the same state as it would be for a call to queue_operation.
179/* g_preempt_me makes it possible for operations to be built by
180/* composition of other smaller operations, since newop runs, in
181/* a sense, as a subroutine of oldop. opdop must (1) reset its
182/* initialization routine to be a routine to be called when newop
183/* completes or cancels and (2) return the status OP_PREEMPTED to
184/* its caller.
185/*
186/************************************************************************/
187
188int
189g_preempt_me(oldop, newop)
190OPERATION oldop;
191OPERATION newop;
192{
193 register OPERATION old=oldop, new=newop;
194 register HALF_CONNECTION hc = old->halfcon;
195
196 /*
197 * Write message to debugging log
198 */
199 if (gdb_Debug & GDB_LOG)
200 fprintf(gdb_log, "op preempted: halfcon=0x%x oldop=0x%x newop=0x%x\n",
201 oldop,newop);
202 /*
203 * link in the new operation
204 */
205 old->prev = new;
206 hc->op_q_first = new;
207 new->prev = (OPERATION)hc;
208 new->next = old;
209 /*
210 * Set the status of the new operation
211 */
212 new->status = OP_QUEUED;
213 new->halfcon = hc;
214 /*
215 * Change the status of the old operation (one could argue that
216 * this should be done in gdb_hcon_progress after the return code
217 * is detected.)
218 */
219 old->status = OP_QUEUED;
220 return OP_QUEUED;
221}
222
223
224\f
225/************************************************************************/
226/*
227/* gdb_progress
228/*
229/* This routine should be called whenever it is suspected that
230/* progress can be made on any connection. This routine will
231/* cause all connections to proceed as far as they can without
232/* blocking, and will make a best effort to avoid long blocks.
233/* This routine MAY retain control for long periods when sustained
234/* progress is possible, but it will not knowingly hang.
235/*
236/* Returns: number of connections on which OPERATIONS have
237/* COMPLETED (not just progressed).
238/*
239/************************************************************************/
240
241int
242
243gdb_progress()
244{
245 register int i; /* index to available */
246 /* connections */
247 register int return_value = 0; /* the value we return */
248 int rc; /* short term storage for */
249 /* a return code */
250 int progress_made; /* true when some con */
251 /* made progress during */
252 /* latest pass through list */
253 int complete_map[GDB_MAX_CONNECTIONS]; /* indicates whether a */
254 /* transmission operation */
255 /* is newly complete on */
256 /* corresponding connection */
257 /* 1 if yes else 0 */
258 int maxcon = gdb_mcons; /* gdb_mcons may change */
259 /* out from under us if */
260 /* connections break. This */
261 /* is the initial value. */
262
263 /*
264 * Zero out the completion map for all connections.
265 */
266 for (i=0; i<maxcon; i++)
267 complete_map[i]=0;
268
269 /*
270 * Make repeated passes through all the fd's until a pass is made
271 * in which none makes any progress. This logic is important,
272 * because it catches the case where A is blocked, B makes progress,
273 * and A unblocks during the period where B is progressing.
274 */
275
276 do {
277 progress_made = FALSE;
278 for (i=0; i<gdb_mcons; i++) {
279 if (rc = g_con_progress(i)) { /* note: NOPROGRESS==0 */
280 progress_made = TRUE;
281 if (rc == COMPLETE)
282 complete_map[i] = 1;
283 }
284 }
285 } while (progress_made);
286
287 /*
288 * We've gone as far as we can, now find out how many connections
289 * have had operations complete.
290 */
291 for (i=0; i<maxcon; i++)
292 return_value += complete_map[i];
293
294 return return_value;
295}
296\f
297/************************************************************************/
298/*
299/* g_con_progress
300/*
301/* Make as much progress as possible on the specified connection.
302/* Returns NOPROGRESS if no bytes moved on either half connection,
303/* PROGRESS, if some moved and no operations completed, or COMPLETE if
304/* any of the operations completed. Note that each connection
305/* consists of two half connections, and we must make each of them
306/* progress as far as possible.
307/*
308/* The nest here starts getting so deep that it's hard to pass state
309/* around efficiently. We use a single global variable, gdb_conok,
310/* to indicate whether the connection we're working on now has died.
311/* The move data routines set this to FALSE whenever there is a
312/* fatal error on a connection. We check it, and do a proper
313/* sever on the connection if it seems to be in trouble.
314/*
315/************************************************************************/
316
317
318int
319g_con_progress(con_id)
320int con_id; /* index of this connection */
321 /* in the connection desc. */
322 /* arrays*/
323{
324 register CONNECTION con= (&gdb_cons[con_id]);
325 /* pointer to the connection */
326 /* data structure */
327 register int progress = NOPROGRESS;
328 register int live = TRUE; /* true when we've seen */
329 /* enough to make sure we */
330 /* want to go around again*/
331 int rc;
332 /*
333 * Check status of connection-if it's not running, then just return.
334 */
335 if (con->status != CON_UP)
336 return NOPROGRESS;
337 /*
338 * Repeatedly make progress on each half connection until both
339 * are idle. Important to keep trying as one may become active
340 * while the other is progressing.
341 */
342
343 gdb_conok = TRUE; /* this gets set to FALSE */
344 /* for fatal I/O errors */
345 /* there may be a timing */
346 /* window here in use of */
347 /* HCON_BUSY */
348 while (live) {
349 live = FALSE; /* until proven otherwise */
350 /*
351 * make progress on the input connection note that following
352 * logic depends on NOPROGRESS being 0
353 */
354 if (rc = gdb_hcon_progress(CON_INPUT, &con->in)) {
355 live = TRUE;
356 progress = max(rc, progress);
357 }
358 /*
359 * See if connection has died
360 */
361 if (!gdb_conok) {
362 g_stop_connection(con);
363 return COMPLETE; /* dying connection always */
364 /* implies that the */
365 /* operation at the head */
366 /* of the queue completed */
367 }
368 /*
369 * make progress on the output connection
370 */
371 if (rc = gdb_hcon_progress(CON_OUTPUT, &con->out)) {
372 live = TRUE;
373 progress = max(rc, progress);
374 }
375 /*
376 * See if connection has died
377 */
378 if (!gdb_conok) {
379 g_stop_connection(con);
380 return COMPLETE;
381 }
382 }
383
384 return progress;
385}
386
387
388/************************************************************************/
389/*
390/* gdb_hcon_progress
391/*
392/* Allows a specified half-connection to progress as much as possible,
393/* and returns true iff at least one operation is newly completed.
394/*
395/************************************************************************/
396
397int
398gdb_hcon_progress(direction, hc)
399int direction; /* CON_INPUT or CON_OUTPUT */
400struct half_con_data *hc; /* pointer to control struct */
401 /* for this half connection */
402{
403 HALF_CONNECTION half_con = hc;
404 /* half connection pointer */
405 /* fast copy in register */
406 register OPERATION op; /* current operation on this */
407 /* half connection */
408 int progress = NOPROGRESS; /* can indicate any progress */
409 /* on the half con or */
410 /* whether any operations */
411 /* completed */
412 int done; /* true when no more progress*/
413 /* can be made */
414 int fcn_result; /* result of latest init or */
415 /* continue function */
416
417 /*
418 * Write message to debugging log
419 */
420 if (gdb_Debug & GDB_LOG)
421 fprintf(gdb_log, "hcon_progress: halfcon=0x%x dir=%s ",
422 half_con, (direction==CON_INPUT)?"INPUT":"OUTPUT");
423
424 /*----------------------------------------------------------*/
425 /*
426 /* See if we are being re-entered and are already working
427 /* on this half_con. If so, return right now.
428 /*
429 /*----------------------------------------------------------*/
430
431 if (half_con->flags & HCON_BUSY) {
432 /*
433 * Write message to debugging log
434 */
435 if (gdb_Debug & GDB_LOG)
436 fprintf(gdb_log, "BUSY, returning\n");
437 return NOPROGRESS;
438 }
439
440 /*----------------------------------------------------------*/
441 /*
442 /* See if there is an operation on this half connection.
443 /* If not, return.
444 /*
445 /*----------------------------------------------------------*/
446
447
448 op = half_con->op_q_first; /* pick up first operation */
449 /* in queue */
450 if (op == (OPERATION)half_con) { /* see if end of circular */
451 /* list */
452 /*
453 * Write message to debugging log
454 */
455 if (gdb_Debug & GDB_LOG)
456 fprintf(gdb_log, "Q EMPTY, returning\n");
457 return NOPROGRESS; /* nothing to do on */
458 /* this half session */
459 }
460
461
462 /*----------------------------------------------------------*/
463 /*
464 /* Loop until all operations are complete, or until no further
465 /* progress can be made on this one.
466 /*
467 /* Loop invariants:
468 /*
469 /* 1) Op contains the operation at the head of the q, or
470 /* else is == half_con, indicating no more operationos
471 /* to be processed.
472 /*
473 /* 2) The operation at the head of the queue is either running
474 /* or continuing. As soon as one completes, it is dequeued.
475 /*
476 /* Progress is declared whenever an operation newly
477 /* returns OP_COMPLETE, i.e. whenever there has been
478 /* an operation which went from running to complete.
479 /*
480 /* Done is declared whenever an operation returns anything
481 /* other than complete, indicating that it cannot progress
482 /* further at this time. Loop ends.
483 /*
484 /* While we're here, mark us busy so we won't try the
485 /* same half_con on reentry.
486 /*
487 /*----------------------------------------------------------*/
488
489 done = FALSE; /* this one may be able to */
490 /* progress */
491
492 half_con->flags |= HCON_BUSY; /* don't try this hcon */
493 /* while we already doing */
494 /* it. Could happen if */
495 /* we queue new ops */
496 half_con->flags &= ~HCON_PROGRESS; /* gdb_move_data will */
497 /* indicate progress here*/
498 if (gdb_Debug & GDB_LOG)
499 fprintf(gdb_log, "LOOPING\n");
500
501 /*----------------------------------------------------------*/
502 /*
503 /* Loop through the operations queued on this half con
504 /* trying to make progress on them, in order.
505 /*
506 /*----------------------------------------------------------*/
507
508 while (!done &&
509 op != (OPERATION)half_con) {
510
511 if (gdb_Debug & GDB_LOG)
512 fprintf(gdb_log, "\top=0x%x status%d...",
513 op, OP_STATUS(op));
514
515 switch (op->status) {
516 /*
517 * Operation is at head of queue for first time and has
518 * never been started. Try to start it up.
519 */
520 case OP_QUEUED:
521 /*
522 * Call the initialization routine for this operation
523 */
524 fcn_result = (*op->fcn.init)(op,half_con,op->arg);
525 if (gdb_Debug & GDB_LOG)
526 fprintf(gdb_log, "init result=%d\n",
527 fcn_result);
528
529 switch (fcn_result) {
530 case OP_COMPLETE:
531 case OP_CANCELLED:
532 op->status = fcn_result;
533 op = g_op_newhead(half_con);
534 progress = COMPLETE;
535 break;
536 case OP_PREEMPTED:
537 op->status = OP_QUEUED;
538 /* fall thru */
539 case OP_REQUEUED:
540 /* important: don't set status on re-queued */
541 /* op as it may already have completed in */
542 /* its second life ! */
543 op = half_con->op_q_first;
544 progress = max(progress, PROGRESS);
545 break;
546 default:
547 op->status = fcn_result;
548 done = TRUE; /* could not get done */
549 }
550 break;
551 /*
552 * Operation is at head of queue and has already
553 * started trying to run. The only reason we could be in this
554 * state is that the last time we tried to do the requested input
555 * or output, all the data could not be moved synchronously.
556 * We therefore try to move some more, and if it all goes now,
557 * we call the continuation routine.
558 */
559 case OP_RUNNING:
560 /*
561 * Try to move some more data. If it won't all
562 * go now, we're done with this half connection.
563 *
564 * If this is a special listening connection which
565 * has an operation queued trying to do a listen,
566 * then do the listen. Otherwise do an ordinary
567 * data move.
568 */
569 if (half_con->flags & HCON_PENDING_LISTEN) {
570 if (gdb_listen(half_con)==FALSE) {
571 if (gdb_Debug & GDB_LOG)
572 fprintf(gdb_log, "NO LISTEN\n");
573 done = TRUE;
574 break;
575 }
576 } else
577 if (gdb_move_data(direction, half_con)==FALSE) {
578 done = TRUE;
579 if (gdb_Debug & GDB_LOG)
580 fprintf(gdb_log, "NO DATA\n");
581 break;
582 }
583 /*
584 * The pending data transmission has now completed.
585 * Call the continuation routine for this operation
586 */
587 fcn_result = (*op->fcn.cont)(op,half_con,op->arg);
588 if (gdb_Debug & GDB_LOG)
589 fprintf(gdb_log, "cont result=%d\n",
590 fcn_result);
591
592 switch (fcn_result) {
593 case OP_COMPLETE:
594 case OP_CANCELLED:
595 op->status = fcn_result;
596 op = g_op_newhead(half_con);
597 progress = COMPLETE;
598 break;
599 case OP_PREEMPTED:
600 op->status = OP_QUEUED;
601 /* fall thru */
602 case OP_REQUEUED:
603 /* important: don't set status on re-queued */
604 /* op as it may already have completed in */
605 /* its second life ! */
606 op = half_con->op_q_first;
607 progress = max(progress, PROGRESS);
608 break;
609 default:
610 op->status = fcn_result;
611 done = TRUE; /* could not get done */
612 }
613 break;
614 /*
615 * Following cases are all unexpected, at least for the
616 * moment. (See explanation of loop invariants for this while
617 * loop. Give up if they turn up.
618 */
619 case OP_COMPLETE:
620 GDB_GIVEUP("gdb_hcon_progress: found OP_COMPLETE on q")
621 case OP_CANCELLED:
622 GDB_GIVEUP("gdb_hcon_progress: found OP_CANCELLED on q")
623 case OP_CANCELLING:
624 GDB_GIVEUP("gdb_hcon_progress: OP_CANCELLING")
625 default:
626 GDB_GIVEUP("gdb_hcon_progress: Operation is queued, but is not runnable")
627 }
628 }
629
630 if (progress == NOPROGRESS && (half_con->flags & HCON_PROGRESS))
631 progress = PROGRESS;
632
633 half_con->flags &= ~HCON_BUSY;
634
635 if (gdb_Debug & GDB_LOG)
636 fprintf(gdb_log, "hcon_progress: returns %d\n",progress);
637
638 return progress; /* NOPROGRESS, PROGRESS */
639 /* or COMPLETE */
640}
641\f
642/************************************************************************/
643/*
644/* g_op_newhead
645/*
646/* Dequeues the operation at the head of the queue for the
647/* given half connection and returns the pointer to the
648/* new head of the queue. If the queue is null, then a pointer
649/* to the half_con itself is returned. (The lists are
650/* linked circularly.)
651/*
652/************************************************************************/
653
654OPERATION
655g_op_newhead(hcp)
656HALF_CONNECTION hcp;
657{
658 register OPERATION newhead, oldhead;
659
660 /*
661 * Get old and new heads of chain
662 */
663 oldhead = hcp->op_q_first;
664 newhead = oldhead->next;
665 /*
666 * Make sure nobody chained a bad one on us
667 */
668 if (newhead == NULL) {
669 if (gdb_Debug & GDB_LOG) {
670 fprintf(gdb_log,"\t\tg_op_newhead: found null link, oldhead = 0x%x newhead=0x%x halfcon=0x%x\n\t\t\t hc->first=0x%x hc->last=0x%x\n",
671 oldhead, newhead, hcp, hcp->op_q_first,
672 hcp->op_q_last);
673 }
674 GDB_GIVEUP("g_op_newhead: found NULL chain link")
675 }
676 /*
677 * Remove oldhead from chain, fixing up chain pointers
678 */
679 newhead->prev = oldhead->prev;
680 hcp->op_q_first = newhead;
681
682 /*
683 * Clean up pointers in the newly dequeued operation. This is
684 * just for cleanliness and ease of debugging.
685 */
686 oldhead->next = oldhead->prev = NULL;
687 oldhead->halfcon = NULL;
688
689 return newhead;
690}
691\f
692/************************************************************************/
693/*
694/* gdb_move_data
695/*
696/* This routine attempts to make further progress on the pending
697/* level transmission operation pending on this half connection.
698/* (Presumes that such an operation is pending.) Returns TRUE
699/* if all the requested data has been moved, else FALSE.
700/*
701/* We assume here that all fd's are set to non-blocking I/O, so
702/* we can safely try reading and writing until they return 0 bytes.
703/*
704/************************************************************************/
705
706int
707gdb_move_data(direction, hc)
708int direction; /* CON_INPUT or CON_OUTPUT */
709struct half_con_data *hc; /* pointer to control struct */
710 /* for this half connection */
711{
712 register HALF_CONNECTION half_con = hc;
713 /* half connection pointer */
714 /* fast copy in register */
715 register int count; /* number of bytes read */
716 /* or written in latest */
717 /* attempt */
718 fd_set *fdbits; /* the mask we should adjust */
719 /* for this direction */
720 fd_set tst_bits; /* these are used for */
721 /* the select we do prior */
722 /* to reading which tells */
723 /* us whether 0 byte read */
724 /* means empty or closed */
725 int selected; /* TRUE iff select says */
726 /* we should be able to */
727 /* progress */
728
729 /*
730 * For safety, in case we're called when nothing is pending.
731 */
732 if (half_con->remaining == 0)
733 return TRUE;
734 /*
735 * Loop until either (1) the connection reported that it could
736 * not progress any further or (2) the full count has been
737 * satisfied. Some versions of Unix observe the rule that
738 * a closed connection, especially when reading, is indicated
739 * by select claiming that there is data when read says there
740 * isn't. Also, some other versions return errors from the
741 * select on that FD. We test for both situations here.
742 */
743 FD_ZERO(&tst_bits);
744
745 while(half_con->remaining>0) {
746 FD_SET(half_con->fd,&tst_bits);
747 if (direction == CON_INPUT) {
748 selected = select(gdb_mfd,&tst_bits, NULL, NULL,
749 &gdb_notime);
750 /*
751 * If selected==(-1), then we know there's something
752 * wrong with the socket
753 */
754 if (selected == (-1)) {
755 gdb_conok = FALSE;
756 break;
757 }
758 /*
759 * if selected==0, then we know read won't do
760 * anything, so save the extraneous system call
761 */
762 if (selected == 0) {
763 count =0;
764 break;
765 }
766 /*
767 * Selected is >0. Either the read is going to
768 * return 0, or this is one of those versions of
769 * Unix that tells us the connection has died by
770 * indicating select=1, read=0.
771 */
772 count = read(half_con->fd, half_con->next_byte,
773 half_con->remaining);
774 } else {
775 selected = select(gdb_mfd, NULL, &tst_bits, NULL,
776 &gdb_notime);
777 if (selected == (-1)) {
778 gdb_conok = FALSE;
779 break;
780 }
781 if (selected == 0) {
782 count =0;
783 break;
784 }
785 count = write(half_con->fd, half_con->next_byte,
786 min(half_con->remaining,
787 GDB_MAX_SOCK_WRITE));
788 }
789 /*
790 * We moved some data
791 */
792 if (count >0)
793 half_con->flags |= HCON_PROGRESS;
794 /*
795 * rc==0 means we didn't mvoe any data, but if accompanied
796 * by select claiming there was data, it really means the
797 * connection is dead!
798 */
799 if (count==0) {
800 if (selected == 1)
801 gdb_conok = FALSE;
802 break; /* no more data available now*/
803 }
804 if (count<0) {
805 count = 0;
806 if (errno != EWOULDBLOCK) {
807 gdb_conok = FALSE; /* tell callers that */
808 /* con has died */
809 }
810 break;
811
812 }
813 half_con->remaining -=count;
814 half_con->next_byte +=count;
815 }
816
817 /*
818 * The file descriptor masks used for doing selects must be activated
819 * when and only when there is a pending operation trying to use
820 * the connection. Update the masks for this half connection.
821 */
822 fdbits = (direction == CON_INPUT)? &gdb_crfds : &gdb_cwfds;
823 if (half_con->remaining >0)
824 FD_SET(half_con->fd, fdbits);
825 else
826 FD_CLR(half_con->fd, fdbits);
827
828 return (half_con->remaining == 0);
829}
830\f
831/************************************************************************/
832/*
833/* gdb_receive_data (gdb_receive_data)
834/*
835/* This routine is called by an init or continuation routine to
836/* request that a specified amount of data be read, without
837/* blocking, on the supplied connection. This routine returns
838/* OP_COMPLETE if the entire read completed synchronously,
839/* or OP_RUNNING if the read remains ongoing or is cancelling
840/* due to error on the socket.
841/*
842/************************************************************************/
843
844int
845gdb_receive_data(half_con, ptr, len)
846HALF_CONNECTION half_con; /* read on this connection*/
847char *ptr; /* put first byte here */
848int len; /* number of bytes to read */
849{
850 /*
851 * Fill in the initial state of the attempted receive
852 */
853 half_con->remaining = len;
854 half_con->next_byte = ptr;
855
856 /*
857 * Now see if we can make some progress on this read, possibly
858 * even completing it synchronously. Return appropriate
859 * result to our caller. Note: errors are reflected as OP_RUNNING
860 * with global variable gdb_cnok set to FALSE.
861 */
862 if(gdb_move_data(CON_INPUT, half_con))
863 return OP_COMPLETE;
864 else
865 return OP_RUNNING;
866}
867
868/************************************************************************/
869/*
870/* gdb_send_data (gdb_sndat)
871/*
872/* This routine is called by an init or continuation routine to
873/* request that a specified amount of data be written, without
874/* blocking, on the supplied connection. This routine returns
875/* OP_COMPLETE if the entire write completed synchronously,
876/* or OP_RUNNING if the output remains ongoing or there was an error.
877/*
878/************************************************************************/
879
880int
881gdb_sndat(half_con, ptr, len)
882HALF_CONNECTION half_con; /* write on this connection*/
883char *ptr; /* put first byte here */
884int len; /* number of bytes to read */
885{
886
887 /*
888 * Fill in the initial state of the attempted receive
889 */
890 half_con->remaining = len;
891 half_con->next_byte = ptr;
892
893 /*
894 * Now see if we can make some progress on this read, possibly
895 * even completing it synchronously. Return appropriate
896 * result to our caller.
897 */
898 if(gdb_move_data(CON_OUTPUT, half_con))
899 return OP_COMPLETE;
900 else
901 return OP_RUNNING;
902}
903
904/************************************************************************/
905/*
906/* gdb_start_a_listen
907/*
908/* This routine is called by an init or continuation routine to
909/* request that a connection be done. This routine returns
910/* OP_COMPLETE if the accept completed synchronously,
911/* or OP_RUNNING if the output remains ongoing or there was an error.
912/*
913/************************************************************************/
914
915int
916gdb_start_a_listen(half_con, otherside, lenp, fdp)
917HALF_CONNECTION half_con; /* write on this connection*/
918char *otherside; /* put first byte here */
919int *lenp; /* number of bytes to read */
920int *fdp;
921{
922
923 /*
924 * Fill in the initial state of the attempted accept
925 */
926 half_con->accepted_len = lenp;
927 half_con->next_byte = otherside;
928 half_con->accepted_fdp = fdp;
929
930 /*
931 * Now see if we can make some progress on this read, possibly
932 * even completing it synchronously. Return appropriate
933 * result to our caller.
934 */
935 if(gdb_listen(half_con))
936 return OP_COMPLETE;
937 else
938 return OP_RUNNING;
939}
940\f
941/************************************************************************/
942/*
943/* gdb_listen (gdb_listen)
944/*
945/* This routine is called from gdb_start_a_listen or hcon_progress to attempt
946/* to continue making progress in accepting a connection on a
947/* listening connection.
948/*
949/************************************************************************/
950
951int
952gdb_listen(hc)
953struct half_con_data *hc; /* pointer to control struct */
954 /* for this half connection */
955{
956 register HALF_CONNECTION half_con = hc;
957 /* half connection pointer */
958 /* fast copy in register */
959
960 fd_set tst_bits; /* these are used for */
961 /* the select we do prior */
962 /* to reading which tells */
963 /* us whether 0 byte read */
964 /* means empty or closed */
965 int selected; /* TRUE iff select says */
966 /* we should be able to */
967 /* progress */
968
969
970 GDB_INIT_CHECK
971
972 half_con->flags &= ~HCON_PENDING_LISTEN;/* in case we succeed */
973
974 FD_ZERO(&tst_bits);
975 FD_SET(half_con->fd,&tst_bits);
976 selected = select(gdb_mfd,&tst_bits, NULL, NULL, &gdb_notime);
977 /*
978 * If selected==(-1), then we know there's something
979 * wrong with the socket
980 */
981 if (selected == (-1)) {
982 gdb_conok = FALSE;
983 return FALSE;
984 }
985 /*
986 * if selected==0, then we know accept won't do anything, so
987 * don't try.
988 */
989 if (selected == 0) {
990 half_con->flags |= HCON_PENDING_LISTEN;
991 FD_SET(half_con->fd, &gdb_crfds); /* we'll be looking for */
992 /* this whenever we select*/
993 return FALSE;
994 }
995 /*
996 * Selected is >0. The accept SHOULD not hang.
997 */
998 *(half_con->accepted_fdp) = accept(half_con->fd, half_con->next_byte,
999 half_con->accepted_len);
1000 /*
1001 * See whether the accept succeeded
1002 */
1003 if (*(half_con->accepted_fdp) < 0) {
1004 perror("gdb: start_listening: error on listen");
1005 GDB_GIVEUP("Unexpected listen error");
1006 }
1007
1008 FD_CLR(half_con->fd, &gdb_crfds); /* don't select on this */
1009 return TRUE;
1010}
This page took 0.198137 seconds and 5 git commands to generate.