1/* 2 * User Process PPP 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan, Inc. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * |
20 * $FreeBSD: head/usr.sbin/ppp/main.c 66898 2000-10-09 21:18:23Z brian $ |
21 * 22 * TODO: 23 */ 24 25#include <sys/param.h> 26#include <netinet/in.h> 27#include <netinet/in_systm.h> 28#include <netinet/ip.h> --- 247 unchanged lines hidden (view full) --- 276} 277 278 279int 280main(int argc, char **argv) 281{ 282 char *name; 283 const char *lastlabel; |
284 int label, arg; |
285 struct bundle *bundle; 286 struct prompt *prompt; 287 struct switches sw; 288 |
289 name = strrchr(argv[0], '/'); 290 log_Open(name ? name + 1 : argv[0]); 291 292#ifndef NONAT 293 PacketAliasInit(); 294#endif 295 label = ProcessArgs(argc, argv, &sw); 296 --- 189 unchanged lines hidden (view full) --- 486 AbortProgram(EX_NORMAL); 487 488 return EX_NORMAL; 489} 490 491static void 492DoLoop(struct bundle *bundle) 493{ |
494 fd_set *rfds, *wfds, *efds; |
495 int i, nfds, nothing_done; 496 struct probe probe; 497 498 probe_Init(&probe); 499 |
500 if ((rfds = mkfdset()) == NULL) { 501 log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n"); 502 return; 503 } 504 505 if ((wfds = mkfdset()) == NULL) { 506 log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n"); 507 free(rfds); 508 return; 509 } 510 511 if ((efds = mkfdset()) == NULL) { 512 log_Printf(LogERROR, "DoLoop: Cannot create fd_set\n"); 513 free(rfds); 514 free(wfds); 515 return; 516 } 517 |
518 for (; !bundle_IsDead(bundle); bundle_CleanDatalinks(bundle)) { 519 nfds = 0; |
520 zerofdset(rfds); 521 zerofdset(wfds); 522 zerofdset(efds); |
523 524 /* All our datalinks, the tun device and the MP socket */ |
525 descriptor_UpdateSet(&bundle->desc, rfds, wfds, efds, &nfds); |
526 527 /* All our prompts and the diagnostic socket */ |
528 descriptor_UpdateSet(&server.desc, rfds, NULL, NULL, &nfds); |
529 530 bundle_CleanDatalinks(bundle); 531 if (bundle_IsDead(bundle)) 532 /* Don't select - we'll be here forever */ 533 break; 534 535 /* 536 * It's possible that we've had a signal since we last checked. If 537 * we don't check again before calling select(), we may end up stuck 538 * after having missed the event.... sig_Handle() tries to be as 539 * quick as possible if nothing is likely to have happened. 540 * This is only really likely if we block in open(... O_NONBLOCK) 541 * which will happen with a misconfigured device. 542 */ 543 if (sig_Handle()) 544 continue; 545 |
546 i = select(nfds, rfds, wfds, efds, NULL); |
547 548 if (i < 0 && errno != EINTR) { 549 log_Printf(LogERROR, "DoLoop: select(): %s\n", strerror(errno)); 550 if (log_IsKept(LogTIMER)) { 551 struct timeval t; 552 553 for (i = 0; i <= nfds; i++) { |
554 if (FD_ISSET(i, rfds)) { |
555 log_Printf(LogTIMER, "Read set contains %d\n", i); |
556 FD_CLR(i, rfds); |
557 t.tv_sec = t.tv_usec = 0; |
558 if (select(nfds, rfds, wfds, efds, &t) != -1) { |
559 log_Printf(LogTIMER, "The culprit !\n"); 560 break; 561 } 562 } |
563 if (FD_ISSET(i, wfds)) { |
564 log_Printf(LogTIMER, "Write set contains %d\n", i); |
565 FD_CLR(i, wfds); |
566 t.tv_sec = t.tv_usec = 0; |
567 if (select(nfds, rfds, wfds, efds, &t) != -1) { |
568 log_Printf(LogTIMER, "The culprit !\n"); 569 break; 570 } 571 } |
572 if (FD_ISSET(i, efds)) { |
573 log_Printf(LogTIMER, "Error set contains %d\n", i); |
574 FD_CLR(i, efds); |
575 t.tv_sec = t.tv_usec = 0; |
576 if (select(nfds, rfds, wfds, efds, &t) != -1) { |
577 log_Printf(LogTIMER, "The culprit !\n"); 578 break; 579 } 580 } 581 } 582 } 583 break; 584 } 585 586 log_Printf(LogTIMER, "Select returns %d\n", i); 587 588 sig_Handle(); 589 590 if (i <= 0) 591 continue; 592 593 for (i = 0; i <= nfds; i++) |
594 if (FD_ISSET(i, efds)) { |
595 log_Printf(LogPHASE, "Exception detected on descriptor %d\n", i); 596 /* We deal gracefully with link descriptor exceptions */ 597 if (!bundle_Exception(bundle, i)) { 598 log_Printf(LogERROR, "Exception cannot be handled !\n"); 599 break; 600 } 601 } 602 603 if (i <= nfds) 604 break; 605 606 nothing_done = 1; 607 |
608 if (descriptor_IsSet(&server.desc, rfds)) { 609 descriptor_Read(&server.desc, bundle, rfds); |
610 nothing_done = 0; 611 } 612 |
613 if (descriptor_IsSet(&bundle->desc, rfds)) { 614 descriptor_Read(&bundle->desc, bundle, rfds); |
615 nothing_done = 0; 616 } 617 |
618 if (descriptor_IsSet(&bundle->desc, wfds)) 619 if (!descriptor_Write(&bundle->desc, bundle, wfds) && nothing_done) { |
620 /* 621 * This is disasterous. The OS has told us that something is 622 * writable, and all our write()s have failed. Rather than 623 * going back immediately to do our UpdateSet()s and select(), 624 * we sleep for a bit to avoid gobbling up all cpu time. 625 */ 626 struct timeval t; 627 628 t.tv_sec = 0; 629 t.tv_usec = 100000; 630 select(0, NULL, NULL, NULL, &t); 631 } 632 } 633 634 log_Printf(LogDEBUG, "DoLoop done.\n"); 635} |