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