]>
Commit | Line | Data |
---|---|---|
5580185e | 1 | /* |
2 | * $Source$ | |
3 | * $Header$ | |
4 | */ | |
5 | ||
6 | #ifndef lint | |
7 | static char *rcsid_gdb_trans_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_trans.c | |
33 | /* | |
34 | /* GDB - Data Transport Services Routines (Part 1) | |
35 | /* | |
36 | /* Author: Noah Mendelsohn | |
37 | /* Copyright: 1986 MIT Project Athena | |
0a5ff702 | 38 | /* For copying and distribution information, please see |
39 | /* the file <mit-copyright.h>. | |
5580185e | 40 | /* |
41 | /* These routines implement layer 6 of the Client Library | |
42 | /* Specification of the GDB system, as well as the facilities | |
43 | /* outlined in the GDB Protocol Specification. (Part 1 of 2) | |
44 | /* | |
45 | /* Some of the routines specified are actually implemented as | |
46 | /* macros defined in gdb.h. | |
47 | /* | |
48 | /************************************************************************/ | |
49 | ||
0a5ff702 | 50 | #include <mit-copyright.h> |
5580185e | 51 | #include <sys/types.h> |
f4c08abd | 52 | #include <string.h> |
5580185e | 53 | #include <stdio.h> |
54 | #include <varargs.h> | |
55 | #include <errno.h> | |
56 | extern int errno; | |
57 | #include "gdb.h" | |
58 | ||
59 | \f | |
60 | /************************************************************************/ | |
61 | /* | |
62 | /* OPERATION Manipulation | |
63 | /* | |
64 | /* The routines in this section provide services for creating | |
65 | /* and manipulating GDB queueable operations. | |
66 | /* | |
67 | /************************************************************************/ | |
68 | ||
69 | /*----------------------------------------------------------*/ | |
70 | /* | |
71 | /* create_operation (create_operation) | |
72 | /* | |
73 | /* Allocates space for an operation descriptor and | |
74 | /* returns a pointer to it. Initialize the eyecatcher | |
75 | /* so that in the future we can prove by inspection that | |
76 | /* this really is an operation descriptor. | |
77 | /* | |
78 | /*----------------------------------------------------------*/ | |
79 | ||
80 | OPERATION | |
81 | create_operation() | |
82 | { | |
83 | register OPERATION op; | |
84 | GDB_INIT_CHECK | |
85 | op = (OPERATION)db_alloc(sizeof(OPERATION_DATA)); | |
86 | op->status = OP_NOT_STARTED; /* things like */ | |
87 | /* reset_operation */ | |
88 | /* want valid status */ | |
89 | /* at all times*/ | |
90 | op->id = GDB_OP_ID; | |
91 | return op; | |
92 | } | |
93 | ||
94 | /*----------------------------------------------------------*/ | |
95 | /* | |
96 | /* reset_operation (reset_operation) | |
97 | /* | |
98 | /* Sets the status of an operation to OP_NOT_STARTED | |
99 | /* | |
100 | /*----------------------------------------------------------*/ | |
101 | ||
102 | int | |
103 | reset_operation(op) | |
104 | OPERATION op; | |
105 | { | |
106 | register int status; | |
107 | ||
108 | GDB_CHECK_OP(op, "reset_operation") | |
109 | ||
110 | status = OP_STATUS(op); | |
111 | if (status == OP_QUEUED || | |
112 | status == OP_RUNNING) | |
113 | GDB_GIVEUP("gdb:reset_operation invalid on running operation") | |
114 | op->status = OP_NOT_STARTED; | |
115 | } | |
116 | ||
117 | /*----------------------------------------------------------*/ | |
118 | /* | |
119 | /* delete_operation(delete_operation) | |
120 | /* | |
121 | /* Frees an operation descriptor. | |
122 | /* | |
123 | /*----------------------------------------------------------*/ | |
124 | ||
125 | int | |
126 | delete_operation(op) | |
127 | OPERATION op; | |
128 | { | |
129 | GDB_CHECK_OP(op, "delete_operation"); | |
130 | op->id = -1; | |
131 | db_free((char *)op, sizeof(OPERATION_DATA)); | |
132 | } | |
133 | ||
134 | /*----------------------------------------------------------*/ | |
135 | /* | |
136 | /* initialize_operation(initialize_operation) | |
137 | /* | |
138 | /* Initialize the data in an operation descriptor | |
139 | /* based on the supplied parameters. | |
140 | /* | |
141 | /*----------------------------------------------------------*/ | |
142 | ||
143 | int | |
144 | initialize_operation(operation, init_function, arg, cancel_function) | |
145 | OPERATION operation; /* initialize this */ | |
146 | int (*init_function)(); /* function to call when */ | |
147 | /* starting operation */ | |
148 | char *arg; /* arg to pass to init and */ | |
149 | /* continue routines */ | |
150 | int (*cancel_function)(); /* call this function */ | |
151 | /* when cancelling the op. */ | |
152 | /* may be NULL, may not */ | |
153 | /* be elided */ | |
154 | { | |
155 | register OPERATION op = operation; /* just for speed */ | |
156 | ||
157 | GDB_CHECK_OP(op, "initialize_operation") | |
158 | ||
159 | ||
160 | /* | |
161 | * Fill in boilerplate - same for all newly initialized ops. | |
162 | */ | |
163 | op->next = op->prev = NULL; /* it's not in a queue yet */ | |
164 | op->tag = (-1); /* not tagged until queued */ | |
165 | op->status = OP_NOT_STARTED; | |
166 | op->flags = 0; | |
167 | op->result = (-1); /* result is not valid until */ | |
168 | /* status is OP_COMPLETE. */ | |
169 | /* All users of result field */ | |
170 | /* are expected to treat -1 */ | |
171 | /* invalid */ | |
172 | op->halfcon = NULL; /* not queued yet */ | |
173 | ||
174 | /* | |
175 | * Fill in supplied parameters | |
176 | */ | |
177 | op->arg = arg; | |
178 | op->fcn.init = init_function; | |
179 | op->cancel = cancel_function; | |
180 | ||
181 | return; | |
182 | } | |
183 | ||
184 | /*----------------------------------------------------------*/ | |
185 | /* | |
186 | /* create_list_of_operations (create_list_of_operations) | |
187 | /* | |
188 | /* Allocates and fills in a data structure which | |
189 | /* contains a list of operations. This list is | |
190 | /* suitable for passing to op_select. | |
191 | /* | |
192 | /* The facilities of <varargs.h> are used to parse | |
193 | /* the variable length parameter list to this function. | |
194 | /* See "man 3 varargs" for details. | |
195 | /* | |
196 | /*----------------------------------------------------------*/ | |
197 | ||
198 | /*VARARGS1*/ | |
199 | ||
200 | LIST_OF_OPERATIONS | |
201 | create_list_of_operations(count, va_alist) | |
202 | int count; | |
203 | va_dcl | |
204 | { | |
205 | va_list ap; /* the control structure */ | |
206 | /* for varargs parsing */ | |
207 | ||
208 | register int i; | |
209 | register LIST_OF_OPERATIONS newlist; /* newly allocated list */ | |
210 | ||
211 | /* | |
212 | * Allocate the new list of operations, initialize its count. | |
213 | */ | |
214 | newlist = (LIST_OF_OPERATIONS) | |
215 | db_alloc(size_of_list_of_operations(count)); | |
216 | newlist->count = count; | |
217 | ||
218 | /* | |
219 | * Using the facilities of varargs.h, pick up the operations | |
220 | * and put them in the list. | |
221 | */ | |
222 | va_start(ap); | |
223 | for (i=0; i<count; i++) { | |
224 | newlist->op[i] = va_arg(ap, OPERATION); | |
225 | GDB_CHECK_OP((newlist->op[i]), "create_list_of_operations") | |
226 | } | |
227 | va_end(ap); | |
228 | ||
229 | return newlist; | |
230 | } | |
231 | ||
232 | /*----------------------------------------------------------*/ | |
233 | /* | |
234 | /* delete_list_of_operations(delete_list_of_operations) | |
235 | /* | |
236 | /* Deallocate the space for a list of operations. | |
237 | /* | |
238 | /*----------------------------------------------------------*/ | |
239 | ||
240 | int | |
241 | delete_list_of_operations(op_list) | |
242 | LIST_OF_OPERATIONS op_list; | |
243 | { | |
244 | db_free((char *)op_list, size_of_list_of_operations(op_list->count)); | |
245 | } | |
246 | \f | |
247 | /************************************************************************/ | |
248 | /* | |
249 | /* OPERATION QUEUE MANIPULATION | |
250 | /* | |
251 | /* Routines to queue (initiate) and track completion of GDB | |
252 | /* operations. | |
253 | /* | |
254 | /************************************************************************/ | |
255 | ||
256 | /*----------------------------------------------------------*/ | |
257 | /* | |
258 | /* op_select(op_select) | |
259 | /* | |
260 | /* This function is an analog of the standard Berkeley | |
261 | /* select system call. It provides all the functions | |
262 | /* of select, but in addition, it awaits completion | |
263 | /* of a specified list of queued gdb operations. | |
264 | /* | |
265 | /* This function returns when any combination of the | |
266 | /* following are found to be true: | |
267 | /* | |
268 | /* 1) Any of the designated operations has completed | |
269 | /* or terminated prematurely. | |
270 | /* | |
271 | /* 2) Activity is detected on any of the explictly supplied | |
272 | /* file descriptors or the supplied timer has expired. | |
273 | /* | |
274 | /* The count returned is only for file descriptors | |
275 | /* explicitly listed. Completed operatons may be detected | |
276 | /* by checking OP_STATUS for each of the operations in | |
277 | /* the list. File descriptors controlled by CONNECTIONS | |
278 | /* should never be passed explictly in the bit maps to | |
279 | /* this routine. Only user controlled file descriptors | |
280 | /* may be explictly selected. | |
281 | /* | |
282 | /* Return code summary: | |
283 | /* | |
284 | /* -2 One or more listed operations completed. | |
285 | /* Timer did not ring (as far as we could | |
286 | /* tell), other fd's did not complete, or | |
287 | /* we didn't get far enough to bother | |
288 | /* looking. (see fairness below.) | |
289 | /* | |
290 | /* -1 An error was returned on select of a | |
291 | /* user supplied socket. errno has the | |
292 | /* error code. | |
293 | /* | |
294 | /* 0 The timer rang. Some operations may | |
295 | /* be complete, but it's unlikely. | |
296 | /* | |
297 | /* >0 This many user supplied fd's were | |
298 | /* satisfied--same as for select. | |
299 | /* Operations in the list may also have | |
300 | /* completed. | |
301 | /* | |
302 | /* Fairness is not guaranteed. This routine tends to | |
303 | /* favor activity on CONNECTIONs. In particular, if | |
304 | /* some operation(s) in the list can be completed | |
305 | /* synchronously, a real select is never done to | |
306 | /* check on the file descriptors. | |
307 | /* | |
308 | /*----------------------------------------------------------*/ | |
309 | ||
310 | int | |
311 | op_select(op_list, nfds, readfds, writefds, exceptfds, timeout) | |
312 | LIST_OF_OPERATIONS op_list; | |
313 | int nfds; | |
314 | fd_set *readfds, *writefds, *exceptfds; | |
315 | struct timeval *timeout; | |
316 | { | |
317 | int rc; /* return code holder */ | |
318 | fd_set rfds, wfds, efds; /* local copys of read */ | |
319 | /* write, and exception */ | |
320 | /* fd's */ | |
321 | ||
322 | /* | |
323 | * Make sure that any activity which can be done immediately is | |
324 | * indeed done now--we may not have to wait at all. | |
325 | */ | |
326 | (void) gdb_fastprogress(); /*<==FIX (check to make sure this is OK)*/ | |
327 | ||
328 | /* | |
329 | * Loop checking for termination conditions, and if none arise, | |
330 | * use con_select to make wait for one or more of the | |
331 | * connections to wake up and do the appropriate processing. | |
332 | */ | |
333 | while (TRUE) { | |
334 | /* | |
335 | * If any of the queue operations have completed, | |
336 | * then just return now. | |
337 | */ | |
338 | if (gdb_list_complete(op_list)) | |
339 | return (-2); /* no fd's satisfied here */ | |
340 | ||
341 | /* | |
342 | * Use con_select to await all the appropriate events | |
343 | */ | |
344 | g_fd_copy(nfds, readfds, &rfds); | |
345 | g_fd_copy(nfds, writefds, &wfds); | |
346 | g_fd_copy(nfds, exceptfds, &efds); | |
347 | ||
348 | rc = con_select(nfds, &rfds, &wfds, &efds, timeout); | |
349 | ||
350 | /* | |
351 | * At this point, either some of the supplied fd's have | |
352 | * been satisfied(rc>0), or the timer has rung (rc=0), | |
353 | * an error was returned from select on a user specified socket | |
354 | * (-1) or none of these (-2). In any case, there may | |
355 | * have been progress on one of the connections, and | |
356 | * con_select will already have progressed as far as | |
357 | * possible before returning. Now, decide what to | |
358 | * do, given the return code. | |
359 | */ | |
360 | if (rc>= (-1)) { | |
361 | /* | |
362 | * Return updated bit-maps to caller. | |
363 | */ | |
364 | g_fd_copy(nfds, &rfds, readfds); | |
365 | g_fd_copy(nfds, &wfds, writefds); | |
366 | g_fd_copy(nfds, &efds, exceptfds); | |
367 | return rc; | |
368 | } | |
369 | } | |
370 | } | |
371 | \f | |
372 | /*----------------------------------------------------------*/ | |
373 | /* | |
374 | /* op_select_all(op_select_all) | |
375 | /* | |
376 | /* Similar to op_select_any, but returns (-1) only | |
377 | /* in the case that all of the designated descriptors | |
378 | /* are OP_COMPLETE or OP_CANCELLED. | |
379 | /* | |
380 | /*----------------------------------------------------------*/ | |
381 | ||
382 | int | |
383 | op_select_all(op_list, nfds, readfds, writefds, exceptfds, timeout) | |
384 | LIST_OF_OPERATIONS op_list; | |
385 | int nfds; | |
386 | fd_set *readfds, *writefds, *exceptfds; | |
387 | struct timeval *timeout; | |
388 | { | |
389 | register int i; | |
390 | int rc = -1; | |
391 | register int left = op_list->count; | |
392 | ||
393 | /* | |
394 | * take care of those which are already complete by decrementing | |
395 | * and reseting them | |
396 | */ | |
397 | ||
398 | for (i=0; i<op_list->count; i++) { | |
399 | if (op_list->op[i]->status==OP_COMPLETE) { | |
400 | op_list->op[i]->flags |= OPF_MARKED_COMPLETE; | |
401 | op_list->op[i]->status = OP_MARKED; | |
402 | /* so op_select_any won't */ | |
403 | /* fall right through*/ | |
404 | ||
405 | left--; | |
406 | continue; | |
407 | } | |
408 | if (op_list->op[i]->status==OP_CANCELLED) { | |
409 | op_list->op[i]->flags |= OPF_MARKED_CANCELLED; | |
410 | op_list->op[i]->status = OP_MARKED; | |
411 | /* so op_select_any won't */ | |
412 | /* fall right through*/ | |
413 | ||
414 | left--; | |
415 | } | |
416 | } | |
417 | ||
418 | ||
419 | /* | |
420 | * As long as there are incomplete operations left in the list, | |
421 | * keep calling op_select_any | |
422 | */ | |
423 | while (left) { | |
424 | rc = op_select(op_list, nfds, readfds, writefds, exceptfds, | |
425 | timeout); | |
426 | if (rc>=0) | |
427 | break; | |
428 | for (i=0; i<op_list->count; i++) { | |
429 | if (op_list->op[i]->status==OP_COMPLETE) { | |
430 | op_list->op[i]->flags |= OPF_MARKED_COMPLETE; | |
431 | op_list->op[i]->status = OP_MARKED; | |
432 | /* so op_select_any won't */ | |
433 | /* fall right through*/ | |
434 | ||
435 | left--; | |
436 | continue; | |
437 | } | |
438 | if (op_list->op[i]->status==OP_CANCELLED) { | |
439 | op_list->op[i]->flags |= OPF_MARKED_CANCELLED; | |
440 | op_list->op[i]->status = OP_MARKED; | |
441 | /* so op_select_any won't */ | |
442 | /* fall right through*/ | |
443 | ||
444 | left--; | |
445 | } | |
446 | } | |
447 | } | |
448 | ||
449 | /* | |
450 | * Clean up the marked operations and return | |
451 | */ | |
452 | for (i=0; i<op_list->count; i++) { | |
453 | if (op_list->op[i]->status==OP_MARKED) { | |
454 | op_list->op[i]->status = (op_list->op[i]->flags & | |
455 | OPF_MARKED_COMPLETE) ? | |
456 | OP_COMPLETE : | |
457 | OP_CANCELLED; | |
458 | op_list->op[i]->flags &= ~(OPF_MARKED_COMPLETE | | |
459 | OPF_MARKED_CANCELLED); | |
460 | } | |
461 | } | |
462 | ||
463 | return rc; | |
464 | ||
465 | } | |
466 | \f | |
467 | /************************************************************************/ | |
468 | /* | |
469 | /* Internal transport layer routines, not called directly | |
470 | /* from client library. | |
471 | /* | |
472 | /************************************************************************/ | |
473 | ||
474 | /*----------------------------------------------------------*/ | |
475 | /* | |
476 | /* gdb_list_complete | |
477 | /* | |
478 | /* Given a list of gdb operations, return TRUE if any | |
479 | /* of them are complete, otherwise return FALSE. | |
480 | /* | |
481 | /*----------------------------------------------------------*/ | |
482 | ||
483 | int | |
484 | gdb_list_complete(op_list) | |
485 | LIST_OF_OPERATIONS op_list; | |
486 | { | |
487 | register int i; | |
488 | register int status; | |
489 | register LIST_OF_OPERATIONS oplist = op_list; /* for speed */ | |
490 | int count = oplist -> count; | |
491 | ||
492 | for (i=0; i<count; i++) { | |
493 | status = OP_STATUS(oplist->op[i]); | |
494 | if (status == OP_COMPLETE || | |
495 | status == OP_CANCELLED) | |
496 | return TRUE; | |
497 | } | |
498 | ||
499 | return FALSE; | |
500 | } | |
501 | ||
502 | /*----------------------------------------------------------*/ | |
503 | /* | |
504 | /* g_fd_copy | |
505 | /* | |
506 | /* Copy one set of fd masks to another. | |
507 | /* | |
508 | /*----------------------------------------------------------*/ | |
509 | ||
510 | g_fd_copy(nfds, source, targ) | |
511 | int nfds; | |
512 | fd_set *source, *targ; | |
513 | { | |
514 | register int i; | |
515 | register int n = howmany(nfds, NFDBITS); /* number of words for */ | |
516 | /* this many fd's */ | |
517 | ||
518 | for (i=0; i<n; i++) | |
519 | targ->fds_bits[i] = source->fds_bits[i]; | |
520 | } | |
521 | /*----------------------------------------------------------*/ | |
522 | /* | |
523 | /* g_fd_or_and_copy | |
524 | /* | |
525 | /* Or two sets of file descriptor masks together and | |
526 | /* copy to a third. Parameters are: | |
527 | /* | |
528 | /* 1) First mask count | |
529 | /* 2) Second mask count | |
530 | /* 3) pointer to first mask | |
531 | /* 4) Pointer to second mask | |
532 | /* 5) Pointer to output mask | |
533 | /* | |
534 | /*----------------------------------------------------------*/ | |
535 | ||
536 | g_fd_or_and_copy(nfds1, nfds2 , source1, source2, targ) | |
537 | int nfds1, nfds2; | |
538 | fd_set *source1, *source2, *targ; | |
539 | { | |
540 | register int i; | |
541 | fd_set *longer; /* points to whichever */ | |
542 | /* of the two masks is */ | |
543 | /* longer */ | |
544 | int tot_words = howmany(max(nfds1,nfds2), NFDBITS); | |
545 | int shared_words = howmany(min(nfds1,nfds2), NFDBITS); | |
546 | ||
547 | ||
548 | /* | |
549 | * For words which exist in both masks, or the bits together | |
550 | */ | |
551 | for (i=0; i<shared_words; i++) | |
552 | targ->fds_bits[i] = source1->fds_bits[i] | | |
553 | source2->fds_bits[i]; | |
554 | /* | |
555 | * Copy the rest of whichever is longer | |
556 | */ | |
557 | longer = (nfds1>nfds2) ? source1 : source2; | |
558 | ||
559 | while (i<tot_words) { | |
560 | targ->fds_bits[i] = longer->fds_bits[i]; | |
561 | i++; | |
562 | } | |
563 | ||
564 | return; | |
565 | } | |
566 | ||
567 | /*----------------------------------------------------------*/ | |
568 | /* | |
569 | /* g_compute_return_fds | |
570 | /* | |
571 | /* When con_select returns, the count it gives back | |
572 | /* applies only to user supplied fd's, not those | |
573 | /* relating to connections. Unfortunately, select | |
574 | /* gives back both in the masks it returns. Here we | |
575 | /* fix only the count to reflect the fact that we will be | |
576 | /* turning off bits when and if they are returned. | |
577 | /* | |
578 | /* We can assume here that the masks provided are as long | |
579 | /* as merged_nfds, which means they are at least as long | |
580 | /* as gdb_mfd. | |
581 | /* | |
582 | /*----------------------------------------------------------*/ | |
583 | ||
584 | int | |
585 | g_compute_return_fds(select_count, rfds, wfds, efds) | |
586 | int select_count; /* count of 1 bits as */ | |
587 | /* returned from select */ | |
588 | fd_set *rfds, *wfds, *efds; /* read, write, and except */ | |
589 | /* maps as returned from */ | |
590 | /* select */ | |
591 | { | |
592 | register int i; | |
593 | register int return_count = select_count; /* the value we'll return */ | |
594 | register int words; /* number of words in each */ | |
595 | /* of the connection masks */ | |
596 | ||
597 | ||
598 | /* | |
599 | * Since we can only decrement the count, there's no sense doing | |
600 | * any work if it's already 0; | |
601 | */ | |
602 | if (return_count == 0) | |
603 | return 0; | |
604 | /* | |
605 | * Figure out how many words we have to look at to get all the | |
606 | * bits covered by connection masks. | |
607 | */ | |
608 | words = howmany(gdb_mfd, NFDBITS); | |
609 | ||
610 | /* | |
611 | * For words which are involved in the connection masks, check | |
612 | * for matches and decrement the count accordingly. Stop when | |
613 | * the count hits 0 or we're out of words. | |
614 | */ | |
615 | for (i=0; i<words && (return_count>0) ; i++) { | |
616 | return_count -= g_bitcount((unsigned int) | |
617 | (gdb_crfds.fds_bits[i] & | |
618 | rfds->fds_bits[i])); | |
619 | return_count -= g_bitcount((unsigned int) | |
620 | (gdb_cwfds.fds_bits[i] & | |
621 | wfds->fds_bits[i])); | |
622 | return_count -= g_bitcount((unsigned int) | |
623 | (gdb_cefds.fds_bits[i] & | |
624 | efds->fds_bits[i])); | |
625 | } | |
626 | ||
627 | return return_count; | |
628 | } | |
629 | ||
630 | /*----------------------------------------------------------*/ | |
631 | /* | |
632 | /* g_fd_reset_conbits | |
633 | /* | |
634 | /* Given a user supplied fd bit mask and a connection | |
635 | /* related bit mask, turn off any of the connection related | |
636 | /* bits in the user mask, and copy the result to a supplied | |
637 | /* target. | |
638 | /* | |
639 | /* 1) User mask count | |
640 | /* 2) Connection mask count | |
641 | /* 3) Pointer to user mask | |
642 | /* 4) Pointer to connection mask | |
643 | /* 5) Pointer to output mask | |
644 | /* | |
645 | /* Output is always the same length as the user mask. | |
646 | /* | |
647 | /*----------------------------------------------------------*/ | |
648 | ||
649 | ||
650 | g_fd_reset_conbits(nfds, con_nfds , source, conbits, targ) | |
651 | int nfds, con_nfds; | |
652 | fd_set *source, *conbits, *targ; | |
653 | { | |
654 | register int i; | |
655 | register int tot_words = howmany(nfds, NFDBITS); /* this rtn never*/ | |
656 | /* returns a mask longer */ | |
657 | /* than nfds */ | |
658 | register int shared_words = howmany(min(nfds, con_nfds), NFDBITS); | |
659 | ||
660 | ||
661 | /* | |
662 | * For words which exist in both masks, turn off bits from conmask | |
663 | */ | |
664 | for (i=0; i<shared_words; i++) | |
665 | targ->fds_bits[i] = source->fds_bits[i] & | |
666 | ~(conbits->fds_bits[i]); | |
667 | /* | |
668 | * Copy the rest of source, if any | |
669 | */ | |
670 | if (tot_words > shared_words) | |
671 | while (i<tot_words) { | |
672 | targ->fds_bits[i] = source->fds_bits[i]; | |
673 | i++; | |
674 | } | |
675 | ||
676 | return; | |
677 | } | |
678 | ||
679 | \f | |
680 | /************************************************************************/ | |
681 | /* | |
682 | /* CONNECTION MANIPULATION | |
683 | /* | |
684 | /* Routines to control data transmission on gdb connections. | |
685 | /* | |
686 | /************************************************************************/ | |
687 | ||
688 | /*----------------------------------------------------------*/ | |
689 | /* | |
690 | /* con_select (con_select) | |
691 | /* | |
692 | /* This operation has exactly the same semantics as the select | |
693 | /* system call, except that (1) it implicitly selects all file | |
694 | /* descriptors controlled by connections, as well as those | |
695 | /* explictly specified and (2) it allows transmission and | |
696 | /* receipt to progress on all connections and (3) it considers | |
697 | /* a connection to be selected iff a transmission operation | |
698 | /* which had been pending becomes complete. One may consider | |
699 | /* that con_select turns the fd's controlled by sockets into | |
700 | /* packet streams rather than byte streams. Note also that | |
701 | /* this operation differs from a traditional select and an | |
702 | /* op_select in that it is not robust against waiting for | |
703 | /* connections with pre-completed activity. This could be | |
704 | /* added, but since it's an internal routine anyway, it seems | |
705 | /* not to be worthwhile. Also, this routine presumes that all | |
706 | /* possible progress has been made before con_select is invoked. | |
707 | /* | |
708 | /* This operation hangs in a select. If activity is | |
709 | /* discovered on any of the sockets controlled by the database | |
710 | /* library, then the corresponding input is read and | |
711 | /* appropriate processing is done. If any of the transmission | |
712 | /* operations which had been pending on one of these | |
713 | /* connections completes, then con_select may return. In | |
714 | /* fact, con_select attempts to complete any further | |
715 | /* connection related activity which can be done without | |
716 | /* blocking, but con_select never blocks AFTER a transmission | |
717 | /* operation has gone complete. | |
718 | /* | |
719 | /* If activity is detected on any of the file descriptors | |
720 | /* supplied by the user, then a count and bit fields are | |
721 | /* returned just as for select. (Activity on database sockets | |
722 | /* is never reflected in either count or bitfields.) Timeout | |
723 | /* causes a return, as with select. Upon return, the program | |
724 | /* must check for competion or termination on all of the | |
725 | /* connections in which he/she is interested, for activity on | |
726 | /* the selected file descriptors, and for timeouts, if | |
727 | /* requested, since any or all of these may be reported | |
728 | /* together. | |
729 | /* | |
730 | /* Return values for con_select: >0 same as for select, 0 time | |
731 | /* expired, -1, error in select on user fd, -2, connections | |
732 | /* have progressed but nothing else of interest. | |
733 | /* | |
734 | /* | |
735 | /*----------------------------------------------------------*/ | |
736 | ||
737 | int | |
738 | con_select(nfds, readfds, writefds, exceptfds, timeout) | |
739 | int nfds; | |
740 | fd_set *readfds, *writefds, *exceptfds; | |
741 | struct timeval *timeout; | |
742 | { | |
743 | int merged_nfds; /* the index of the last */ | |
744 | /* file desc we care about.*/ | |
745 | int select_fds; /* number of file */ | |
746 | /* returned from select */ | |
747 | /* descriptors */ | |
748 | int return_fds; /* fds count to be returned */ | |
749 | /* to the user */ | |
750 | int complete_count; /* number of connections on */ | |
751 | /* which operations have */ | |
752 | ||
753 | /* completed */ | |
754 | ||
755 | /* | |
756 | * figure out highest number file descriptor to worry about | |
757 | */ | |
758 | merged_nfds = max(nfds, gdb_mfd); /* the number we control */ | |
759 | /* or last one the user */ | |
760 | /* supplied, whichevere is */ | |
761 | /* higher */ | |
762 | /* | |
763 | * Loop waiting for activity to occur and processing it as appropriate. | |
764 | * Note that the order of the tests, calls to select, and gdb_progress | |
765 | * in this code is critical. Think it through before you change it | |
766 | * to make sure that progress is always made when possible, and that | |
767 | * returns are always made when needed. | |
768 | */ | |
769 | while (TRUE) { | |
770 | /* | |
771 | * Prepare working copies of the file descriptor maps | |
772 | * based on the ones supplied by the caller, as well as | |
773 | * all the descriptors used by connections. The latter | |
774 | * are mapped in the gdb_c?fds global variables. | |
775 | */ | |
776 | g_fd_or_and_copy(nfds,gdb_mfd,readfds,&gdb_crfds,&last_crfds); | |
777 | g_fd_or_and_copy(nfds,gdb_mfd,writefds,&gdb_cwfds,&last_cwfds); | |
778 | g_fd_or_and_copy(nfds,gdb_mfd,exceptfds,&gdb_cefds,&last_cefds); | |
779 | /* | |
780 | * Use select to wait for something to happen. Compute | |
781 | * number select would have returned if connection related | |
782 | * fd's had not been supplied. | |
783 | */ | |
784 | select_fds = select(merged_nfds, &last_crfds, &last_cwfds, &last_cefds, | |
785 | timeout); | |
786 | /* | |
787 | * There are some messy things we have to worry about here: | |
788 | * | |
789 | * 1) Select could return an error. In particular, some | |
790 | * versions of Unix will return -1 with EBADF if one | |
791 | * of the sockets has closed. We should call a | |
792 | * procedure here to see if this has happened to one | |
793 | * of ours. | |
794 | * | |
795 | * 2) Other versions of Unix will claim that there is activity | |
796 | * on our socket when in fact the other end is closed. | |
797 | * We will leave it to gdb_move_data to try the select | |
798 | * and make the appropriate decision. | |
799 | * | |
800 | * Yes folks, messy but true. If we got an error (case 1), | |
801 | * then let's see if we get the same error when we're only | |
802 | * looking at the caller's fd's. | |
803 | * | |
804 | */ | |
805 | return_fds = 0; | |
806 | if (select_fds < 0) | |
807 | if ( errno != EBADF) | |
808 | return -1; | |
809 | else { | |
810 | g_fd_or_and_copy(nfds,0,readfds,&gdb_crfds,&last_crfds); | |
811 | g_fd_or_and_copy(nfds,0,writefds,&gdb_cwfds,&last_cwfds); | |
812 | g_fd_or_and_copy(nfds,0,exceptfds,&gdb_cefds,&last_cefds); | |
813 | if (select(nfds, &last_crfds, &last_cwfds, &last_cefds, | |
814 | &gdb_notime)<0) { | |
815 | g_fd_copy(nfds, &last_crfds, readfds); | |
816 | g_fd_copy(nfds, &last_cwfds, writefds); | |
817 | g_fd_copy(nfds, &last_cefds, exceptfds); | |
818 | return -1; /* select EBADF */ | |
819 | } else { | |
820 | /* | |
821 | * We should close the connection here | |
822 | */ | |
823 | GDB_GIVEUP("con_select: EBADF on GDB controlled file.") | |
824 | } | |
825 | } | |
826 | else { | |
827 | return_fds = g_compute_return_fds(select_fds, | |
828 | &last_crfds, &last_cwfds, &last_cefds); | |
829 | } | |
830 | /* | |
831 | * If some connection related descriptors were selected, then | |
832 | * try to make progress on them. Find out if any new operations | |
833 | * could be completed. | |
834 | */ | |
835 | if (select_fds != return_fds) | |
836 | complete_count = gdb_fastprogress(); | |
837 | else | |
838 | complete_count = 0; | |
839 | /* | |
840 | * Now, based on the number of operations complete, | |
841 | * the number of user file descriptors satisfied, and | |
842 | * the possible return of a timeout from select, decide | |
843 | * whether to return to the caller. Note that timeout | |
844 | * is identified by select_fds == 0. | |
845 | */ | |
846 | if (complete_count > 0 || /* operations are complete */ | |
847 | return_fds >0 || /* user files satisfied */ | |
848 | select_fds ==0) { /* timeout in select */ | |
849 | /* | |
850 | * Connection related fd bits are never returned | |
851 | * to the caller. Reset them. The count of bits | |
852 | * was already adjusted appropriately above. I don't | |
853 | * think there's too much wasted effort in this, | |
854 | * but we should watch it if profiling indicates | |
855 | * lots of time being spent computing in con_select. | |
856 | * Put the updated bit masks in the caller supplied | |
857 | * maps. | |
858 | */ | |
859 | g_fd_reset_conbits(nfds,gdb_mfd,&last_crfds,&gdb_crfds, | |
860 | readfds); | |
861 | g_fd_reset_conbits(nfds,gdb_mfd,&last_cwfds,&gdb_cwfds, | |
862 | writefds); | |
863 | g_fd_reset_conbits(nfds,gdb_mfd,&last_cefds,&gdb_cefds, | |
864 | exceptfds); | |
865 | if (select_fds ==0) | |
866 | return 0; /* real timeout */ | |
867 | if (return_fds ==0) /* something must have */ | |
868 | /* completed, but our */ | |
869 | /* count looks like a */ | |
870 | /* timeout*/ | |
871 | return (-2); /* only connections have */ | |
872 | /* somethine complete */ | |
873 | else | |
874 | return return_fds; | |
875 | } | |
876 | } | |
877 | } |