]> andersk Git - moira.git/blob - gdb/test.c
fix RCS Id strings
[moira.git] / gdb / test.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 #ifndef lint
7 static 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
53 extern 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
74 int
75 queue_operation(con, direction, op)
76 CONNECTION con;
77 int     direction;
78 OPERATION 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
142 int
143 requeue_operation(con, direction, op)
144 CONNECTION con;
145 int     direction;
146 OPERATION 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
188 int
189 g_preempt_me(oldop, newop)
190 OPERATION oldop;
191 OPERATION 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
241 int
242
243 gdb_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
318 int
319 g_con_progress(con_id)
320 int     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
397 int
398 gdb_hcon_progress(direction, hc)
399 int     direction;                              /* CON_INPUT or CON_OUTPUT */
400 struct  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
654 OPERATION
655 g_op_newhead(hcp)
656 HALF_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
706 int
707 gdb_move_data(direction, hc)
708 int     direction;                              /* CON_INPUT or CON_OUTPUT */
709 struct  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
844 int
845 gdb_receive_data(half_con, ptr, len)
846 HALF_CONNECTION half_con;                       /* read on this connection*/
847 char    *ptr;                                   /* put first byte here */
848 int     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
880 int
881 gdb_sndat(half_con, ptr, len)
882 HALF_CONNECTION half_con;                       /* write on this connection*/
883 char    *ptr;                                   /* put first byte here */
884 int     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
915 int
916 gdb_start_a_listen(half_con, otherside, lenp, fdp)
917 HALF_CONNECTION half_con;                       /* write on this connection*/
918 char    *otherside;                             /* put first byte here */
919 int     *lenp;                                  /* number of bytes to read */
920 int     *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
951 int
952 gdb_listen(hc)
953 struct  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.125612 seconds and 5 git commands to generate.