Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch win32-jump-point-1 Excluding Merge-Ins
This is equivalent to a diff from 4a5c83adb9 to 3b3b7d3e33
2002-03-22
| ||
05:26 | new "follow the mouse" test case. check-in: 8a18d3f5f5 user: davygrvy tags: trunk, telco-tec-win32-take2-branch | |
2002-03-16
| ||
00:38 | no message Leaf check-in: 3b3b7d3e33 user: davygrvy tags: trunk, win32-jump-point-1 | |
00:37 | fixed a nasty bug in the SetArgv() function that was all my fault. check-in: abce3fafb9 user: davygrvy tags: trunk, win32-jump-point-1 | |
2001-09-13
| ||
01:06 | moved from root check-in: 73c5ce26d6 user: davygrvy tags: trunk, win32-jump-point-1 | |
2001-07-06
| ||
19:36 | 2001-06-05 Andreas Kupries <[email protected]> * exp_main_sub.c: Fixed bug [#418892]. check-in: 99ef534017 user: andreas_kupries tags: trunk, expect-sf418892-sf439042-branch | |
1999-06-07
| ||
17:49 | Initial 8.1 changes. check-in: ccd6fc80e5 user: libes tags: trunk, master-UNNAMED-BRANCH | |
1998-10-14
| ||
22:53 | Import of Expect v. 5.28.1 check-in: 4a5c83adb9 user: cvsadmin tags: trunk, master-UNNAMED-BRANCH | |
22:53 | *** empty log message *** check-in: c9cbab5472 user: cvsadmin tags: trunk | |
Changes to ChangeLog.
1 2 3 4 5 6 7 | Thu Mar 20 14:27:45 1997 Geoffrey Noer <[email protected]> * configure.in: don't check if stty reads stdout for i[[3456]]86-*-sysv4.2MP during config; hard code instead Tue Nov 19 09:22:08 1996 Tom Tromey <[email protected]> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 2001-08-01 Jeff Hobbs <[email protected]> * Dbg.c (Dbg_On): fixed handling of stepping. [Bug: #446412] 2000-04-26 Rob Savoye <[email protected]> * pty_termios.h: Only include stropts.h if it exists, rather than deciding it exists based on HAVE_PTMX. * configure.in: Make sure libpt exists, rather than blindly using it for all our configure tests, which then all fail. Also assume our svr4 style ptys are broken, if /dev/ptmx exists, but stropts.h doesn't exist. 1999-08-31 Jennifer Hom <[email protected]> * Makefile.in: Changed test target to source tests/all.tcl instead of tests/all * tests/README: Modified documentation to reflect the change from usage of a defs file to the use of package tcltest to run the tests * tests/all: * tests/defs: * tests/all.tcl: * tests/cat.test: * tests/expect.test: * tests/logfile.test: * tests/pid.test: * tests/send.test: * tests/spawn.test * tests/stty.test: Modified test files to use package tcltest, removed tests/all and tests/defs, and added tests/all.tcl 1999-06-22 <[email protected]> * expect.c: Fixed bug in token parsing where index was not being incremented properly. * configure.in: Changed version number to 5.31. * aclocal.m4: Fixed CY_AC_LOAD_TKCONFIG so it tests for Tk_Init instead of Tk_Main (which is only a macro in 8.1 and later). Also added TCL_BUILD_LIB_SPEC to the set of flags used in this test to avoid linker errors. * Dbgconfig.in: move CY_*_TCLCONFIG tests below AC_PROG_CC so it will work with gcc Thu Mar 20 14:27:45 1997 Geoffrey Noer <[email protected]> * configure.in: don't check if stty reads stdout for i[[3456]]86-*-sysv4.2MP during config; hard code instead Tue Nov 19 09:22:08 1996 Tom Tromey <[email protected]> |
︙ | ︙ |
Added ChangeLog.win32.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 | 2002-03-16 davygrvy * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinMessage.cpp: * win/expWinMessage.hpp: * win/expWinSlaveMain.cpp: * win/expWinUtils.cpp: * win/expWinUtils.hpp: * win/slavedrv.dsp: fixed a nasty bug in the SetArgv() function that was all my fault. -=[ TAGGED as 'win32-jump-point-1' ]=- 2002-03-15 davygrvy * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinMessage.cpp: * win/expWinMessage.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: * win/expWinSpawnClient.hpp: * win/expWinSpawnStdioClient.cpp: final instalment. tried to work on cleanup issues, but more testing needed. Fixed a big bug in ConsoleDebugger:: OnFillConsoleOutputCharacter() where the master console handle was null. I successfully logged into panix.com with Win2k's telnet.exe and trapped it all! 2002-03-13 davygrvy * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: * win/slavedrv.dsp: milestone! It works. 2002-03-12 davygrvy * win/MsvcDbgControl.cpp: * win/MsvcDbgControl.h: * win/expWinSlaveMain.cpp: * win/slavedrv.dsp: Got debug build working again. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinMessage.cpp: * win/expWinMessage.hpp: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrap.hpp: * win/expWinSlaveTrapDbg.cpp: * win/expWinSpawnClient.hpp: * win/expWinSpawnPipeClient.cpp: removed all use of Tcl from the slavedrv. It was only being used for hash tables. replaced them with std::map. It's a bit fatter now, but i'll live. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: re-added use of tcl's hash tables, but this time using the template. * win/expWinDynloadTclStubs.c: * win/expWinDynloadTclStubs.cpp: * win/expWinSpawnPipeClient.cpp: * win/expWinSpawnStdioClient.cpp: renamed * win/TclAdapter.hpp: * win/expWinConsoleDebugger.hpp: * win/expWinMessage.cpp: * win/expWinMessage.hpp: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSpawnPipeClient.cpp: * win/expWinTest.cpp: * win/expWinUtils.cpp: * win/expWinUtils.hpp: * win/slavedrv.dsp: * win/slavedrv_test.dsp: Message class pulled-out to a seperate source file, due to expected growth in that area. * win/expWinConsoleDebugger.hpp: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: * win/expWinUtils.cpp: * win/expWinUtils.hpp: * win/slavedrv.dsp: * win/slavedrv.rc: * win/slavedrv_test.dsp: final cleaning of Tcl from the slavedrv. * win/MsvcDbgControl.cpp: * win/expWinMessage.cpp: * win/expWinMessage.hpp: * win/expWinSlaveMain.cpp: * win/expWinSpawnPipeClient.cpp: more stuff added to the pipe client component. slavedrv.exe now sits at a miniature 29,184 bytes :) * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: Re-arranged headers. The ConsoleDebugger class is now hidden from public veiw. I might have to pull off a bridge pattern to hide it more correctly. * win/TclHash.hpp: Added a Top() and Next() for hash searches. * win/expWinSlaveMain.cpp: * win/expWinSpawnClient.hpp: renamed SpawnPipeClient to SpawnStdioClient to be more meaningful. * win/expWinDynloadTclStubs.c: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSlaveKey.c: not needed anymore * win/expWinDynloadTclStubs.cpp: * win/expWinSlave.hpp: added a ShutdownTcl() so I wouldn't have to share the HMODULE. * win/TclHash.hpp: Wait a sec. I'm not happy with the STL's map template. It adds too much bloat. Let's go back to Tcl's hash tables. * win/expWinDynloadTclStubs.c: we'll need this again. * win/expWinSlaveTrap.hpp: * win/expWinSlaveTrapDbg.cpp: added a write() method. 2002-03-11 davygrvy * win/expWinUtils.cpp: * win/expWinUtils.hpp: Moved BuildCommandLine out of the ConsoleDebugger class for testing reasons. * win/expWinUtils.cpp: minor lint * win/TclAdapter.hpp: * win/expWinTest.cpp: * win/slavedrv.dsw: * win/slavedrv_test.dsp: Added a test for the BuildCommandLine function. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinDynloadTclStubs.c: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSpawnMailboxCli.cpp: * win/expWinSpawnPipeClient.cpp: * win/slavedrv.dsp: replacing mailboxing with simple pipes as our transport. * win/expWinSpawnPipeClient.cpp: * win/expWinUtils.cpp: added missing file header comments * generic/exp.decls: * generic/expIntPlatDecls.h: * generic/expStubInit.c: added ExpSyslogGetSysMsg() 2002-03-10 davygrvy * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: * win/expWinSpawnMailboxCli.cpp: * win/slavedrvmc.mc: Added more fatal error checks. 2002-03-09 davygrvy * win/MsvcDbgControl.cpp: * win/MsvcDbgControl.h: * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinInt.h: * win/expWinSlaveMain.cpp: * win/expWinSpawnMailboxCli.cpp: * win/slavedrv.dsp: * win/slavedrv.dsw: Almost linkable again. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebuggerBreakPoints.cpp: Changed all uses of NULL to the C++ 0L understanding. * win/slavedrv.mc: fixed file header comments, again. * win/slavedrv.dsp: now builds for release once more. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinDynloadTclStubs.c: * win/expWinInt.h: * win/expWinLog.c: * win/expWinProcess.c: * win/expWinSlaveMain.cpp: Got error codes working. * win/slavedrv.mc: * win/slavedrvmc.mc: Needed to rename this. * win/slavedrv.dsp: * win/slavedrv.rc: resource script for the slave driver. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: * win/expWinSlaveTrapDbg.cpp: links once more, but isn't yet working again. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSlaveTrapDbg.cpp: Started on the app-level message queue. * win/expWinConsoleDebugger.hpp: more little stuff. 2002-03-08 davygrvy * win/expWinSlave.hpp: * win/expWinSlaveTrapDbg.cpp: not close to done, but a good launch point. * win/expWinProcess.c: When is a pid not a pid? When it's a process handle, so stop lying about it. * win/slavedrv.mc: fixed file header comments. * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: more cleanup. * win/slavedrv.mc: multi-lingual message catalog used for error messages in the slave driver. * win/expWinSlaveMain.cpp: name change for the event loop function. * win/expWinPort.h: stopped including the IntPlat stuff from here. 2002-03-07 davygrvy * win/expWinConsoleDebugger.cpp: * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: C++ rewrite of the debugger code is coming along well. * generic/exp.decls: * generic/exp.h: * generic/expInt.h: * generic/expIntPlatDecls.h: changed some win protos. * win/expWinConsoleDebugger.hpp: ++ rewrite of expWinSlaveDbg.c (mostly done.. good time to save it) * win/expWinConsoleDebugger.hpp: * win/expWinConsoleDebuggerBreakPoints.cpp: breakpoints completed. module compiles cleanly, but does not yet function. The hook-in for posting work has not been established. 2002-03-06 davygrvy * generic/exp.h: small changes that are minor. * win/expWinInt.h: * win/expWinSlave.hpp: * win/expWinSlaveMain.cpp: * win/expWinSpawnMailboxCli.cpp: * win/slavedrv.dsp: Our main() for the slave driver is getting a deep rewrite. This shell has a good structure. The outer edges are in process. slavedrv.exe currently won't link at this time. 2002-02-16 davygrvy * win/expWinInit.c: * win/winDllMain.c: A static build issue. 2002-02-13 davygrvy * generic/exp.decls: * generic/expCommand.c: * generic/expInt.h: * generic/expIntDecls.h: * generic/exp_main_sub.c: Changed a few functions to be CONST char* and some general reformatting to improve readability. 2002-02-11 davygrvy * win/expWinCommand.c: * win/expWinInit.c: * win/expWinPort.h: * win/expect.dsp: Can now build for Stubs and provide a Stubs table, too, WeeHoo.. * generic/exp_command.h: * generic/exp_event.h: * generic/exp_int.h: * generic/exp_log.h: * generic/exp_port.h: * generic/exp_printify.h: * generic/exp_prog.h: * generic/exp_regexp.h: * generic/exp_rename.h: * generic/exp_tstamp.h: * generic/exp_tty.h: * generic/exp_win.h: * generic/getopt.h: Old header files not used have been removed * generic/exp.h: * generic/exp_main_sub.c: small changes for Stubs 2002-02-10 davygrvy * generic/exp.h: * generic/expStubLib.c: small lint * generic/exp.h: fixed some preprocessor logic that was in error. * generic/exp_memmove.c: already in compat/ * generic/exp.decls: * generic/exp.h: * generic/expDecls.h: * generic/expIntDecls.h: * generic/expIntPlatDecls.h: * generic/expStubInit.c: * generic/exp_main_sub.c: More modifications have been done to support providing a Stubs table. This isn't complete, but close. * win/etest.tcl: * win/expect.dsp: * win/testa2.c: * win/testcalc.c: * win/testcalc.h: * win/testcat.c: * win/testcat.mak: * win/testclib.c: * win/testclib2.c: * win/testconsout.c: * win/testcrash.c: * win/testmodem.c: * win/tests/etest.tcl: * win/tests/testa2.c: * win/tests/testcalc.c: * win/tests/testcalc.h: * win/tests/testcat.c: * win/tests/testcat.mak: * win/tests/testconsout.c: * win/tests/testcrash.c: * win/tests/testmodem.c: * win/tests/testsig.c: * win/tests/testwprog.c: * win/tests/testwstation.c: * win/tests/testwstation.tcl: * win/testsig.c: * win/testwprog.c: * win/testwstation.c: * win/testwstation.tcl: moved all test related files out of the source dir * generic/exp_clib.c: This file shall not be part of the porting job I am doing. After Expect becomes a "friendly" extension, we can then get creative and put the "C" API lib back. * win/msjexhnd.cpp: * win/msjexhnd.h: These are not part of the extension and have no place here, at this time. * compat/exp_strf.c: * generic/exp.decls: * generic/exp.h: * generic/expChan.c: * generic/expCommand.c: * generic/expDecls.h: * generic/expInt.h: * generic/expIntDecls.h: * generic/expIntPlatDecls.h: * generic/expPlatDecls.h: * generic/expPort.h: * generic/expSpawnChan.c: * generic/expStubInit.c: * generic/expStubLib.c: * generic/expTrap.c: * generic/exp_clib.c: * generic/exp_command.h: * generic/exp_event.c: * generic/exp_glob.c: * generic/exp_inter.c: * generic/exp_log.c: * generic/exp_main_sub.c: * generic/exp_port.h: * generic/exp_printify.c: * generic/exp_strf.c: * generic/expect.c: * generic/expect.h: * generic/expect_comm.h: * generic/expect_tcl.h: * unix/expUnixCommand.c: * unix/expUnixTty.c: * unix/exp_clib_orig.c: * unix/exp_command.c: * unix/exp_pty.c: * unix/exp_trap.c: * unix/pty_termios.c: * unix/pty_unicos.c: * win/ExpWinInit.c: * win/ExpWinInit.c: * win/MsvcDbgControl.cpp: * win/expWin.h: * win/expWinCommand.c: * win/expWinDynloadTclStubs.c: * win/expWinInt.h: * win/expWinInt.h: * win/expWinLog.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSlaveKey.c: * win/expWinSpawnChan.c: * win/expWinTty.c: * win/expect.dsp: * win/slavedrv.dsp: moved all header files over to a more core style with the beginnings of a Stubs table. This work is far from complete. * win/expect.dsp: * win/expect.rc: even more rc script problems repaired. * generic/exp_version.h: * win/expWin.h: not needed anymore * win/expect.dsp: * win/expect.rc: rc script problems repaired * win/expect.rc: more rc script problems repaired. * win/ExpWinInit.c: * win/expWinInit.c: * win/expect.dsp: * win/slavedrv.dsp: fixing filename case problem * generic/exp.decls: * generic/exp.h: * generic/expChan.c: * generic/expCommand.c: * generic/expDecls.h: * generic/expInt.h: * generic/expIntDecls.h: * generic/expIntPlatDecls.h: * generic/expPlatDecls.h: * generic/expSpawnChan.c: * generic/expStubInit.c: * generic/expTrap.c: * generic/exp_closetcl.c: * generic/exp_event.c: * generic/exp_glob.c: * generic/exp_inter.c: * generic/exp_log.c: * generic/exp_main_sub.c: * generic/exp_printify.c: * generic/exp_strf.c: * generic/expect.c: * win/MsvcDbgControl.cpp: * win/MsvcDbgControl.h: * win/expWinCommand.c: * win/expWinInit.c: * win/expWinInt.h: * win/expWinLog.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinSpawnChan.c: * win/expWinTty.c: * win/expect.rc: * win/winDllMain.c: All file comments have the same form. * generic/exp.decls: * generic/exp.h: * generic/expCommand.c: * generic/expInt.h: * generic/expIntDecls.h: * generic/expStubInit.c: * generic/exp_strf.c: * win/expect.dsp: More rounds of edits getting the new Stubs table more towards perfection. * win/expect.dsp: updated settings for a release build. 2001-12-22 davygrvy * win/MsvcDbgControl.cpp: * win/MsvcDbgControl.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinSlaveDrv.c: * win/slavedrv.dsp: * win/winDllMain.c: Got the spawndrv.exe using Stubs. Tried to get the extension, but more work needs to be done first. Most Expect commands are now in the ::exp namespace. * win/expect.dsp: Took-out link references to tcl84(d).lib. we'll let winDllmain.c handle it through #pragmas * win/expWinDynloadTclStubs.c: re-added from the original branch 2001-12-21 davygrvy * win/ExpWinInit.c: * win/ExpWinVCDbgLaunch.cpp: * win/MsvcDbgControl.cpp: * win/MsvcDbgControl.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinSlaveDrv.c: * win/expect.dsp: * win/expect.dsp: * win/slavedrv.dsp: Second shot (and final) of automating VC++ for the debugger friendly replacement to CreateProcess(). What a nightmare... 2001-12-19 davygrvy * win/ExpWinInit.c: * win/ExpWinVCDbgLaunch.cpp: * win/expWin.h: * win/expWinProcess.c: * win/expWinSlaveDrv.c: * win/slavedrv.dsp: * win/winDllMain.c: Moved expWinProc initting to a new file. Also realized COM control over the slavedrv debugger is much more work than antisipated to get right. * win/expWinCommand.c: removed -iomode fconfigure option, as there isn't one of that type found in the stock pipe driver. 2001-12-18 davygrvy * win/ExpWinVCDbgLaunch.cpp: * win/expWin.h: * win/expWinCommand.c: * win/expWinProcess.c: * win/expect.dsp: * win/expect.dsw: * win/slavedrv.dsw: * win/winDllMain.c: First shot at trying to automate VC++ so I can run slavedrv.exe and get around the "can't debug child processes" issue. * win/expWinCLib.c: * win/expectlib.rc: * win/makefile: * win/tclHash.c: not used anymore * generic/exp_main_sub.c: * win/expWin.h: * win/expWinCommand.c: * win/expWinProcess.c: * win/expWinSlaveDrv.c: OutputDebugString added to the winprocs for the Tchar thing that Tcl_WinUtfToTChar() does. 2001-12-17 davygrvy * win/expWin.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinProcess.c: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expect.dsp: * win/slavedrv.dsp: Changed ExpWinCreateProcess() to support unicode (aka TCHAR at run-time through Tcl_WinUtfToTchar()) 2001-11-23 davygrvy * win/.cvsignore: added an ignore file for a cleaner appearing workspace. 2001-11-22 davygrvy * win/Mcl/.cvsignore: * win/Mcl/ChangeLog: * win/Mcl/Mcl.dsp: * win/Mcl/Mcl.dsw: * win/Mcl/help/MCL.HLP: * win/Mcl/help/MCL4MFC.HLP: * win/Mcl/help/Mcl C++ Class Library.chm: * win/Mcl/help/Mcl4Mfc C++ Class Library.chm: * win/Mcl/help/mcl.CNT: * win/Mcl/help/mcl4mfc.CNT: * win/Mcl/include/CMcl.h: * win/Mcl/include/CMclAutoLock.h: * win/Mcl/include/CMclAutoPtr.h: * win/Mcl/include/CMclCritSec.h: * win/Mcl/include/CMclEvent.h: * win/Mcl/include/CMclGlobal.h: * win/Mcl/include/CMclKernel.h: * win/Mcl/include/CMclLinkedLists.h: * win/Mcl/include/CMclMailbox.h: * win/Mcl/include/CMclMonitor.h: * win/Mcl/include/CMclMutex.h: * win/Mcl/include/CMclSemaphore.h: * win/Mcl/include/CMclSharedMemory.h: * win/Mcl/include/CMclThread.h: * win/Mcl/include/CMclWaitableCollection.h: * win/Mcl/include/CMclWaitableObject.h: * win/Mcl/readme.txt: * win/Mcl/src/CMclAutoLock.cpp: * win/Mcl/src/CMclAutoPtr.cpp: * win/Mcl/src/CMclCritSec.cpp: * win/Mcl/src/CMclEvent.cpp: * win/Mcl/src/CMclGlobal.cpp: * win/Mcl/src/CMclKernel.cpp: * win/Mcl/src/CMclMailbox.cpp: * win/Mcl/src/CMclMonitor.cpp: * win/Mcl/src/CMclMutex.cpp: * win/Mcl/src/CMclSemaphore.cpp: * win/Mcl/src/CMclSharedMemory.cpp: * win/Mcl/src/CMclThread.cpp: * win/Mcl/src/CMclWaitableCollection.cpp: Merged Mcl into the take2 branch * win/expWinSlaveDrv.c: Oopps.. left some bad debugging cruft around * generic/expSpawnChan.c: removed some left-over C++ style comments. * win/expWinCommand.c: removed some small cruft. * win/expAlloc.c: * win/expDString.c: not used anymore * win/panic.c: this is not needed * generic/exp_main_sub.c: Oopps.. removed a small namespacing left-over of an experiment. * expTcl.c: * expTcl.h: * exp_chan.c: * exp_clib.c: * exp_closetcl.c: * exp_command.c: * exp_command.h: * exp_console.c: * exp_event.c: * exp_event.h: * exp_glob.c: * exp_int.h: * exp_inter.c: * exp_log.c: * exp_log.h: * exp_main_exp.c: * exp_main_sub.c: * exp_main_tk.c: * exp_noevent.c: * exp_poll.c: * exp_prog.h: * exp_pty.c: * exp_pty.h: * exp_regexp.c: * exp_regexp.h: * exp_rename.h: * exp_simple.c: * exp_trap.c: * exp_tstamp.h: * exp_tty.c: * exp_tty.h: * exp_tty_comm.c: * exp_tty_in.h: * exp_win.c: * exp_win.h: * expect.c: * expect.h: * expect_cf.h.in: * expect_comm.h: * expect_tcl.h: * fixcat: * fixline1: * generic/expChan.c: * generic/expCommand.c: * generic/expSpawnChan.c: * generic/expTrap.c: * generic/exp_command.h: * generic/exp_event.c: * generic/exp_inter.c: * generic/exp_log.h: * generic/exp_main_exp.c: * generic/exp_main_sub.c: * generic/expect.c: * generic/expect.h: * generic/expect_tcl.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinPort.h: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSpawnChan.c: * win/expWinTty.c: * win/expect.dsp: * win/expect.dsw: * win/makefile: * win/slavedrv.dsp: A working set of code against Tcl8.4! 2001-11-15 davygrvy * win/expWinSlaveTrapPipe.cpp: file expWinSlaveTrapPipe.cpp was initially added on branch telco-tec-win32-branch. * win/expWinSlaveEvents.cpp: file expWinSlaveEvents.cpp was initially added on branch telco tec-win32-branch. * win/expWinSlaveEvents.cpp: * win/expWinSlaveTrap.cpp: * win/expWinSlaveTrapPipe.cpp: * win/expWinSpawnCliTransport.cpp: * win/expWinSpawnSocketCli.cpp: * win/expWinSpawnTransport.cpp: unfinished work committed anyway. * mkconfig.mif: * win/makefile.vc32: * win/mkbc32.mif: * win/mkfiles.mif: * win/mkmgw32.mif: * win/mkprepvc32.mif: * win/mkvc32.mif: * win/mkwc32.mif: old build files removed. * win/expWinSpawnSocketCli.cpp: file expWinSpawnSocketCli.cpp was initially added on branch telco-tec-win32-branch. * win/expWinSpawnCliTransport.cpp: file expWinSpawnCliTransport.cpp was initially added on branch telco-tec-win32-branch. * win/expWinSlaveTrap.cpp: file expWinSlaveTrap.cpp was initially added on branch telco tec-win32-branch. 2001-11-09 davygrvy * win/expWinSpawnTransport.cpp: file expWinSpawnTransport.cpp was initially added on branch telco-tec-win32-branch. * win/expSlaveDrvMain.c: * win/expWinMailboxCli.cpp: * win/expWinSpawnTransport.cpp: beginning the C++ rewrite. 2001-11-07 davygrvy * win/expWinMailboxCli.cpp: file expWinMailboxCli.cpp was initially added on branch telco tec-win32-branch. * win/expSlaveDrvMain.c: More trims for unicode, but I'm dropping the attempt to build for unicode. Too much wierd stuff to handle along with tchar.h having a C++ bug that I don't understand why overloading is problematic. * expect.dsw: * win/buildfiles.dsp: * win/genStubs.dsp: Changed to an IDE project rather than a makefile project. The makefiles will be disappearing. * win/expSlaveDrvMain.c: file expSlaveDrvMain.c was initially added on branch telco-tec win32-branch. * win/dllEntryPoint.c: * win/expSlaveDrvMain.c: * win/makefile.vc32: * win/spawndrv.rc: * win/spawndrvmc.mc: Numerous changes * win/expWinMailboxCli.cpp: * win/expWinMailboxSrv.cpp: Small test beginnings of the IPC channel driver with client for spawndrv.exe * win/expWinMailboxSrv.cpp: file expWinMailboxSrv.cpp was initially added on branch telco tec-win32-branch. 2001-10-30 davygrvy * win/makefile.vc32: * win/mkfiles.mif: * win/mkvc32.mif: added a 'clean' target. * win/dllEntryPoint.c: new) not neccessarily needed, but being explict is a good thing. * win/dllEntryPoint.c: file dllEntryPoint.c was initially added on branch telco-tec win32-branch. * README.win32.txt: file README.win32.txt was initially added on branch telco-tec win32-branch. * README.win32.txt: (new) 2001-10-29 davygrvy * generic/expPlatIntDecls.h: improper naming convention. Should be PlatInt not IntPlat * win/spawndrv.rc: set use the newer exp.h * generic/expPlatIntDecls.h: file expPlatIntDecls.h was initially added on branch telco-tec win32-branch. * win/makefile.vc32: added the 'genstubs' target * generic/expPlatIntDecls.h: Whoops. should be IntPlat, not PlatInt. * mkconfig.mif: had to put the !error directive back in place. 2001-10-28 davygrvy * win/genStubs.dsp: file genStubs.dsp was initially added on branch telco-tec-win32 branch. * expect.dsw: * win/genStubs.dsp: (new) IDE file for rebuilding the Stubs table. * win/buildfiles.dsp: * win/makefile.vc32: * win/mkfiles.mif: build instruction changes * makefile.win: extension target changed from 'release' to 'expect' 2001-10-26 davygrvy * win/buildfiles.dsp: file buildfiles.dsp was initially added on branch telco-tec win32-branch. * win/spawndrvmc.mc: adding more calls to ExpSyslog() where needed. * win/spawndrvmc.mc: ExpSyslog() is finally doing what I want. More work to do, but the groundwork is now set. * expect.dsw: * win/buildfiles.dsp: a couple more IDE project files for MsDev 2001-10-22 davygrvy * win/makefile.vc32: Needed to include the temp directory in the include path so spawndrvmc.h is picked-up. * expect.dsw: file expect.dsw was initially added on branch telco-tec-win32 branch. * expect.dsw: MSVC++ v6 workspace file for the IDE. * .cvsignore: file .cvsignore was initially added on branch telco-tec-win32 branch. * .cvsignore: globs to ignore by CVS. 2001-10-14 davygrvy * win/spawndrv.rc: * win/spawndrvmc.mc: Added #define RESOURCE_INCLUDED because tcl.h doesn't use RC_INVOKED. Which it should, but doesn't. * mkconfig.mif: * win/makefile.vc32: * win/mkfiles.mif: * win/mkprepvc32.mif: * win/mkvc32.mif: Changed the build files to be run from the /win directory instead of the top-root. This will help get MS project .dsp files working. 2001-10-12 davygrvy * win/spawndrv.rc: file spawndrv.rc was initially added on branch telco-tec-win32 branch. * win/spawndrv.rc: * win/spawndrv.rc: * win/spawndrvmc.mc: spawndrv.exe needed a resource script and a message catalog. * win/spawndrv.rc: * win/spawndrvmc.mc: getting closer to building the message catalog. * win/spawndrvmc.mc: corrected title block text. * win/spawndrvmc.mc: file spawndrvmc.mc was initially added on branch telco-tec win32-branch. 2001-10-02 davygrvy * generic/tcldbg.h: Brought in 5.32.2 and fixed compiler warnings about inappropriate casts. * generic/tcldbg.h: file tcldbg.h was initially added on branch telco-tec-win32 branch. 2001-09-13 davygrvy * exp_memmove.c: * exp_select.c: * exp_strf.c: * expect.man: * expectk.man: * libexpect.man: moved from root |
Changes to Dbg.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* Dbg.c - Tcl Debugger - See cmdHelp() for commands Written by: Don Libes, NIST, 3/23/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include <stdio.h> #include "tcldbgcf.h" #if 0 /* tclInt.h drags in stdlib. By claiming no-stdlib, force it to drag in */ | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* Dbg.c - Tcl Debugger - See cmdHelp() for commands Written by: Don Libes, NIST, 3/23/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. RCS: @(#) $Id: Exp $ */ #include <stdio.h> #include "tcldbgcf.h" #if 0 /* tclInt.h drags in stdlib. By claiming no-stdlib, force it to drag in */ |
︙ | ︙ | |||
84 85 86 87 88 89 90 | /* every time a new debugger command is issued that is an action */ static debug_new_action; #define NO_LINE -1 /* if break point is not set by line number */ struct breakpoint { int id; | | > | < | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /* every time a new debugger command is issued that is an action */ static debug_new_action; #define NO_LINE -1 /* if break point is not set by line number */ struct breakpoint { int id; Tcl_Obj *file; /* file where breakpoint is */ int line; /* line where breakpoint is */ int re; /* 1 if this is regexp pattern */ Tcl_Obj *pat; /* pattern defining where breakpoint can be */ Tcl_Obj *expr; /* expr to trigger breakpoint */ Tcl_Obj *cmd; /* cmd to eval at breakpoint */ struct breakpoint *next, *previous; }; static struct breakpoint *break_base = 0; static int breakpoint_max_id = 0; static struct breakpoint * |
︙ | ︙ | |||
120 121 122 123 124 125 126 | static void breakpoint_print(interp,b) Tcl_Interp *interp; struct breakpoint *b; { | | | | | | | | | | | | | | | | | | | > > | | < < > | > > | > | < < < | | < < | | > > > > | > > > | > > > > | | > | | | | | | | | | | | | | | | | | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | static void breakpoint_print(interp,b) Tcl_Interp *interp; struct breakpoint *b; { print(interp,"breakpoint %d: ",b->id); if (b->re) { print(interp,"-re \"%s\" ",Tcl_GetString(b->pat)); } else if (b->pat) { print(interp,"-glob \"%s\" ",Tcl_GetString(b->pat)); } else if (b->line != NO_LINE) { if (b->file) { print(interp,"%s:",Tcl_GetString(b->file)); } print(interp,"%d ",b->line); } if (b->expr) print(interp,"if {%s} ",Tcl_GetString(b->expr)); if (b->cmd) print(interp,"then {%s}",Tcl_GetString(b->cmd)); print(interp,"\n"); } static void save_re_matches(interp, re, objPtr) Tcl_Interp *interp; Tcl_RegExp re; Tcl_Obj *objPtr; { Tcl_RegExpInfo info; int i, start; char name[20]; Tcl_RegExpGetInfo(re, &info); for (i=0;i<=info.nsubs;i++) { start = info.matches[i].start; /* end = info.matches[i].end-1;*/ if (start == -1) continue; sprintf(name,"%d",i); Tcl_SetVar2Ex(interp, Dbg_VarName, name, Tcl_GetRange(objPtr, info.matches[i].start, info.matches[i].end-1), 0); } } /* return 1 to break, 0 to continue */ static int breakpoint_test(interp,cmd,bp) Tcl_Interp *interp; char *cmd; /* command about to be executed */ struct breakpoint *bp; /* breakpoint to test */ { if (bp->re) { int found = 0; Tcl_Obj *cmdObj; Tcl_RegExp re = Tcl_GetRegExpFromObj(NULL, bp->pat, TCL_REG_ADVANCED); cmdObj = Tcl_NewStringObj(cmd,-1); Tcl_IncrRefCount(cmdObj); if (Tcl_RegExpExecObj(NULL, re, cmdObj, 0 /* offset */, -1 /* nmatches */, 0 /* eflags */) > 0) { save_re_matches(interp, re, cmdObj); found = 1; } Tcl_DecrRefCount(cmdObj); if (!found) return 0; } else if (bp->pat) { if (0 == Tcl_StringMatch(cmd, Tcl_GetString(bp->pat))) return 0; } else if (bp->line != NO_LINE) { /* not yet implemented - awaiting support from Tcl */ return 0; } if (bp->expr) { int value; /* ignore errors, since they are likely due to */ /* simply being out of scope a lot */ if (TCL_OK != Tcl_ExprBooleanObj(interp,bp->expr,&value) || (value == 0)) return 0; } if (bp->cmd) { Tcl_EvalObjEx(interp, bp->cmd, 0); } else { breakpoint_print(interp,bp); } return 1; } static char *already_at_top_level = "already at top level"; /* similar to TclGetFrame but takes two frame ptrs and a direction. If direction is up, search up stack from curFrame If direction is down, simulate searching down stack by |
︙ | ︙ | |||
287 288 289 290 291 292 293 | return result; } static char *printify(s) char *s; { | | | | | | > | | | | | | | | | < < < | | | | | | | | | | | | | | | | | > > | | | | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | return result; } static char *printify(s) char *s; { static int destlen = 0; char *d; /* ptr into dest */ unsigned int need; static char buf_basic[DEFAULT_WIDTH+1]; static char *dest = buf_basic; Tcl_UniChar ch; if (s == 0) return("<null>"); /* worst case is every character takes 4 to printify */ need = strlen(s)*6; if (need > destlen) { if (dest && (dest != buf_basic)) ckfree(dest); dest = (char *)ckalloc(need+1); destlen = need; } for (d = dest;*s;) { s += Tcl_UtfToUniChar(s, &ch); if (ch == '\b') { strcpy(d,"\\b"); d += 2; } else if (ch == '\f') { strcpy(d,"\\f"); d += 2; } else if (ch == '\v') { strcpy(d,"\\v"); d += 2; } else if (ch == '\r') { strcpy(d,"\\r"); d += 2; } else if (ch == '\n') { strcpy(d,"\\n"); d += 2; } else if (ch == '\t') { strcpy(d,"\\t"); d += 2; } else if ((unsigned)ch < 0x20) { /* unsigned strips parity */ sprintf(d,"\\%03o",ch); d += 4; } else if (ch == 0177) { strcpy(d,"\\177"); d += 4; } else if ((ch < 0x80) && isprint(UCHAR(ch))) { *d = (char)ch; d += 1; } else { sprintf(d,"\\u%04x",ch); d += 6; } } *d = '\0'; return(dest); } static char * print_argv(interp,argc,argv) Tcl_Interp *interp; int argc; |
︙ | ︙ | |||
363 364 365 366 367 368 369 | len = strlen(buf); space = buf_width - len; bufp = buf + len; argc--; argv++; arg_index = 1; while (argc && (space > 0)) { | | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | len = strlen(buf); space = buf_width - len; bufp = buf + len; argc--; argv++; arg_index = 1; while (argc && (space > 0)) { CONST char *elementPtr; CONST char *nextPtr; int wrap; /* braces/quotes have been stripped off arguments */ /* so put them back. We wrap everything except lists */ /* with one argument. One exception is to always wrap */ /* proc's 2nd arg (the arg list), since people are */ /* used to always seeing it this way. */ |
︙ | ︙ | |||
425 426 427 428 429 430 431 | Tcl_Interp *interp; int objc; Tcl_Obj *objv[]; { char **argv; int argc; int len; | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | Tcl_Interp *interp; int objc; Tcl_Obj *objv[]; { char **argv; int argc; int len; argv = (char **)ckalloc(objc+1 * sizeof(char *)); for (argc=0 ; argc<objc ; argc++) { argv[argc] = Tcl_GetStringFromObj(objv[argc],&len); } argv[argc] = NULL; return(print_argv(interp,argc,argv)); } #endif |
︙ | ︙ | |||
747 748 749 750 751 752 753 | } static void breakpoint_destroy(b) struct breakpoint *b; { | | | | | | | | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | } static void breakpoint_destroy(b) struct breakpoint *b; { if (b->file) Tcl_DecrRefCount(b->file); if (b->pat) Tcl_DecrRefCount(b->pat); if (b->cmd) Tcl_DecrRefCount(b->cmd); if (b->expr) Tcl_DecrRefCount(b->expr); /* unlink from chain */ if ((b->previous == 0) && (b->next == 0)) { break_base = 0; } else if (b->previous == 0) { break_base = b->next; b->next->previous = 0; } else if (b->next == 0) { b->previous->next = 0; } else { b->previous->next = b->next; b->next->previous = b->previous; } ckfree((char *)b); } static void savestr(objPtr,str) Tcl_Obj **objPtr; char *str; { *objPtr = Tcl_NewStringObj(str, -1); Tcl_IncrRefCount(*objPtr); } /* return 1 if a string is substring of a flag */ static int flageq(flag,string,minlen) char *flag; char *string; |
︙ | ︙ | |||
876 877 878 879 880 881 882 | } } b = breakpoint_new(); if (flageq("-regexp",argv[0],2)) { argc--; argv++; | | > | > > > > > | | 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 | } } b = breakpoint_new(); if (flageq("-regexp",argv[0],2)) { argc--; argv++; if (argc > 0) { b->re = 1; savestr(&b->pat,argv[0]); if (Tcl_GetRegExpFromObj(interp, b->pat, TCL_REG_ADVANCED) == NULL) { breakpoint_destroy(b); return TCL_ERROR; } argc--; argv++; } else { breakpoint_fail("bad regular expression") } } else if (flageq("-glob",argv[0],2)) { argc--; argv++; if (argc > 0) { savestr(&b->pat,argv[0]); |
︙ | ︙ | |||
913 914 915 916 917 918 919 | if (TCL_OK == Tcl_GetInt(interp,linep,&b->line)) { argc--; argv++; print(interp,"setting breakpoints by line number is currently unimplemented - use patterns or expressions\n"); } else { /* not an int? - unwind & assume it is an expression */ | | | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 | if (TCL_OK == Tcl_GetInt(interp,linep,&b->line)) { argc--; argv++; print(interp,"setting breakpoints by line number is currently unimplemented - use patterns or expressions\n"); } else { /* not an int? - unwind & assume it is an expression */ if (b->file) Tcl_DecrRefCount(b->file); } } if (argc > 0) { int do_if = FALSE; if (flageq("if",argv[0],1)) { |
︙ | ︙ | |||
1277 1278 1279 1280 1281 1282 1283 | Tcl_Interp *interp; int immediate; /* if true, stop immediately */ /* should only be used in safe places */ /* i.e., when Tcl_Eval can be called */ { if (!debugger_active) init_debugger(interp); | | < > | > | | | 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | Tcl_Interp *interp; int immediate; /* if true, stop immediately */ /* should only be used in safe places */ /* i.e., when Tcl_Eval can be called */ { if (!debugger_active) init_debugger(interp); /* Initialize debugger in single-step mode. * * Note: if the command reader is already active, it's too late * which is why we also statically initialize debug_cmd to step. */ debug_cmd = step; step_count = 1; if (immediate) { static char *fake_cmd = "--interrupted-- (command_unknown)"; debugger_trap((ClientData)0,interp,-1,fake_cmd,(int (*)())0, (ClientData)0,1,&fake_cmd); |
︙ | ︙ |
Changes to DbgMkfl.in.
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 | ###################################### # Targets for pushing out releases ###################################### FTPDIR = /proj/itl/www/div826/subject/expect/tcl-debug ftp: tcl-debug-$(VERSION).tar.Z tcl-debug-$(VERSION).tar.gz cp tcl-debug-$(VERSION).tar.Z $(FTPDIR)/tcl-debug.tar.Z cp tcl-debug-$(VERSION).tar.gz $(FTPDIR)/tcl-debug.tar.gz cp HISTORY $(FTPDIR) cp README $(FTPDIR)/README.distribution rm tcl-debug-$(VERSION).tar* ls -l $(FTPDIR)/tcl-debug.tar* | > > > > | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | ###################################### # Targets for pushing out releases ###################################### FTPDIR = /proj/itl/www/div826/subject/expect/tcl-debug # make a private tar file for myself tar: tcl-debug-$(VERSION).tar mv tcl-debug-$(VERSION).tar tcl-debug.tar ftp: tcl-debug-$(VERSION).tar.Z tcl-debug-$(VERSION).tar.gz cp tcl-debug-$(VERSION).tar.Z $(FTPDIR)/tcl-debug.tar.Z cp tcl-debug-$(VERSION).tar.gz $(FTPDIR)/tcl-debug.tar.gz cp HISTORY $(FTPDIR) cp README $(FTPDIR)/README.distribution rm tcl-debug-$(VERSION).tar* ls -l $(FTPDIR)/tcl-debug.tar* |
︙ | ︙ |
Changes to Dbgconfig.in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | dnl Process this file with autoconf to produce a configure script. AC_INIT(tcldbg.h) DBG_MAJOR_VERSION=1 DBG_MINOR_VERSION=9 DBG_MICRO_VERSION=1 DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION AC_CONFIG_HEADER(tcldbgcf.h) CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC | > > > > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | dnl Process this file with autoconf to produce a configure script. AC_INIT(tcldbg.h) DBG_MAJOR_VERSION=1 DBG_MINOR_VERSION=9 DBG_MICRO_VERSION=1 DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION AC_CONFIG_HEADER(tcldbgcf.h) OLD_CFLAGS=$CFLAGS AC_PROG_CC CFLAGS=$OLD_CFLAGS CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC CY_AC_C_WORKS # this'll use a BSD compatible install or our included install-sh AC_PROG_INSTALL # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared AC_PROG_RANLIB |
︙ | ︙ |
Changes to Dbgconfigure.
1 2 3 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. | | | 1 2 3 4 5 6 7 8 9 10 11 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.9 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= |
︙ | ︙ | |||
55 56 57 58 59 60 61 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= | < < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then |
︙ | ︙ | |||
338 339 340 341 342 343 344 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.9" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } |
︙ | ︙ | |||
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tclconfig # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tclconfig or --without-tclconfig was given. if test "${with_tclconfig+set}" = set; then withval="$with_tclconfig" with_tclconfig=${withval} fi echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION OLD_CFLAGS=$CFLAGS # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:624: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes if test "${CFLAGS+set}" != set; then echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_gcc_g=yes else ac_cv_prog_gcc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 if test $ac_cv_prog_gcc_g = yes; then CFLAGS="-g -O" else CFLAGS="-O" fi fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi CFLAGS=$OLD_CFLAGS # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tclconfig # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tclconfig or --without-tclconfig was given. if test "${with_tclconfig+set}" = set; then withval="$with_tclconfig" with_tclconfig=${withval} fi echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # First check to see if --with-tclconfig was specified. if test x"${with_tclconfig}" != x ; then |
︙ | ︙ | |||
620 621 622 623 624 625 626 |
| | > > > < | < < | > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > | < < | | > | < < | 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 | # Tcl defines TCL_SHLIB_SUFFIX but TCL_SHARED_LIB_SUFFIX then looks for it # as just SHLIB_SUFFIX. How bizarre. SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX # if Tcl's build directory has been removed, TCL_LIB_SPEC should # be used instead of TCL_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TCL_DBGX eval "LIBS=\"$TCL_BUILD_LIB_SPEC $TCL_LIBS\"" echo $ac_n "checking Tcl build library""... $ac_c" 1>&6 echo "$ac_t""$LIBS" 1>&6 echo $ac_n "checking for Tcl_CreateCommand""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_Tcl_CreateCommand'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 775 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char Tcl_CreateCommand(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ char Tcl_CreateCommand(); int main() { return 0; } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_Tcl_CreateCommand) || defined (__stub___Tcl_CreateCommand) choke me #else Tcl_CreateCommand(); #endif ; return 0; } EOF if { (eval echo configure:797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_Tcl_CreateCommand=yes" else rm -rf conftest* eval "ac_cv_func_Tcl_CreateCommand=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'Tcl_CreateCommand`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking if Tcl library build specification is valid""... $ac_c" 1>&6 echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. echo $ac_n "checking if Tcl library build specification is valid""... $ac_c" 1>&6 echo "$ac_t""no" 1>&6 fi LIBS=$SAVELIBS CC=$TCL_CC # If we cannot compile and link a trivial program, we can't expect anything to work echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6 cat > conftest.$ac_ext <<EOF #line 836 "configure" #include "confdefs.h" int main() { return 0; } int t() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:844: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* c_compiles=yes else rm -rf conftest* c_compiles=no fi rm -f conftest* cat > conftest.$ac_ext <<EOF #line 855 "configure" #include "confdefs.h" int main() { return 0; } int t() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:863: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* c_links=yes else rm -rf conftest* c_links=no fi rm -f conftest* if test x"${c_compiles}" = x"no" ; then |
︙ | ︙ | |||
954 955 956 957 958 959 960 | # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 | < | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. |
︙ | ︙ | |||
1008 1009 1010 1011 1012 1013 1014 | test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | < | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | # building. It's weirder than that, cause the flag varies depending # how old the compiler is. So... # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 | < | | < < | | < < < | | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 | # building. It's weirder than that, cause the flag varies depending # how old the compiler is. So... # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF #line 1016 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1022: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF #line 1031 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1063 "configure" #include "confdefs.h" /* * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__" */ #if defined(__Lynx__) || defined(Lynx) yes #endif |
︙ | ︙ | |||
1141 1142 1143 1144 1145 1146 1147 | if test "$ac_cv_os_lynx" = "yes" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define LYNX 1 EOF echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6 | < | | > | < < | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 | if test "$ac_cv_os_lynx" = "yes" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define LYNX 1 EOF echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1097 "configure" #include "confdefs.h" int main() { return 0; } int t() { /* * This flag varies depending on how old the compiler is. * -X is for the old "cc" and "gcc" (based on 1.42). * -mposix is for the new gcc (at least 2.5.8). */ #if defined(__GNUC__) && __GNUC__ >= 2 choke me #endif ; return 0; } EOF if { (eval echo configure:1114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_posix_flag=" -mposix" else rm -rf conftest* ac_cv_c_posix_flag=" -X" fi rm -f conftest* fi |
︙ | ︙ | |||
1193 1194 1195 1196 1197 1198 1199 | # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6 | < | 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 | # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then |
︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 | ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tclh}" = x ; then | | < | | < < | 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 | ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tclh}" = x ; then ac_safe=`echo "tclInt.h" | tr './\055' '___'` echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1212 "configure" #include "confdefs.h" #include <tclInt.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 |
︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 | echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # Use -g on all systems but Linux where it upsets the dynamic X libraries. echo $ac_n "checking if we are running Linux""... $ac_c" 1>&6 | < < | < < | > | < < | < | | < < | 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 | echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # Use -g on all systems but Linux where it upsets the dynamic X libraries. echo $ac_n "checking if we are running Linux""... $ac_c" 1>&6 if test "x`(uname) 2>/dev/null`" = xLinux; then echo "$ac_t""yes" 1>&6 linux=1 DBG_CFLAGS= else echo "$ac_t""no" 1>&6 linux=0 DBG_CFLAGS=-g fi # # Look for functions that may be missing # echo $ac_n "checking for strchr""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_strchr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1294 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strchr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ char strchr(); int main() { return 0; } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strchr) || defined (__stub___strchr) choke me #else strchr(); #endif ; return 0; } EOF if { (eval echo configure:1316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_strchr=yes" else rm -rf conftest* eval "ac_cv_func_strchr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strchr`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRCHR 1 EOF else echo "$ac_t""no" 1>&6 fi # # Look for various header files # ac_safe=`echo "stdlib.h" | tr './\055' '___'` echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1346 "configure" #include "confdefs.h" #include <stdlib.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1351: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 |
︙ | ︙ | |||
1460 1461 1462 1463 1464 1465 1466 | enable_gcc=no fi DBG_UNSHARED_LIB_FILE=libtcldbg.a echo $ac_n "checking type of library to build""... $ac_c" 1>&6 | < | 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 | enable_gcc=no fi DBG_UNSHARED_LIB_FILE=libtcldbg.a echo $ac_n "checking type of library to build""... $ac_c" 1>&6 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" enable_shared=yes else enable_shared=no fi |
︙ | ︙ | |||
1519 1520 1521 1522 1523 1524 1525 | # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. | < | | 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file |
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) | | | 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.9" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 | s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_DELETEME@%$TCL_DELETEME%g s%@TCL_DBGX@%$TCL_DBGX%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g | > > < | 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 | s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_DELETEME@%$TCL_DELETEME%g s%@TCL_DBGX@%$TCL_DBGX%g s%@TCL_EXEC_PREFIX@%$TCL_EXEC_PREFIX%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@RANLIB@%$RANLIB%g s%@CPP@%$CPP%g s%@TCLHDIR@%$TCLHDIR%g s%@TCLHDIRDASHI@%$TCLHDIRDASHI%g s%@TCL_LIBRARY@%$TCL_LIBRARY%g |
︙ | ︙ | |||
1650 1651 1652 1653 1654 1655 1656 | s%@DBG_LIB_FILE@%$DBG_LIB_FILE%g s%@DBG_LIB_FILES@%$DBG_LIB_FILES%g s%@DBG_CFLAGS@%$DBG_CFLAGS%g s%@UNSHARED_RANLIB@%$UNSHARED_RANLIB%g CEOF EOF | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 | s%@DBG_LIB_FILE@%$DBG_LIB_FILE%g s%@DBG_LIB_FILES@%$DBG_LIB_FILES%g s%@DBG_CFLAGS@%$DBG_CFLAGS%g s%@UNSHARED_RANLIB@%$UNSHARED_RANLIB%g CEOF EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile pkgIndex"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust relative srcdir, etc. for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" |
︙ | ︙ | |||
1727 1728 1729 1730 1731 1732 1733 | top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac | < | | < < < | < < < | 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 | top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done rm -f conftest.subs # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' CONFIG_HEADERS=${CONFIG_HEADERS-"tcldbgcf.h"} for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac |
︙ | ︙ | |||
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi | > > | 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 | # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. # Maximum number of lines to put in a single here document. ac_max_here_lines=12 rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi |
︙ | ︙ | |||
1840 1841 1842 1843 1844 1845 1846 | echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else | < < < < < < | 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 | echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else rm -f $ac_file mv conftest.h $ac_file fi fi; done |
︙ | ︙ |
Changes to HISTORY.
1 2 3 4 5 6 7 8 9 10 11 12 | This is the HISTORY file for Expect. Modifications made by Cygnus support are in ChangeLog. - Don Date Version Description ------- ------- ------------------------------------------------------ 9/30/98 5.28.1 Brian France <[email protected]> noted that his compiler rejected label with no statement. 9/28/98 5.28.0 Fixed two bugs in tcl-debugger (see that HISTORY file). Submitted Expect documentation for official NIST review. At their request, modified a couple things. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | This is the HISTORY file for Expect. Modifications made by Cygnus support are in ChangeLog. - Don Date Version Description ------- ------- ------------------------------------------------------ 8/4/00 5.32.2 Allen J. Newton <[email protected]> provided code for generating passwords with special characters in mkpasswd. Brent Welch <[email protected]> changed the fix1line install script so that "autoexpect" and other scripts that get installed into the platform-independent bin directory generically invoke "expect" from the users PATH instead of hardwiring the platform-specific expect pathname. TclPro 1.4 released with 5.32.2 bundled. 7/13/00 5.32.1 Uwe Klein <[email protected]> reported segfaults from reading nulls. Due to code rewrite in 5.30->5.31 transition. 5/14/00 5.32.0 New version for timing with Ajuba TclPro 1.4. This version of Expect has no new features or behaviors but a lot has been fixed since 5.31.0. Martin Buchholz <[email protected]> noted that his alphaev56-dec-osf4.0e has ptmx and ptmx_bsd (and ptm, pts, pty, ptym). He suggested that BSD things are now usually deprecated so to skip ptmx_bsd if ptmx avail. Chang Li <[email protected]> noted that debugger's bp cmd broke on every command. Was a bug in breakpoint_trace from when we installed the new regexp engine. Jonathan Kamens fixed printf formats in several pty diags. rm_nulls -d was set to wrong value. 5/12/00 5.31.8 After receiving yet another request for fully versioned archives, gave in. Signal handler sometimes sent error to stderr inappropriately. 4/27/00 5.31.7 Rob Savoye fixed Debian ptys and properly checking of libpt. 3/8/00 5.31.6 Petrus Vloet <[email protected]> noted that Expect installed tclRegexp.h which included regex.h which of course misbehaves when it reads the system's version. This is new since 8.0. Since I need to revise the Clib anyway (which is what this install was for), I'll back this out for now. 3/6/00 5.31.5 Larry Virden noted that configure checked for threads twice. 2/19/00 5.31.4 Omer Azmon <[email protected]> note errors in pty_termios.c in exp_pty_test that caused problems during pty testing. Jeffrey Hobbs recommended having configure accept and warn about --enable-threads. John Ellson <[email protected]> noted configure's autoconf testing had leftover debugging code. Also provided a fix for building w/shared libs on HP - appeared to be leftover from earlier Tcl-required configuration that has now disappeared. Susan Muston <[email protected]> noted that exp_wait with no spawned processes exited immediately which is different than 5.29 behavior which reported "no children". This new behavior was evidentally a gratuitous change during the channel driver addition. Backed out. At the same time, neither behavior matches documentation - doc should be fixed and improved except I'm not sure if the behavior should yet be something else (depending if stdin closed or not). [email protected] reported "spawn cat;exp_open" failed. Uninited variable. Scriptics reported memory leak. Was bug in parse_expect_args. "Michael P. Reilly" <[email protected]> noted clib was hanging in spawn code. status_pipe wasn't being closed. Egil Kvaleberg <[email protected]> provided fix due to new gcc which defines strchr as a macro. Dave Morrison <[email protected]> noted some printfs in exp_log.c that misinterpreted embedded %'s with resulting core dumps. Dick Goodwin <[email protected]> noted that "system echo foo" returned with no apparent effect. Due to closeonexec in expect's channel driver. Added skip if std channel. Fixed similar bug in stty command. Minor bug left in stty which isn't passing output back from underlying exec. Stacy W. Smith <[email protected]> provided patch that uses sigsetjmp instead of setjmp that he says fixes a problem he encountered with C lib where it stopped timing out in expect() as if the signals were corrupted. The man page doesn't explain the difference between these calls in a way that makes sense as to why they should make a difference, but I'll the names are certainly suggestive so I'll try it. He says "it appears that the linux setjmp behaves a little differently compared to setjmp on some other OSs. Specifically, setjmp on linux does not save the signal context. It seems most BSDish OSs do save the signal context with setjmp. On those machines, it appears setjmp(env) is equivalent to sigsetjmp(env,1) whereas on linux, setjmp(env) is equivalent to sigsetjmp(env,0). My patch made a (probably bad) assumption that if siglongjmp() exists that we should use the sigXXX versions. I specifically tested for siglongjmp rather than sigsetjmp because on linux, sigsetjmp is just a #define for __sigsetjmp. It appears that linux will give the BSD behaviour if __FAVOR_BSD is defined, but I didn't know what other implications that might have. Michael Schumacher provided fix so that test for whether configure was out-of-date worked when not using the default build dir. 11/1/99 5.31.3 Shlomi Mahlab <[email protected]> noted all.tcl in CVS but not distribution. More notes from Keith Brown on HP cc complaints in exp_pty.c. 10/28/99 5.31.2 "Keith Brown" <[email protected]> noted that HP cc objected to auto aggregate initialization in expLogChannelOpen. 10/22/99 5.31.1 Official release! P Darcy Barnett <[email protected]> noted Makefile could produce "autoconf not found" for non-developers using CVS. Made configure detect and provide advice on workaround. Fixed bug in interact -echo exhibited in rftp example. Ryan Murray <[email protected]> noted Expect wasn't handling handling 8-bit bytes correctly. I had accidentally used Tcl_Write instead of Tcl_WriteChar. Ashley Pittman <[email protected]> noted that digital unix V5.0 prefers openpty (4000 ptys) over ptmx (60 ptys), so I'm reversing the login in pty_termios.c. This also controls linux, but no linux hackers have weighed in on this subject yet. Andrew Tannenbaum <[email protected]> noted exp_internal command and "expect -exact" were broken. 6/29/99 5.31.0 See the NEWS file for this date for an overview. (I'm too tired to add all the details. Maybe later.) Fixed exp_clib so that it immediately reported failure of exec (in spawn) rather than passing it back through pipe. Removed error checking from ioctl(TIOCSCTTY) to pacify the variety of (but not all) Linux systems and a few others which define TIOCSCTTY but return an error although seem to work anyway. Added configure test for 0 vs 2-arg setpgrp. Kenji Kamizono <[email protected]> noted it was possible to compile Linux (2.2.5) so that it recognized both openpty and ptmx leading to conflicts. I arbitrarily chose ptmx. 10/15/99 5.30.2 Herve Tireford <[email protected]> noted extraneous sleep(20) in clib. Apparently left over from debugging, oops. 8/18/99 5.30.1 Added test for newer versions of Tcl that are incompatible. Kenji Kamizono <[email protected]> noted it was possible to compile Linux (2.2.5) so that it recognized both openpty and ptmx leading to conflicts. I arbitrarily chose ptmx. 4/1/99 5.30.0 Martin Forssen <[email protected]> provided fix to allow configure to start with LDFLAGS from environment. Paul Tazzyman <[email protected]> noted that log_file didn't check for logging twice without turning off logging first. Ben <[email protected]> provided updated host for weather example. Jonathon Kamens noted that Expect didn't build properly if Tcl and/or Tk used build/install directories out of the usual hierarchy. At the same time, I fixed a number of other related problems in Makefile/configure. Pierre Pomes <[email protected]> provided fix to ftp-inband. It blew up from an unprotected send that was handed a uuencoded line that started with a -. Autoexpect was thrown off by simple-minded [file executable] test picking up expect directory while searching for executable. 1/21/99 5.29.0 Martin Forssen provides mods to support INSTALL_ROOT. Bryan Surles <[email protected]> modified configure.in to map DBGX to the same value as TCL_DBGX so the .so is named correctly. Suresh Sastry <[email protected]> forced $LIBS to be added to EXP_SHLIB_LD_LIBS. It's not clear to me why this is necessary (since Tk doesn't) but he was having a problem with openpty not being found during runtime on Linux. Martin Forssen noted expectk was crashing if a Tcl error was encountered. He found that exp_exit_handlers() was trying to write into interp->result after interp had been deleted. Added another copy to distribution site - with version number. Stanislav Shalunov <[email protected]> closed race in pty code. Fixed man page: -brace should be -nobrace. Dan O'Brien <[email protected]> noted that Expect needed to call Tcl_FindExecutable at startup for info nameofexecutable. Robbie Gilbert <[email protected]> noted indirect spawn ids occasionally failed. Fixed. 9/30/98 5.28.1 Brian France <[email protected]> noted that his compiler rejected label with no statement. 9/28/98 5.28.0 Fixed two bugs in tcl-debugger (see that HISTORY file). Submitted Expect documentation for official NIST review. At their request, modified a couple things. |
︙ | ︙ | |||
40 41 42 43 44 45 46 | Kristina <[email protected]> noted that tip failed when spawned from a cgi script (BSDI BSD/OS 3.1 i386) because tip didn't see a definition for SHELL and HOME. They need to be set. (Doesn't have to be anything useful; the empty string is fine!) Solution: documented this in Expect man page. Zachariah Baum <[email protected]> noted that config.sub | | | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | Kristina <[email protected]> noted that tip failed when spawned from a cgi script (BSDI BSD/OS 3.1 i386) because tip didn't see a definition for SHELL and HOME. They need to be set. (Doesn't have to be anything useful; the empty string is fine!) Solution: documented this in Expect man page. Zachariah Baum <[email protected]> noted that config.sub didn't recognize Intel 686. Found a newer version that did in autoconf-2.11. POTENTIAL INCOMPATIBILITY: Changed interact so that it observes parity while matching. It used to ignore parity. This impacts people who use interact to connect through to a real serial device that generates parity. If matches don't work, use the exp_parity command. (This fix should have been made years ago, |
︙ | ︙ | |||
243 244 245 246 247 248 249 | LIBS to find strftime. This test should really be done by Tcl. 8/12/96 5.20b17 Glen Biagioni <[email protected]> noted interact -re "A(xx)" failed to match. Problem turned out to be that Tcl 7.5 changed a constant which in the regexp code, which Expect didn't see because it provides its own defn for interact. Alas, the one thing Expect reuses from Tcl was where the change was. This | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | LIBS to find strftime. This test should really be done by Tcl. 8/12/96 5.20b17 Glen Biagioni <[email protected]> noted interact -re "A(xx)" failed to match. Problem turned out to be that Tcl 7.5 changed a constant which in the regexp code, which Expect didn't see because it provides its own defn for interact. Alas, the one thing Expect reuses from Tcl was where the change was. This should really be fixed so Expect doesn't rely on Tcl in this way, but there's no point in putting in a lot of work on regexp when we're anticipating a new one soon anyway. Bjorn S. Nilsson <[email protected]> noted fixcat hangs. Turned out that new Tcl (7.5p1) now waits for all children to disappear. But Expect still had a handle to a child. I added an exit handler to close the connections before Tcl's exit |
︙ | ︙ | |||
1614 1615 1616 1617 1618 1619 1620 | Gary Shea noted that a recent change to expectk made it not default to interactive. 4/12/93 4.5.1 At request of Rusty Wilson <[email protected]>, added "-console" to spawn. Pang Wai Man Raymond <[email protected]> reported that | | | 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 | Gary Shea noted that a recent change to expectk made it not default to interactive. 4/12/93 4.5.1 At request of Rusty Wilson <[email protected]>, added "-console" to spawn. Pang Wai Man Raymond <[email protected]> reported that passmass didn't recognize DEC's passwd prompts for root. 4/7/93 4.5.0 Fixed bug in interact regexp preventing match of multichar literals. 4/6/93 4.4.3 Bennett Todd <[email protected]> noted missing example scripts timed-read and time-run. |
︙ | ︙ | |||
1647 1648 1649 1650 1651 1652 1653 | 3/15/93 4.3.0 Cleaned up /tmp files used during pty locking. Added command "parity" to enable parity stripping. Fixed match_max to do -i correctly. 3/15/93 4.2.4 Fixed to work on new SGI which returns slave-close via excep | | < | 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 | 3/15/93 4.3.0 Cleaned up /tmp files used during pty locking. Added command "parity" to enable parity stripping. Fixed match_max to do -i correctly. 3/15/93 4.2.4 Fixed to work on new SGI which returns slave-close via excep (select) or POLLERR (poll) rather than thru read(). 3/12/93 4.2.3 Fixed to work on AIX (using /dev/ptc) and UTS (using getpty). 3/11/93 4.2.1-2 Fixed numerous bugs relating to HP ptys. It's amazing that for their bewildering complexity, they couldn't support generation of EOF to the master (or at least enable trapping of just close), rather than forcing the code to know about opens, too. |
︙ | ︙ | |||
1938 1939 1940 1941 1942 1943 1944 | it. 2/21/92 3.18.0 Worked on the HP port some more. The HP causes a real problem by insisting SIGCLD be delivered in order for wait to return a status. This royally complicated the code, partly because of the special casing all over the place in the trap command, the asynchronous delivery of SIGCLD and also because Tcl itself | | | < | | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 | it. 2/21/92 3.18.0 Worked on the HP port some more. The HP causes a real problem by insisting SIGCLD be delivered in order for wait to return a status. This royally complicated the code, partly because of the special casing all over the place in the trap command, the asynchronous delivery of SIGCLD and also because Tcl itself is not prepared to have system calls be interrupted. The HP also defines both CLD and CHLD which threw my macros off. Anyway, the end result is that on the HP, SIGCLD is ignored. The manual claims wait status will not be delivered but it seems to be anyway. Good grief! (Even if it were ignored, it would not be such a calamity, since wait is used mainly to discard zombies on other systems.) A remaining problem is that there appears to be some odd interaction, perhaps with fork, such that the script is rolled back at eof if a spawned process happens to exit at the same time. The solution for now is to exit all scripts via exit rather than letting exit be called implicitly. There must be some real bug, but I'm unable to find anything after lots of testing, line and Saber. At the moment, I'm highly suspicious of the HP itself rather than expect. Bob Proulx and Jeff Okamoto supplied me with patches for inter_select.c. HP transmits some pty interactions via the exception field in select. Michael Grant gave me a mod to recognize ~ in the logfile and debug commands. 2/17/92 3.17.1 Brian Keves <[email protected]> pointed out that the man page still referred to "expect_match" instead of "expect_out". 2/12/92 3.17.0 Eric Arnold <[email protected]> ran into a problem when running in the background. interact did ioctl(0...)s to |
︙ | ︙ | |||
2202 2203 2204 2205 2206 2207 2208 | #ifdef va_dcl and put my inclusion after tclInt.h. 10/31/91 3.3.0 Converted most of the examples. Three more to go. Worked on man page some more. Modified expect so that if timeout > 0, and nothing in the buffer matched, it will force a read, no matter how long the | | | 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 | #ifdef va_dcl and put my inclusion after tclInt.h. 10/31/91 3.3.0 Converted most of the examples. Three more to go. Worked on man page some more. Modified expect so that if timeout > 0, and nothing in the buffer matched, it will force a read, no matter how long the preceding code took. This may be hard to understand, but is the intuitive behavior that I always desired. 10/30/91 3.2.0 Fixed bug in eof handling. Converted some more of the examples, and added to Makefile. 10/29/91 3.1.0 Fixed slight bugs in tty mode switching, pty initialization (via stty). |
︙ | ︙ | |||
2920 2921 2922 2923 2924 2925 2926 | 3/17/90 Sent copies of man page to Doug Gwyn and Larry Wall for comments. Note that gwyn downloaded it. 3/16/90 Am really irritated by USENIX. My paper has been put in a session against another session, the BSD people. Furthermore, they called my paper an application, when it is no more so than any other shell or language. Better I should be in "lessons | | | | | 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 | 3/17/90 Sent copies of man page to Doug Gwyn and Larry Wall for comments. Note that gwyn downloaded it. 3/16/90 Am really irritated by USENIX. My paper has been put in a session against another session, the BSD people. Furthermore, they called my paper an application, when it is no more so than any other shell or language. Better I should be in "lessons learned". But it was too late to change the schedule. On top of that, our session has four people in it, so I'll have very little time to speak. Grrrr. 3/13/90 1.6 Added "stty", because without it you can't do things like turning off echo to accept a password. 3/8/90 1.5 Abstract was accepted into USENIX!!!! Time to start writing it! Sent man page to Ousterhout. He didn't seem too impressed. |
︙ | ︙ |
Changes to INSTALL.
︙ | ︙ | |||
78 79 80 81 82 83 84 | these from uunet or any good archive site. -------------------- Trying Expect Without Installing Tcl -------------------- Once expect is built, you can try it out. If Tcl has not been | | | | > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | these from uunet or any good archive site. -------------------- Trying Expect Without Installing Tcl -------------------- Once expect is built, you can try it out. If Tcl has not been installed (but it has been compiled), you will need to define the environment variable TCL_LIBRARY. It should name the directory contain the Tcl libraries. For example, if you are using csh with Tcl 8.0.3: $ setenv TCL_LIBRARY ../tcl8.0.3/library Now you can run expect. The same advice applies to Tk. If it is available but has not been installed, you can try out expectk but only after defining TK_LIBRARY. |
︙ | ︙ | |||
135 136 137 138 139 140 141 | configure Tcl with it and then reconfigure Expect. Expect will inherit the definition that way. It is not safe to modify the Makefile to use gcc by hand. If you do this, then information related to dynamic linking will be incorrect. | > > > > | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | configure Tcl with it and then reconfigure Expect. Expect will inherit the definition that way. It is not safe to modify the Makefile to use gcc by hand. If you do this, then information related to dynamic linking will be incorrect. --enable-threads This switch is ignored so that you can configure Expect with the same configure command as Tcl. --with-tcl=... Specifies the directory containing Tcl's configure file (tclConfig.sh). --with-tclinclude=... Specifies the directory containing Tcl's private include files (such as tclInt.h) --with-tk=... Specifies the directory containing Tk's configure file (tkConfig.sh). --with-tkinclude=... Specifies the directory containing Tk's private include files (such as tkInt.h) Some of the defaults in "configure" can be overridden by environment variables. This is a convenience intended for environments that are |
︙ | ︙ | |||
182 183 184 185 186 187 188 | By default, configure uses the latest Tcl it can find. You can override this by creating a symbolic link of "tcl" which points to the release you want. If you can't or don't want to create symbolic links, you can instead indicate where Tcl and Tk are by using the following environment variables: | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | By default, configure uses the latest Tcl it can find. You can override this by creating a symbolic link of "tcl" which points to the release you want. If you can't or don't want to create symbolic links, you can instead indicate where Tcl and Tk are by using the following environment variables: with_tcl Directory containing Tcl configure file (tclConfig.h) with_tclinclude Directory containing Tcl include files with_tkinclude Directory containing Tk include files with_tk Directory containing Tk binary library (tkConfig.h) -------------------- Multiple-Architecture Installation -------------------- You might want to compile a software package in a different directory from the one that contains the source code. Doing this allows you to |
︙ | ︙ |
Changes to Makefile.in.
︙ | ︙ | |||
57 58 59 60 61 62 63 | # your Expect scripts. # Note: On Linux systems which only have dynamic X libraries, the -g prevents # the linker from using them. So do not use -g on such systems. CFLAGS = @CFLAGS@ #XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ @EXP_SHLIB_CFLAGS@ XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ | | > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # your Expect scripts. # Note: On Linux systems which only have dynamic X libraries, the -g prevents # the linker from using them. So do not use -g on such systems. CFLAGS = @CFLAGS@ #XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ @EXP_SHLIB_CFLAGS@ XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ # Libraries built with optimization switches have this additional extension TCL_DBGX = @TCL_DBGX@ TK_DBGX = @TK_DBGX@ # From now on, CFLAGS is never used. Instead, use XCFLAGS. This is done so # that we can provide a public interface for CFLAGS thereby allowing users # to add to it on the Make command-line and still get the rest of the flags # computed by configure. Do this at your own risk - it obvious goes against # the idea of configure's interface, however this is established tradition # at some sites (e.g., Cygnus)! |
︙ | ︙ | |||
90 91 92 93 94 95 96 97 98 99 100 101 102 103 | # See the INSTALL file for more information. (Analogous information # applies to the next variable as well.) prefix = @prefix@ # You can specify a separate installation prefix for architecture-specific # files such as binaries and libraries. exec_prefix = @exec_prefix@ # The following Expect scripts are not necessary to have installed as # commands, but are very useful. Edit out what you don't want installed. # The INSTALL file describes these and others in more detail. # Some Make's screw up if you delete all of them because SCRIPTS is a # target. If this is a problem, just comment out the SCRIPTS target itself. SCRIPTS = timed-run timed-read ftp-rfc autopasswd lpunlock weather \ | > > > > > > > | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # See the INSTALL file for more information. (Analogous information # applies to the next variable as well.) prefix = @prefix@ # You can specify a separate installation prefix for architecture-specific # files such as binaries and libraries. exec_prefix = @exec_prefix@ # The following definition can be set to non-null for special systems # like AFS with replication. It allows the pathnames used for installation # to be different than those used for actually reference files at # run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix # when installing files. INSTALL_ROOT = # The following Expect scripts are not necessary to have installed as # commands, but are very useful. Edit out what you don't want installed. # The INSTALL file describes these and others in more detail. # Some Make's screw up if you delete all of them because SCRIPTS is a # target. If this is a problem, just comment out the SCRIPTS target itself. SCRIPTS = timed-run timed-read ftp-rfc autopasswd lpunlock weather \ |
︙ | ︙ | |||
157 158 159 160 161 162 163 | ###################################################################### # End of things you may want to change # # Do not change anything after this ###################################################################### | | | | | | | | | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | ###################################################################### # End of things you may want to change # # Do not change anything after this ###################################################################### bindir = $(INSTALL_ROOT)@bindir@ bindir_arch_indep = $(INSTALL_ROOT)$(prefix)/bin tcl_libdir = $(INSTALL_ROOT)@libdir@ libdir = $(INSTALL_ROOT)@libdir@/expect$(VERSION) libdir_arch_indep = $(INSTALL_ROOT)$(prefix)/lib/expect$(VERSION) mandir = $(INSTALL_ROOT)@mandir@ man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 infodir = $(INSTALL_ROOT)@infodir@ includedir = $(INSTALL_ROOT)@includedir@ # Expect's utility script directories - arch-independent and arch-non- # independent. These correspond to the variables "exp_library" and # "exp_exec_library". SCRIPTDIR = $(libdir_arch_indep) EXECSCRIPTDIR = $(libdir) SHELL = @EXP_CONFIG_SHELL@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ AR = ar ARFLAGS = cr LOCAL_EXPECT=LD_LIBRARY_PATH=.:@TCL_EXEC_PREFIX@/lib:$(tcl_libdir):$$LD_LIBRARY_PATH ./expect # These definitions are used by the "subdirs_do" target to pass # the compile flags down recursively. FLAGS_TO_PASS = \ "CC=$(CC)" \ "CFLAGS=$(XCFLAGS)" \ "CFLAGS_INT=$(CFLAGS_INT)" \ |
︙ | ︙ | |||
225 226 227 228 229 230 231 | else echo runtest ; fi` PTY_TYPE = @PTY_TYPE@ PTY = pty_$(PTY_TYPE) CFILES = exp_command.c expect.c $(PTY).c \ exp_inter.c exp_regexp.c exp_tty.c \ exp_log.c exp_main_sub.c exp_pty.c \ | | | | > | | | > | | | > | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | else echo runtest ; fi` PTY_TYPE = @PTY_TYPE@ PTY = pty_$(PTY_TYPE) CFILES = exp_command.c expect.c $(PTY).c \ exp_inter.c exp_regexp.c exp_tty.c \ exp_log.c exp_main_sub.c exp_pty.c \ exp_trap.c exp_strf.c \ exp_console.c exp_glob.c exp_win.c exp_clib.c \ exp_closetcl.c exp_memmove.c exp_tty_comm.c \ exp_$(EVENT_TYPE).c exp_$(EVENT_ABLE).c \ exp_chan.c Dbg.c OFILES = exp_command.o expect.o $(PTY).o exp_inter.o exp_regexp.o exp_tty.o \ exp_log.o exp_main_sub.o exp_pty.o exp_trap.o \ exp_console.o exp_strf.o exp_glob.o exp_win.o exp_clib.o \ exp_closetcl.o exp_memmove.o exp_tty_comm.o \ exp_$(EVENT_TYPE).o exp_$(EVENT_ABLE).o \ exp_chan.o Dbg.o SHARED_OFILES = shared/exp_command.o shared/expect.o shared/$(PTY).o \ shared/exp_inter.o shared/exp_regexp.o shared/exp_tty.o \ shared/exp_log.o shared/exp_main_sub.o shared/exp_pty.o \ shared/exp_trap.o \ shared/exp_console.o shared/exp_strf.o shared/exp_glob.o \ shared/exp_win.o shared/exp_clib.o \ shared/exp_closetcl.o shared/exp_memmove.o shared/exp_tty_comm.o \ shared/exp_$(EVENT_TYPE).o shared/exp_$(EVENT_ABLE).o \ shared/exp_chan.o shared/Dbg.o # Expect libraries (both .a and shared) EXP_LIB_FILES = @EXP_LIB_FILES@ # default Expect library (shared if possible, otherwise static) EXP_LIB_FILE = @EXP_LIB_FILE@ # Expect object library (.a) EXP_UNSHARED_LIB_FILE = @EXP_UNSHARED_LIB_FILE@ |
︙ | ︙ | |||
312 313 314 315 316 317 318 | if [ "x$(EXP_UNSHARED_LIB_FILE)" != "x$(EXP_LIB_FILE)" ] ; then \ if [ ! -d shared ] ; then \ mkdir shared ; \ else true; fi ; \ $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ $(STTY) $(HDEFS) $< -o shared/$@ ; \ fi | > > | > > > > > | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | if [ "x$(EXP_UNSHARED_LIB_FILE)" != "x$(EXP_LIB_FILE)" ] ; then \ if [ ! -d shared ] ; then \ mkdir shared ; \ else true; fi ; \ $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ $(STTY) $(HDEFS) $< -o shared/$@ ; \ fi all: binaries libraries doc binaries: expect $(EXP_LIB_FILES) ${X11_PROGS} @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS) libraries: doc: info dvi info: dvi: # build expect binary that does not depend on Expect's shared libs # IFF static Tcl/Tk libraries are available. expect: exp_main_exp.o $(EXP_UNSHARED_LIB_FILE) $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expect exp_main_exp.o $(EXP_UNSHARED_LIB_FILE) $(TCLLIB) $(EXP_AND_TCL_LIBS) $(SETUID) expect # install Expect library # This is done before the install target because the libraries have to be # in place before the installed expect is built. Actually, only the shared |
︙ | ︙ | |||
355 356 357 358 359 360 361 | $(SETUID) expect_installed # Build Expect with TestCenter expect.tc: exp_main_exp.o $(OFILES) proof $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect.tc $(OFILES) exp_main_exp.o $(TCLLIB) $(EXP_AND_TCL_LIBS) $(SETUID) expect.tc | | > > > > > | < < < < < > | > > > > > > > > > > > > > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | $(SETUID) expect_installed # Build Expect with TestCenter expect.tc: exp_main_exp.o $(OFILES) proof $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect.tc $(OFILES) exp_main_exp.o $(TCLLIB) $(EXP_AND_TCL_LIBS) $(SETUID) expect.tc # Build an executable with both Expect and Tk # IFF static Tcl/Tk libraries are available. # Yes, I know that the link line can have libraries repeated. This is a # consequence of Tcl's configure combining the Tcl and X dependent libs # together. I could fix it by testing all the libraries (again, in Expect's # configure) separately for Expectk, but as far as I know, it doesn't hurt # anything here, so I'm not worrying about it. expectk: exp_main_tk.o $(EXP_UNSHARED_LIB_FILE) $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk exp_main_tk.o $(EXP_UNSHARED_LIB_FILE) $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk expectk_installed: exp_main_tk.o $(EXP_LIB_FILE) $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expectk_installed exp_main_tk.o @EXP_LIB_SPEC@ $(TKLIB_INSTALLED) $(TCLLIB_INSTALLED) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk_installed # Build Expectk with TestCenter expectk.tc: exp_main_tk.o $(OFILES) proof $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk.tc $(OFILES) exp_main_tk.o $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk.tc expect-unshared-lib-file :: $(EXP_UNSHARED_LIB_FILE) $(EXP_UNSHARED_LIB_FILE): $(OFILES) -rm -f $(EXP_UNSHARED_LIB_FILE) $(AR) $(ARFLAGS) $(EXP_UNSHARED_LIB_FILE) $(OFILES) -$(UNSHARED_RANLIB) $(EXP_UNSHARED_LIB_FILE) # the dependency should really be SHARED_OFILES rather than OFILES # but there's no way to write a rule that says shared/XYZ.o should # depend on XYZ.c in a different directory (except by writing the # rule out for each file, sigh). expect-shared-lib-file :: $(EXP_SHARED_LIB_FILE) $(EXP_SHARED_LIB_FILE): $(OFILES) -rm -f $(EXP_SHARED_LIB_FILE) @TCL_SHLIB_LD@ -o $(EXP_SHARED_LIB_FILE) $(SHARED_OFILES) @EXP_LD_SEARCH_FLAGS@ @EXP_SHLIB_LD_LIBS@ .PHONY: install-info install info install-info: install: all install-binaries install-libraries install-doc install-binaries: expect expect_installed ${X11_PROGS_INSTALLED} $(SCRIPTS) ${srcdir}/mkinstalldirs $(man1dir) $(man3dir) $(bindir) $(tcl_libdir) $(includedir) # install Expect $(INSTALL_PROGRAM) expect_installed $(bindir)/expect # install Expectk (and man page) if present -if [ -s expectk_installed ] ; then \ $(INSTALL_PROGRAM) expectk_installed $(bindir)/expectk ; \ else true; fi # install Expect's public include files # $(INSTALL_DATA) expect_cf.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect_tcl.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect_comm.h $(includedir) # force installation of Tcl's private regexp definition - we simply have to # make it public in order for people to use Expect's C lib. # hmm - no longer appropriate for Tcl 8.2+ - work on better solution? # $(INSTALL_DATA) $(TCLHDIR)/tclRegexp.h $(includedir) # install Debugger's public include file (just in case it's not there) $(INSTALL_DATA) $(srcdir)/tcldbg.h $(includedir) # some people don't install Tcl, sigh TCL_LIBRARY=$(TCL_LIBRARY) ; \ export TCL_LIBRARY ; \ if $(LOCAL_EXPECT) $(srcdir)/fixcat ; then \ $(INSTALL_DATA) $(srcdir)/fixcat $(EXECSCRIPTDIR)/cat-buffers ; \ else true; fi install-libraries: # install standalone scripts and their man pages, if requested ${srcdir}/mkinstalldirs $(bindir_arch_indep) $(man1dir) $(SCRIPTDIR) $(EXECSCRIPTDIR) -for i in $(SCRIPT_LIST) ; do \ if [ -f $$i ] ; then \ $(INSTALL_PROGRAM) $$i $(bindir_arch_indep)/$$i ; \ rm -f $$i ; \ else true; fi ; \ done install-doc: ${srcdir}/mkinstalldirs $(man1dir) $(man3dir) # install Expectk man page if present -if [ -s expectk_installed ] ; then \ $(INSTALL_DATA) $(srcdir)/expectk.man $(man1dir)/expectk.1 ; \ else true; fi # install Expect man page $(INSTALL_DATA) $(srcdir)/expect.man $(man1dir)/expect.1 # install man page for Expect and Expectk libraries $(INSTALL_DATA) $(srcdir)/libexpect.man $(man3dir)/libexpect.3 -for i in $(SCRIPT_MANPAGE_LIST) ; do \ if [ -f $(srcdir)/example/$$i.man ] ; then \ $(INSTALL_DATA) $(srcdir)/example/$$i.man $(man1dir)/$$i.1 ; \ else true; fi ; \ done $(SCRIPT_LIST): |
︙ | ︙ | |||
600 601 602 603 604 605 606 607 608 | GCCROOT = /depot/gnu/arch/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3 GCCLIB = $(GCCROOT)/libgcc.a GCCINC = -I$(GCCROOT)/include # following only on Sparcs SABERDEFINE = -D__sparc__ # Following target builds expect under CodeCenter. # If using ObjectCenter, before loading, type: setopt primary_language C exp: $(CFILES) exp_main_exp.c | > > > | < < > | > < < < < < < < < < < | 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | GCCROOT = /depot/gnu/arch/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3 GCCLIB = $(GCCROOT)/libgcc.a GCCINC = -I$(GCCROOT)/include # following only on Sparcs SABERDEFINE = -D__sparc__ # Following target builds expect under CodeCenter. # Note that CodeCenter doesn't understand backslashes in STTY - there is a # default value in the code itself that is used. So if you don't use the default, # you'll have to hand-edit the source. # If using ObjectCenter, before loading, type: setopt primary_language C exp: $(CFILES) exp_main_exp.c #load $(CPPFLAGS) $(CFILES) exp_main_exp.c $(TCLLIB) $(GCCLIB) $(EXP_AND_TCL_LIBS) # Following target builds expectk under CodeCenter. Notes: # Because of explicit #includes of <X11/...> in tk.h, you need to create # a symlink from your X11 include directory to this directory tk: $(CFILES) exp_main_tk.c #load $(CPPFLAGS) $(STTY) $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS) # Follow definitions are for building expect and expectk under ObjectCenter oexp: $(CFILES) exp_main_exp.c #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_exp.c $(TCLLIB) $(GCCLIB) $(EXP_AND_TCL_LIBS) otk: $(CFILES) exp_main_tk.c #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS) ###################################### # Targets for pushing out releases ###################################### FTPDIR = /proj/itl/www/div826/subject/expect # make a private tar file for myself tar: expect-$(VERSION).tar mv expect-$(VERSION).tar expect.tar # make a release and install it on ftp server # update web page to reflect new version ftp: expect-$(VERSION).tar.Z expect-$(VERSION).tar.gz install-html cp expect-$(VERSION).tar.Z $(FTPDIR)/expect.tar.Z cp expect-$(VERSION).tar.gz $(FTPDIR)/expect.tar.gz cp expect-$(VERSION).tar.gz $(FTPDIR)/old/expect-@[email protected] cp HISTORY $(FTPDIR) cp README $(FTPDIR)/README.distribution cp example/README $(FTPDIR)/example cp `pubfile example` $(FTPDIR)/example ls -l $(FTPDIR)/expect.tar* # delete temp files rm expect-$(VERSION).tar* # make an alpha release and install it on ftp server alpha: expect-$(VERSION).tar.Z expect-$(VERSION).tar.gz cp expect-$(VERSION).tar.Z $(FTPDIR)/alpha.tar.Z cp expect-$(VERSION).tar.gz $(FTPDIR)/alpha.tar.gz cp HISTORY $(FTPDIR) rm expect-$(VERSION).tar* |
︙ | ︙ | |||
687 688 689 690 691 692 693 | test: expect rm -f .tmp echo "set objdir" `pwd` > .tmp if [ "$(srcdir)" = "." ] ; then \ echo "set srcdir" `pwd` >> .tmp ; \ else echo "set srcdir" $(srcdir) >> .tmp ; fi echo "cd \$${srcdir}/tests" >> .tmp | | | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | test: expect rm -f .tmp echo "set objdir" `pwd` > .tmp if [ "$(srcdir)" = "." ] ; then \ echo "set srcdir" `pwd` >> .tmp ; \ else echo "set srcdir" $(srcdir) >> .tmp ; fi echo "cd \$${srcdir}/tests" >> .tmp echo "source all.tcl" >> .tmp rootme=`pwd`; export rootme; \ srcdir=${srcdir} ; export srcdir ; \ if [ -f ./expect ] ; then \ TCL_LIBRARY=$(TCL_LIBRARY) ; \ export TCL_LIBRARY ; fi ; \ $(LOCAL_EXPECT) -f .tmp rm -f .tmp |
︙ | ︙ | |||
744 745 746 747 748 749 750 | Dbg.o: $(srcdir)/Dbg.c tcldbg.h exp_$(EVENT_ABLE).o: $(srcdir)/exp_$(EVENT_ABLE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_$(EVENT_TYPE).o: $(srcdir)/exp_$(EVENT_TYPE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_command.o: $(srcdir)/exp_command.c expect_cf.h exp_tty.h \ exp_rename.h expect.h exp_command.h \ | | > > > | | | | < | | | | | | < | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | Dbg.o: $(srcdir)/Dbg.c tcldbg.h exp_$(EVENT_ABLE).o: $(srcdir)/exp_$(EVENT_ABLE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_$(EVENT_TYPE).o: $(srcdir)/exp_$(EVENT_TYPE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_command.o: $(srcdir)/exp_command.c expect_cf.h exp_tty.h \ exp_rename.h expect.h exp_command.h \ exp_log.h exp_event.h exp_pty.h exp_console.o: $(srcdir)/exp_console.c expect_cf.h exp_rename.h exp_prog.h \ exp_log.h exp_glob.o: $(srcdir)/exp_glob.c expect_cf.h exp_inter.o: $(srcdir)/exp_inter.c expect_cf.h \ exp_tty_in.h exp_tty.h exp_rename.h expect.h exp_command.h \ exp_log.h exp_regexp.h exp_tstamp.h exp_log.o: $(srcdir)/exp_log.c expect_cf.h expect.h \ exp_rename.h exp_log.h exp_main_exp.o: $(srcdir)/exp_main_exp.c expect_cf.h \ expect.h exp_rename.h exp_command.h exp_log.h exp_main_sub.o: $(srcdir)/exp_main_sub.c expect_cf.h \ exp_rename.h \ expect.h exp_command.h exp_tty_in.h exp_tty.h exp_log.h \ exp_event.h exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h tcldbg.h $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $< shared/exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h tcldbg.h $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $< exp_noevent.o: $(srcdir)/exp_noevent.c expect_cf.h exp_prog.h exp_command.h \ exp_event.h exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \ exp_command.h exp_event.h $(CC) -c $(CFLAGS_INT) @TCL_DEFS@ $(HDEFS) $< shared/exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \ exp_command.h exp_event.h $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ @TCL_DEFS@ $(HDEFS) $< -o shared/$@ exp_pty.o: $(srcdir)/exp_pty.c expect_cf.h exp_rename.h exp_pty.h exp_regexp.o: $(srcdir)/exp_regexp.c expect_cf.h \ expect.h exp_regexp.h exp_select.o: $(srcdir)/exp_select.c expect_cf.h \ expect.h exp_command.h exp_event.h exp_simple.o: $(srcdir)/exp_simple.c expect_cf.h \ expect.h exp_command.h exp_event.h exp_strf.o: $(srcdir)/exp_strf.c expect_cf.h exp_trap.o: $(srcdir)/exp_trap.c expect_cf.h expect.h \ exp_command.h exp_log.h exp_tty.o: $(srcdir)/exp_tty.c expect_cf.h \ expect.h exp_rename.h exp_tty_in.h exp_tty.h exp_log.h \ exp_command.h exp_win.o: $(srcdir)/exp_win.c exp_win.h expect_cf.h expect.o: $(srcdir)/expect.c expect_cf.h \ exp_rename.h expect.h exp_command.h \ exp_log.h exp_event.h exp_tty.h exp_tstamp.h lib_exp.o: $(srcdir)/lib_exp.c expect_cf.h exp_rename.h expect.h pty_sgttyb.o: $(srcdir)/pty_sgttyb.c expect_cf.h exp_rename.h exp_tty_in.h \ exp_tty.h exp_pty.h pty_termios.o: $(srcdir)/pty_termios.c expect_cf.h exp_win.h \ exp_tty_in.h exp_tty.h exp_rename.h exp_pty.h pty_unicos.o: $(srcdir)/pty_unicos.c expect_cf.h exp_rename.h |
Changes to NEWS.
1 2 3 4 5 6 7 8 9 10 11 12 13 | This file is the NEWS file from the Expect distribution. ====================================================================== ====================================================================== Date: 8/18/96 Expect now works with Tcl 8.0. No changes were made to take advantage of 8.0 features such as namespaces. (If you want to put the Expect commands in a namespace, declare a namespace before loading them in.) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | This file is the NEWS file from the Expect distribution. ====================================================================== ====================================================================== Date: 08/01/00 ** SUMMARY Expect 5.32 is being released in conjuction with Tcl 8.3.2. This is a fairly minor update with no feature changes but with a number of useful bug fixes in the way expects uses the new regular expression engine and the UTF-8 features of Tcl. Details are in the HISTORY and ChangeLog files. ====================================================================== ====================================================================== Date: 10/22/99 ** SUMMARY Expect 5.31 now works with Tcl 8.2. Expect 5.31 does NOT work with prior releases of Tcl. Thanks to an incredible amount of work by Scott Stanton, Henry Spencer, Melissa Hirschl, and funding from Scriptics for making this possible. ** NEW FEATURES What? You mean that working with Tcl 8.2 isn't enough????? Expect supports Tcl's new regexp engine. Expect supports null bytes in strings directly. (You no longer have to use the "null" keyword to send or match nulls. Of course, the "null" keyword will continue to be supported.) Null removal (on input) is still enabled by default since nulls are almost never intended for end-user consumption in interactive dialogues. ** CHANGES IN BEHAVIOR (POTENTIAL INCOMPATIBILITIES) The interpreter command used to exit upon eof. Now it uses "-eof script" to control this behavior. The default behavior is to return. (This change was required because Expect now gives control to Tcl upon exit and Tcl waits (potentially forever) for all processes to die on exit.) Explicit calls to interpreter are almost non-existent. However, you should look for *implicit* calls via interact commands with a pattern but no action. This required changes in the examples: dislocate, dvorak, kibitz, and xkibitz. Indirect variables can no longer start with "exp". Such variables will be interpreted as channel names. Old-style regexps may need conversion. If you have been protecting regexps containing backslashes with {}, then you need to examine all your backslashes since the new regexp engine interprets backslash sequences (such as \n) itself. For example: expect "\n" (works the same in Tcl 8.0 and 8.1) expect {\n} (works differently in Tcl 8.0 and 8.1) Scriptics has also created a new-regexp-features page which you should read: http://www.scriptics.com/support/howto/regexp81.html. Some of the new features allow much more efficient regexps than before. For example, non-greedy quantifiers can replace [split] looping constructions with a single regexp, enabling Tcl to parse very efficiently. For the whole story, read the re_syntax man page. The interact command's regexp matching no longer skips nulls. (I'd be surprised if anyone misses this. At least I hope ....) Expect's C library now reports failures in spawn's underlying exec directly (by returning -1) rather than the way it used to (as data in the pty). This makes user code more robust. However, it requires you to simplify your code, alas. See the chesslib.c example. Linking with Expect's C library no longer requires the Tcl library (unless, of course, you make Tcl calls yourself). Tcl is still required to build the library in the first place, however. ** CHANGES IN BEHAVIOR (SHOULD NOT CAUSE INCOMPATIBILITIES) The match_max command now controls by bytes, not chars. This won't cause problems unless your existing scripts are interacting using sizeable chunks of multibyte characters. (If you don't know what I'm talking about, ignore this.) The Make/configure suite now corresponds to the TEA conventions (at least in theory; the conventions are changing regularly so it's hard to be less vague on this point). Significantly, this means that you should be able to use the same configure flags as when compiling Tcl or any other TEA-compatible extension. (See the INSTALL file.) The values of special variables such as exp_spawn_id_any have changed. (The values were never documented so you shouldn't have been using them anyway.) Spawn ids now appear as "exp...". (They used to be small integers.) Do not assume that spawn ids will continue to be represented in any particular way (other than unique strings). ** OTHER NOTES Expect uses channels. There is an Expect channel type. It is possible to use Tcl's channel commands, such as fconfigure, to change the encoding. However, Expect layers its own buffering system on top of Tcl's channel handler so don't expect intuitive behavior when using commands such as gets and puts. Unless you know what you're doing, I recommend manipulating the Expect channels only with the expect commands. Some effort was made to make Expect support threads, however it is not complete. You can compile Expect with threads enabled but don't run Expect in multiple threads just yet. So much code has changed, there are bound to be bugs in dark corners. Please let me know of such cases. The best response will come by supplying a simple test case that can be added to Expect's test suite. In places where the behavior of Expect was not precisely documented, full advantage was taken to do something different :-) Several esoteric bugs were fixed. Although Expect itself uses Henry Spencer's new regexp engine, Expect's C library still uses his original regexp engine. No testing has been done of the poll and non-event subsystems. (These are used on systems which don't support select on ptys or ttys. Some minor work needs to be done on them (because the event subsystem was rewritten) which I'll probably do only if anyone requests it. Many deprecated features (deprecated for many years!) have been removed. All such features were deprecated prior to Exploring Expect so if that's how you learned Expect, you have nothing to worry about. For example, Expect's getpid command predates Tcl's pid command and it's been deprecated for, oh.... 6 years - wow! Other deprecated features include: expect -timestamp (flag only; behavior itself was removed years ago) expect -iwrite (flag only; behavior occurs all the time) expect_version (use "exp_version" command) expect_library (use "exp_library" global variable) interact -eof (use "eof" keyword) interact -timeout (use "timeout" keyword) interact -timestamp (use "clock" command) getpid (use "pid" command) system stty (use "stty" command) With this release, the following are deprecated: timestamp (use "clock" command) debugger (use a different one; there are very nice replacements around. Fortunately the Expect debugger is not something anyone is wiring into their scripts, so for now, consider it on the endangered species list. Anyone still want this debugger?) From now on, the most current snapshots of Expect will be found in the Scriptics CVS repository. Not all snapshots are official releases. ====================================================================== ====================================================================== Date: 8/18/96 Expect now works with Tcl 8.0. No changes were made to take advantage of 8.0 features such as namespaces. (If you want to put the Expect commands in a namespace, declare a namespace before loading them in.) Even though Tcl allows embedded nulls in commands, Expect still does not. Tcl still doesn't support embedded in patterns and regexps. I'll wait til Tcl supports that before rewriting Expect's null support. ====================================================================== ====================================================================== |
︙ | ︙ | |||
548 549 550 551 552 553 554 | 3) String manipulation can be reduced or avoided entirely if you use expect -re. 4) exec is no longer necessary to retrieve environment variables, since they can now be retrieved from $env. | | | | | | 704 705 706 707 708 709 710 711 712 713 714 715 | 3) String manipulation can be reduced or avoided entirely if you use expect -re. 4) exec is no longer necessary to retrieve environment variables, since they can now be retrieved from $env. 5) If you have been really careful about testing for timeout and eof, you can dramatically reduce the size of your scripts by using expect_before and expect_after. This is more efficient, as well, since those actions are only parsed once. |
Changes to README.
1 2 3 4 5 6 7 8 9 10 11 | NOTE: ALPHA AND BETA RELEASES OF TCL/TK ARE NOT SUPPORTED! -------------------- Introduction -------------------- This is the README file for Expect, a program that performs programmed dialogue with other interactive programs. It is briefly described by its man page, expect(1). This directory contains the source and man page for Expect. | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | NOTE: ALPHA AND BETA RELEASES OF TCL/TK ARE NOT SUPPORTED! -------------------- Introduction -------------------- This is the README file for Expect, a program that performs programmed dialogue with other interactive programs. It is briefly described by its man page, expect(1). This directory contains the source and man page for Expect. This is Expect 5.32 for Tcl 8.2 and Tk 8.2 (and Tcl and Tk 8.3). Significant changes and other news can be found in the NEWS file. The Expect home page is: http://expect.nist.gov The Expect FAQ is: http://expect.nist.gov/FAQ.html -------------------- Getting Started - The Preferable Way -------------------- |
︙ | ︙ | |||
221 222 223 224 225 226 227 | The usual way of using Expect is as a standalone program with Tcl as the control language. Since you may already have Tcl, it is available separately. Tcl may be retrieved as tcl.tar.Z in the same way as described above for Expect. When new releases of Tcl appear, I will try to check them out for Expect as soon as possible. If you would like to get the newest Tcl release without waiting, ftp it from | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | The usual way of using Expect is as a standalone program with Tcl as the control language. Since you may already have Tcl, it is available separately. Tcl may be retrieved as tcl.tar.Z in the same way as described above for Expect. When new releases of Tcl appear, I will try to check them out for Expect as soon as possible. If you would like to get the newest Tcl release without waiting, ftp it from ftp.scriptics.com (directory pub/tcl). Expect may also be built using the Tk library, a Tcl interface to the X Window System. Tk is available in the same way as Tcl. It is possible to embed the Expect/Tcl core and optionally Tk in your own C programs. This is described in libexpect(3). |
︙ | ︙ |
Changes to aclocal.m4.
︙ | ︙ | |||
96 97 98 99 100 101 102 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ | | > | > | > | > | > | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[9]].[[0-9]].[[0-9]] ${srcdir}/../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8]].[[2-9]].[[0-9]] ${srcdir}/../tcl[[8]].[[2-9]] 2>/dev/null` \ ${srcdir}/../../tcl \ `ls -dr ${srcdir}/../../tcl[[9]].[[0-9]].[[0-9]] ${srcdir}/../../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../../tcl[[8]].[[2-9]].[[0-9]] ${srcdir}/../../tcl[[8]].[[2-9]] 2>/dev/null` \ ${srcdir}/../../../tcl \ `ls -dr ${srcdir}/../../../tcl[[9]].[[0-9]].[[0-9]] ${srcdir}/../../../tcl[[9]].[[0-9]] 2>/dev/null ` \ `ls -dr ${srcdir}/../../../tcl[[8]].[[2-9]].[[0-9]] ${srcdir}/../../../tcl[[8]].[[2-9]] 2>/dev/null ` ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ `ls -dr /usr/local/src/tcl[[9]].[[0-9]].[[0-9]] /usr/local/src/tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/src/tcl[[8]].[[2-9]].[[0-9]] /usr/local/src/tcl[[8]].[[2-9]] 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[[9]].[[0-9]].[[0-9]] /usr/local/lib/tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[[8]].[[2-9]].[[0-9]] /usr/local/lib/tcl[[8]].[[2-9]] 2>/dev/null` \ /usr/local/src/tcl \ /usr/local/lib/tcl \ ${prefix}/include ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi |
︙ | ︙ | |||
159 160 161 162 163 164 165 | ]) AC_DEFUN(CY_AC_PATH_TCLCONFIG, [ # # Ok, lets find the tcl configuration # First, look for one uninstalled. | | | | | > | > | > | > | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | ]) AC_DEFUN(CY_AC_PATH_TCLCONFIG, [ # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, [ --with-tcl directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[9]].[[0-9]].[[0-9]] ../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8]].[[2-9]].[[0-9]] ../tcl[[8]].[[2-9]] 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[9]].[[0-9]].[[0-9]] ../../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8]].[[2-9]].[[0-9]] ../../tcl[[8]].[[2-9]] 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[9]].[[0-9]].[[0-9]] ../../../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8]].[[2-9]].[[0-9]] ../../../tcl[[8]].[[2-9]] 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[9]].[[0-9]].[[0-9]] ${srcdir}/../tcl[[9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8]].[[2-9]].[[0-9]] ${srcdir}/../tcl[[8]].[[2-9]] 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi ]) |
︙ | ︙ | |||
248 249 250 251 252 253 254 | dnl AC_SUBST(TCL_LIB_FILE) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_PREFIX) | < | < | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | dnl AC_SUBST(TCL_LIB_FILE) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_PREFIX) AC_SUBST(TCL_EXEC_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_SHLIB_CFLAGS) AC_SUBST(TCL_SHLIB_LD) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_SHLIB_LD_LIBS) |
︙ | ︙ | |||
276 277 278 279 280 281 282 283 284 285 286 287 288 289 | dnl AC_SUBST(TCL_RANLIB) # if Tcl's build directory has been removed, TCL_LIB_SPEC should # be used instead of TCL_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TCL_DBGX eval "LIBS=\"$TCL_BUILD_LIB_SPEC $TCL_LIBS\"" AC_CHECK_FUNC(Tcl_CreateCommand,[ AC_MSG_CHECKING([if Tcl library build specification is valid]) AC_MSG_RESULT(yes) ],[ TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. | > > > | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | dnl AC_SUBST(TCL_RANLIB) # if Tcl's build directory has been removed, TCL_LIB_SPEC should # be used instead of TCL_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TCL_DBGX eval "LIBS=\"$TCL_BUILD_LIB_SPEC $TCL_LIBS\"" AC_MSG_CHECKING([Tcl build library]) AC_MSG_RESULT($LIBS) AC_CHECK_FUNC(Tcl_CreateCommand,[ AC_MSG_CHECKING([if Tcl library build specification is valid]) AC_MSG_RESULT(yes) ],[ TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. |
︙ | ︙ | |||
303 304 305 306 307 308 309 | ]) # Warning: Tk definitions are very similar to Tcl definitions but # are not precisely the same. There are a couple of differences, # so don't do changes to Tcl thinking you can cut and paste it do # the Tk differences and later simply substitute "Tk" for "Tcl". # Known differences: | | | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | ]) # Warning: Tk definitions are very similar to Tcl definitions but # are not precisely the same. There are a couple of differences, # so don't do changes to Tcl thinking you can cut and paste it do # the Tk differences and later simply substitute "Tk" for "Tcl". # Known differences: # - Acceptable Tcl major version #s is 8.2-9.* while Tk is 8.2-9.* # - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h # - Computing major/minor versions is different because Tk depends on # headers to Tcl, Tk, and X. # - Symbols in tkConfig.sh are different than tclConfig.sh # - Acceptable for Tk to be missing but not Tcl. AC_DEFUN(CY_AC_PATH_TKH, [ |
︙ | ︙ | |||
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../tk[[4-9]].[[0-9]] 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../tk[[4-9]].[[0-9]] 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../../tk[[4-9]].[[0-9]] 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/src/tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/lib/tk[[4-9]].[[0-9]] 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break | > > > > > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../tk[[4-9]].[[0-9]] 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../tk[[4-9]].[[0-9]] 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../../tk[[4-9]].[[0-9]] 2>/dev/null ` \ `ls -dr ${srcdir}/../../../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../../../tk[[4-9]].[[0-9]] 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/src/tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/src/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/src/tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/lib/tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[[4-9]].[[0-9]].[[0-9]] /usr/local/lib/tk[[4-9]].[[0-9]] 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break |
︙ | ︙ | |||
408 409 410 411 412 413 414 | ]) AC_DEFUN(CY_AC_PATH_TKCONFIG, [ # # Ok, lets find the tk configuration # First, look for one uninstalled. | | | | > > > > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | ]) AC_DEFUN(CY_AC_PATH_TKCONFIG, [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, [ --with-tk directory containing tk configuration (tkConfig.sh)], with_tkconfig=${withval}) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tk was specified. if test x"${with_tkconfig}" != x ; then if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[4-9]].[[0-9]].[[0-9]] ../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[4-9]].[[0-9]].[[0-9]] ../tk[[4-9]].[[0-9]] 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[4-9]].[[0-9]].[[0-9]] ../../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[4-9]].[[0-9]].[[0-9]] ../../tk[[4-9]].[[0-9]] 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[4-9]].[[0-9]].[[0-9]] ../../../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[4-9]].[[0-9]].[[0-9]] ../../../tk[[4-9]].[[0-9]] 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../tk[[4-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[4-9]].[[0-9]].[[0-9]] ${srcdir}/../tk[[4-9]].[[0-9]] 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi |
︙ | ︙ | |||
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 | AC_SUBST(TK_VERSION) dnl not actually used, don't export to save symbols dnl AC_SUBST(TK_MAJOR_VERSION) dnl AC_SUBST(TK_MINOR_VERSION) AC_SUBST(TK_DEFS) dnl not used, don't export to save symbols dnl AC_SUBST(TK_LIB_FILE) dnl not used outside of configure dnl AC_SUBST(TK_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TK_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TK_EXEC_PREFIX) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_XLIBSW) AC_SUBST(TK_BUILD_LIB_SPEC) AC_SUBST(TK_LIB_SPEC) ]) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | AC_SUBST(TK_VERSION) dnl not actually used, don't export to save symbols dnl AC_SUBST(TK_MAJOR_VERSION) dnl AC_SUBST(TK_MINOR_VERSION) AC_SUBST(TK_DEFS) AC_SUBST(TK_DBGX) dnl not used, don't export to save symbols dnl AC_SUBST(TK_LIB_FILE) dnl not used outside of configure dnl AC_SUBST(TK_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TK_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TK_EXEC_PREFIX) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_XLIBSW) # if Tk's build directory has been removed, TK_LIB_SPEC should # be used instead of TK_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TK_DBGX eval "LIBS=\"$TK_BUILD_LIB_SPEC $TCL_BUILD_LIB_SPEC $TK_LIBS\"" AC_CHECK_FUNC(Tk_Init,[ AC_MSG_CHECKING([if Tk library build specification is valid]) AC_MSG_RESULT(yes) ],[ TK_BUILD_LIB_SPEC=$TK_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. AC_MSG_CHECKING([if Tk library build specification is valid]) AC_MSG_RESULT(no) ]) LIBS=$SAVELIBS AC_SUBST(TK_BUILD_LIB_SPEC) AC_SUBST(TK_LIB_SPEC) ]) #------------------------------------------------------------------------ # SC_ENABLE_THREADS -- # # Specify if thread support should be enabled # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # #------------------------------------------------------------------------ AC_DEFUN(SC_ENABLE_THREADS, [ AC_MSG_CHECKING(for building with threads) AC_ARG_ENABLE(threads, [ --enable-threads build with threads (not supported)], [tcl_ok=$enableval], [tcl_ok=no]) if test "$tcl_ok" = "yes"; then AC_MSG_WARN([Expect is not fully thread-enabled. Although significant work has been done towards that goal, it is not complete. Continue compiling at your own risk.]) fi # if test "$tcl_ok" = "yes"; then # AC_MSG_RESULT(yes) # TCL_THREADS=1 # AC_DEFINE(TCL_THREADS) # AC_DEFINE(_REENTRANT) # # AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) # if test "$tcl_ok" = "yes"; then # # The space is needed # THREADS_LIBS=" -lpthread" # else # TCL_THREADS=0 # AC_MSG_WARN("Don t know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...") # fi # else # TCL_THREADS=0 # AC_MSG_RESULT(no (default)) # fi AC_MSG_RESULT(no (default)) ]) |
Added compat/exp_memmove.c.
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* memmove - some systems lack this */ #include "expect_cf.h" #include "tcl.h" /* like memcpy but can handle overlap */ #ifndef HAVE_MEMMOVE char * memmove(dest,src,n) VOID *dest; CONST VOID *src; int n; { char *d; CONST char *s; d = dest; s = src; if (s<d && (d < s+n)) { for (d+=n, s+=n; 0<n; --n) *--d = *--s; } else for (;0<n;--n) *d++ = *s++; return dest; } #endif /* HAVE_MEMMOVE */ |
Added compat/exp_select.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | /* exp_select.c - select() interface for Expect Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* suppress file-empty warnings produced by some compilers */ void exp_unused() {} #if 0 /* WHOLE FILE!!!! */ #include "expect_cf.h" #include <stdio.h> #include <errno.h> #include <sys/types.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #ifdef HAVE_SYSSELECT_H # include <sys/select.h> /* Intel needs this for timeval */ #endif #ifdef HAVE_PTYTRAP # include <sys/ptyio.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef _AIX /* AIX has some unusual definition of FD_SET */ #include <sys/select.h> #endif #if !defined( FD_SET ) && defined( HAVE_SYS_BSDTYPES_H ) /* like AIX, ISC has it's own definition of FD_SET */ # include <sys/bsdtypes.h> #endif /* ! FD_SET && HAVE_SYS_BSDTYPES_H */ #include "tcl.h" #include "exp_prog.h" #include "exp_command.h" /* for struct exp_f defs */ #include "exp_event.h" #ifdef HAVE_SYSCONF_H #include <sys/sysconfig.h> #endif #ifndef FD_SET #define FD_SET(fd,fdset) (fdset)->fds_bits[0] |= (1<<(fd)) #define FD_CLR(fd,fdset) (fdset)->fds_bits[0] &= ~(1<<(fd)) #define FD_ZERO(fdset) (fdset)->fds_bits[0] = 0 #define FD_ISSET(fd,fdset) (((fdset)->fds_bits[0]) & (1<<(fd))) #ifndef AUX2 typedef struct fd_set { long fds_bits[1]; /* any implementation so pathetic as to not define FD_SET will just */ /* have to suffer with only 32 bits worth of fds */ } fd_set; #endif /* AUX2 */ #endif static struct timeval zerotime = {0, 0}; static struct timeval anytime = {0, 0}; /* can be changed by user */ /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; int *masters; int n; /* # of masters */ int *master_out; /* 1st event master, not set if none */ int timeout; /* seconds */ int key; { static rr = 0; /* round robin ptr */ int i; /* index into in-array */ struct timeval *t; fd_set rdrs; fd_set excep; /* FIXME: This is really gross, but the folks at Lynx said their select is * way hosed and to ignore all exceptions. */ #ifdef __Lynx__ #define EXCEP 0 #else #define EXCEP &excep #endif for (i=0;i<n;i++) { struct exp_f *f; int m; rr++; if (rr >= n) rr = 0; m = masters[rr]; f = exp_fs + m; if (f->key != key) { f->key = key; f->force_read = FALSE; *master_out = m; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { *master_out = m; return(EXP_DATA_OLD); } } if (timeout >= 0) { t = &anytime; t->tv_sec = timeout; } else { t = NULL; } restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); /* anything in the environment could have changed */ return EXP_RECONFIGURE; } FD_ZERO(&rdrs); FD_ZERO(&excep); for (i = 0;i < n;i++) { FD_SET(masters[i],&rdrs); FD_SET(masters[i],&excep); } /* The reason all fd masks are (seemingly) redundantly cast to */ /* SELECT_MASK_TYPE is that the HP defines its mask in terms of */ /* of int * and yet defines FD_SET in terms of fd_set. */ if (-1 == select(exp_fd_max+1, (SELECT_MASK_TYPE *)&rdrs, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)EXCEP, t)) { /* window refreshes trigger EINTR, ignore */ if (errno == EINTR) goto restart; else if (errno == EBADF) { /* someone is rotten */ for (i=0;i<n;i++) { fd_set suspect; FD_ZERO(&suspect); FD_SET(masters[i],&suspect); if (-1 == select(exp_fd_max+1, (SELECT_MASK_TYPE *)&suspect, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &zerotime)) { exp_error(interp,"invalid spawn_id (%d)\r",masters[i]); return(EXP_TCLERROR); } } } else { /* not prepared to handle anything else */ exp_error(interp,"select: %s\r",Tcl_PosixError(interp)); return(EXP_TCLERROR); } } for (i=0;i<n;i++) { rr++; if (rr >= n) rr = 0; /* ">" catches previous readys that */ /* used more fds then we're using now */ if (FD_ISSET(masters[rr],&rdrs)) { *master_out = masters[rr]; return(EXP_DATA_NEW); /*#ifdef HAVE_PTYTRAP*/ } else if (FD_ISSET(masters[rr], &excep)) { #ifndef HAVE_PTYTRAP *master_out = masters[rr]; return(EXP_EOF); #else struct request_info ioctl_info; if (ioctl(masters[rr],TIOCREQCHECK,&ioctl_info) < 0) { exp_DiagLog("ioctl error on TIOCREQCHECK: %s",Tcl_ErrnoMsg(errno)); break; } if (ioctl_info.request == TIOCCLOSE) { /* eof */ *master_out = masters[rr]; return(EXP_EOF); } if (ioctl(masters[rr], TIOCREQSET, &ioctl_info) < 0) expDiagLog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno)); /* presumably, we trapped an open here */ goto restart; #endif /* HAVE_PTYTRAP */ } } return(EXP_TIMEOUT); } /*ARGSUSED*/ int exp_get_next_event_info(interp,fd,ready_mask) Tcl_Interp *interp; int fd; int ready_mask; { /* this function is only used when running with Tk */ /* hence, it is merely a stub in this file but to */ /* pacify lint, return something */ return 0; } int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { struct timeval t; t.tv_sec = sec; t.tv_usec = (sec - t.tv_sec) * 1000000L; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return rc; } if (-1 == select(1, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &t) && errno == EINTR) goto restart; return TCL_OK; } #if 0 int /* returns TCL_XXX */ exp_usleep(interp,usec) Tcl_Interp *interp; long usec; /* microseconds */ { struct timeval t; t.tv_sec = usec/1000000L; t.tv_usec = usec%1000000L; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); } if (-1 == select(1, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &t) && errno == EINTR) goto restart; return TCL_OK; } #endif /*0*/ /* set things up for later calls to event handler */ void exp_init_event() { #if 0 #ifdef _SC_OPEN_MAX maxfds = sysconf(_SC_OPEN_MAX); #else maxfds = getdtablesize(); #endif #endif exp_event_exit = 0; } #endif /* WHOLE FILE !!!! */ |
Added compat/exp_strf.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | /* exp_strp.c - functions for exp_timestamp */ /* * strftime.c * * Public-domain implementation of ANSI C library routine. * * It's written in old-style C for maximal portability. * However, since I'm used to prototypes, I've included them too. * * If you want stuff in the System V ascftime routine, add the SYSV_EXT define. * For extensions from SunOS, add SUNOS_EXT. * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE. * For VMS dates, add VMS_EXT. * For complete POSIX semantics, add POSIX_SEMANTICS. * * The code for %c, %x, and %X now follows the 1003.2 specification for * the POSIX locale. * This version ignores LOCALE information. * It also doesn't worry about multi-byte characters. * So there. * * This file is also shipped with GAWK (GNU Awk), gawk specific bits of * code are included if GAWK is defined. * * Arnold Robbins <[email protected]> * January, February, March, 1991 * Updated March, April 1992 * Updated April, 1993 * Updated February, 1994 * Updated May, 1994 * Updated January 1995 * Updated September 1995 * * Fixes from [email protected] * February 1991, May 1992 * Fixes from Tor Lillqvist [email protected] * May, 1993 * Further fixes from [email protected] * February 1994 * %z code from [email protected] * Applied September 1995 * * * Modified by Don Libes for Expect, 10/93 and 12/95. * Forced POSIX semantics. * Replaced inline/min/max stuff with a single range function. * Removed tzset stuff. * Commented out tzname stuff. * * According to Arnold, the current version of this code can ftp'd from * ftp.mathcs.emory.edu:/pub/arnold/strftime.shar.gz * */ #include "expect_cf.h" #include "tcl.h" #include <stdio.h> #include <ctype.h> #include "string.h" #include <sys/types.h> #define SYSV_EXT 1 /* stuff in System V ascftime routine */ #define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */ #if defined(POSIX2_DATE) && ! defined(SYSV_EXT) #define SYSV_EXT 1 #endif #if defined(POSIX2_DATE) #define adddecl(stuff) stuff #else #define adddecl(stuff) #endif #ifndef __STDC__ #define const extern char *getenv(); static int weeknumber(); adddecl(static int iso8601wknum();) #else #ifndef strchr extern char *strchr(const char *str, int ch); #endif extern char *getenv(const char *v); static int weeknumber(const struct tm *timeptr, int firstweekday); adddecl(static int iso8601wknum(const struct tm *timeptr);) #endif /* attempt to use strftime to compute timezone, else fallback to */ /* less portable ways */ #if !defined(HAVE_STRFTIME) # if defined(HAVE_SV_TIMEZONE) extern char *tzname[2]; extern int daylight; # else # if defined(HAVE_TIMEZONE) char * zone_name (tp) struct tm *tp; { char *timezone (); struct timeval tv; struct timezone tz; gettimeofday (&tv, &tz); return timezone (tz.tz_minuteswest, tp->tm_isdst); } # endif /* HAVE_TIMEZONE */ # endif /* HAVE_SV_TIMEZONE */ #endif /* HAVE_STRFTIME */ static int range(low,item,hi) int low, item, hi; { if (item < low) return low; if (item > hi) return hi; return item; } /* strftime --- produce formatted time */ void /*size_t*/ #ifndef __STDC__ exp_strftime(/*s,*/ format, timeptr, dstring) /*char *s;*/ char *format; const struct tm *timeptr; Tcl_DString *dstring; #else /*exp_strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)*/ exp_strftime(char *format, const struct tm *timeptr,Tcl_DString *dstring) #endif { int copied; /* used to suppress copying when called recursively */ #if 0 char *endp = s + maxsize; char *start = s; #endif char *percentptr; char tbuf[100]; int i; /* various tables, useful in North America */ static char *days_a[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", }; static char *days_l[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", }; static char *months_a[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", }; static char *months_l[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; static char *ampm[] = { "AM", "PM", }; /* for (; *format && s < endp - 1; format++) {*/ for (; *format ; format++) { tbuf[0] = '\0'; copied = 0; /* has not been copied yet */ percentptr = strchr(format,'%'); if (percentptr == 0) { Tcl_DStringAppend(dstring,format,-1); goto out; } else if (percentptr != format) { Tcl_DStringAppend(dstring,format,percentptr - format); format = percentptr; } #if 0 if (*format != '%') { *s++ = *format; continue; } #endif again: switch (*++format) { case '\0': Tcl_DStringAppend(dstring,"%",1); #if 0 *s++ = '%'; #endif goto out; case '%': Tcl_DStringAppend(dstring,"%",1); copied = 1; break; #if 0 *s++ = '%'; continue; #endif case 'a': /* abbreviated weekday name */ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) strcpy(tbuf, "?"); else strcpy(tbuf, days_a[timeptr->tm_wday]); break; case 'A': /* full weekday name */ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) strcpy(tbuf, "?"); else strcpy(tbuf, days_l[timeptr->tm_wday]); break; #ifdef SYSV_EXT case 'h': /* abbreviated month name */ #endif case 'b': /* abbreviated month name */ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) strcpy(tbuf, "?"); else strcpy(tbuf, months_a[timeptr->tm_mon]); break; case 'B': /* full month name */ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) strcpy(tbuf, "?"); else strcpy(tbuf, months_l[timeptr->tm_mon]); break; case 'c': /* appropriate date and time representation */ sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d", days_a[range(0, timeptr->tm_wday, 6)], months_a[range(0, timeptr->tm_mon, 11)], range(1, timeptr->tm_mday, 31), range(0, timeptr->tm_hour, 23), range(0, timeptr->tm_min, 59), range(0, timeptr->tm_sec, 61), timeptr->tm_year + 1900); break; case 'd': /* day of the month, 01 - 31 */ i = range(1, timeptr->tm_mday, 31); sprintf(tbuf, "%02d", i); break; case 'H': /* hour, 24-hour clock, 00 - 23 */ i = range(0, timeptr->tm_hour, 23); sprintf(tbuf, "%02d", i); break; case 'I': /* hour, 12-hour clock, 01 - 12 */ i = range(0, timeptr->tm_hour, 23); if (i == 0) i = 12; else if (i > 12) i -= 12; sprintf(tbuf, "%02d", i); break; case 'j': /* day of the year, 001 - 366 */ sprintf(tbuf, "%03d", timeptr->tm_yday + 1); break; case 'm': /* month, 01 - 12 */ i = range(0, timeptr->tm_mon, 11); sprintf(tbuf, "%02d", i + 1); break; case 'M': /* minute, 00 - 59 */ i = range(0, timeptr->tm_min, 59); sprintf(tbuf, "%02d", i); break; case 'p': /* am or pm based on 12-hour clock */ i = range(0, timeptr->tm_hour, 23); if (i < 12) strcpy(tbuf, ampm[0]); else strcpy(tbuf, ampm[1]); break; case 'S': /* second, 00 - 61 */ i = range(0, timeptr->tm_sec, 61); sprintf(tbuf, "%02d", i); break; case 'U': /* week of year, Sunday is first day of week */ sprintf(tbuf, "%02d", weeknumber(timeptr, 0)); break; case 'w': /* weekday, Sunday == 0, 0 - 6 */ i = range(0, timeptr->tm_wday, 6); sprintf(tbuf, "%d", i); break; case 'W': /* week of year, Monday is first day of week */ sprintf(tbuf, "%02d", weeknumber(timeptr, 1)); break; case 'x': /* appropriate date representation */ sprintf(tbuf, "%s %s %2d %d", days_a[range(0, timeptr->tm_wday, 6)], months_a[range(0, timeptr->tm_mon, 11)], range(1, timeptr->tm_mday, 31), timeptr->tm_year + 1900); break; case 'X': /* appropriate time representation */ sprintf(tbuf, "%02d:%02d:%02d", range(0, timeptr->tm_hour, 23), range(0, timeptr->tm_min, 59), range(0, timeptr->tm_sec, 61)); break; case 'y': /* year without a century, 00 - 99 */ i = timeptr->tm_year % 100; sprintf(tbuf, "%02d", i); break; case 'Y': /* year with century */ sprintf(tbuf, "%d", 1900 + timeptr->tm_year); break; case 'Z': /* time zone name or abbrevation */ #if defined(HAVE_STRFTIME) strftime(tbuf,sizeof tbuf,"%Z",timeptr); #else # if defined(HAVE_SV_TIMEZONE) i = 0; if (daylight && timeptr->tm_isdst) i = 1; strcpy(tbuf, tzname[i]); # else strcpy(tbuf, zone_name (timeptr)); # if defined(HAVE_TIMEZONE) # endif /* HAVE_TIMEZONE */ /* no timezone available */ /* feel free to add others here */ # endif /* HAVE_SV_TIMEZONE */ #endif /* HAVE STRFTIME */ break; #ifdef SYSV_EXT case 'n': /* same as \n */ tbuf[0] = '\n'; tbuf[1] = '\0'; break; case 't': /* same as \t */ tbuf[0] = '\t'; tbuf[1] = '\0'; break; case 'D': /* date as %m/%d/%y */ exp_strftime("%m/%d/%y", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);*/ break; case 'e': /* day of month, blank padded */ sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31)); break; case 'r': /* time as %I:%M:%S %p */ exp_strftime("%I:%M:%S %p", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);*/ break; case 'R': /* time as %H:%M */ exp_strftime("%H:%M", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);*/ break; case 'T': /* time as %H:%M:%S */ exp_strftime("%H:%M:%S", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);*/ break; #endif #ifdef POSIX2_DATE case 'C': sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100); break; case 'E': case 'O': /* POSIX locale extensions, ignored for now */ goto again; case 'V': /* week of year according ISO 8601 */ sprintf(tbuf, "%02d", iso8601wknum(timeptr)); break; case 'u': /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday); break; #endif /* POSIX2_DATE */ default: tbuf[0] = '%'; tbuf[1] = *format; tbuf[2] = '\0'; break; } if (!copied) Tcl_DStringAppend(dstring,tbuf,-1); #if 0 i = strlen(tbuf); if (i) { if (s + i < endp - 1) { strcpy(s, tbuf); s += i; } else return 0; #endif } out:; #if 0 if (s < endp && *format == '\0') { *s = '\0'; return (s - start); } else return 0; #endif } /* isleap --- is a year a leap year? */ #ifndef __STDC__ static int isleap(year) int year; #else static int isleap(int year) #endif { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); } #ifdef POSIX2_DATE /* iso8601wknum --- compute week number according to ISO 8601 */ #ifndef __STDC__ static int iso8601wknum(timeptr) const struct tm *timeptr; #else static int iso8601wknum(const struct tm *timeptr) #endif { /* * From 1003.2: * If the week (Monday to Sunday) containing January 1 * has four or more days in the new year, then it is week 1; * otherwise it is the highest numbered week of the previous * (52 or 53) year, and the next week is week 1. * * ADR: This means if Jan 1 was Monday through Thursday, * it was week 1, otherwise week 53. * * XPG4 erroneously included POSIX.2 rationale text in the * main body of the standard. Thus it requires week 53. */ int weeknum, jan1day; /* get week number, Monday as first day of the week */ weeknum = weeknumber(timeptr, 1); /* * With thanks and tip of the hatlo to [email protected] * * What day of the week does January 1 fall on? * We know that * (timeptr->tm_yday - jan1.tm_yday) MOD 7 == * (timeptr->tm_wday - jan1.tm_wday) MOD 7 * and that * jan1.tm_yday == 0 * and that * timeptr->tm_wday MOD 7 == timeptr->tm_wday * from which it follows that. . . */ jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7); if (jan1day < 0) jan1day += 7; /* * If Jan 1 was a Monday through Thursday, it was in * week 1. Otherwise it was last year's highest week, which is * this year's week 0. * * What does that mean? * If Jan 1 was Monday, the week number is exactly right, it can * never be 0. * If it was Tuesday through Thursday, the weeknumber is one * less than it should be, so we add one. * Otherwise, Friday, Saturday or Sunday, the week number is * OK, but if it is 0, it needs to be 52 or 53. */ switch (jan1day) { case 1: /* Monday */ break; case 2: /* Tuesday */ case 3: /* Wednesday */ case 4: /* Thursday */ weeknum++; break; case 5: /* Friday */ case 6: /* Saturday */ case 0: /* Sunday */ if (weeknum == 0) { #ifdef USE_BROKEN_XPG4 /* XPG4 (as of March 1994) says 53 unconditionally */ weeknum = 53; #else /* get week number of last week of last year */ struct tm dec31ly; /* 12/31 last year */ dec31ly = *timeptr; dec31ly.tm_year--; dec31ly.tm_mon = 11; dec31ly.tm_mday = 31; dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1; dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900); weeknum = iso8601wknum(& dec31ly); #endif } break; } if (timeptr->tm_mon == 11) { /* * The last week of the year * can be in week 1 of next year. * Sigh. * * This can only happen if * M T W * 29 30 31 * 30 31 * 31 */ int wday, mday; wday = timeptr->tm_wday; mday = timeptr->tm_mday; if ( (wday == 1 && (mday >= 29 && mday <= 31)) || (wday == 2 && (mday == 30 || mday == 31)) || (wday == 3 && mday == 31)) weeknum = 1; } return weeknum; } #endif /* weeknumber --- figure how many weeks into the year */ /* With thanks and tip of the hatlo to [email protected] */ #ifndef __STDC__ static int weeknumber(timeptr, firstweekday) const struct tm *timeptr; int firstweekday; #else static int weeknumber(const struct tm *timeptr, int firstweekday) #endif { int wday = timeptr->tm_wday; int ret; if (firstweekday == 1) { if (wday == 0) /* sunday */ wday = 6; else wday--; } ret = ((timeptr->tm_yday + 7 - wday) / 7); if (ret < 0) ret = 0; return ret; } |
Changes to configure.
1 2 3 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. | | > > | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-threads build with threads (not supported)" ac_help="$ac_help --with-tcl directory containing tcl configuration (tclConfig.sh)" ac_help="$ac_help --with-tk directory containing tk configuration (tkConfig.sh)" ac_help="$ac_help --enable-symbols allow use of symbols if available" ac_help="$ac_help --with-tclinclude directory where tcl private headers are" ac_help="$ac_help --enable-shared build libexpect as a shared library" ac_help="$ac_help --with-x whether or not to use X (default yes)" ac_help="$ac_help |
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do |
︙ | ︙ | |||
344 345 346 347 348 349 350 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } |
︙ | ︙ | |||
446 447 448 449 450 451 452 | *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. | < | | > > > | > | 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that |
︙ | ︙ | |||
504 505 506 507 508 509 510 | done ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' | | > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | done ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says [email protected]. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # note when updating version numbers here, also update pkgIndex.in (see # comments in Makefile) EXP_MAJOR_VERSION=5 EXP_MINOR_VERSION=32 EXP_MICRO_VERSION=2 EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION # Too many people send me configure output without identifying the version. # This forced identification should reduce my pain significantly. echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION" # People (when downloading Expect from CVS archive) sometimes run into # Make thinking configure is old and needs to be rebuilt. If they # don't have a clue about autoconf, they get confused. This is # particular irritating because the problem only crops up after # configure has successfully completed. Help them out by checking it # right now and giving some advice. Alas, we cannot summarily fix the # problem because it might conceivably be someone doing real # development. # Test if configure is older than configure.in and explain if no autoconf # Extract the first word of "autoconf", so it can be a program name with args. set dummy autoconf; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:566: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_found'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$found"; then ac_cv_prog_found="$found" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_found="yes" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_found" && ac_cv_prog_found="no" fi fi found="$ac_cv_prog_found" if test -n "$found"; then echo "$ac_t""$found" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking configure up to date""... $ac_c" 1>&6 echo "configure:594: checking configure up to date" >&5 for i in `ls -tr ${srcdir}/configure ${srcdir}/configure.in ${srcdir}/Makefile.in` ; do newest=$i done if test "$srcdir/configure" = "$newest" ; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi if test $found = "no" -a "$newest" != "$srcdir/configure" ; then echo "configure: warning: $srcdir/configure appears to be old ($srcdir/configure.in and/or $srcdir/Makefile.in are newer) and the autoconf program to fix this situation was not found. If you've no idea what this means, enter the command \"touch $srcdir/configure\" and restart $srcdir/configure." 1>&2 exit fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break |
︙ | ︙ | |||
577 578 579 580 581 582 583 | case $host---$target---$nonopt in NONE---*---* | *---NONE---* | *---*---NONE) ;; *) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; esac # Make sure we can run config.sub. | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | case $host---$target---$nonopt in NONE---*---* | *---NONE---* | *---*---NONE) ;; *) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; esac # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:655: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 echo "configure:676: checking target system type" >&5 target_alias=$target case "$target_alias" in NONE) case $nonopt in NONE) target_alias=$host_alias ;; *) target_alias=$nonopt ;; esac ;; esac target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 echo "configure:694: checking build system type" >&5 build_alias=$build case "$build_alias" in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 test "$host_alias" != "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # /bin/sh on some systems is too deficient (in particular, Ultrix 4.3 # sh lacks unset and we *need* that), but all these systems come with # alternatives, so take user's choice or whatever we're using here and # allow it to be seen by Make. echo $ac_n "checking shell to use within Make""... $ac_c" 1>&6 echo "configure:724: checking shell to use within Make" >&5 EXP_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} echo "$ac_t""$CONFIG_SHELL" 1>&6 # If `configure' is invoked (in)directly via `make', ensure that it # encounters no `make' conflicts. # MFLAGS= MAKEFLAGS= # An explanation is in order for the strange things going on with the # various LIBS. There are three separate definitions for LIBS. The # reason is that some systems require shared libraries include # references to their dependent libraries, i.e., any additional # libraries that must be linked to. And some systems get upset if the # references are repeated on the link line. So therefore, we create # one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl |
︙ | ︙ | |||
959 960 961 962 963 964 965 | # are swapping out the one for Expect's shared library, we save it in # EXP_LIBS. Sigh. OLD_CFLAGS=$CFLAGS # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | | | > | | | > | | 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | # are swapping out the one for Expect's shared library, we save it in # EXP_LIBS. Sigh. OLD_CFLAGS=$CFLAGS # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:758: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:788: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" |
︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 | CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < < < < < < < < | < < < < | > < | | | | < < | | > > > > | | | | | | | | | | | | > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < | | < > | | > > | < | > > | | > | | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 | CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:839: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:871: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 882 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:913: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:918: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:927: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:946: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi CFLAGS=$OLD_CFLAGS #------------------------------------------------------------------------ # Hook for when threading is supported in Expect. The --enable-threads # flag currently has no effect. #------------------------------------------------------------------------ echo $ac_n "checking for building with threads""... $ac_c" 1>&6 echo "configure:986: checking for building with threads" >&5 # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=no fi if test "$tcl_ok" = "yes"; then echo "configure: warning: Expect is not fully thread-enabled. Although significant work has been done towards that goal, it is not complete. Continue compiling at your own risk." 1>&2 fi # if test "$tcl_ok" = "yes"; then # AC_MSG_RESULT(yes) # TCL_THREADS=1 # AC_DEFINE(TCL_THREADS) # AC_DEFINE(_REENTRANT) # # AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) # if test "$tcl_ok" = "yes"; then # # The space is needed # THREADS_LIBS=" -lpthread" # else # TCL_THREADS=0 # AC_MSG_WARN("Don t know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...") # fi # else # TCL_THREADS=0 # AC_MSG_RESULT(no (default)) # fi echo "$ac_t""no (default)" 1>&6 # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl or --without-tcl was given. if test "${with_tcl+set}" = set; then withval="$with_tcl" with_tclconfig=${withval} fi echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6 echo "configure:1039: checking for Tcl configuration" >&5 if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; } fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[9].[0-9].[0-9] ../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8].[2-9].[0-9] ../tcl[8].[2-9] 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[9].[0-9].[0-9] ../../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8].[2-9].[0-9] ../../tcl[8].[2-9] 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[9].[0-9].[0-9] ../../../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8].[2-9].[0-9] ../../../tcl[8].[2-9] 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[9].[0-9].[0-9] ${srcdir}/../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8].[2-9].[0-9] ${srcdir}/../tcl[8].[2-9] 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCLCONFIG="# no Tcl configs found" echo "configure: warning: Can't find Tcl configuration definitions" 1>&2 else no_tcl= TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh echo "$ac_t""found $TCLCONFIG" 1>&6 fi fi . $TCLCONFIG # Tcl defines TCL_SHLIB_SUFFIX but TCL_SHARED_LIB_SUFFIX then looks for it # as just SHLIB_SUFFIX. How bizarre. SHLIB_SUFFIX=$TCL_SHLIB_SUFFIX # if Tcl's build directory has been removed, TCL_LIB_SPEC should # be used instead of TCL_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TCL_DBGX eval "LIBS=\"$TCL_BUILD_LIB_SPEC $TCL_LIBS\"" echo $ac_n "checking Tcl build library""... $ac_c" 1>&6 echo "configure:1132: checking Tcl build library" >&5 echo "$ac_t""$LIBS" 1>&6 echo $ac_n "checking for Tcl_CreateCommand""... $ac_c" 1>&6 echo "configure:1136: checking for Tcl_CreateCommand" >&5 if eval "test \"`echo '$''{'ac_cv_func_Tcl_CreateCommand'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1141 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char Tcl_CreateCommand(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tcl_CreateCommand(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_Tcl_CreateCommand) || defined (__stub___Tcl_CreateCommand) choke me #else Tcl_CreateCommand(); #endif ; return 0; } EOF if { (eval echo configure:1164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_Tcl_CreateCommand=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_Tcl_CreateCommand=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'Tcl_CreateCommand`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking if Tcl library build specification is valid""... $ac_c" 1>&6 echo "configure:1180: checking if Tcl library build specification is valid" >&5 echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 TCL_BUILD_LIB_SPEC=$TCL_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. echo $ac_n "checking if Tcl library build specification is valid""... $ac_c" 1>&6 echo "configure:1190: checking if Tcl library build specification is valid" >&5 echo "$ac_t""no" 1>&6 fi LIBS=$SAVELIBS CC=$TCL_CC EXP_AND_TCL_LIBS=$TCL_LIBS # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk or --without-tk was given. if test "${with_tk+set}" = set; then withval="$with_tk" with_tkconfig=${withval} fi echo $ac_n "checking for Tk configuration""... $ac_c" 1>&6 echo "configure:1222: checking for Tk configuration" >&5 if eval "test \"`echo '$''{'ac_cv_c_tkconfig'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # First check to see if --with-tk was specified. if test x"${with_tkconfig}" != x ; then if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { echo "configure: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" 1>&2; exit 1; } fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[4-9].[0-9].[0-9] ../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[4-9].[0-9].[0-9] ../tk[4-9].[0-9] 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[4-9].[0-9].[0-9] ../../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[4-9].[0-9].[0-9] ../../tk[4-9].[0-9] 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[4-9].[0-9].[0-9] ../../../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[4-9].[0-9].[0-9] ../../../tk[4-9].[0-9] 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[4-9].[0-9].[0-9] ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[4-9].[0-9].[0-9] ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TKCONFIG="# no Tk configs found" echo "configure: warning: Can't find Tk configuration definitions" 1>&2 else no_tk= TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh echo "$ac_t""found $TKCONFIG" 1>&6 fi fi if test -f "$TKCONFIG" ; then . $TKCONFIG fi # if Tk's build directory has been removed, TK_LIB_SPEC should # be used instead of TK_BUILD_LIB_SPEC SAVELIBS=$LIBS # eval used to expand out TK_DBGX eval "LIBS=\"$TK_BUILD_LIB_SPEC $TCL_BUILD_LIB_SPEC $TK_LIBS\"" echo $ac_n "checking for Tk_Init""... $ac_c" 1>&6 echo "configure:1311: checking for Tk_Init" >&5 if eval "test \"`echo '$''{'ac_cv_func_Tk_Init'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1316 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char Tk_Init(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char Tk_Init(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_Tk_Init) || defined (__stub___Tk_Init) choke me #else Tk_Init(); #endif ; return 0; } EOF if { (eval echo configure:1339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_Tk_Init=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_Tk_Init=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'Tk_Init`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking if Tk library build specification is valid""... $ac_c" 1>&6 echo "configure:1355: checking if Tk library build specification is valid" >&5 echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 TK_BUILD_LIB_SPEC=$TK_LIB_SPEC # Can't pull the following CHECKING call out since it will be # broken up by the CHECK_FUNC just above. echo $ac_n "checking if Tk library build specification is valid""... $ac_c" 1>&6 echo "configure:1365: checking if Tk library build specification is valid" >&5 echo "$ac_t""no" 1>&6 fi LIBS=$SAVELIBS EXP_AND_TK_LIBS=$TK_LIBS # If we cannot compile and link a trivial program, we can't expect anything to work echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6 echo "configure:1380: checking whether the compiler ($CC) actually works" >&5 cat > conftest.$ac_ext <<EOF #line 1382 "configure" #include "confdefs.h" int main() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:1389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* c_compiles=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* c_compiles=no fi rm -f conftest* cat > conftest.$ac_ext <<EOF #line 1401 "configure" #include "confdefs.h" int main() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:1408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* c_links=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* c_links=no fi rm -f conftest* if test x"${c_compiles}" = x"no" ; then { echo "configure: error: the native compiler is broken and won't compile." 1>&2; exit 1; } fi if test x"${c_links}" = x"no" ; then { echo "configure: error: the native compiler is broken and won't link." 1>&2; exit 1; } fi echo "$ac_t""yes" 1>&6 # this'll use a BSD compatible install or our included install-sh # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1442: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1499: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | # This is for LynxOS, which needs a flag to force true POSIX when # building. The flag varies depending how old the compiler is. # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 | | | | | | > > > > > > > > > > > > > > > > > | | > > | | | 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 | # This is for LynxOS, which needs a flag to force true POSIX when # building. The flag varies depending how old the compiler is. # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1539: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF #line 1554 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1560: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF #line 1571 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1577: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext <<EOF #line 1588 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1594: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6 echo "configure:1620: checking if running LynxOS" >&5 if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1625 "configure" #include "confdefs.h" /* * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__" */ #if defined(__Lynx__) || defined(Lynx) yes #endif |
︙ | ︙ | |||
1378 1379 1380 1381 1382 1383 1384 | if test "$ac_cv_os_lynx" = "yes" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define LYNX 1 EOF echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6 | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | | 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | if test "$ac_cv_os_lynx" = "yes" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define LYNX 1 EOF echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6 echo "configure:1655: checking whether -mposix or -X is available" >&5 if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1660 "configure" #include "confdefs.h" int main() { /* * This flag varies depending on how old the compiler is. * -X is for the old "cc" and "gcc" (based on 1.42). * -mposix is for the new gcc (at least 2.5.8). */ #if defined(__GNUC__) && __GNUC__ >= 2 choke me #endif ; return 0; } EOF if { (eval echo configure:1676: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_posix_flag=" -mposix" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_posix_flag=" -X" fi rm -f conftest* fi CC="$CC $ac_cv_c_posix_flag" echo "$ac_t""$ac_cv_c_posix_flag" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1696: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1701 "configure" #include "confdefs.h" #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1709: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext <<EOF #line 1726 "configure" #include "confdefs.h" #include <string.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext <<EOF #line 1744 "configure" #include "confdefs.h" #include <stdlib.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF #line 1765 "configure" #include "confdefs.h" #include <ctype.h> #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1776: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi |
︙ | ︙ | |||
1555 1556 1557 1558 1559 1560 1561 | cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 | | | | | | | < | | | < | | | < > > > > > > > > > | > > > > > | | | | | | | 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 | cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo "configure:1800: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1805 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS #include <stdlib.h> #include <stddef.h> #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else rm -rf conftest* ac_cv_type_pid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_pid_t" 1>&6 if test $ac_cv_type_pid_t = no; then cat >> confdefs.h <<\EOF #define pid_t int EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:1833: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1838 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:1855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <<EOF #define RETSIGTYPE $ac_cv_type_signal EOF echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1874: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1879 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/time.h> #include <time.h> int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1888: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 echo "configure:1909: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1914 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/wait.h> #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main() { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF if { (eval echo configure:1930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_sys_wait_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 if test $ac_cv_header_sys_wait_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_SYS_WAIT_H 1 EOF fi # Check whether --enable-symbols or --disable-symbols was given. if test "${enable_symbols+set}" = set; then enableval="$enable_symbols" enable_symbols=$enableval else enable_symbols=no fi if test "$enable_symbols" = "no"; then EXP_CFLAGS="$TCL_EXTRA_CFLAGS" else EXP_CFLAGS="-g $TCL_EXTRA_CFLAGS" # This is always "g" for unix. DBGX=g fi case "${host}" in # Use -g on all systems but Linux where it upsets the dynamic X libraries. i[3456]86-*-linux*) EXP_CFLAGS="" ;; esac echo $ac_n "checking if running Mach""... $ac_c" 1>&6 echo "configure:1972: checking if running Mach" >&5 mach=0 case "${host}" in # Both Next and pure Mach behave identically with respect # to a few things, so just lump them together as "mach" *-*-mach*) mach=1 ;; *-*-next*) mach=1 ; next=1 ;; esac if test $mach -eq 1 ; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if running MachTen""... $ac_c" 1>&6 echo "configure:1988: checking if running MachTen" >&5 # yet another Mach clone if test -r /MachTen ; then echo "$ac_t""yes" 1>&6 mach=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if on Pyramid""... $ac_c" 1>&6 echo "configure:1998: checking if on Pyramid" >&5 if test -r /bin/pyr ; then echo "$ac_t""yes" 1>&6 pyr=1 else echo "$ac_t""no" 1>&6 pyr=0 fi echo $ac_n "checking if on Apollo""... $ac_c" 1>&6 echo "configure:2008: checking if on Apollo" >&5 if test -r /usr/apollo/bin ; then echo "$ac_t""yes" 1>&6 apollo=1 else echo "$ac_t""no" 1>&6 apollo=0 fi echo $ac_n "checking if on Interactive""... $ac_c" 1>&6 echo "configure:2018: checking if on Interactive" >&5 if test "x`(uname -s) 2>/dev/null`" = xIUNIX; then echo "$ac_t""yes" 1>&6 iunix=1 else echo "$ac_t""no" 1>&6 iunix=0 fi echo $ac_n "checking if stty reads stdout""... $ac_c" 1>&6 echo "configure:2028: checking if stty reads stdout" >&5 # On some systems stty can't be run in the background (svr4) or get it # wrong because they fail to complain (next, mach), so don't attempt # the test on some systems. stty_reads_stdout="" case "${host}" in |
︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 | else echo "$ac_t""no" 1>&6 fi # Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts # of traditional but nonstandard stuff in header files. echo $ac_n "checking if running Solaris""... $ac_c" 1>&6 | | | | | 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 | else echo "$ac_t""no" 1>&6 fi # Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts # of traditional but nonstandard stuff in header files. echo $ac_n "checking if running Solaris""... $ac_c" 1>&6 echo "configure:2084: checking if running Solaris" >&5 solaris=0 case "${host}" in *-*-solaris*) solaris=1;; esac if test $solaris -eq 1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define SOLARIS 1 EOF else echo "$ac_t""no" 1>&6 fi # On a few systems, libm.a is the same as libc.a # Don't bother to test against Tcl and Tk libs, they always include -lm echo $ac_n "checking for sin""... $ac_c" 1>&6 echo "configure:2104: checking for sin" >&5 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2109 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
1876 1877 1878 1879 1880 1881 1882 | choke me #else sin(); #endif ; return 0; } EOF | | < > | | | 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 | choke me #else sin(); #endif ; return 0; } EOF if { (eval echo configure:2132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sin=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 LIBS="${LIBS} -lm" fi # On Interactive UNIX, -Xp must be added to LIBS in order to find strftime. # This test should really be done by Tcl. So just check Tcl's definition. # If defective, add to all three LIBS. (It's not actually necessary for # EXP_LIBS since -Xp will just be ignored the way that EXP_LIBS is used in # the Makefile, but we include it for consistency.) if test $iunix -eq 1 ; then EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS echo $ac_n "checking for strftime""... $ac_c" 1>&6 echo "configure:2162: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2167 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strftime(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
1934 1935 1936 1937 1938 1939 1940 | choke me #else strftime(); #endif ; return 0; } EOF | | < > | 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 | choke me #else strftime(); #endif ; return 0; } EOF if { (eval echo configure:2190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strftime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_LIBS="${LIBS} -Xp" |
︙ | ︙ | |||
1974 1975 1976 1977 1978 1979 1980 | # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6 | | | 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 | # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6 echo "configure:2230: checking for Tcl private headers" >&5 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then |
︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ | | > | > | > | > | > | | | | | 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[9].[0-9].[0-9] ${srcdir}/../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8].[2-9].[0-9] ${srcdir}/../tcl[8].[2-9] 2>/dev/null` \ ${srcdir}/../../tcl \ `ls -dr ${srcdir}/../../tcl[9].[0-9].[0-9] ${srcdir}/../../tcl[9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../../tcl[8].[2-9].[0-9] ${srcdir}/../../tcl[8].[2-9] 2>/dev/null` \ ${srcdir}/../../../tcl \ `ls -dr ${srcdir}/../../../tcl[9].[0-9].[0-9] ${srcdir}/../../../tcl[9].[0-9] 2>/dev/null ` \ `ls -dr ${srcdir}/../../../tcl[8].[2-9].[0-9] ${srcdir}/../../../tcl[8].[2-9] 2>/dev/null ` ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ `ls -dr /usr/local/src/tcl[9].[0-9].[0-9] /usr/local/src/tcl[9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/src/tcl[8].[2-9].[0-9] /usr/local/src/tcl[8].[2-9] 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[9].[0-9].[0-9] /usr/local/lib/tcl[9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[8].[2-9].[0-9] /usr/local/lib/tcl[8].[2-9] 2>/dev/null` \ /usr/local/src/tcl \ /usr/local/lib/tcl \ ${prefix}/include ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tclh}" = x ; then ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6 echo "configure:2301: checking for tclInt.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2306 "configure" #include "confdefs.h" #include <tclInt.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2311: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
2111 2112 2113 2114 2115 2116 2117 | echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # have to know whether we're generating shared libs before configuring debugger echo $ac_n "checking type of library to build""... $ac_c" 1>&6 | | | 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 | echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # have to know whether we're generating shared libs before configuring debugger echo $ac_n "checking type of library to build""... $ac_c" 1>&6 echo "configure:2372: checking type of library to build" >&5 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" enable_shared=$enableval else enable_shared=no fi |
︙ | ︙ | |||
2190 2191 2192 2193 2194 2195 2196 | echo "up to three times. First test is for building Expect's shared library." echo "Second set is for building with Tcl. Third is for building with Tk." ###################################################################### # required by Sequent ptx2 unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 | | | | 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 | echo "up to three times. First test is for building Expect's shared library." echo "Second set is for building with Tcl. Third is for building with Tk." ###################################################################### # required by Sequent ptx2 unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2451: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2456 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2218 2219 2220 2221 2222 2223 2224 | choke me #else gethostname(); #endif ; return 0; } EOF | | < > | | | | 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2502: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2510 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2521: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2286 2287 2288 2289 2290 2291 2292 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 | | | | 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2547: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2552 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2314 2315 2316 2317 2318 2319 2320 | choke me #else gethostname(); #endif ; return 0; } EOF | | < > | | | | 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 | choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2598: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2606 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2382 2383 2384 2385 2386 2387 2388 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 | | | | 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2643: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2648 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 | choke me #else gethostname(); #endif ; return 0; } EOF | | < > | | | | 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 | choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2694: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2702 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2713: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2481 2482 2483 2484 2485 2486 2487 | EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # required by Fischman's ISC 4.0 unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 | | | | 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 | EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # required by Fischman's ISC 4.0 unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2742: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2747 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2509 2510 2511 2512 2513 2514 2515 | choke me #else socket(); #endif ; return 0; } EOF | | < > | | | | 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 | choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2793: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2801 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:2812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2577 2578 2579 2580 2581 2582 2583 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 | | | | 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2838: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2843 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2605 2606 2607 2608 2609 2610 2611 | choke me #else socket(); #endif ; return 0; } EOF | | < > | | | | 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 | choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2889: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2897 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2673 2674 2675 2676 2677 2678 2679 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 | | | | 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2934: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2939 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2701 2702 2703 2704 2705 2706 2707 | choke me #else socket(); #endif ; return 0; } EOF | | < > | | | | 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 | choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2985: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2993 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:3004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2771 2772 2773 2774 2775 2776 2777 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 | | | | 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:3032: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3037 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2799 2800 2801 2802 2803 2804 2805 | choke me #else select(); #endif ; return 0; } EOF | | < > | | | | 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 | choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:3060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:3083: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 3091 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:3102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2867 2868 2869 2870 2871 2872 2873 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 | | | | 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:3128: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3133 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2895 2896 2897 2898 2899 2900 2901 | choke me #else select(); #endif ; return 0; } EOF | | < > | | | | 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 | choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:3156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:3179: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 3187 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:3198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
2963 2964 2965 2966 2967 2968 2969 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 | | | | 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:3224: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3229 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
2991 2992 2993 2994 2995 2996 2997 | choke me #else select(); #endif ; return 0; } EOF | | < > | | | | 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 | choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:3252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:3275: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 3283 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:3294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3061 3062 3063 3064 3065 3066 3067 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 | | | | 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:3322: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3327 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3089 3090 3091 3092 3093 3094 3095 | choke me #else getpseudotty(); #endif ; return 0; } EOF | | < > | | | | 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 | choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:3350: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:3373: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3381 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3164 3165 3166 3167 3168 3169 3170 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 | | | | 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:3425: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3430 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3192 3193 3194 3195 3196 3197 3198 | choke me #else getpseudotty(); #endif ; return 0; } EOF | | < > | | | | 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 | choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:3453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:3476: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3484 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3267 3268 3269 3270 3271 3272 3273 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 | | | | 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:3528: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3533 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3295 3296 3297 3298 3299 3300 3301 | choke me #else getpseudotty(); #endif ; return 0; } EOF | | < > | | | | 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 | choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:3556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:3579: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3587 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3373 3374 3375 3376 3377 3378 3379 | EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # Check for FreeBSD/NetBSD openpty() unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 | | | | 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 | EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # Check for FreeBSD/NetBSD openpty() unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3634: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3639 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3401 3402 3403 3404 3405 3406 3407 | choke me #else openpty(); #endif ; return 0; } EOF | | < > | | | | 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 | choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3685: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3693 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3478 3479 3480 3481 3482 3483 3484 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 | | | | 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 | fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3739: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3744 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3506 3507 3508 3509 3510 3511 3512 | choke me #else openpty(); #endif ; return 0; } EOF | | < > | | | | 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 | choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3790: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3798 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3580 3581 3582 3583 3584 3585 3586 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 | | | | 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 | fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3841: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3846 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
3608 3609 3610 3611 3612 3613 3614 | choke me #else openpty(); #endif ; return 0; } EOF | | < > | | | | 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 | choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3892: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3900 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" |
︙ | ︙ | |||
3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # End of library/func checking ###################################################################### ###################################################################### # # Look for various header files # ac_safe=`echo "sys/sysmacros.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/sysmacros.h""... $ac_c" 1>&6 | > > > > > > > > > > > | | | | | 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # End of library/func checking ###################################################################### # Hand patches to library/func checking. echo $ac_n "checking if running Sequent running SVR4""... $ac_c" 1>&6 echo "configure:3949: checking if running Sequent running SVR4" >&5 if test "$host_alias" = "i386-sequent-sysv4" ; then EXP_AND_TCL_LIBS="-lnsl -lsocket -lm" echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi ###################################################################### # # Look for various header files # ac_safe=`echo "sys/sysmacros.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/sysmacros.h""... $ac_c" 1>&6 echo "configure:3963: checking for sys/sysmacros.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3968 "configure" #include "confdefs.h" #include <sys/sysmacros.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3973: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3727 3728 3729 3730 3731 3732 3733 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6 | | | | | | 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6 echo "configure:3999: checking for stdlib.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4004 "configure" #include "confdefs.h" #include <stdlib.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4009: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3764 3765 3766 3767 3768 3769 3770 | #define NO_STDLIB_H 1 EOF fi ac_safe=`echo "inttypes.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6 | | | | | | 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 | #define NO_STDLIB_H 1 EOF fi ac_safe=`echo "inttypes.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6 echo "configure:4036: checking for inttypes.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4041 "configure" #include "confdefs.h" #include <inttypes.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4046: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3804 3805 3806 3807 3808 3809 3810 | # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! ac_safe=`echo "varargs.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for varargs.h""... $ac_c" 1>&6 | | | | | | 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 | # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! ac_safe=`echo "varargs.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for varargs.h""... $ac_c" 1>&6 echo "configure:4076: checking for varargs.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4081 "configure" #include "confdefs.h" #include <varargs.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4086: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3840 3841 3842 3843 3844 3845 3846 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "unistd.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for unistd.h""... $ac_c" 1>&6 | | | | | | 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "unistd.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for unistd.h""... $ac_c" 1>&6 echo "configure:4112: checking for unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4117 "configure" #include "confdefs.h" #include <unistd.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4122: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3874 3875 3876 3877 3878 3879 3880 3881 3882 | #define HAVE_UNISTD_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/stropts.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/stropts.h""... $ac_c" 1>&6 | > > | | | | > | | | | | 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 | #define HAVE_UNISTD_H 1 EOF else echo "$ac_t""no" 1>&6 fi # If no stropts.h, then the svr4 implementation is broken. # At least it is on my Debian "potato" system. - Rob Savoye ac_safe=`echo "sys/stropts.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/stropts.h""... $ac_c" 1>&6 echo "configure:4150: checking for sys/stropts.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4155 "configure" #include "confdefs.h" #include <sys/stropts.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4160: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STROPTS_H 1 EOF else echo "$ac_t""no" 1>&6 svr4_ptys_broken=1 fi ac_safe=`echo "sys/sysconfig.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/sysconfig.h""... $ac_c" 1>&6 echo "configure:4187: checking for sys/sysconfig.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4192 "configure" #include "confdefs.h" #include <sys/sysconfig.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3948 3949 3950 3951 3952 3953 3954 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/fcntl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/fcntl.h""... $ac_c" 1>&6 | | | | | | 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/fcntl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/fcntl.h""... $ac_c" 1>&6 echo "configure:4223: checking for sys/fcntl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4228 "configure" #include "confdefs.h" #include <sys/fcntl.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4233: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
3984 3985 3986 3987 3988 3989 3990 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/select.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/select.h""... $ac_c" 1>&6 | | | | | | 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/select.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/select.h""... $ac_c" 1>&6 echo "configure:4259: checking for sys/select.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4264 "configure" #include "confdefs.h" #include <sys/select.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4269: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4020 4021 4022 4023 4024 4025 4026 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/time.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/time.h""... $ac_c" 1>&6 | | | | | | 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/time.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/time.h""... $ac_c" 1>&6 echo "configure:4295: checking for sys/time.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4300 "configure" #include "confdefs.h" #include <sys/time.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4305: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4056 4057 4058 4059 4060 4061 4062 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/ptem.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/ptem.h""... $ac_c" 1>&6 | | | | | | 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/ptem.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/ptem.h""... $ac_c" 1>&6 echo "configure:4331: checking for sys/ptem.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4336 "configure" #include "confdefs.h" #include <sys/ptem.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4341: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4092 4093 4094 4095 4096 4097 4098 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strredir.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strredir.h""... $ac_c" 1>&6 | | | | | | 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strredir.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strredir.h""... $ac_c" 1>&6 echo "configure:4367: checking for sys/strredir.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4372 "configure" #include "confdefs.h" #include <sys/strredir.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4377: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4128 4129 4130 4131 4132 4133 4134 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strpty.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strpty.h""... $ac_c" 1>&6 | | | | | | 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 | else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strpty.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strpty.h""... $ac_c" 1>&6 echo "configure:4403: checking for sys/strpty.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4408 "configure" #include "confdefs.h" #include <sys/strpty.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4413: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4165 4166 4167 4168 4169 4170 4171 | else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sys/bsdtypes.h""... $ac_c" 1>&6 | | | | | | | 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 | else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sys/bsdtypes.h""... $ac_c" 1>&6 echo "configure:4440: checking for sys/bsdtypes.h" >&5 if test "ISC_${ISC}" = "ISC_1" ; then echo "$ac_t""yes" 1>&6 # if on ISC 1, we need <sys/bsdtypes.h> to get FD_SET macros for ac_hdr in sys/bsdtypes.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:4448: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4453 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4458: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
4217 4218 4219 4220 4221 4222 4223 | echo "$ac_t""no" 1>&6 fi # # Look for functions that may be missing # echo $ac_n "checking for memmove""... $ac_c" 1>&6 | | | | 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 | echo "$ac_t""no" 1>&6 fi # # Look for functions that may be missing # echo $ac_n "checking for memmove""... $ac_c" 1>&6 echo "configure:4492: checking for memmove" >&5 if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4497 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char memmove(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4245 4246 4247 4248 4249 4250 4251 | choke me #else memmove(); #endif ; return 0; } EOF | | < > | | | 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 | choke me #else memmove(); #endif ; return 0; } EOF if { (eval echo configure:4520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_memmove=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_memmove=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_MEMMOVE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sysconf""... $ac_c" 1>&6 echo "configure:4543: checking for sysconf" >&5 if eval "test \"`echo '$''{'ac_cv_func_sysconf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4548 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sysconf(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4296 4297 4298 4299 4300 4301 4302 | choke me #else sysconf(); #endif ; return 0; } EOF | | < > | | | 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 | choke me #else sysconf(); #endif ; return 0; } EOF if { (eval echo configure:4571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sysconf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sysconf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sysconf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSCONF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strftime""... $ac_c" 1>&6 echo "configure:4594: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4599 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strftime(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4347 4348 4349 4350 4351 4352 4353 | choke me #else strftime(); #endif ; return 0; } EOF | | < > | | | 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 | choke me #else strftime(); #endif ; return 0; } EOF if { (eval echo configure:4622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strftime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRFTIME 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strchr""... $ac_c" 1>&6 echo "configure:4645: checking for strchr" >&5 if eval "test \"`echo '$''{'ac_cv_func_strchr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4650 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strchr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4398 4399 4400 4401 4402 4403 4404 | choke me #else strchr(); #endif ; return 0; } EOF | | < > | | | 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 | choke me #else strchr(); #endif ; return 0; } EOF if { (eval echo configure:4673: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_strchr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strchr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strchr`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRCHR 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for timezone""... $ac_c" 1>&6 echo "configure:4696: checking for timezone" >&5 if eval "test \"`echo '$''{'ac_cv_func_timezone'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4701 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char timezone(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4449 4450 4451 4452 4453 4454 4455 | choke me #else timezone(); #endif ; return 0; } EOF | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | < | | | | | | | | | 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 | choke me #else timezone(); #endif ; return 0; } EOF if { (eval echo configure:4724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_timezone=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_timezone=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'timezone`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_TIMEZONE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for siglongjmp""... $ac_c" 1>&6 echo "configure:4747: checking for siglongjmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_siglongjmp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4752 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char siglongjmp(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char siglongjmp(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_siglongjmp) || defined (__stub___siglongjmp) choke me #else siglongjmp(); #endif ; return 0; } EOF if { (eval echo configure:4775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_siglongjmp=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_siglongjmp=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'siglongjmp`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SIGLONGJMP 1 EOF else echo "$ac_t""no" 1>&6 fi # dnl check for memcpy by hand # because Unixware 2.0 handles it specially and refuses to compile # autoconf's automatic test that is a call with no arguments echo $ac_n "checking for memcpy""... $ac_c" 1>&6 echo "configure:4802: checking for memcpy" >&5 cat > conftest.$ac_ext <<EOF #line 4804 "configure" #include "confdefs.h" int main() { char *s1, *s2; memcpy(s1,s2,0); ; return 0; } EOF if { (eval echo configure:4814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_MEMCPY 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* # Some systems only define WNOHANG if _POSIX_SOURCE is defined # The following merely tests that sys/wait.h can be included # and if so that WNOHANG is not defined. The only place I've # seen this is ISC. echo $ac_n "checking if WNOHANG requires _POSIX_SOURCE""... $ac_c" 1>&6 echo "configure:4836: checking if WNOHANG requires _POSIX_SOURCE" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 4842 "configure" #include "confdefs.h" #include <sys/wait.h> main() { #ifndef WNOHANG return 0; #else return 1; #endif } EOF if { (eval echo configure:4854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define WNOHANG_REQUIRES_POSIX_SOURCE 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking if any value exists for WNOHANG""... $ac_c" 1>&6 echo "configure:4874: checking if any value exists for WNOHANG" >&5 rm -rf wnohang if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 4881 "configure" #include "confdefs.h" #include <stdio.h> #include <sys/wait.h> main() { #ifdef WNOHANG FILE *fp = fopen("wnohang","w"); fprintf(fp,"%d",WNOHANG); fclose(fp); return 0; #else return 1; #endif } EOF if { (eval echo configure:4897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<EOF #define WNOHANG_BACKUP_VALUE `cat wnohang` EOF rm -f wnohang |
︙ | ︙ | |||
4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 | EOF fi rm -fr conftest* fi # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then # proceeds to ignore it and use int. # Pattern matching on int could be loosened. # Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp. echo $ac_n "checking mask type of select""... $ac_c" 1>&6 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 | EOF fi rm -fr conftest* fi #-----Stolen from Tcl's configure file------------------------------- # The check below checks whether <sys/wait.h> defines the type # "union wait" correctly. It's needed because of weirdness in # HP-UX where "union wait" is defined in both the BSD and SYS-V # environments. Checking the usability of WIFEXITED seems to do # the trick. #-------------------------------------------------------------------- echo $ac_n "checking union wait""... $ac_c" 1>&6 echo "configure:4930: checking union wait" >&5 cat > conftest.$ac_ext <<EOF #line 4932 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/wait.h> int main() { union wait x; WIFEXITED(x); /* Generates compiler error if WIFEXITED * uses an int. */ ; return 0; } EOF if { (eval echo configure:4944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* tcl_ok=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* tcl_ok=no fi rm -f conftest* echo "$ac_t""$tcl_ok" 1>&6 if test $tcl_ok = no; then cat >> confdefs.h <<\EOF #define NO_UNION_WAIT 1 EOF fi # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then # proceeds to ignore it and use int. # Pattern matching on int could be loosened. # Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp. echo $ac_n "checking mask type of select""... $ac_c" 1>&6 echo "configure:4974: checking mask type of select" >&5 if egrep "select\(size_t, int" /usr/include/sys/time.h >/dev/null 2>&1; then echo "$ac_t""int" 1>&6 cat >> confdefs.h <<\EOF #define SELECT_MASK_TYPE int EOF else echo "$ac_t""none" 1>&6 fi # FIXME: check if alarm exists echo $ac_n "checking if signals need to be re-armed""... $ac_c" 1>&6 echo "configure:4988: checking if signals need to be re-armed" >&5 if test "$cross_compiling" = yes; then echo "configure: warning: Expect can't be cross compiled" 1>&2 else cat > conftest.$ac_ext <<EOF #line 4994 "configure" #include "confdefs.h" #include <signal.h> #define RETSIGTYPE $retsigtype int signal_rearms = 0; |
︙ | ︙ | |||
4665 4666 4667 4668 4669 4670 4671 | wait(&status); unlink("core"); exit(signal_rearms); } } EOF | | | | 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 | wait(&status); unlink("core"); exit(signal_rearms); } } EOF if { (eval echo configure:5033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define REARM_SIG 1 EOF else |
︙ | ︙ | |||
4696 4697 4698 4699 4700 4701 4702 | # # There are multiple versions of getpty, alas. # I don't remember who has the first one, but Convex just added one # so check for it. Unfortunately, there is no header so the only # reasonable way to make sure is to look it we are on a Convex. echo $ac_n "checking if on Convex""... $ac_c" 1>&6 | | | | | | | | | | 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 | # # There are multiple versions of getpty, alas. # I don't remember who has the first one, but Convex just added one # so check for it. Unfortunately, there is no header so the only # reasonable way to make sure is to look it we are on a Convex. echo $ac_n "checking if on Convex""... $ac_c" 1>&6 echo "configure:5064: checking if on Convex" >&5 convex=0 case "${host}" in c[12]-*-*) convex=1;; esac if test $convex -eq 1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define CONVEX 1 EOF else echo "$ac_t""no" 1>&6 fi EXP_LDFLAGS="$LDFLAGS" echo $ac_n "checking if on NeXT""... $ac_c" 1>&6 echo "configure:5083: checking if on NeXT" >&5 if test -r /NextApps ; then echo "$ac_t""yes" 1>&6 # "-m" flag suppresses complaints about multiple strtod EXP_LDFLAGS="$EXP_LDFLAGS -m" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if on HP""... $ac_c" 1>&6 echo "configure:5094: checking if on HP" >&5 if test "x`(uname) 2>/dev/null`" = xHP-UX; then echo "$ac_t""yes" 1>&6 hp=1 else echo "$ac_t""no" 1>&6 hp=0 fi echo $ac_n "checking sane default stty arguments""... $ac_c" 1>&6 echo "configure:5104: checking sane default stty arguments" >&5 DEFAULT_STTY_ARGS="sane" if test $mach -eq 1 ; then DEFAULT_STTY_ARGS="cooked" fi if test $hp -eq 1 ; then DEFAULT_STTY_ARGS="sane kill " fi echo "$ac_t""$DEFAULT_STTY_ARG" 1>&6 # Look for various features to determine what kind of pty # we have. For some weird reason, ac_compile_check would not # work, but ac_test_program does. # echo $ac_n "checking for HP style pty allocation""... $ac_c" 1>&6 echo "configure:5122: checking for HP style pty allocation" >&5 # following test fails on DECstations and other things that don't grok -c # but that's ok, since they don't have PTYMs anyway if test -r /dev/ptym/ptyp0 2>/dev/null ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTYM 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for HP style pty trapping""... $ac_c" 1>&6 echo "configure:5136: checking for HP style pty trapping" >&5 cat > conftest.$ac_ext <<EOF #line 5138 "configure" #include "confdefs.h" #include <sys/ptyio.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct.*request_info" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 |
︙ | ︙ | |||
4792 4793 4794 4795 4796 4797 4798 | echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for AIX new-style pty allocation""... $ac_c" 1>&6 | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 | echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for AIX new-style pty allocation""... $ac_c" 1>&6 echo "configure:5160: checking for AIX new-style pty allocation" >&5 if test -r /dev/ptc -a -r /dev/pts ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTC_PTS 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for SGI old-style pty allocation""... $ac_c" 1>&6 echo "configure:5172: checking for SGI old-style pty allocation" >&5 if test -r /dev/ptc -a ! -r /dev/pts ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTC 1 EOF else echo "$ac_t""no" 1>&6 fi # On SCO OpenServer, two types of ptys are available: SVR4 streams and c-list. # The library routines to open the SVR4 ptys are broken on certain systems and # the SCO command to increase the number of ptys only configure c-list ones # anyway. So we chose these, which have a special numbering scheme. # echo $ac_n "checking for SCO style pty allocation""... $ac_c" 1>&6 echo "configure:5189: checking for SCO style pty allocation" >&5 sco_ptys="" case "${host}" in *-sco3.2v[45]*) sco_clist_ptys=1 svr4_ptys_broken=1;; esac if test x"${sco_clist_ptys}" != x"" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SCO_CLIST_PTYS 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for SVR4 style pty allocation""... $ac_c" 1>&6 echo "configure:5206: checking for SVR4 style pty allocation" >&5 if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTMX 1 EOF # aargg. Some systems need libpt.a to use /dev/ptmx echo $ac_n "checking for libpts="-lpt" in -lpt""... $ac_c" 1>&6 echo "configure:5215: checking for libpts="-lpt" in -lpt" >&5 ac_lib_var=`echo pt'_'libpts="-lpt" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lpt $LIBS" cat > conftest.$ac_ext <<EOF #line 5223 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char libpts="-lpt"(); int main() { libpts="-lpt"() ; return 0; } EOF if { (eval echo configure:5234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 libpts="" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:5255: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5260 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char ptsname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_ptsname) || defined (__stub___ptsname) choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:5283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 LIBS="${LIBS} $libpts" fi # I've never seen Tcl or Tk include -lpt so don't bother with explicit test echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:5305: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5310 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4875 4876 4877 4878 4879 4880 4881 | choke me #else ptsname(); #endif ; return 0; } EOF | | < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 | choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:5333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} $libpts" fi echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:5354: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5359 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
4974 4975 4976 4977 4978 4979 4980 | choke me #else ptsname(); #endif ; return 0; } EOF | | < > | | | | | 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 | choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:5382: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} $libpts" fi else echo "$ac_t""no" 1>&6 fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp <[email protected]> 17Aug93 echo $ac_n "checking for OSF/1 style pty allocation""... $ac_c" 1>&6 echo "configure:5409: checking for OSF/1 style pty allocation" >&5 if test -r /dev/ptmx_bsd ; then cat >> confdefs.h <<\EOF #define HAVE_PTMX_BSD 1 EOF echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi tcgetattr=0 tcsetattr=0 echo $ac_n "checking for tcgetattr""... $ac_c" 1>&6 echo "configure:5423: checking for tcgetattr" >&5 if eval "test \"`echo '$''{'ac_cv_func_tcgetattr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5428 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char tcgetattr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5043 5044 5045 5046 5047 5048 5049 | choke me #else tcgetattr(); #endif ; return 0; } EOF | | < > | | | 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 | choke me #else tcgetattr(); #endif ; return 0; } EOF if { (eval echo configure:5451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_tcgetattr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tcgetattr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tcgetattr`\" = yes"; then echo "$ac_t""yes" 1>&6 tcgetattr=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for tcsetattr""... $ac_c" 1>&6 echo "configure:5471: checking for tcsetattr" >&5 if eval "test \"`echo '$''{'ac_cv_func_tcsetattr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5476 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char tcsetattr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5091 5092 5093 5094 5095 5096 5097 | choke me #else tcsetattr(); #endif ; return 0; } EOF | | < > | | | | | 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 | choke me #else tcsetattr(); #endif ; return 0; } EOF if { (eval echo configure:5499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_tcsetattr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tcsetattr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tcsetattr`\" = yes"; then echo "$ac_t""yes" 1>&6 tcsetattr=1 else echo "$ac_t""no" 1>&6 fi if test $tcgetattr -eq 1 -a $tcsetattr -eq 1 ; then cat >> confdefs.h <<\EOF #define HAVE_TCSETATTR 1 EOF cat >> confdefs.h <<\EOF #define POSIX 1 EOF fi # first check for the pure bsd echo $ac_n "checking for struct sgttyb""... $ac_c" 1>&6 echo "configure:5531: checking for struct sgttyb" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5537 "configure" #include "confdefs.h" #include <sgtty.h> main() { struct sgttyb tmp; exit(0); } EOF if { (eval echo configure:5547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SGTTYB 1 EOF PTY_TYPE=sgttyb |
︙ | ︙ | |||
5168 5169 5170 5171 5172 5173 5174 | if test $mach -eq 0 ; then # next check for the older style ttys # note that if we detect termio.h (only), we still set PTY_TYPE=termios # since that just controls which of pty_XXXX.c file is use and # pty_termios.c is set up to handle pty_termio. echo $ac_n "checking for struct termio""... $ac_c" 1>&6 | | | | | | | | | | | | | | | | | | | | | | 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 | if test $mach -eq 0 ; then # next check for the older style ttys # note that if we detect termio.h (only), we still set PTY_TYPE=termios # since that just controls which of pty_XXXX.c file is use and # pty_termios.c is set up to handle pty_termio. echo $ac_n "checking for struct termio""... $ac_c" 1>&6 echo "configure:5576: checking for struct termio" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5582 "configure" #include "confdefs.h" #include <termio.h> main() { struct termio tmp; exit(0); } EOF if { (eval echo configure:5591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_TERMIO 1 EOF PTY_TYPE=termios echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # now check for the new style ttys (not yet posix) echo $ac_n "checking for struct termios""... $ac_c" 1>&6 echo "configure:5613: checking for struct termios" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5619 "configure" #include "confdefs.h" /* including termios.h on Solaris 5.6 fails unless inttypes.h included */ # ifdef HAVE_INTTYPES_H # include <inttypes.h> # endif # include <termios.h> main() { struct termios tmp; exit(0); } EOF if { (eval echo configure:5633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_TERMIOS 1 EOF PTY_TYPE=termios echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi fi echo $ac_n "checking if TCGETS or TCGETA in termios.h""... $ac_c" 1>&6 echo "configure:5655: checking if TCGETS or TCGETA in termios.h" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5661 "configure" #include "confdefs.h" /* including termios.h on Solaris 5.6 fails unless inttypes.h included */ #ifdef HAVE_INTTYPES_H #include <inttypes.h> #endif #include <termios.h> main() { #if defined(TCGETS) || defined(TCGETA) return 0; #else return 1; #endif } EOF if { (eval echo configure:5677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking if TIOCGWINSZ in termios.h""... $ac_c" 1>&6 echo "configure:5697: checking if TIOCGWINSZ in termios.h" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5703 "configure" #include "confdefs.h" /* including termios.h on Solaris 5.6 fails unless inttypes.h included */ #ifdef HAVE_INTTYPES_H #include <inttypes.h> #endif #include <termios.h> main() { #ifdef TIOCGWINSZ return 0; #else return 1; #endif } EOF if { (eval echo configure:5719: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_TIOCGWINSZ_IN_TERMIOS_H 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # finally check for Cray style ttys echo $ac_n "checking for Cray-style ptys""... $ac_c" 1>&6 echo "configure:5740: checking for Cray-style ptys" >&5 SETUID=":" if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5747 "configure" #include "confdefs.h" main(){ #ifdef CRAY return 0; #else return 1; #endif } EOF if { (eval echo configure:5759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then PTY_TYPE=unicos SETUID="chmod u+s" echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
5376 5377 5378 5379 5380 5381 5382 | # Check for select and/or poll. If both exist, we prefer select. # if neither exists, define SIMPLE_EVENT. # select=0 poll=0 unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 | | | | 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 | # Check for select and/or poll. If both exist, we prefer select. # if neither exists, define SIMPLE_EVENT. # select=0 poll=0 unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:5784: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5789 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5404 5405 5406 5407 5408 5409 5410 | choke me #else select(); #endif ; return 0; } EOF | | < > | | | 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 | choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:5812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for poll""... $ac_c" 1>&6 echo "configure:5832: checking for poll" >&5 if eval "test \"`echo '$''{'ac_cv_func_poll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5837 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char poll(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5452 5453 5454 5455 5456 5457 5458 | choke me #else poll(); #endif ; return 0; } EOF | | < > | | 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 | choke me #else poll(); #endif ; return 0; } EOF if { (eval echo configure:5860: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_poll=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_poll=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'poll`\" = yes"; then echo "$ac_t""yes" 1>&6 poll=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking event handling""... $ac_c" 1>&6 echo "configure:5880: checking event handling" >&5 if test $select -eq 1 ; then EVENT_TYPE=select EVENT_ABLE=event echo "$ac_t""via select" 1>&6 elif test $poll -eq 1 ; then EVENT_TYPE=poll EVENT_ABLE=event |
︙ | ︙ | |||
5494 5495 5496 5497 5498 5499 5500 | EOF fi for ac_func in _getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | | | | 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 | EOF fi for ac_func in _getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:5902: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5907 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5522 5523 5524 5525 5526 5527 5528 | choke me #else $ac_func(); #endif ; return 0; } EOF | | < > | | | 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 | choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:5930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF else echo "$ac_t""no" 1>&6 fi done for ac_func in getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:5957: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5962 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ |
︙ | ︙ | |||
5577 5578 5579 5580 5581 5582 5583 | choke me #else $ac_func(); #endif ; return 0; } EOF | | < > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 | choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:5985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF else echo "$ac_t""no" 1>&6 fi done # following test sets SETPGRP_VOID if setpgrp takes 0 args, else takes 2 echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6 echo "configure:6012: checking whether setpgrp takes no argument" >&5 if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 6020 "configure" #include "confdefs.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif /* * If this system has a BSD-style setpgrp, which takes arguments, exit * successfully. */ main() { if (setpgrp(1,1) == -1) exit(0); else exit(1); } EOF if { (eval echo configure:6040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_setpgrp_void=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_setpgrp_void=yes fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6 if test $ac_cv_func_setpgrp_void = yes; then cat >> confdefs.h <<\EOF #define SETPGRP_VOID 1 EOF fi # # check for timezones # echo $ac_n "checking for SV-style timezone""... $ac_c" 1>&6 echo "configure:6068: checking for SV-style timezone" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 6074 "configure" #include "confdefs.h" extern char *tzname[2]; extern int daylight; main() { int *x = &daylight; char **y = tzname; exit(0); } EOF if { (eval echo configure:6087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF #define HAVE_SV_TIMEZONE 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 |
︙ | ︙ | |||
5671 5672 5673 5674 5675 5676 5677 | # recursive cache variables for the path will work right. We check all # the possible paths in one loop rather than many seperate loops to speed # things up. # the alternative search directory is involked by --with-tkinclude # #no_tk=true echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6 | | | 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 | # recursive cache variables for the path will work right. We check all # the possible paths in one loop rather than many seperate loops to speed # things up. # the alternative search directory is involked by --with-tkinclude # #no_tk=true echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6 echo "configure:6133: checking for Tk private headers" >&5 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi if eval "test \"`echo '$''{'ac_cv_c_tkh'+set}'`\" = set"; then |
︙ | ︙ | |||
5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[4-9].[0-9].[0-9] ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[4-9].[0-9].[0-9] ${srcdir}/../../tk[4-9].[0-9] 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[4-9].[0-9].[0-9] ${srcdir}/../../../tk[4-9].[0-9] 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[4-9].[0-9].[0-9] /usr/local/src/tk[4-9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[4-9].[0-9].[0-9] /usr/local/lib/tk[4-9].[0-9] 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tkh}" = x ; then ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tk.h""... $ac_c" 1>&6 | > > > > > | | | | | 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 | # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[4-9].[0-9].[0-9] ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[4-9].[0-9].[0-9] ${srcdir}/../tk[4-9].[0-9] 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[4-9].[0-9].[0-9] ${srcdir}/../../tk[4-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../../tk[4-9].[0-9].[0-9] ${srcdir}/../../tk[4-9].[0-9] 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[4-9].[0-9].[0-9] ${srcdir}/../../../tk[4-9].[0-9] 2>/dev/null ` \ `ls -dr ${srcdir}/../../../tk[4-9].[0-9].[0-9] ${srcdir}/../../../tk[4-9].[0-9] 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[4-9].[0-9].[0-9] /usr/local/src/tk[4-9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/src/tk[4-9].[0-9].[0-9] /usr/local/src/tk[4-9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[4-9].[0-9].[0-9] /usr/local/lib/tk[4-9].[0-9] 2>/dev/null` \ `ls -dr /usr/local/lib/tk[4-9].[0-9].[0-9] /usr/local/lib/tk[4-9].[0-9] 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tkh}" = x ; then ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tk.h""... $ac_c" 1>&6 echo "configure:6204: checking for tk.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 6209 "configure" #include "confdefs.h" #include <tk.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:6214: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 |
︙ | ︙ | |||
5846 5847 5848 5849 5850 5851 5852 | if test $iunix -eq 1 ; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) echo $ac_n "checking for long file names""... $ac_c" 1>&6 | | | 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 | if test $iunix -eq 1 ; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) echo $ac_n "checking for long file names""... $ac_c" 1>&6 echo "configure:6313: checking for long file names" >&5 if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_long_file_names=yes # Test for long file names in all the places we know might matter: # . the current directory, where building will happen # $prefix/lib where we will be installing things |
︙ | ︙ | |||
5893 5894 5895 5896 5897 5898 5899 | fi if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi | | | | > > > > > | < < < < < < | | 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 | fi if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}${DBGX}" EXP_LIB_SPEC="-L\${INSTALL_ROOT}\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}${DBGX}" EXP_UNSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}${DBGX}.a # The TCL_SHARED_LIB_SUFFIX macro below relies on the DBGX macro, # which is set way far above here. Don't set it to the value of # TCL_DBGX, or you'll run into problems if you build Tcl with symbols # and expect without (and vice versa?) echo $ac_n "checking for type of library to build""... $ac_c" 1>&6 echo "configure:6370: checking for type of library to build" >&5 if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS eval "EXP_SHARED_LIB_FILE=libexpect${TCL_SHARED_LIB_SUFFIX}" EXP_LIB_FILE=$EXP_SHARED_LIB_FILE EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_UNSHARED_LIB_FILE" echo "$ac_t""both shared and unshared" 1>&6 else EXP_SHLIB_CFLAGS= EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library" EXP_LIB_FILE=$EXP_UNSHARED_LIB_FILE EXP_LIB_FILES="$EXP_UNSHARED_LIB_FILE" echo "$ac_t""unshared" 1>&6 fi # Sigh - Tcl defines SHLIB_LD_LIBS to be either empty or ${LIBS} and # LIBS is intended to be expanded by Make. But since we're too close # to hitting config's max symbols, pack everything together here and # do test ourselves. Ugh. # if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then EXP_SHLIB_LD_LIBS="$LIBS" else # seems a little strange to build in Tcl's build-lib, but # that's what Tk does. EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc" fi #-------------------------------------------------------------------- |
︙ | ︙ | |||
5950 5951 5952 5953 5954 5955 5956 | #-------------------------------------------------------------------- LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}' # If Tcl and Expect are installed in different places, adjust the library # search path to reflect this. | > | | > > > > > > > | | > | > > > | > > > > > > > | 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 | #-------------------------------------------------------------------- LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}' # If Tcl and Expect are installed in different places, adjust the library # search path to reflect this. if test x"$no_tk" = x"true" ; then if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib" fi else if test "$TK_EXEC_PREFIX" != "$exec_prefix"; then LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TK_EXEC_PREFIX}/lib" # no need to include TCL's search path, because TK does it already # (it is actually appended later, via TK_LD_SEARCH_FLAGS trick below) fi fi if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'` fi # The eval below is tricky! It *evaluates* the string in # ..._CC_SEARCH_FLAGS, which causes a substitution of the # variable LIB_RUNTIME_DIR. if test x"$no_tk" = x"true" ; then eval "EXP_CC_SEARCH_FLAGS=\"$TCL_CC_SEARCH_FLAGS\"" EXP_LD_SEARCH_FLAGS=${TCL_LD_SEARCH_FLAGS} else eval "EXP_CC_SEARCH_FLAGS=\"$TK_CC_SEARCH_FLAGS\"" EXP_LD_SEARCH_FLAGS=${TK_LD_SEARCH_FLAGS} fi # now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this # in order to avoid repeating lib specs to which some systems object. EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $EXP_CC_SEARCH_FLAGS" EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $EXP_CC_SEARCH_FLAGS" # # Set up makefile substitutions # |
︙ | ︙ | |||
6039 6040 6041 6042 6043 6044 6045 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) | | > | > > > > > > < > | 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile \ pkgIndex expect_cf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@found@%$found%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@target@%$target%g s%@target_alias@%$target_alias%g s%@target_cpu@%$target_cpu%g s%@target_vendor@%$target_vendor%g s%@target_os@%$target_os%g s%@build@%$build%g s%@build_alias@%$build_alias%g s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@CC@%$CC%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_DELETEME@%$TCL_DELETEME%g s%@TCL_DBGX@%$TCL_DBGX%g s%@TCL_EXEC_PREFIX@%$TCL_EXEC_PREFIX%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@SHLIB_SUFFIX@%$SHLIB_SUFFIX%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TCL_SHARED_LIB_SUFFIX@%$TCL_SHARED_LIB_SUFFIX%g s%@TK_VERSION@%$TK_VERSION%g s%@TK_DEFS@%$TK_DEFS%g s%@TK_DBGX@%$TK_DBGX%g s%@TK_XINCLUDES@%$TK_XINCLUDES%g s%@TK_XLIBSW@%$TK_XLIBSW%g s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@RANLIB@%$RANLIB%g s%@subdirs@%$subdirs%g s%@CPP@%$CPP%g s%@TCLHDIR@%$TCLHDIR%g s%@TCLHDIRDASHI@%$TCLHDIRDASHI%g s%@TCL_LIBRARY@%$TCL_LIBRARY%g |
︙ | ︙ | |||
6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 | s%@EXP_LIB_FILE@%$EXP_LIB_FILE%g s%@EXP_LIB_FILES@%$EXP_LIB_FILES%g s%@EXP_BUILD_LIB_SPEC@%$EXP_BUILD_LIB_SPEC%g s%@EXP_LIB_SPEC@%$EXP_LIB_SPEC%g s%@EXP_CFLAGS@%$EXP_CFLAGS%g s%@EXP_LDFLAGS@%$EXP_LDFLAGS%g s%@EXP_LD_SEARCH_FLAGS@%$EXP_LD_SEARCH_FLAGS%g s%@EXP_AND_TCL_LIBS@%$EXP_AND_TCL_LIBS%g s%@EXP_AND_TK_LIBS@%$EXP_AND_TK_LIBS%g s%@EXP_SHLIB_LD_LIBS@%$EXP_SHLIB_LD_LIBS%g s%@X_PROGS@%$X_PROGS%g s%@PTY_TYPE@%$PTY_TYPE%g s%@EVENT_TYPE@%$EVENT_TYPE%g s%@EVENT_ABLE@%$EVENT_ABLE%g | > | 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 | s%@EXP_LIB_FILE@%$EXP_LIB_FILE%g s%@EXP_LIB_FILES@%$EXP_LIB_FILES%g s%@EXP_BUILD_LIB_SPEC@%$EXP_BUILD_LIB_SPEC%g s%@EXP_LIB_SPEC@%$EXP_LIB_SPEC%g s%@EXP_CFLAGS@%$EXP_CFLAGS%g s%@EXP_LDFLAGS@%$EXP_LDFLAGS%g s%@EXP_LD_SEARCH_FLAGS@%$EXP_LD_SEARCH_FLAGS%g s%@TCL_LD_SEARCH_FLAGS@%$TCL_LD_SEARCH_FLAGS%g s%@EXP_AND_TCL_LIBS@%$EXP_AND_TCL_LIBS%g s%@EXP_AND_TK_LIBS@%$EXP_AND_TK_LIBS%g s%@EXP_SHLIB_LD_LIBS@%$EXP_SHLIB_LD_LIBS%g s%@X_PROGS@%$X_PROGS%g s%@PTY_TYPE@%$PTY_TYPE%g s%@EVENT_TYPE@%$EVENT_TYPE%g s%@EVENT_ABLE@%$EVENT_ABLE%g |
︙ | ︙ | |||
6187 6188 6189 6190 6191 6192 6193 | if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF | | > | | | 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 | if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile \ pkgIndex"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. |
︙ | ︙ | |||
6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 | rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g | > > | | 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 | rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. |
︙ | ︙ | |||
6263 6264 6265 6266 6267 6268 6269 | ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' | | | | > | | 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 | ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <<EOF CONFIG_HEADERS="expect_cf.h" EOF cat >> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. |
︙ | ︙ | |||
6350 6351 6352 6353 6354 6355 6356 | test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done | | > > > > | 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 | test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <<EOF EOF cat >> $CONFIG_STATUS <<\EOF chmod +x ${srcdir}/install-sh ${srcdir}/mkinstalldirs exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 if test "$no_recursion" != yes; then |
︙ | ︙ |
Changes to configure.in.
1 2 3 4 5 6 7 8 9 10 11 12 | # Process this file with autoconf to produce a configure script. # while Expect is in alpha/beta, disable caching so as not to confuse # people trying to fix configure bugs define([AC_CACHE_LOAD], ) define([AC_CACHE_SAVE], ) AC_INIT(expect.h) # note when updating version numbers here, also update pkgIndex.in (see # comments in Makefile) EXP_MAJOR_VERSION=5 | | | > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # Process this file with autoconf to produce a configure script. # while Expect is in alpha/beta, disable caching so as not to confuse # people trying to fix configure bugs define([AC_CACHE_LOAD], ) define([AC_CACHE_SAVE], ) AC_INIT(expect.h) # note when updating version numbers here, also update pkgIndex.in (see # comments in Makefile) EXP_MAJOR_VERSION=5 EXP_MINOR_VERSION=32 EXP_MICRO_VERSION=2 EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION # Tcl's handling of shared_lib_suffix requires this symbol exist VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION # Too many people send me configure output without identifying the version. # This forced identification should reduce my pain significantly. echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION" # People (when downloading Expect from CVS archive) sometimes run into # Make thinking configure is old and needs to be rebuilt. If they # don't have a clue about autoconf, they get confused. This is # particular irritating because the problem only crops up after # configure has successfully completed. Help them out by checking it # right now and giving some advice. Alas, we cannot summarily fix the # problem because it might conceivably be someone doing real # development. # Test if configure is older than configure.in and explain if no autoconf AC_CHECK_PROG(found,autoconf,yes,no,) AC_MSG_CHECKING([configure up to date]) for i in `ls -tr ${srcdir}/configure ${srcdir}/configure.in ${srcdir}/Makefile.in` ; do newest=$i done if test "$srcdir/configure" = "$newest" ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi if test $found = "no" -a "$newest" != "$srcdir/configure" ; then AC_MSG_WARN([$srcdir/configure appears to be old ($srcdir/configure.in and/or $srcdir/Makefile.in are newer) and the autoconf program to fix this situation was not found. If you've no idea what this means, enter the command \"touch $srcdir/configure\" and restart $srcdir/configure.]) exit fi dnl AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..) AC_CANONICAL_SYSTEM AC_CONFIG_HEADER(expect_cf.h) # /bin/sh on some systems is too deficient (in particular, Ultrix 4.3 |
︙ | ︙ | |||
38 39 40 41 42 43 44 | # If `configure' is invoked (in)directly via `make', ensure that it # encounters no `make' conflicts. # dnl unset MFLAGS MAKEFLAGS MFLAGS= MAKEFLAGS= | < < < < < < < < | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | # If `configure' is invoked (in)directly via `make', ensure that it # encounters no `make' conflicts. # dnl unset MFLAGS MAKEFLAGS MFLAGS= MAKEFLAGS= # An explanation is in order for the strange things going on with the # various LIBS. There are three separate definitions for LIBS. The # reason is that some systems require shared libraries include # references to their dependent libraries, i.e., any additional # libraries that must be linked to. And some systems get upset if the # references are repeated on the link line. So therefore, we create # one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl |
︙ | ︙ | |||
72 73 74 75 76 77 78 79 80 81 82 83 84 85 | dnl AC_PROG_CC insists on sticking crap -g and -O in CFLAGS dnl but I want to control it. Can't just throw it out at the dnl end alas, because the user might have defined CFLAGS. OLD_CFLAGS=$CFLAGS AC_PROG_CC CFLAGS=$OLD_CFLAGS CY_AC_C_WORKS # this'll use a BSD compatible install or our included install-sh AC_PROG_INSTALL # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared | > > > > > > > > > > > > > > > > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | dnl AC_PROG_CC insists on sticking crap -g and -O in CFLAGS dnl but I want to control it. Can't just throw it out at the dnl end alas, because the user might have defined CFLAGS. OLD_CFLAGS=$CFLAGS AC_PROG_CC CFLAGS=$OLD_CFLAGS #------------------------------------------------------------------------ # Hook for when threading is supported in Expect. The --enable-threads # flag currently has no effect. #------------------------------------------------------------------------ SC_ENABLE_THREADS CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC EXP_AND_TCL_LIBS=$TCL_LIBS CY_AC_PATH_TKCONFIG CY_AC_LOAD_TKCONFIG EXP_AND_TK_LIBS=$TK_LIBS CY_AC_C_WORKS # this'll use a BSD compatible install or our included install-sh AC_PROG_INSTALL # Tcl sets TCL_RANLIB appropriately for shared library if --enable-shared |
︙ | ︙ | |||
99 100 101 102 103 104 105 | AC_TYPE_PID_T AC_RETSIGTYPE dnl AC_TIME_WITH_SYS_TIME AC_HEADER_TIME AC_HEADER_SYS_WAIT | > > > > | > > > > > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | AC_TYPE_PID_T AC_RETSIGTYPE dnl AC_TIME_WITH_SYS_TIME AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_ARG_ENABLE(symbols, [ --enable-symbols allow use of symbols if available], [enable_symbols=$enableval], [enable_symbols=no]) if test "$enable_symbols" = "no"; then EXP_CFLAGS="$TCL_EXTRA_CFLAGS" else EXP_CFLAGS="-g $TCL_EXTRA_CFLAGS" # This is always "g" for unix. DBGX=g fi case "${host}" in # Use -g on all systems but Linux where it upsets the dynamic X libraries. i[[3456]]86-*-linux*) EXP_CFLAGS="" ;; esac AC_MSG_CHECKING([if running Mach]) mach=0 |
︙ | ︙ | |||
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # End of library/func checking ###################################################################### ###################################################################### # # Look for various header files # AC_CHECK_HEADER(sys/sysmacros.h, AC_DEFINE(HAVE_SYSMACROS_H)) AC_CHECK_HEADER(stdlib.h, ,AC_DEFINE(NO_STDLIB_H)) AC_CHECK_HEADER(inttypes.h, AC_DEFINE(HAVE_INTTYPES_H)) # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! dnl AC_CHECK_HEADER(stdarg.h, AC_DEFINE(HAVE_STDARG_H)) AC_CHECK_HEADER(varargs.h, AC_DEFINE(HAVE_VARARGS_H)) AC_CHECK_HEADER(unistd.h, AC_DEFINE(HAVE_UNISTD_H)) | > > > > > > > > > > > > > > > | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS ###################################################################### # End of library/func checking ###################################################################### # Hand patches to library/func checking. dnl From: Michael Kuhl <[email protected]> dnl To get expect to compile on a Sequent NUMA-Q running DYNIX/ptx v4.4.2. AC_MSG_CHECKING([if running Sequent running SVR4]) if test "$host_alias" = "i386-sequent-sysv4" ; then EXP_AND_TCL_LIBS="-lnsl -lsocket -lm" dnl if there's something similar required for Tk, no one's told me! AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi ###################################################################### # # Look for various header files # AC_CHECK_HEADER(sys/sysmacros.h, AC_DEFINE(HAVE_SYSMACROS_H)) AC_CHECK_HEADER(stdlib.h, ,AC_DEFINE(NO_STDLIB_H)) AC_CHECK_HEADER(inttypes.h, AC_DEFINE(HAVE_INTTYPES_H)) # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! dnl AC_CHECK_HEADER(stdarg.h, AC_DEFINE(HAVE_STDARG_H)) AC_CHECK_HEADER(varargs.h, AC_DEFINE(HAVE_VARARGS_H)) AC_CHECK_HEADER(unistd.h, AC_DEFINE(HAVE_UNISTD_H)) # If no stropts.h, then the svr4 implementation is broken. # At least it is on my Debian "potato" system. - Rob Savoye AC_CHECK_HEADER(sys/stropts.h, AC_DEFINE(HAVE_STROPTS_H), svr4_ptys_broken=1) AC_CHECK_HEADER(sys/sysconfig.h, AC_DEFINE(HAVE_SYSCONF_H)) AC_CHECK_HEADER(sys/fcntl.h, AC_DEFINE(HAVE_SYS_FCNTL_H)) AC_CHECK_HEADER(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H)) AC_CHECK_HEADER(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H)) AC_CHECK_HEADER(sys/ptem.h, AC_DEFINE(HAVE_SYS_PTEM_H)) AC_CHECK_HEADER(sys/strredir.h, AC_DEFINE(HAVE_STRREDIR_H)) AC_CHECK_HEADER(sys/strpty.h, AC_DEFINE(HAVE_STRPTY_H)) |
︙ | ︙ | |||
535 536 537 538 539 540 541 542 543 544 545 546 547 548 | # dnl AC_CHECK_FUNC(memcpy, AC_DEFINE(HAVE_MEMCPY)) AC_CHECK_FUNC(memmove, AC_DEFINE(HAVE_MEMMOVE)) AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF)) AC_CHECK_FUNC(strftime, AC_DEFINE(HAVE_STRFTIME)) AC_CHECK_FUNC(strchr, AC_DEFINE(HAVE_STRCHR)) AC_CHECK_FUNC(timezone, AC_DEFINE(HAVE_TIMEZONE)) # dnl check for memcpy by hand # because Unixware 2.0 handles it specially and refuses to compile # autoconf's automatic test that is a call with no arguments AC_MSG_CHECKING([for memcpy]) AC_TRY_LINK(,[ char *s1, *s2; | > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | # dnl AC_CHECK_FUNC(memcpy, AC_DEFINE(HAVE_MEMCPY)) AC_CHECK_FUNC(memmove, AC_DEFINE(HAVE_MEMMOVE)) AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF)) AC_CHECK_FUNC(strftime, AC_DEFINE(HAVE_STRFTIME)) AC_CHECK_FUNC(strchr, AC_DEFINE(HAVE_STRCHR)) AC_CHECK_FUNC(timezone, AC_DEFINE(HAVE_TIMEZONE)) AC_CHECK_FUNC(siglongjmp, AC_DEFINE(HAVE_SIGLONGJMP)) # dnl check for memcpy by hand # because Unixware 2.0 handles it specially and refuses to compile # autoconf's automatic test that is a call with no arguments AC_MSG_CHECKING([for memcpy]) AC_TRY_LINK(,[ char *s1, *s2; |
︙ | ︙ | |||
596 597 598 599 600 601 602 603 604 605 606 607 608 609 | rm -f wnohang , AC_MSG_RESULT(no) AC_DEFINE(WNOHANG_BACKUP_VALUE, 1) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then | > > > > > > > > > > > > > > > > > > > > > > | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | rm -f wnohang , AC_MSG_RESULT(no) AC_DEFINE(WNOHANG_BACKUP_VALUE, 1) , AC_MSG_ERROR([Expect can't be cross compiled]) ) #-----Stolen from Tcl's configure file------------------------------- # The check below checks whether <sys/wait.h> defines the type # "union wait" correctly. It's needed because of weirdness in # HP-UX where "union wait" is defined in both the BSD and SYS-V # environments. Checking the usability of WIFEXITED seems to do # the trick. #-------------------------------------------------------------------- AC_MSG_CHECKING([union wait]) AC_TRY_LINK([#include <sys/types.h> #include <sys/wait.h>], [ union wait x; WIFEXITED(x); /* Generates compiler error if WIFEXITED * uses an int. */ ], tcl_ok=yes, tcl_ok=no) AC_MSG_RESULT($tcl_ok) if test $tcl_ok = no; then AC_DEFINE(NO_UNION_WAIT) fi # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then |
︙ | ︙ | |||
688 689 690 691 692 693 694 | if test $convex -eq 1 ; then AC_MSG_RESULT(yes) AC_DEFINE(CONVEX) else AC_MSG_RESULT(no) fi | | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | if test $convex -eq 1 ; then AC_MSG_RESULT(yes) AC_DEFINE(CONVEX) else AC_MSG_RESULT(no) fi EXP_LDFLAGS="$LDFLAGS" AC_MSG_CHECKING([if on NeXT]) if test -r /NextApps ; then AC_MSG_RESULT(yes) # "-m" flag suppresses complaints about multiple strtod EXP_LDFLAGS="$EXP_LDFLAGS -m" else |
︙ | ︙ | |||
783 784 785 786 787 788 789 | fi AC_MSG_CHECKING([for SVR4 style pty allocation]) if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTMX) # aargg. Some systems need libpt.a to use /dev/ptmx | > | | | | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 | fi AC_MSG_CHECKING([for SVR4 style pty allocation]) if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTMX) # aargg. Some systems need libpt.a to use /dev/ptmx AC_CHECK_LIB(pt, libpts="-lpt", libpts="") AC_CHECK_FUNC(ptsname, , LIBS="${LIBS} $libpts") # I've never seen Tcl or Tk include -lpt so don't bother with explicit test AC_CHECK_FUNC(ptsname, , EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} $libpts") AC_CHECK_FUNC(ptsname, , EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} $libpts") else AC_MSG_RESULT(no) fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp <[email protected]> 17Aug93 AC_MSG_CHECKING([for OSF/1 style pty allocation]) |
︙ | ︙ | |||
968 969 970 971 972 973 974 975 976 977 978 979 980 981 | AC_MSG_RESULT(none) AC_DEFINE(SIMPLE_EVENT) fi AC_HAVE_FUNCS(_getpty) AC_HAVE_FUNCS(getpty) # # check for timezones # AC_MSG_CHECKING([for SV-style timezone]) AC_TRY_RUN([ extern char *tzname[2]; extern int daylight; | > > > | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 | AC_MSG_RESULT(none) AC_DEFINE(SIMPLE_EVENT) fi AC_HAVE_FUNCS(_getpty) AC_HAVE_FUNCS(getpty) # following test sets SETPGRP_VOID if setpgrp takes 0 args, else takes 2 AC_FUNC_SETPGRP # # check for timezones # AC_MSG_CHECKING([for SV-style timezone]) AC_TRY_RUN([ extern char *tzname[2]; extern int daylight; |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) AC_SYS_LONG_FILE_NAMES if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi | | | | > > > > > < < < < < < | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) AC_SYS_LONG_FILE_NAMES if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}${DBGX}" EXP_LIB_SPEC="-L\${INSTALL_ROOT}\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}${DBGX}" EXP_UNSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}${DBGX}.a # The TCL_SHARED_LIB_SUFFIX macro below relies on the DBGX macro, # which is set way far above here. Don't set it to the value of # TCL_DBGX, or you'll run into problems if you build Tcl with symbols # and expect without (and vice versa?) AC_MSG_CHECKING([for type of library to build]) if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS eval "EXP_SHARED_LIB_FILE=libexpect${TCL_SHARED_LIB_SUFFIX}" EXP_LIB_FILE=$EXP_SHARED_LIB_FILE EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_UNSHARED_LIB_FILE" AC_MSG_RESULT(both shared and unshared) else EXP_SHLIB_CFLAGS= EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library" EXP_LIB_FILE=$EXP_UNSHARED_LIB_FILE EXP_LIB_FILES="$EXP_UNSHARED_LIB_FILE" AC_MSG_RESULT(unshared) fi # Sigh - Tcl defines SHLIB_LD_LIBS to be either empty or ${LIBS} and # LIBS is intended to be expanded by Make. But since we're too close # to hitting config's max symbols, pack everything together here and # do test ourselves. Ugh. # if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then EXP_SHLIB_LD_LIBS="$LIBS" else # seems a little strange to build in Tcl's build-lib, but # that's what Tk does. EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc" fi #-------------------------------------------------------------------- |
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | #-------------------------------------------------------------------- LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}' # If Tcl and Expect are installed in different places, adjust the library # search path to reflect this. | > | | > > > > > > > | | > | > > > | > > > > > > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 | #-------------------------------------------------------------------- LIB_RUNTIME_DIR='${LIB_RUNTIME_DIR}' # If Tcl and Expect are installed in different places, adjust the library # search path to reflect this. if test x"$no_tk" = x"true" ; then if test "$TCL_EXEC_PREFIX" != "$exec_prefix"; then LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib" fi else if test "$TK_EXEC_PREFIX" != "$exec_prefix"; then LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TK_EXEC_PREFIX}/lib" # no need to include TCL's search path, because TK does it already # (it is actually appended later, via TK_LD_SEARCH_FLAGS trick below) fi fi if test "${TCL_LD_SEARCH_FLAGS}" = '-L${LIB_RUNTIME_DIR}'; then LIB_RUNTIME_DIR=`echo ${LIB_RUNTIME_DIR} |sed -e 's/:/ -L/g'` fi # The eval below is tricky! It *evaluates* the string in # ..._CC_SEARCH_FLAGS, which causes a substitution of the # variable LIB_RUNTIME_DIR. if test x"$no_tk" = x"true" ; then eval "EXP_CC_SEARCH_FLAGS=\"$TCL_CC_SEARCH_FLAGS\"" EXP_LD_SEARCH_FLAGS=${TCL_LD_SEARCH_FLAGS} else eval "EXP_CC_SEARCH_FLAGS=\"$TK_CC_SEARCH_FLAGS\"" EXP_LD_SEARCH_FLAGS=${TK_LD_SEARCH_FLAGS} fi # now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this # in order to avoid repeating lib specs to which some systems object. EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $EXP_CC_SEARCH_FLAGS" EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $EXP_CC_SEARCH_FLAGS" # # Set up makefile substitutions # AC_SUBST(EXP_MAJOR_VERSION) AC_SUBST(EXP_MINOR_VERSION) AC_SUBST(EXP_MICRO_VERSION) |
︙ | ︙ | |||
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 | AC_SUBST(EXP_LIB_FILE) AC_SUBST(EXP_LIB_FILES) AC_SUBST(EXP_BUILD_LIB_SPEC) AC_SUBST(EXP_LIB_SPEC) AC_SUBST(EXP_CFLAGS) AC_SUBST(EXP_LDFLAGS) AC_SUBST(EXP_LD_SEARCH_FLAGS) AC_SUBST(EXP_AND_TCL_LIBS) AC_SUBST(EXP_AND_TK_LIBS) AC_SUBST(EXP_SHLIB_LD_LIBS) AC_SUBST(X_PROGS) AC_SUBST(PTY_TYPE) AC_SUBST(EVENT_TYPE) AC_SUBST(EVENT_ABLE) AC_SUBST(SETUID) AC_SUBST(UNSHARED_RANLIB) AC_SUBST(DEFAULT_STTY_ARGS) | > | > > | 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | AC_SUBST(EXP_LIB_FILE) AC_SUBST(EXP_LIB_FILES) AC_SUBST(EXP_BUILD_LIB_SPEC) AC_SUBST(EXP_LIB_SPEC) AC_SUBST(EXP_CFLAGS) AC_SUBST(EXP_LDFLAGS) AC_SUBST(EXP_LD_SEARCH_FLAGS) AC_SUBST(TCL_LD_SEARCH_FLAGS) AC_SUBST(EXP_AND_TCL_LIBS) AC_SUBST(EXP_AND_TK_LIBS) AC_SUBST(EXP_SHLIB_LD_LIBS) AC_SUBST(X_PROGS) AC_SUBST(PTY_TYPE) AC_SUBST(EVENT_TYPE) AC_SUBST(EVENT_ABLE) AC_SUBST(SETUID) AC_SUBST(UNSHARED_RANLIB) AC_SUBST(DEFAULT_STTY_ARGS) AC_OUTPUT([Makefile \ pkgIndex], chmod +x ${srcdir}/install-sh ${srcdir}/mkinstalldirs) |
Added doc/expect.man.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 | .TH EXPECT 1 "29 December 1994" .SH NAME expect \- programmed dialogue with interactive programs, Version 5 .SH SYNOPSIS .B expect [ .B \-dDinN ] [ .B \-c .I cmds ] [ .BR \- [ f | b ] ] .I cmdfile ] [ .I args ] .SH INTRODUCTION .B Expect is a program that "talks" to other interactive programs according to a script. Following the script, .B Expect knows what can be expected from a program and what the correct response should be. An interpreted language provides branching and high-level control structures to direct the dialogue. In addition, the user can take control and interact directly when desired, afterward returning control to the script. .PP .B Expectk is a mixture of .B Expect and .BR Tk . It behaves just like .B Expect and .BR Tk 's .BR wish . .B Expect can also be used directly in C or C++ (that is, without Tcl). See libexpect(3). .PP The name "Expect" comes from the idea of .I send/expect sequences popularized by uucp, kermit and other modem control programs. However unlike uucp, .B Expect is generalized so that it can be run as a user-level command with any program and task in mind. .B Expect can actually talk to several programs at the same time. .PP For example, here are some things .B Expect can do: .RS .TP 4 \(bu Cause your computer to dial you back, so that you can login without paying for the call. .TP \(bu Start a game (e.g., rogue) and if the optimal configuration doesn't appear, restart it (again and again) until it does, then hand over control to you. .TP \(bu Run fsck, and in response to its questions, answer "yes", "no" or give control back to you, based on predetermined criteria. .TP \(bu Connect to another network or BBS (e.g., MCI Mail, CompuServe) and automatically retrieve your mail so that it appears as if it was originally sent to your local system. .TP \(bu Carry environment variables, current directory, or any kind of information across rlogin, telnet, tip, su, chgrp, etc. .RE .PP There are a variety of reasons why the shell cannot perform these tasks. (Try, you'll see.) All are possible with .BR Expect . .PP In general, .B Expect is useful for running any program which requires interaction between the program and the user. All that is necessary is that the interaction can be characterized programmatically. .B Expect can also give the user back control (without halting the program being controlled) if desired. Similarly, the user can return control to the script at any time. .SH USAGE .B Expect reads .I cmdfile for a list of commands to execute. .B Expect may also be invoked implicitly on systems which support the #! notation by marking the script executable, and making the first line in your script: #!/usr/local/bin/expect \-f Of course, the path must accurately describe where .B Expect lives. /usr/local/bin is just an example. The .B \-c flag prefaces a command to be executed before any in the script. The command should be quoted to prevent being broken up by the shell. This option may be used multiple times. Multiple commands may be executed with a single .B \-c by separating them with semicolons. Commands are executed in the order they appear. (When using Expectk, this option is specified as .BR \-command .) .PP The .B \-d flag enables some diagnostic output, which primarily reports internal activity of commands such as .B expect and .BR interact . This flag has the same effect as "exp_internal 1" at the beginning of an Expect script, plus the version of .B Expect is printed. (The .B strace command is useful for tracing statements, and the .B trace command is useful for tracing variable assignments.) (When using Expectk, this option is specified as .BR \-diag .) .PP The .B \-D flag enables an interactive debugger. An integer value should follow. The debugger will take control before the next Tcl procedure if the value is non-zero or if a ^C is pressed (or a breakpoint is hit, or other appropriate debugger command appears in the script). See the README file or SEE ALSO (below) for more information on the debugger. (When using Expectk, this option is specified as .BR \-Debug .) .PP The .B \-f flag prefaces a file from which to read commands from. The flag itself is optional as it is only useful when using the #! notation (see above), so that other arguments may be supplied on the command line. (When using Expectk, this option is specified as .BR \-file .) .PP By default, the command file is read into memory and executed in its entirety. It is occasionally desirable to read files one line at a time. For example, stdin is read this way. In order to force arbitrary files to be handled this way, use the .B \-b flag. (When using Expectk, this option is specified as .BR \-buffer .) .PP If the string "\-" is supplied as a filename, standard input is read instead. (Use "./\-" to read from a file actually named "\-".) .PP The .B \-i flag causes .B Expect to interactively prompt for commands instead of reading them from a file. Prompting is terminated via the .B exit command or upon EOF. See .B interpreter (below) for more information. .B \-i is assumed if neither a command file nor .B \-c is used. (When using Expectk, this option is specified as .BR \-interactive .) .PP .B \-\- may be used to delimit the end of the options. This is useful if you want to pass an option-like argument to your script without it being interpreted by .BR Expect . This can usefully be placed in the #! line to prevent any flag-like interpretation by Expect. For example, the following will leave the original arguments (including the script name) in the variable .IR argv . #!/usr/local/bin/expect \-\- Note that the usual getopt(3) and execve(2) conventions must be observed when adding arguments to the #! line. .PP The file $exp_library/expect.rc is sourced automatically if present, unless the .B \-N flag is used. (When using Expectk, this option is specified as .BR \-NORC .) Immediately after this, the file ~/.expect.rc is sourced automatically, unless the .B \-n flag is used. If the environment variable DOTDIR is defined, it is treated as a directory and .expect.rc is read from there. (When using Expectk, this option is specified as .BR \-norc .) This sourcing occurs only after executing any .B \-c flags. .PP .B \-v causes Expect to print its version number and exit. (The corresponding flag in Expectk, which uses long flag names, is \-version.) .PP Optional .I args are constructed into a list and stored in the variable named .IR argv . .I argc is initialized to the length of argv. .PP .I argv0 is defined to be the name of the script (or binary if no script is used). For example, the following prints out the name of the script and the first three arguments: .nf send_user "$argv0 [lrange $argv 0 2]\\n" .fi .SH COMMANDS .B Expect uses .I Tcl (Tool Command Language). Tcl provides control flow (e.g., if, for, break), expression evaluation and several other features such as recursion, procedure definition, etc. Commands used here but not defined (e.g., .BR set , .BR if , .BR exec ) are Tcl commands (see tcl(3)). .B Expect supports additional commands, described below. Unless otherwise specified, commands return the empty string. .PP Commands are listed alphabetically so that they can be quickly located. However, new users may find it easier to start by reading the descriptions of .BR spawn , .BR send , .BR expect , and .BR interact , in that order. Note that the best introduction to the language (both Expect and Tcl) is provided in the book "Exploring Expect" (see SEE ALSO below). Examples are included in this man page but they are very limited since this man page is meant primarily as reference material. Note that in the text of this man page, "Expect" with an uppercase "E" refers to the .B Expect program while "expect" with a lower-case "e" refers to the .B expect command within the .B Expect program.) .I .TP 6 .BI close " [-slave] [\-onexec 0|1] [\-i spawn_id]" closes the connection to the current process. Most interactive programs will detect EOF on their stdin and exit; thus .B close usually suffices to kill the process as well. The .B \-i flag declares the process to close corresponding to the named spawn_id. Both .B expect and .B interact will detect when the current process exits and implicitly do a .BR close . But if you kill the process by, say, "exec kill $pid", you will need to explicitly call .BR close . The .BR \-onexec flag determines whether the spawn id will be closed in any new spawned processes or if the process is overlayed. To leave a spawn id open, use the value 0. A non-zero integer value will force the spawn closed (the default) in any new processes. The .B \-slave flag closes the slave associated with the spawn id. (See "spawn -pty".) When the connection is closed, the slave is automatically closed as well if still open. No matter whether the connection is closed implicitly or explicitly, you should call .B wait to clear up the corresponding kernel process slot. .B close does not call .B wait since there is no guarantee that closing a process connection will cause it to exit. See .B wait below for more info. .TP .BI debug " [[-now] 0|1]" controls a Tcl debugger allowing you to step through statements, set breakpoints, etc. With no arguments, a 1 is returned if the debugger is not running, otherwise a 0 is returned. With a 1 argument, the debugger is started. With a 0 argument, the debugger is stopped. If a 1 argument is preceded by the .B \-now flag, the debugger is started immediately (i.e., in the middle of the .B debug command itself). Otherwise, the debugger is started with the next Tcl statement. The .B debug command does not change any traps. Compare this to starting Expect with the .B -D flag (see above). See the README file or SEE ALSO (below) for more information on the debugger. .TP .B disconnect disconnects a forked process from the terminal. It continues running in the background. The process is given its own process group (if possible). Standard I/O is redirected to /dev/null. .IP The following fragment uses .B disconnect to continue running the script in the background. .nf if {[fork]!=0} exit disconnect . . . .fi The following script reads a password, and then runs a program every hour that demands a password each time it is run. The script supplies the password so that you only have to type it once. (See the .B stty command which demonstrates how to turn off password echoing.) .nf send_user "password?\\ " expect_user -re "(.*)\\n" for {} 1 {} { if {[fork]!=0} {sleep 3600;continue} disconnect spawn priv_prog expect Password: send "$expect_out(1,string)\\r" . . . exit } .fi An advantage to using .B disconnect over the shell asynchronous process feature (&) is that .B Expect can save the terminal parameters prior to disconnection, and then later apply them to new ptys. With &, .B Expect does not have a chance to read the terminal's parameters since the terminal is already disconnected by the time .B Expect receives control. .TP .BI exit " [\-opts] [status]" causes .B Expect to exit or otherwise prepare to do so. The .B \-onexit flag causes the next argument to be used as an exit handler. Without an argument, the current exit handler is returned. The .B \-noexit flag causes .B Expect to prepare to exit but stop short of actually returning control to the operating system. The user-defined exit handler is run as well as Expect's own internal handlers. No further Expect commands should be executed. This is useful if you are running Expect with other Tcl extensions. The current interpreter (and main window if in the Tk environment) remain so that other Tcl extensions can clean up. If Expect's .B exit is called again (however this might occur), the handlers are not rerun. Upon exiting, all connections to spawned processes are closed. Closure will be detected as an EOF by spawned processes. .B exit takes no other actions beyond what the normal _exit(2) procedure does. Thus, spawned processes that do not check for EOF may continue to run. (A variety of conditions are important to determining, for example, what signals a spawned process will be sent, but these are system-dependent, typically documented under exit(3).) Spawned processes that continue to run will be inherited by init. .I status (or 0 if not specified) is returned as the exit status of .BR Expect . .B exit is implicitly executed if the end of the script is reached. .TP .B exp_continue The command .B exp_continue allows .B expect itself to continue executing rather than returning as it normally would. (See .B expect for more information.) .TP .BI exp_internal " [\-f file] value" causes further commands to send diagnostic information internal to .B Expect to stderr if .I value is non-zero. This output is disabled if .I value is 0. The diagnostic information includes every character received, and every attempt made to match the current output against the patterns. .IP If the optional .I file is supplied, all normal and debugging output is written to that file (regardless of the value of .IR value ). Any previous diagnostic output file is closed. The .B \-info flag causes exp_internal to return a description of the most recent non-info arguments given. .TP .BI exp_open " [args] [\-i spawn_id]" returns a Tcl file identifier that corresponds to the original spawn id. The file identifier can then be used as if it were opened by Tcl's .B open command. (The spawn id should no longer be used. A .B wait should not be executed. The .B \-leaveopen flag leaves the spawn id open for access through Expect commands. A .B wait must be executed on the spawn id. .TP .BI exp_pid " [\-i spawn_id]" returns the process id corresponding to the currently spawned process. If the .B \-i flag is used, the pid returned corresponds to that of the given spawn id. .TP .B exp_send is an alias for .BR send . .TP .B exp_send_error is an alias for .BR send_error . .TP .B exp_send_log is an alias for .BR send_log . .TP .B exp_send_tty is an alias for .BR send_tty . .TP .B exp_send_user is an alias for .BR send_user . .TP .BI exp_version " [[\-exit] version]" is useful for assuring that the script is compatible with the current version of Expect. .IP With no arguments, the current version of .B Expect is returned. This version may then be encoded in your script. If you actually know that you are not using features of recent versions, you can specify an earlier version. .IP Versions consist of three numbers separated by dots. First is the major number. Scripts written for versions of .B Expect with a different major number will almost certainly not work. .B exp_version returns an error if the major numbers do not match. .IP Second is the minor number. Scripts written for a version with a greater minor number than the current version may depend upon some new feature and might not run. .B exp_version returns an error if the major numbers match, but the script minor number is greater than that of the running .BR Expect . .IP Third is a number that plays no part in the version comparison. However, it is incremented when the .B Expect software distribution is changed in any way, such as by additional documentation or optimization. It is reset to 0 upon each new minor version. .IP With the .B \-exit flag, .B Expect prints an error and exits if the version is out of date. .TP .BI expect " [[\-opts] pat1 body1] ... [\-opts] patn [bodyn]" waits until one of the patterns matches the output of a spawned process, a specified time period has passed, or an end-of-file is seen. If the final body is empty, it may be omitted. .IP Patterns from the most recent .B expect_before command are implicitly used before any other patterns. Patterns from the most recent .B expect_after command are implicitly used after any other patterns. .IP If the arguments to the entire .B expect statement require more than one line, all the arguments may be "braced" into one so as to avoid terminating each line with a backslash. In this one case, the usual Tcl substitutions will occur despite the braces. .IP If a pattern is the keyword .BR eof , the corresponding body is executed upon end-of-file. If a pattern is the keyword .BR timeout , the corresponding body is executed upon timeout. If no timeout keyword is used, an implicit null action is executed upon timeout. The default timeout period is 10 seconds but may be set, for example to 30, by the command "set timeout 30". An infinite timeout may be designated by the value \-1. If a pattern is the keyword .BR default , the corresponding body is executed upon either timeout or end-of-file. .IP If a pattern matches, then the corresponding body is executed. .B expect returns the result of the body (or the empty string if no pattern matched). In the event that multiple patterns match, the one appearing first is used to select a body. .IP Each time new output arrives, it is compared to each pattern in the order they are listed. Thus, you may test for absence of a match by making the last pattern something guaranteed to appear, such as a prompt. In situations where there is no prompt, you must use .B timeout (just like you would if you were interacting manually). .IP Patterns are specified in three ways. By default, patterns are specified as with Tcl's .B string match command. (Such patterns are also similar to C-shell regular expressions usually referred to as "glob" patterns). The .B \-gl flag may may be used to protect patterns that might otherwise match .B expect flags from doing so. Any pattern beginning with a "-" should be protected this way. (All strings starting with "-" are reserved for future options.) .IP For example, the following fragment looks for a successful login. (Note that .B abort is presumed to be a procedure defined elsewhere in the script.) .nf .ta \w' expect 'u +\w'invalid password 'u expect { busy {puts busy\\n ; exp_continue} failed abort "invalid password" abort timeout abort connected } .fi Quotes are necessary on the fourth pattern since it contains a space, which would otherwise separate the pattern from the action. Patterns with the same action (such as the 3rd and 4th) require listing the actions again. This can be avoid by using regexp-style patterns (see below). More information on forming glob-style patterns can be found in the Tcl manual. .IP Regexp-style patterns follow the syntax defined by Tcl's .B regexp (short for "regular expression") command. regexp patterns are introduced with the flag .BR \-re . The previous example can be rewritten using a regexp as: .nf .ta \w' expect 'u +\w'connected 'u expect { busy {puts busy\\n ; exp_continue} \-re "failed|invalid password" abort timeout abort connected } .fi Both types of patterns are "unanchored". This means that patterns do not have to match the entire string, but can begin and end the match anywhere in the string (as long as everything else matches). Use ^ to match the beginning of a string, and $ to match the end. Note that if you do not wait for the end of a string, your responses can easily end up in the middle of the string as they are echoed from the spawned process. While still producing correct results, the output can look unnatural. Thus, use of $ is encouraged if you can exactly describe the characters at the end of a string. Note that in many editors, the ^ and $ match the beginning and end of lines respectively. However, because expect is not line oriented, these characters match the beginning and end of the data (as opposed to lines) currently in the expect matching buffer. (Also, see the note below on "system indigestion.") The .B \-ex flag causes the pattern to be matched as an "exact" string. No interpretation of *, ^, etc is made (although the usual Tcl conventions must still be observed). Exact patterns are always unanchored. .IP The .B \-nocase flag causes uppercase characters of the output to compare as if they were lowercase characters. The pattern is not affected. .IP While reading output, more than 2000 bytes can force earlier bytes to be "forgotten". This may be changed with the function .BR match_max . (Note that excessively large values can slow down the pattern matcher.) If .I patlist is .BR full_buffer , the corresponding body is executed if .I match_max bytes have been received and no other patterns have matched. Whether or not the .B full_buffer keyword is used, the forgotten characters are written to expect_out(buffer). If .I patlist is the keyword .BR null , and nulls are allowed (via the .B remove_nulls command), the corresponding body is executed if a single ASCII 0 is matched. It is not possible to match 0 bytes via glob or regexp patterns. Upon matching a pattern (or eof or full_buffer), any matching and previously unmatched output is saved in the variable .IR expect_out(buffer) . Up to 9 regexp substring matches are saved in the variables .I expect_out(1,string) through .IR expect_out(9,string) . If the .B -indices flag is used before a pattern, the starting and ending indices (in a form suitable for .BR lrange ) of the 10 strings are stored in the variables .I expect_out(X,start) and .I expect_out(X,end) where X is a digit, corresponds to the substring position in the buffer. 0 refers to strings which matched the entire pattern and is generated for glob patterns as well as regexp patterns. For example, if a process has produced output of "abcdefgh\\n", the result of: .nf expect "cd" .fi is as if the following statements had executed: .nf set expect_out(0,string) cd set expect_out(buffer) abcd .fi and "efgh\\n" is left in the output buffer. If a process produced the output "abbbcabkkkka\\n", the result of: .nf expect \-indices \-re "b(b*).*(k+)" .fi is as if the following statements had executed: .nf set expect_out(0,start) 1 set expect_out(0,end) 10 set expect_out(0,string) bbbcabkkkk set expect_out(1,start) 2 set expect_out(1,end) 3 set expect_out(1,string) bb set expect_out(2,start) 10 set expect_out(2,end) 10 set expect_out(2,string) k set expect_out(buffer) abbbcabkkkk .fi and "a\\n" is left in the output buffer. The pattern "*" (and -re ".*") will flush the output buffer without reading any more output from the process. .IP Normally, the matched output is discarded from Expect's internal buffers. This may be prevented by prefixing a pattern with the .B \-notransfer flag. This flag is especially useful in experimenting (and can be abbreviated to "-n" for convenience while experimenting). The spawn id associated with the matching output (or eof or full_buffer) is stored in .IR expect_out(spawn_id) . The .B \-timeout flag causes the current expect command to use the following value as a timeout instead of using the value of the timeout variable. By default, patterns are matched against output from the current process, however the .B \-i flag declares the output from the named spawn_id list be matched against any following patterns (up to the next .BR \-i ). The spawn_id list should either be a whitespace separated list of spawn_ids or a variable referring to such a list of spawn_ids. For example, the following example waits for "connected" from the current process, or "busy", "failed" or "invalid password" from the spawn_id named by $proc2. .nf expect { \-i $proc2 busy {puts busy\\n ; exp_continue} \-re "failed|invalid password" abort timeout abort connected } .fi The value of the global variable .I any_spawn_id may be used to match patterns to any spawn_ids that are named with all other .B \-i flags in the current .B expect command. The spawn_id from a .B \-i flag with no associated pattern (i.e., followed immediately by another .BR \-i ) is made available to any other patterns in the same .B expect command associated with .I any_spawn_id. The .B \-i flag may also name a global variable in which case the variable is read for a list of spawn ids. The variable is reread whenever it changes. This provides a way of changing the I/O source while the command is in execution. Spawn ids provided this way are called "indirect" spawn ids. Actions such as .B break and .B continue cause control structures (i.e., .BR for , .BR proc ) to behave in the usual way. The command .B exp_continue allows .B expect itself to continue executing rather than returning as it normally would. .IP This is useful for avoiding explicit loops or repeated expect statements. The following example is part of a fragment to automate rlogin. The .B exp_continue avoids having to write a second .B expect statement (to look for the prompt again) if the rlogin prompts for a password. .nf expect { Password: { stty -echo send_user "password (for $user) on $host: " expect_user -re "(.*)\\n" send_user "\\n" send "$expect_out(1,string)\\r" stty echo exp_continue } incorrect { send_user "invalid password or account\\n" exit } timeout { send_user "connection to $host timed out\\n" exit } eof { send_user \\ "connection to host failed: $expect_out(buffer)" exit } -re $prompt } .fi For example, the following fragment might help a user guide an interaction that is already totally automated. In this case, the terminal is put into raw mode. If the user presses "+", a variable is incremented. If "p" is pressed, several returns are sent to the process, perhaps to poke it in some way, and "i" lets the user interact with the process, effectively stealing away control from the script. In each case, the .B exp_continue allows the current .B expect to continue pattern matching after executing the current action. .nf stty raw \-echo expect_after { \-i $user_spawn_id "p" {send "\\r\\r\\r"; exp_continue} "+" {incr foo; exp_continue} "i" {interact; exp_continue} "quit" exit } .fi .IP By default, .B exp_continue resets the timeout timer. The timer is not restarted, if .B exp_continue is called with the .B \-continue_timer flag. .TP .BI expect_after " [expect_args]" works identically to the .B expect_before except that if patterns from both .B expect and .B expect_after can match, the .B expect pattern is used. See the .B expect_before command for more information. .TP .BI expect_background " [expect_args]" takes the same arguments as .BR expect , however it returns immediately. Patterns are tested whenever new input arrives. The pattern .B timeout and .B default are meaningless to .BR expect_background and are silently discarded. Otherwise, the .B expect_background command uses .B expect_before and .B expect_after patterns just like .B expect does. When .B expect_background actions are being evaluated, background processing for the same spawn id is blocked. Background processing is unblocked when the action completes. While background processing is blocked, it is possible to do a (foreground) .B expect on the same spawn id. It is not possible to execute an .B expect while an .B expect_background is unblocked. .B expect_background for a particular spawn id is deleted by declaring a new expect_background with the same spawn id. Declaring .B expect_background with no pattern removes the given spawn id from the ability to match patterns in the background. .TP .BI expect_before " [expect_args]" takes the same arguments as .BR expect , however it returns immediately. Pattern-action pairs from the most recent .B expect_before with the same spawn id are implicitly added to any following .B expect commands. If a pattern matches, it is treated as if it had been specified in the .B expect command itself, and the associated body is executed in the context of the .B expect command. If patterns from both .B expect_before and .B expect can match, the .B expect_before pattern is used. If no pattern is specified, the spawn id is not checked for any patterns. Unless overridden by a .B \-i flag, .B expect_before patterns match against the spawn id defined at the time that the .B expect_before command was executed (not when its pattern is matched). The \-info flag causes .B expect_before to return the current specifications of what patterns it will match. By default, it reports on the current spawn id. An optional spawn id specification may be given for information on that spawn id. For example .nf expect_before -info -i $proc .fi At most one spawn id specification may be given. The flag \-indirect suppresses direct spawn ids that come only from indirect specifications. Instead of a spawn id specification, the flag "-all" will cause "-info" to report on all spawn ids. The output of the \-info flag can be reused as the argument to expect_before. .TP .BI expect_tty " [expect_args]" is like .B expect but it reads characters from /dev/tty (i.e. keystrokes from the user). By default, reading is performed in cooked mode. Thus, lines must end with a return in order for .B expect to see them. This may be changed via .B stty (see the .B stty command below). .TP .BI expect_user " [expect_args]" is like .B expect but it reads characters from stdin (i.e. keystrokes from the user). By default, reading is performed in cooked mode. Thus, lines must end with a return in order for .B expect to see them. This may be changed via .B stty (see the .B stty command below). .TP .B fork creates a new process. The new process is an exact copy of the current .B Expect process. On success, .B fork returns 0 to the new (child) process and returns the process ID of the child process to the parent process. On failure (invariably due to lack of resources, e.g., swap space, memory), .B fork returns \-1 to the parent process, and no child process is created. .IP Forked processes exit via the .B exit command, just like the original process. Forked processes are allowed to write to the log files. If you do not disable debugging or logging in most of the processes, the result can be confusing. .IP Some pty implementations may be confused by multiple readers and writers, even momentarily. Thus, it is safest to .B fork before spawning processes. .TP .BI interact " [string1 body1] ... [stringn [bodyn]]" gives control of the current process to the user, so that keystrokes are sent to the current process, and the stdout and stderr of the current process are returned. .IP String-body pairs may be specified as arguments, in which case the body is executed when the corresponding string is entered. (By default, the string is not sent to the current process.) The .B interpreter command is assumed, if the final body is missing. .IP If the arguments to the entire .B interact statement require more than one line, all the arguments may be "braced" into one so as to avoid terminating each line with a backslash. In this one case, the usual Tcl substitutions will occur despite the braces. .IP For example, the following command runs interact with the following string-body pairs defined: When ^Z is pressed, .B Expect is suspended. (The .B \-reset flag restores the terminal modes.) When ^A is pressed, the user sees "you typed a control-A" and the process is sent a ^A. When $ is pressed, the user sees the date. When ^C is pressed, .B Expect exits. If "foo" is entered, the user sees "bar". When ~~ is pressed, the .B Expect interpreter runs interactively. .nf .ta \w' interact 'u +\w'$CTRLZ 'u +\w'{'u set CTRLZ \\032 interact { -reset $CTRLZ {exec kill \-STOP [pid]} \\001 {send_user "you typed a control\-A\\n"; send "\\001" } $ {send_user "The date is [exec date]."} \\003 exit foo {send_user "bar"} ~~ } .fi .IP In string-body pairs, strings are matched in the order they are listed as arguments. Strings that partially match are not sent to the current process in anticipation of the remainder coming. If characters are then entered such that there can no longer possibly be a match, only the part of the string will be sent to the process that cannot possibly begin another match. Thus, strings that are substrings of partial matches can match later, if the original strings that was attempting to be match ultimately fails. .IP By default, string matching is exact with no wild cards. (In contrast, the .B expect command uses glob-style patterns by default.) The .B \-ex flag may be used to protect patterns that might otherwise match .B interact flags from doing so. Any pattern beginning with a "-" should be protected this way. (All strings starting with "-" are reserved for future options.) The .B \-re flag forces the string to be interpreted as a regexp-style pattern. In this case, matching substrings are stored in the variable .I interact_out similarly to the way .B expect stores its output in the variable .BR expect_out . The .B \-indices flag is similarly supported. The pattern .B eof introduces an action that is executed upon end-of-file. A separate .B eof pattern may also follow the .B \-output flag in which case it is matched if an eof is detected while writing output. The default .B eof action is "return", so that .B interact simply returns upon any EOF. The pattern .B timeout introduces a timeout (in seconds) and action that is executed after no characters have been read for a given time. The .B timeout pattern applies to the most recently specified process. There is no default timeout. The special variable "timeout" (used by the .B expect command) has no affect on this timeout. For example, the following statement could be used to autologout users who have not typed anything for an hour but who still get frequent system messages: .nf interact -input $user_spawn_id timeout 3600 return -output \\ $spawn_id .fi If the pattern is the keyword .BR null , and nulls are allowed (via the .B remove_nulls command), the corresponding body is executed if a single ASCII 0 is matched. It is not possible to match 0 bytes via glob or regexp patterns. Prefacing a pattern with the flag .B \-iwrite causes the variable .I interact_out(spawn_id) to be set to the spawn_id which matched the pattern (or eof). Actions such as .B break and .B continue cause control structures (i.e., .BR for , .BR proc ) to behave in the usual way. However .B return causes interact to return to its caller, while .B inter_return causes .B interact to cause a return in its caller. For example, if "proc foo" called .B interact which then executed the action .BR inter_return , .B proc foo would return. (This means that if .B interact calls .B interpreter interactively typing .B return will cause the interact to continue, while .B inter_return will cause the interact to return to its caller.) .IP During .BR interact , raw mode is used so that all characters may be passed to the current process. If the current process does not catch job control signals, it will stop if sent a stop signal (by default ^Z). To restart it, send a continue signal (such as by "kill \-CONT <pid>"). If you really want to send a SIGSTOP to such a process (by ^Z), consider spawning csh first and then running your program. On the other hand, if you want to send a SIGSTOP to .B Expect itself, first press the escape character, and then press ^Z. .IP String-body pairs can be used as a shorthand for avoiding having to enter the interpreter and execute commands interactively. The previous terminal mode is used while the body of a string-body pair is being executed. .IP For speed, actions execute in raw mode by default. The .B \-reset flag resets the terminal to the mode it had before .B interact was executed (invariably, cooked mode). Note that characters entered when the mode is being switched may be lost (an unfortunate feature of the terminal driver on some systems). The only reason to use .B \-reset is if your action depends on running in cooked mode. .IP The .B \-echo flag sends characters that match the following pattern back to the process that generated them as each character is read. This may be useful when the user needs to see feedback from partially typed patterns. .IP If a pattern is being echoed but eventually fails to match, the characters are sent to the spawned process. If the spawned process then echoes them, the user will see the characters twice. .B \-echo is probably only appropriate in situations where the user is unlikely to not complete the pattern. For example, the following excerpt is from rftp, the recursive-ftp script, where the user is prompted to enter ~g, ~p, or ~l, to get, put, or list the current directory recursively. These are so far away from the normal ftp commands, that the user is unlikely to type ~ followed by anything else, except mistakenly, in which case, they'll probably just ignore the result anyway. .nf interact { -echo ~g {getcurdirectory 1} -echo ~l {getcurdirectory 0} -echo ~p {putcurdirectory} } .fi The .B \-nobuffer flag sends characters that match the following pattern on to the output process as characters are read. This is useful when you wish to let a program echo back the pattern. For example, the following might be used to monitor where a person is dialing (a Hayes-style modem). Each time "atd" is seen the script logs the rest of the line. .nf proc lognumber {} { interact -nobuffer -re "(.*)\\r" return puts $log "[exec date]: dialed $interact_out(1,string)" } interact -nobuffer "atd" lognumber .fi .IP During .BR interact , previous use of .B log_user is ignored. In particular, .B interact will force its output to be logged (sent to the standard output) since it is presumed the user doesn't wish to interact blindly. .IP The .B \-o flag causes any following key-body pairs to be applied to the output of the current process. This can be useful, for example, when dealing with hosts that send unwanted characters during a telnet session. .IP By default, .B interact expects the user to be writing stdin and reading stdout of the .B Expect process itself. The .B \-u flag (for "user") makes .B interact look for the user as the process named by its argument (which must be a spawned id). .IP This allows two unrelated processes to be joined together without using an explicit loop. To aid in debugging, Expect diagnostics always go to stderr (or stdout for certain logging and debugging information). For the same reason, the .B interpreter command will read interactively from stdin. .IP For example, the following fragment creates a login process. Then it dials the user (not shown), and finally connects the two together. Of course, any process may be substituted for login. A shell, for example, would allow the user to work without supplying an account and password. .nf spawn login set login $spawn_id spawn tip modem # dial back out to user # connect user to login interact \-u $login .fi To send output to multiple processes, list each spawn id list prefaced by a .B \-output flag. Input for a group of output spawn ids may be determined by a spawn id list prefaced by a .B \-input flag. (Both .B \-input and .B \-output may take lists in the same form as the .B \-i flag in the .B expect command, except that any_spawn_id is not meaningful in .BR interact .) All following flags and strings (or patterns) apply to this input until another -input flag appears. If no .B \-input appears, .B \-output implies "\-input $user_spawn_id \-output". (Similarly, with patterns that do not have .BR \-input .) If one .B \-input is specified, it overrides $user_spawn_id. If a second .B \-input is specified, it overrides $spawn_id. Additional .B \-input flags may be specified. The two implied input processes default to having their outputs specified as $spawn_id and $user_spawn_id (in reverse). If a .B \-input flag appears with no .B \-output flag, characters from that process are discarded. The .B \-i flag introduces a replacement for the current spawn_id when no other .B \-input or .B \-output flags are used. A \-i flag implies a \-o flag. It is possible to change the processes that are being interacted with by using indirect spawn ids. (Indirect spawn ids are described in the section on the expect command.) Indirect spawn ids may be specified with the -i, -u, -input, or -output flags. .TP .B interpreter causes the user to be interactively prompted for .B Expect and Tcl commands. The result of each command is printed. .IP Actions such as .B break and .B continue cause control structures (i.e., .BR for , .BR proc ) to behave in the usual way. However .B return causes interpreter to return to its caller, while .B inter_return causes .B interpreter to cause a return in its caller. For example, if "proc foo" called .B interpreter which then executed the action .BR inter_return , .B proc foo would return. Any other command causes .B interpreter to continue prompting for new commands. .IP By default, the prompt contains two integers. The first integer describes the depth of the evaluation stack (i.e., how many times Tcl_Eval has been called). The second integer is the Tcl history identifier. The prompt can be set by defining a procedure called "prompt1" whose return value becomes the next prompt. If a statement has open quotes, parens, braces, or brackets, a secondary prompt (by default "+> ") is issued upon newline. The secondary prompt may be set by defining a procedure called "prompt2". .IP During .BR interpreter , cooked mode is used, even if the its caller was using raw mode. .TP .BI log_file " [args] [[\-a] file]" If a filename is provided, .B log_file will record a transcript of the session (beginning at that point) in the file. .B log_file will stop recording if no argument is given. Any previous log file is closed. Instead of a filename, a Tcl file identifier may be provided by using the .B \-open or .B \-leaveopen flags. This is similar to the .B spawn command. (See .B spawn for more info.) The .B \-a flag forces output to be logged that was suppressed by the .B log_user command. By default, the .B log_file command .I appends to old files rather than truncating them, for the convenience of being able to turn logging off and on multiple times in one session. To truncate files, use the .B \-noappend flag. The .B -info flag causes log_file to return a description of the most recent non-info arguments given. .TP .BI log_user " -info|0|1" By default, the send/expect dialogue is logged to stdout (and a logfile if open). The logging to stdout is disabled by the command "log_user 0" and reenabled by "log_user 1". Logging to the logfile is unchanged. The .B -info flag causes log_user to return a description of the most recent non-info arguments given. .TP .BI match_max " [\-d] [\-i spawn_id] [size]" defines the size of the buffer (in bytes) used internally by .BR expect . With no .I size argument, the current size is returned. .IP With the .B \-d flag, the default size is set. (The initial default is 2000.) With the .B \-i flag, the size is set for the named spawn id, otherwise it is set for the current process. .TP .BI overlay " [\-# spawn_id] [\-# spawn_id] [...] program [args]" executes .IR "program args" in place of the current .B Expect program, which terminates. A bare hyphen argument forces a hyphen in front of the command name as if it was a login shell. All spawn_ids are closed except for those named as arguments. These are mapped onto the named file identifiers. .IP Spawn_ids are mapped to file identifiers for the new program to inherit. For example, the following line runs chess and allows it to be controlled by the current process \- say, a chess master. .nf overlay \-0 $spawn_id \-1 $spawn_id \-2 $spawn_id chess .fi This is more efficient than "interact \-u", however, it sacrifices the ability to do programmed interaction since the .B Expect process is no longer in control. .IP Note that no controlling terminal is provided. Thus, if you disconnect or remap standard input, programs that do job control (shells, login, etc) will not function properly. .TP .BI parity " [\-d] [\-i spawn_id] [value]" defines whether parity should be retained or stripped from the output of spawned processes. If .I value is zero, parity is stripped, otherwise it is not stripped. With no .I value argument, the current value is returned. .IP With the .B \-d flag, the default parity value is set. (The initial default is 1, i.e., parity is not stripped.) With the .B \-i flag, the parity value is set for the named spawn id, otherwise it is set for the current process. .TP .BI remove_nulls " [\-d] [\-i spawn_id] [value]" defines whether nulls are retained or removed from the output of spawned processes before pattern matching or storing in the variable .I expect_out or .IR interact_out . If .I value is 1, nulls are removed. If .I value is 0, nulls are not removed. With no .I value argument, the current value is returned. .IP With the .B \-d flag, the default value is set. (The initial default is 1, i.e., nulls are removed.) With the .B \-i flag, the value is set for the named spawn id, otherwise it is set for the current process. Whether or not nulls are removed, .B Expect will record null bytes to the log and stdout. .TP .BI send " [\-flags] string" Sends .IR string to the current process. For example, the command .nf send "hello world\\r" .fi sends the characters, h e l l o <blank> w o r l d <return> to the current process. (Tcl includes a printf-like command (called .BR format ) which can build arbitrarily complex strings.) .IP Characters are sent immediately although programs with line-buffered input will not read the characters until a return character is sent. A return character is denoted "\\r". The .B \-\- flag forces the next argument to be interpreted as a string rather than a flag. Any string can be preceded by "\-\-" whether or not it actually looks like a flag. This provides a reliable mechanism to specify variable strings without being tripped up by those that accidentally look like flags. (All strings starting with "-" are reserved for future options.) The .B \-i flag declares that the string be sent to the named spawn_id. If the spawn_id is .IR user_spawn_id , and the terminal is in raw mode, newlines in the string are translated to return-newline sequences so that they appear as it the terminal was in cooked mode. The .B \-raw flag disables this translation. The .BR \-null flag sends null characters (0 bytes). By default, one null is sent. An integer may follow the .BR \-null to indicate how many nulls to send. The .B \-break flag generates a break condition. This only makes sense if the spawn id refers to a tty device opened via "spawn -open". If you have spawned a process such as tip, you should use tip's convention for generating a break. The .B \-s flag forces output to be sent "slowly", thus avoid the common situation where a computer outtypes an input buffer that was designed for a human who would never outtype the same buffer. This output is controlled by the value of the variable "send_slow" which takes a two element list. The first element is an integer that describes the number of bytes to send atomically. The second element is a real number that describes the number of seconds by which the atomic sends must be separated. For example, "set send_slow {10 .001}" would force "send \-s" to send strings with 1 millisecond in between each 10 characters sent. The .B \-h flag forces output to be sent (somewhat) like a human actually typing. Human-like delays appear between the characters. (The algorithm is based upon a Weibull distribution, with modifications to suit this particular application.) This output is controlled by the value of the variable "send_human" which takes a five element list. The first two elements are average interarrival time of characters in seconds. The first is used by default. The second is used at word endings, to simulate the subtle pauses that occasionally occur at such transitions. The third parameter is a measure of variability where .1 is quite variable, 1 is reasonably variable, and 10 is quite invariable. The extremes are 0 to infinity. The last two parameters are, respectively, a minimum and maximum interarrival time. The minimum and maximum are used last and "clip" the final time. The ultimate average can be quite different from the given average if the minimum and maximum clip enough values. As an example, the following command emulates a fast and consistent typist: .nf set send_human {.1 .3 1 .05 2} send \-h "I'm hungry. Let's do lunch." .fi while the following might be more suitable after a hangover: .nf set send_human {.4 .4 .2 .5 100} send \-h "Goodd party lash night!" .fi Note that errors are not simulated, although you can set up error correction situations yourself by embedding mistakes and corrections in a send argument. The flags for sending null characters, for sending breaks, for forcing slow output and for human-style output are mutually exclusive. Only the one specified last will be used. Furthermore, no .I string argument can be specified with the flags for sending null characters or breaks. It is a good idea to precede the first .B send to a process by an .BR expect . .B expect will wait for the process to start, while .B send cannot. In particular, if the first .B send completes before the process starts running, you run the risk of having your data ignored. In situations where interactive programs offer no initial prompt, you can precede .B send by a delay as in: .nf # To avoid giving hackers hints on how to break in, # this system does not prompt for an external password. # Wait for 5 seconds for exec to complete spawn telnet very.secure.gov sleep 5 send password\\r .fi .B exp_send is an alias for .BI send . If you are using Expectk or some other variant of Expect in the Tk environment, .B send is defined by Tk for an entirely different purpose. .B exp_send is provided for compatibility between environments. Similar aliases are provided for other Expect's other send commands. .TP .BI send_error " [\-flags] string" is like .BR send , except that the output is sent to stderr rather than the current process. .TP .BI send_log " [\--] string" is like .BR send , except that the string is only sent to the log file (see .BR log_file .) The arguments are ignored if no log file is open. .TP .BI send_tty " [\-flags] string" is like .BR send , except that the output is sent to /dev/tty rather than the current process. .TP .BI send_user " [\-flags] string" is like .BR send , except that the output is sent to stdout rather than the current process. .TP .BI sleep " seconds" causes the script to sleep for the given number of seconds. Seconds may be a decimal number. Interrupts (and Tk events if you are using Expectk) are processed while Expect sleeps. .TP .BI spawn " [args] program [args]" creates a new process running .IR "program args" . Its stdin, stdout and stderr are connected to Expect, so that they may be read and written by other .B Expect commands. The connection is broken by .B close or if the process itself closes any of the file identifiers. .IP When a process is started by .BR spawn , the variable .I spawn_id is set to a descriptor referring to that process. The process described by .I spawn_id is considered the .IR "current process" . .I spawn_id may be read or written, in effect providing job control. .IP .I user_spawn_id is a global variable containing a descriptor which refers to the user. For example, when .I spawn_id is set to this value, .B expect behaves like .BR expect_user . .I .I error_spawn_id is a global variable containing a descriptor which refers to the standard error. For example, when .I spawn_id is set to this value, .B send behaves like .BR send_error . .IP .I tty_spawn_id is a global variable containing a descriptor which refers to /dev/tty. If /dev/tty does not exist (such as in a cron, at, or batch script), then .I tty_spawn_id is not defined. This may be tested as: .nf if {[info vars tty_spawn_id]} { # /dev/tty exists } else { # /dev/tty doesn't exist # probably in cron, batch, or at script } .fi .IP .B spawn returns the UNIX process id. If no process is spawned, 0 is returned. The variable .I spawn_out(slave,name) is set to the name of the pty slave device. .IP By default, .B spawn echoes the command name and arguments. The .B \-noecho flag stops .B spawn from doing this. .IP The .B \-console flag causes console output to be redirected to the spawned process. This is not supported on all systems. Internally, .B spawn uses a pty, initialized the same way as the user's tty. This is further initialized so that all settings are "sane" (according to stty(1)). If the variable .I stty_init is defined, it is interpreted in the style of stty arguments as further configuration. For example, "set stty_init raw" will cause further spawned processes's terminals to start in raw mode. .B \-nottycopy skips the initialization based on the user's tty. .B \-nottyinit skips the "sane" initialization. .IP Normally, .B spawn takes little time to execute. If you notice spawn taking a significant amount of time, it is probably encountering ptys that are wedged. A number of tests are run on ptys to avoid entanglements with errant processes. (These take 10 seconds per wedged pty.) Running Expect with the .B \-d option will show if .B Expect is encountering many ptys in odd states. If you cannot kill the processes to which these ptys are attached, your only recourse may be to reboot. If .I program cannot be spawned successfully because exec(2) fails (e.g. when .I program doesn't exist), an error message will be returned by the next .B interact or .B expect command as if .I program had run and produced the error message as output. This behavior is a natural consequence of the implementation of .BR spawn . Internally, spawn forks, after which the spawned process has no way to communicate with the original .B Expect process except by communication via the spawn_id. The .B \-open flag causes the next argument to be interpreted as a Tcl file identifier (i.e., returned by .BR open .) The spawn id can then be used as if it were a spawned process. (The file identifier should no longer be used.) This lets you treat raw devices, files, and pipelines as spawned processes without using a pty. 0 is returned to indicate there is no associated process. When the connection to the spawned process is closed, so is the Tcl file identifier. The .B \-leaveopen flag is similar to .B \-open except that .B \-leaveopen causes the file identifier to be left open even after the spawn id is closed. The .B \-pty flag causes a pty to be opened but no process spawned. 0 is returned to indicate there is no associated process. Spawn_id is set as usual. The variable .I spawn_out(slave,fd) is set to a file identifier corresponding to the pty slave. It can be closed using "close -slave". The .B \-ignore flag names a signal to be ignored in the spawned process. Otherwise, signals get the default behavior. Signals are named as in the .B trap command, except that each signal requires a separate flag. .TP .BI strace " level" causes following statements to be printed before being executed. (Tcl's trace command traces variables.) .I level indicates how far down in the call stack to trace. For example, the following command runs .B Expect while tracing the first 4 levels of calls, but none below that. .nf expect \-c "strace 4" script.exp .fi The .B -info flag causes strace to return a description of the most recent non-info arguments given. .TP .BI stty " args" changes terminal modes similarly to the external stty command. By default, the controlling terminal is accessed. Other terminals can be accessed by appending "< /dev/tty..." to the command. (Note that the arguments should not be grouped into a single argument.) Requests for status return it as the result of the command. If no status is requested and the controlling terminal is accessed, the previous status of the raw and echo attributes are returned in a form which can later be used by the command. For example, the arguments .B raw or .B \-cooked put the terminal into raw mode. The arguments .B \-raw or .B cooked put the terminal into cooked mode. The arguments .B echo and .B \-echo put the terminal into echo and noecho mode respectively. .IP The following example illustrates how to temporarily disable echoing. This could be used in otherwise-automatic scripts to avoid embedding passwords in them. (See more discussion on this under EXPECT HINTS below.) .nf stty \-echo send_user "Password: " expect_user -re "(.*)\\n" set password $expect_out(1,string) stty echo .fi .TP .BI system " args" gives .I args to sh(1) as input, just as if it had been typed as a command from a terminal. .B Expect waits until the shell terminates. The return status from sh is handled the same way that .B exec handles its return status. .IP In contrast to .B exec which redirects stdin and stdout to the script, .B system performs no redirection (other than that indicated by the string itself). Thus, it is possible to use programs which must talk directly to /dev/tty. For the same reason, the results of .B system are not recorded in the log. .TP .BI timestamp " [args]" returns a timestamp. With no arguments, the number of seconds since the epoch is returned. The .B \-format flag introduces a string which is returned but with substitutions made according to the POSIX rules for strftime. For example %a is replaced by an abbreviated weekday name (i.e., Sat). Others are: .nf %a abbreviated weekday name %A full weekday name %b abbreviated month name %B full month name %c date-time as in: Wed Oct 6 11:45:56 1993 %d day of the month (01-31) %H hour (00-23) %I hour (01-12) %j day (001-366) %m month (01-12) %M minute (00-59) %p am or pm %S second (00-61) %u day (1-7, Monday is first day of week) %U week (00-53, first Sunday is first day of week one) %V week (01-53, ISO 8601 style) %w day (0-6) %W week (00-53, first Monday is first day of week one) %x date-time as in: Wed Oct 6 1993 %X time as in: 23:59:59 %y year (00-99) %Y year as in: 1993 %Z timezone (or nothing if not determinable) %% a bare percent sign .fi Other % specifications are undefined. Other characters will be passed through untouched. Only the C locale is supported. The .B \-seconds flag introduces a number of seconds since the epoch to be used as a source from which to format. Otherwise, the current time is used. The .B \-gmt flag forces timestamp output to use the GMT timezone. With no flag, the local timezone is used. .TP .BI trap " [[command] signals]" causes the given .I command to be executed upon future receipt of any of the given signals. The command is executed in the global scope. If .I command is absent, the signal action is returned. If .I command is the string SIG_IGN, the signals are ignored. If .I command is the string SIG_DFL, the signals are result to the system default. .I signals is either a single signal or a list of signals. Signals may be specified numerically or symbolically as per signal(3). The "SIG" prefix may be omitted. With no arguments (or the argument \-number), .B trap returns the signal number of the trap command currently being executed. The .B \-code flag uses the return code of the command in place of whatever code Tcl was about to return when the command originally started running. The .B \-interp flag causes the command to be evaluated using the interpreter active at the time the command started running rather than when the trap was declared. The .B \-name flag causes the .B trap command to return the signal name of the trap command currently being executed. The .B \-max flag causes the .B trap command to return the largest signal number that can be set. For example, the command "trap {send_user "Ouch!"} SIGINT" will print "Ouch!" each time the user presses ^C. By default, SIGINT (which can usually be generated by pressing ^C) and SIGTERM cause Expect to exit. This is due to the following trap, created by default when Expect starts. .nf trap exit {SIGINT SIGTERM} .fi If you use the -D flag to start the debugger, SIGINT is redefined to start the interactive debugger. This is due to the following trap: .nf trap {exp_debug 1} SIGINT .fi The debugger trap can be changed by setting the environment variable EXPECT_DEBUG_INIT to a new trap command. You can, of course, override both of these just by adding trap commands to your script. In particular, if you have your own "trap exit SIGINT", this will override the debugger trap. This is useful if you want to prevent users from getting to the debugger at all. If you want to define your own trap on SIGINT but still trap to the debugger when it is running, use: .nf if ![exp_debug] {trap mystuff SIGINT} .fi Alternatively, you can trap to the debugger using some other signal. .B trap will not let you override the action for SIGALRM as this is used internally to .BR Expect . The disconnect command sets SIGALRM to SIG_IGN (ignore). You can reenable this as long as you disable it during subsequent spawn commands. See signal(3) for more info. .TP .BI wait " [args]" delays until a spawned process (or the current process if none is named) terminates. .IP .B wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set. Additional elements may appear at the end of the return value from .BR wait . An optional fifth element identifies a class of information. Currently, the only possible value for this element is CHILDKILLED in which case the next two values are the C-style signal name and a short textual description. .IP The .B \-i flag declares the process to wait corresponding to the named spawn_id (NOT the process id). Inside a SIGCHLD handler, it is possible to wait for any spawned process by using the spawn id -1. The .B \-nowait flag causes the wait to return immediately with the indication of a successful wait. When the process exits (later), it will automatically disappear without the need for an explicit wait. The .B wait command may also be used wait for a forked process using the arguments "-i -1". Unlike its use with spawned processes, this command can be executed at any time. There is no control over which process is reaped. However, the return value can be checked for the process id. .SH LIBRARIES Expect automatically knows about two built-in libraries for Expect scripts. These are defined by the directories named in the variables exp_library and exp_exec_library. Both are meant to contain utility files that can be used by other scripts. exp_library contains architecture-independent files. exp_exec_library contains architecture-dependent files. Depending on your system, both directories may be totally empty. The existence of the file $exp_exec_library/cat-buffers describes whether your /bin/cat buffers by default. .SH PRETTY-PRINTING A vgrind definition is available for pretty-printing .B Expect scripts. Assuming the vgrind definition supplied with the .B Expect distribution is correctly installed, you can use it as: .nf vgrind \-lexpect file .fi .SH EXAMPLES It many not be apparent how to put everything together that the man page describes. I encourage you to read and try out the examples in the example directory of the .B Expect distribution. Some of them are real programs. Others are simply illustrative of certain techniques, and of course, a couple are just quick hacks. The INSTALL file has a quick overview of these programs. .PP The .B Expect papers (see SEE ALSO) are also useful. While some papers use syntax corresponding to earlier versions of Expect, the accompanying rationales are still valid and go into a lot more detail than this man page. .SH CAVEATS Extensions may collide with Expect's command names. For example, .B send is defined by Tk for an entirely different purpose. For this reason, most of the .B Expect commands are also available as "exp_XXXX". Commands and variables beginning with "exp", "inter", "spawn", and "timeout" do not have aliases. Use the extended command names if you need this compatibility between environments. .B Expect takes a rather liberal view of scoping. In particular, variables read by commands specific to the .B Expect program will be sought first from the local scope, and if not found, in the global scope. For example, this obviates the need to place "global timeout" in every procedure you write that uses .BR expect . On the other hand, variables written are always in the local scope (unless a "global" command has been issued). The most common problem this causes is when spawn is executed in a procedure. Outside the procedure, .I spawn_id no longer exists, so the spawned process is no longer accessible simply because of scoping. Add a "global spawn_id" to such a procedure. If you cannot enable the multispawning capability (i.e., your system supports neither select (BSD *.*), poll (SVR>2), nor something equivalent), .B Expect will only be able to control a single process at a time. In this case, do not attempt to set .IR spawn_id , nor should you execute processes via exec while a spawned process is running. Furthermore, you will not be able to .B expect from multiple processes (including the user as one) at the same time. Terminal parameters can have a big effect on scripts. For example, if a script is written to look for echoing, it will misbehave if echoing is turned off. For this reason, Expect forces sane terminal parameters by default. Unfortunately, this can make things unpleasant for other programs. As an example, the emacs shell wants to change the "usual" mappings: newlines get mapped to newlines instead of carriage-return newlines, and echoing is disabled. This allows one to use emacs to edit the input line. Unfortunately, Expect cannot possibly guess this. You can request that Expect not override its default setting of terminal parameters, but you must then be very careful when writing scripts for such environments. In the case of emacs, avoid depending upon things like echoing and end-of-line mappings. The commands that accepted arguments braced into a single list (the .B expect variants and .BR interact ) use a heuristic to decide if the list is actually one argument or many. The heuristic can fail only in the case when the list actually does represent a single argument which has multiple embedded \\n's with non-whitespace characters between them. This seems sufficiently improbable, however the argument "\-nobrace" can be used to force a single argument to be handled as a single argument. This could conceivably be used with machine-generated Expect code. .SH BUGS It was really tempting to name the program "sex" (for either "Smart EXec" or "Send-EXpect"), but good sense (or perhaps just Puritanism) prevailed. On some systems, when a shell is spawned, it complains about not being able to access the tty but runs anyway. This means your system has a mechanism for gaining the controlling tty that .B Expect doesn't know about. Please find out what it is, and send this information back to me. Ultrix 4.1 (at least the latest versions around here) considers timeouts of above 1000000 to be equivalent to 0. Digital UNIX 4.0A (and probably other versions) refuses to allocate ptys if you define a SIGCHLD handler. See grantpt page for more info. IRIX 6.0 does not handle pty permissions correctly so that if Expect attempts to allocate a pty previously used by someone else, it fails. Upgrade to IRIX 6.1. Telnet (verified only under SunOS 4.1.2) hangs if TERM is not set. This is a problem under cron, at and in cgi scripts, which do not define TERM. Thus, you must set it explicitly - to what type is usually irrelevant. It just has to be set to something! The following probably suffices for most cases. .nf set env(TERM) vt100 .fi Tip (verified only under BSDI BSD/OS 3.1 i386) hangs if SHELL and HOME are not set. This is a problem under cron, at and in cgi scripts, which do not define these environment variables. Thus, you must set them explicitly - to what type is usually irrelevant. It just has to be set to something! The following probably suffices for most cases. .nf set env(SHELL) /bin/sh set env(HOME) /usr/local/bin .fi Some implementations of ptys are designed so that the kernel throws away any unread output after 10 to 15 seconds (actual number is implementation-dependent) after the process has closed the file descriptor. Thus .B Expect programs such as .nf spawn date sleep 20 expect .fi will fail. To avoid this, invoke non-interactive programs with .B exec rather than .BR spawn . While such situations are conceivable, in practice I have never encountered a situation in which the final output of a truly interactive program would be lost due to this behavior. On the other hand, Cray UNICOS ptys throw away any unread output immediately after the process has closed the file descriptor. I have reported this to Cray and they are working on a fix. Sometimes a delay is required between a prompt and a response, such as when a tty interface is changing UART settings or matching baud rates by looking for start/stop bits. Usually, all this is require is to sleep for a second or two. A more robust technique is to retry until the hardware is ready to receive input. The following example uses both strategies: .nf send "speed 9600\\r"; sleep 1 expect { timeout {send "\\r"; exp_continue} $prompt } .fi .SH EXPECT HINTS There are a couple of things about .B Expect that may be non-intuitive. This section attempts to address some of these things with a couple of suggestions. A common expect problem is how to recognize shell prompts. Since these are customized differently by differently people and different shells, portably automating rlogin can be difficult without knowing the prompt. A reasonable convention is to have users store a regular expression describing their prompt (in particular, the end of it) in the environment variable EXPECT_PROMPT. Code like the following can be used. If EXPECT_PROMPT doesn't exist, the code still has a good chance of functioning correctly. .nf set prompt "(%|#|\\\\$) $" ;# default prompt catch {set prompt $env(EXPECT_PROMPT)} expect -re $prompt .fi I encourage you to write .B expect patterns that include the end of whatever you expect to see. This avoids the possibility of answering a question before seeing the entire thing. In addition, while you may well be able to answer questions before seeing them entirely, if you answer early, your answer may appear echoed back in the middle of the question. In other words, the resulting dialogue will be correct but look scrambled. Most prompts include a space character at the end. For example, the prompt from ftp is 'f', 't', 'p', '>' and <blank>. To match this prompt, you must account for each of these characters. It is a common mistake not to include the blank. Put the blank in explicitly. If you use a pattern of the form X*, the * will match all the output received from the end of X to the last thing received. This sounds intuitive but can be somewhat confusing because the phrase "last thing received" can vary depending upon the speed of the computer and the processing of I/O both by the kernel and the device driver. .PP In particular, humans tend to see program output arriving in huge chunks (atomically) when in reality most programs produce output one line at a time. Assuming this is the case, the * in the pattern of the previous paragraph may only match the end of the current line even though there seems to be more, because at the time of the match that was all the output that had been received. .PP .B expect has no way of knowing that further output is coming unless your pattern specifically accounts for it. .PP Even depending on line-oriented buffering is unwise. Not only do programs rarely make promises about the type of buffering they do, but system indigestion can break output lines up so that lines break at seemingly random places. Thus, if you can express the last few characters of a prompt when writing patterns, it is wise to do so. If you are waiting for a pattern in the last output of a program and the program emits something else instead, you will not be able to detect that with the .B timeout keyword. The reason is that .B expect will not timeout \- instead it will get an .B eof indication. Use that instead. Even better, use both. That way if that line is ever moved around, you won't have to edit the line itself. Newlines are usually converted to carriage return, linefeed sequences when output by the terminal driver. Thus, if you want a pattern that explicitly matches the two lines, from, say, printf("foo\\nbar"), you should use the pattern "foo\\r\\nbar". .PP A similar translation occurs when reading from the user, via .BR expect_user . In this case, when you press return, it will be translated to a newline. If .B Expect then passes that to a program which sets its terminal to raw mode (like telnet), there is going to be a problem, as the program expects a true return. (Some programs are actually forgiving in that they will automatically translate newlines to returns, but most don't.) Unfortunately, there is no way to find out that a program put its terminal into raw mode. .PP Rather than manually replacing newlines with returns, the solution is to use the command "stty raw", which will stop the translation. Note, however, that this means that you will no longer get the cooked line-editing features. .PP .B interact implicitly sets your terminal to raw mode so this problem will not arise then. It is often useful to store passwords (or other private information) in .B Expect scripts. This is not recommended since anything that is stored on a computer is susceptible to being accessed by anyone. Thus, interactively prompting for passwords from a script is a smarter idea than embedding them literally. Nonetheless, sometimes such embedding is the only possibility. .PP Unfortunately, the UNIX file system has no direct way of creating scripts which are executable but unreadable. Systems which support setgid shell scripts may indirectly simulate this as follows: .PP Create the .B Expect script (that contains the secret data) as usual. Make its permissions be 750 (\-rwxr\-x\-\-\-) and owned by a trusted group, i.e., a group which is allowed to read it. If necessary, create a new group for this purpose. Next, create a /bin/sh script with permissions 2751 (\-rwxr\-s\-\-x) owned by the same group as before. .PP The result is a script which may be executed (and read) by anyone. When invoked, it runs the .B Expect script. .SH SEE ALSO .BR Tcl (3), .BR libexpect (3) .br .I "Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs" \fRby Don Libes, pp. 602, ISBN 1-56592-090-2, O'Reilly and Associates, 1995. .br .I "expect: Curing Those Uncontrollable Fits of Interactivity" \fRby Don Libes, Proceedings of the Summer 1990 USENIX Conference, Anaheim, California, June 11-15, 1990. .br .I "Using .B expect to Automate System Administration Tasks" \fRby Don Libes, Proceedings of the 1990 USENIX Large Installation Systems Administration Conference, Colorado Springs, Colorado, October 17-19, 1990. .br .I "Tcl: An Embeddable Command Language" \fRby John Ousterhout, Proceedings of the Winter 1990 USENIX Conference, Washington, D.C., January 22-26, 1990. .br .I "expect: Scripts for Controlling Interactive Programs" \fRby Don Libes, Computing Systems, Vol. 4, No. 2, University of California Press Journals, November 1991. .br .I "Regression Testing and Conformance Testing Interactive Programs", \fRby Don Libes, Proceedings of the Summer 1992 USENIX Conference, pp. 135-144, San Antonio, TX, June 12-15, 1992. .br .I "Kibitz \- Connecting Multiple Interactive Programs Together", \fRby Don Libes, Software \- Practice & Experience, John Wiley & Sons, West Sussex, England, Vol. 23, No. 5, May, 1993. .br .I "A Debugger for Tcl Applications", \fRby Don Libes, Proceedings of the 1993 Tcl/Tk Workshop, Berkeley, CA, June 10-11, 1993. .SH AUTHOR Don Libes, National Institute of Standards and Technology .SH ACKNOWLEDGMENTS Thanks to John Ousterhout for Tcl, and Scott Paisley for inspiration. Thanks to Rob Savoye for Expect's autoconfiguration code. .PP The HISTORY file documents much of the evolution of .BR expect . It makes interesting reading and might give you further insight to this software. Thanks to the people mentioned in it who sent me bug fixes and gave other assistance. .PP Design and implementation of .B Expect was paid for in part by the U.S. government and is therefore in the public domain. However the author and NIST would like credit if this program and documentation or portions of them are used. |
Added doc/expectk.man.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | .TH EXPECTK 1 "15 February 1993" .SH NAME expectk \- Expect with Tk support .SH SYNOPSIS .B expectk [ .I args ] .SH INTRODUCTION .B Expectk is a combination of Expect with Tk. (See their respective man pages for a more comprehensive explanation of either.) .B Expectk should run any .B wish or .B Expect script (with minor changes - see below). .PP The differences between the Expectk and Expect environment follows. .PP The .B send command is Tk's. Expect's .B send command can be invoked by the name .BR exp_send . (For compatibility, Expect allows either .B send or .B exp_send to be used.) .PP Scripts may be invoked implicitly on systems which support the #! notation by marking the script executable, and making the first line in your script: #!/usr/local/bin/expectk \-f Of course, the path must accurately describe where .B Expectk lives. /usr/local/bin is just an example. |
Added doc/libexpect.man.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | .TH LIBEXPECT 3 "12 December 1991" .SH NAME libexpect \- programmed dialogue with interactive programs \- C functions .SH DESCRIPTION This library contains functions that allow Expect to be used as a Tcl extension or to be used directly from C or C++ (without Tcl). Adding Expect as a Tcl extension is very short and simple, so that will be covered first. .SH SYNOPSIS .nf .B #include "expect_tcl.h" .B Expect_Init(interp); .B cc files... \-lexpect5.20 \-ltcl7.5 \-lm .fi Note: library versions may differ in the actual release. The Expect_Init function adds expect commands to the named interpreter. It avoids overwriting commands that already exist, however aliases beginning with "exp_" are always created for expect commands. So for example, "send" can be used as "exp_send". Generally, you should only call Expect commands via Tcl_Eval. Certain auxiliary functions may be called directly. They are summarized below. They may be useful in constructing your own main. Look at the file exp_main_exp.c in the Expect distribution as a prototype main. Another prototype is tclAppInit.c in the Tcl source distribution. A prototype for working with Tk is in exp_main_tk.c in the Expect distribution. .nf int exp_cmdlinecmds; int exp_interactive; FILE *exp_cmdfile; char *exp_cmdfilename; int exp_tcl_debugger_available; void exp_parse_argv(Tcl_Interp *,int argc,char **argv); int exp_interpreter(Tcl_Interp *); void exp_interpret_cmdfile(Tcl_Interp *,FILE *); void exp_interpret_cmdfilename(Tcl_Interp *,char *); void exp_interpret_rcfiles(Tcl_Interp *,int my_rc,int sys_rc); char * exp_cook(char *s,int *len); void (*exp_app_exit)EXP_PROTO((Tcl_Interp *); void exp_exit(Tcl_Interp *,int status); void exp_exit_handlers(Tcl_Interp *); void exp_error(Tcl_Interp,char *,...); .fi .B exp_cmdlinecmds is 1 if Expect has been invoked with commands on the program command-line (using "-c" for example). .B exp_interactive is 1 if Expect has been invoked with the -i flag or if no commands or script is being invoked. .B exp_cmdfile is a stream from which Expect will read commands. .B exp_cmdfilename is the name of a file which Expect will open and read commands from. .B exp_tcl_debugger_available is 1 if the debugger has been armed. .B exp_parse_argv reads the representation of the command line. Based on what is found, any of the other variables listed here are initialized appropriately. .B exp_interpreter interactively prompts the user for commands and evaluates them. .B exp_interpret_cmdfile reads the given stream and evaluates any commands found. .B exp_interpret_cmdfilename opens the named file and evaluates any commands found. .B exp_interpret_rcfiles reads and evalutes the .rc files. If my_rc is zero, then ~/.expectrc is skipped. If sys_rc is zero, then the system-wide expectrc file is skipped. .B exp_cook returns a static buffer containing the argument reproduced with newlines replaced by carriage-return linefeed sequences. The primary purpose of this is to allow messages to be produced without worrying about whether the terminal is in raw mode or cooked mode. If length is zero, it is computed via strlen. .B exp_error is a printf-like function that writes the result to interp->result. .SH SYNOPSIS .nf .B #include <expect.h> .B int .B "exp_spawnl(file, arg0 [, arg1, ..., argn] (char *)0);" .B char *file; .B char *arg0, *arg1, ... *argn; .B int .B exp_spawnv(file,argv); .B char *file, *argv[ ]; .B int .B exp_spawnfd(fd); .B int fd; .B FILE * .B exp_popen(command); .B char *command; .B extern int exp_pid; .B extern int exp_ttyinit; .B extern int exp_ttycopy; .B extern int exp_console; .B extern char *exp_stty_init; .B extern void (*exp_close_in_child)(); .B extern void (*exp_child_exec_prelude)(); .B extern void exp_close_tcl_files(); .B cc files... \-lexpect \-ltcl \-lm .fi .SH DESCRIPTION .B exp_spawnl and .B exp_spawnv fork a new process so that its stdin, stdout, and stderr can be written and read by the current process. .I file is the name of a file to be executed. The .I arg pointers are null-terminated strings. Following the style of execve(), .I arg0 (or .IR argv[0] ) is customarily a duplicate of the name of the file. .PP Four interfaces are available, .B exp_spawnl is useful when the number of arguments is known at compile time. .B exp_spawnv is useful when the number of arguments is not known at compile time. .B exp_spawnfd is useful when an open file descriptor is already available as a source. .B exp_popen is explained later on. .PP If the process is successfully created, a file descriptor is returned which corresponds to the process's stdin, stdout and stderr. A stream may be associated with the file descriptor by using fdopen(). (This should almost certainly be followed by setbuf() to unbuffer the I/O.) .PP Closing the file descriptor will typically be detected by the process as an EOF. Once such a process exits, it should be waited upon (via wait) in order to free up the kernel process slot. (Some systems allow you to avoid this if you ignore the SIGCHLD signal). .PP .B exp_popen is yet another interface, styled after popen(). It takes a Bourne shell command line, and returns a stream that corresponds to the process's stdin, stdout and stderr. The actual implementation of .B exp_popen below demonstrates .BR exp_spawnl . .nf FILE * exp_popen(program) char *program; { FILE *fp; int ec; if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0))) return(0); if (NULL == (fp = fdopen(ec,"r+")) return(0); setbuf(fp,(char *)0); return(fp); } .fi After a process is started, the variable .B exp_pid is set to the process-id of the new process. The variable .B exp_pty_slave_name is set to the name of the slave side of the pty. The spawn functions uses a pty to communicate with the process. By default, the pty is initialized the same way as the user's tty (if possible, i.e., if the environment has a controlling terminal.) This initialization can be skipped by setting exp_ttycopy to 0. The pty is further initialized to some system wide defaults if exp_ttyinit is non-zero. The default is generally comparable to "stty sane". The tty setting can be further modified by setting the variable .BR exp_stty_init . This variable is interpreted in the style of stty arguments. For example, exp_stty_init = "sane"; repeats the default initialization. On some systems, it is possible to redirect console output to ptys. If this is supported, you can force the next spawn to obtain the console output by setting the variable .B exp_console to 1. Between the time a process is started and the new program is given control, the spawn functions can clean up the environment by closing file descriptors. By default, the only file descriptors closed are ones internal to Expect and any marked "close-on-exec". If needed, you can close additional file descriptors by creating an appropriate function and assigning it to exp_close_in_child. The function will be called after the fork and before the exec. (This also modifies the behavior of the spawn command in Expect.) If you are also using Tcl, it may be convenient to use the function exp_close_tcl_files which closes all files between the default standard file descriptors and the highest descriptor known to Tcl. (Expect does this.) The function exp_child_exec_prelude is the last function called prior to the actual exec in the child. You can redefine this for effects such as manipulating the uid or the signals. .SH "IF YOU WANT TO ALLOCATE YOUR OWN PTY" .nf .B extern int exp_autoallocpty; .B extern int exp_pty[2]; .fi The spawn functions use a pty to communicate with the process. By default, a pty is automatically allocated each time a process is spawned. If you want to allocate ptys yourself, before calling one of the spawn functions, set .B exp_autoallocpty to 0, .B exp_pty[0] to the master pty file descriptor and .B exp_pty[1] to the slave pty file descriptor. The expect library will not do any pty initializations (e.g., exp_stty_init will not be used). The slave pty file descriptor will be automatically closed when the process is spawned. After the process is started, all further communication takes place with the master pty file descriptor. .PP .B exp_spawnl and .B exp_spawnv duplicate the shell's actions in searching for an executable file in a list of directories. The directory list is obtained from the environment. .SH EXPECT PROCESSING While it is possible to use read() to read information from a process spawned by .B exp_spawnl or .BR exp_spawnv , more convenient functions are provided. They are as follows: .nf .B int .B exp_expectl(fd,type1,pattern1,[re1,],value1,type2,...,exp_end); .B int fd; .B enum exp_type type; .B char *pattern1, *pattern2, ...; .B regexp *re1, *re2, ...; .B int value1, value2, ...; .B .B int .B exp_fexpectl(fp,type1,pattern1,[re1,]value1,type2,...,exp_end); .B FILE *fp; .B enum exp_type type; .B char *pattern1, *pattern2, ...; .B regexp *re1, *re2, ...; .B int value1, value2, ...; .B enum exp_type { .B exp_end, .B exp_glob, .B exp_exact, .B exp_regexp, .B exp_compiled, .B exp_null, .B }; .B struct exp_case { .B char *pattern; .B regexp *re; .B enum exp_type type; .B int value; .B }; .B int .B exp_expectv(fd,cases); .B int fd; .B struct exp_case *cases; .B int .B exp_fexpectv(fp,cases); .B FILE *fp; .B struct exp_case *cases; .B extern int exp_timeout; .B extern char *exp_match; .B extern char *exp_match_end; .B extern char *exp_buffer; .B extern char *exp_buffer_end; .B extern int exp_match_max; .B extern int exp_full_buffer; .B extern int exp_remove_nulls; .fi The functions wait until the output from a process matches one of the patterns, a specified time period has passed, or an EOF is seen. .PP The first argument to each function is either a file descriptor or a stream. Successive sets of arguments describe patterns and associated integer values to return when the pattern matches. .PP The type argument is one of four values. exp_end indicates that no more patterns appear. exp_glob indicates that the pattern is a glob-style string pattern. exp_exact indicates that the pattern is an exact string. exp_regexp indicates that the pattern is a regexp-style string pattern. exp_compiled indicates that the pattern is a regexp-style string pattern, and that its compiled form is also provided. exp_null indicates that the pattern is a null (for debugging purposes, a string pattern must also follow). .PP If the compiled form is not provided with the functions .B exp_expectl and .BR exp_fexpectl , any pattern compilation done internally is thrown away after the function returns. The functions .B exp_expectv and .B exp_fexpectv will automatically compile patterns and will not throw them away. Instead, they must be discarded by the user, by calling free on each pattern. It is only necessary to discard them, the last time the cases are used. .PP Regexp subpatterns matched are stored in the compiled regexp. Assuming "re" contains a compiled regexp, the matched string can be found in re->startp[0]. The match substrings (according to the parentheses) in the original pattern can be found in re->startp[1], re->startp[2], and so on, up to re->startp[9]. The corresponding strings ends are re->endp[x] where x is that same index as for the string start. The type exp_null matches if a null appears in the input. The variable exp_remove_nulls must be set to 0 to prevent nulls from being automatically stripped. By default, exp_remove_nulls is set to 1 and nulls are automatically stripped. .B exp_expectv and .B exp_fexpectv are useful when the number of patterns is not known in advance. In this case, the sets are provided in an array. The end of the array is denoted by a struct exp_case with type exp_end. For the rest of this discussion, these functions will be referred to generically as .IR expect. .PP If a pattern matches, then the corresponding integer value is returned. Values need not be unique, however they should be positive to avoid being mistaken for EXP_EOF, EXP_TIMEOUT, or EXP_FULLBUFFER. Upon EOF or timeout, the value .B EXP_EOF or .B EXP_TIMEOUT is returned. The default timeout period is 10 seconds but may be changed by setting the variable .BR exp_timeout . A value of -1 disables a timeout from occurring. A value of 0 causes the expect function to return immediately (i.e., poll) after one read(). However it must be preceded by a function such as select, poll, or an event manager callback to guarantee that there is data to be read. If the variable exp_full_buffer is 1, then EXP_FULLBUFFER is returned if exp_buffer fills with no pattern having matched. When the expect function returns, .B exp_buffer points to the buffer of characters that was being considered for matching. .B exp_buffer_end points to one past the last character in exp_buffer. If a match occurred, .B exp_match points into .B exp_buffer where the match began. .B exp_match_end points to one character past where the match ended. .PP Each time new input arrives, it is compared to each pattern in the order they are listed. Thus, you may test for absence of a match by making the last pattern something guaranteed to appear, such as a prompt. In situations where there is no prompt, you must check for .B EXP_TIMEOUT (just like you would if you were interacting manually). More philosophy and strategies on specifying .B expect patterns can be found in the documentation on the .B expect program itself. See SEE ALSO below. .PP Patterns are the usual C-shell-style regular expressions. For example, the following fragment looks for a successful login, such as from a telnet dialogue. .nf switch (exp_expectl( exp_glob,"connected",CONN, exp_glob,"busy",BUSY, exp_glob,"failed",ABORT, exp_glob,"invalid password",ABORT, exp_end)) { case CONN: /* logged in successfully */ break; case BUSY: /* couldn't log in at the moment */ break; case EXP_TIMEOUT: case ABORT: /* can't log in at any moment! */ break; default: /* problem with expect */ } .fi Asterisks (as in the example above) are a useful shorthand for omitting line-termination characters and other detail. Patterns must match the entire output of the current process (since the previous read on the descriptor or stream). More than 2000 bytes of output can force earlier bytes to be "forgotten". This may be changed by setting the variable .BR exp_match_max . Note that excessively large values can slow down the pattern matcher. .SH RUNNING IN THE BACKGROUND .nf .B extern int exp_disconnected; .B int exp_disconnect(); .fi It is possible to move a process into the background after it has begun running. A typical use for this is to read passwords and then go into the background to sleep before using the passwords to do real work. .PP To move a process into the background, fork, call exp_disconnect() in the child process and exit() in the parent process. This disassociates your process from the controlling terminal. If you wish to move a process into the background in a different way, you must set the variable exp_disconnected to 1. This allows processes spawned after this point to be started correctly. .SH MULTIPLEXING By default, the expect functions block inside of a read on a single file descriptor. If you want to wait on patterns from multiple file descriptors, use select, poll, or an event manager. They will tell you what file descriptor is ready to read. When a file descriptor is ready to read, you can use the expect functions to do one and only read by setting timeout to 0. .SH SLAVE CONTROL .nf .B void .B exp_slave_control(fd,enable) .B int fd; .B int enable; .fi Pty trapping is normally done automatically by the expect functions. However, if you want to issue an ioctl, for example, directly on the slave device, you should temporary disable trapping. Pty trapping can be controlled with exp_slave_control. The first argument is the file descriptor corresponding to the spawned process. The second argument is a 0 if trapping is to be disabled and 1 if it is to be enabled. .SH ERRORS All functions indicate errors by returning \-1 and setting errno. .PP Errors that occur after the spawn functions fork (e.g., attempting to spawn a non-existent program) are written to the process's stderr, and will be read by the first .BR expect . .SH SIGNALS .nf .B extern int exp_reading; .B extern jmp_buf exp_readenv; .fi .B expect uses alarm() to timeout, thus if you generate alarms during .BR expect , it will timeout prematurely. .PP Internally, .B expect calls read() which can be interrupted by signals. If you define signal handlers, you can choose to restart or abort .BR expect 's internal read. The variable, .BR exp_reading , is true if (and only if) .BR expect 's read has been interrupted. longjmp(exp_readenv,EXP_ABORT) will abort the read. longjmp(exp_readenv,EXP_RESTART) will restart the read. .SH LOGGING .nf .B extern int exp_loguser; .B extern int exp_logfile_all .B extern FILE *exp_logfile; .fi If .B exp_loguser is nonzero, .B expect sends any output from the spawned process to stdout. Since interactive programs typically echo their input, this usually suffices to show both sides of the conversation. If .B exp_logfile is also nonzero, this same output is written to the stream defined by .BR exp_logfile . If .B exp_logfile_all is non-zero, .B exp_logfile is written regardless of the value of .BR exp_loguser . .SH DEBUGGING While I consider the library to be easy to use, I think that the standalone expect program is much, much, easier to use than working with the C compiler and its usual edit, compile, debug cycle. Unlike typical C programs, most of the debugging isn't getting the C compiler to accept your programs - rather, it is getting the dialogue correct. Also, translating scripts from expect to C is usually not necessary. For example, the speed of interactive dialogues is virtually never an issue. So please try the standalone 'expect' program first. I suspect it is a more appropriate solution for most people than the library. .PP Nonetheless, if you feel compelled to debug in C, here are some tools to help you. .nf .B extern int exp_is_debugging; .B extern FILE *exp_debugfile; .fi While expect dialogues seem very intuitive, trying to codify them in a program can reveal many surprises in a program's interface. Therefore a variety of debugging aids are available. They are controlled by the above variables, all 0 by default. Debugging information internal to .B expect is sent to stderr when .B exp_is_debugging is non-zero. The debugging information includes every character received, and every attempt made to match the current input against the patterns. In addition, non-printable characters are translated to a printable form. For example, a control-C appears as a caret followed by a C. If .B exp_logfile is non-zero, this information is also written to that stream. .PP If .B exp_debugfile is non-zero, all normal and debugging information is written to that stream, regardless of the value of .BR exp_is_debugging . .SH CAVEATS The stream versions of the .B expect functions are much slower than the file descriptor versions because there is no way to portably read an unknown number of bytes without the potential of timing out. Thus, characters are read one at a time. You are therefore strongly encouraged to use the file descriptor versions of .B expect (although, automated versions of interactive programs don't usually demand high speed anyway). .PP You can actually get the best of both worlds, writing with the usual stream functions and reading with the file descriptor versions of .B expect as long as you don't attempt to intermix other stream input functions (e.g., fgetc). To do this, pass fileno(stream) as the file descriptor each time. Fortunately, there is little reason to use anything but the .B expect functions when reading from interactive programs. .PP There is no matching exp_pclose to exp_popen (unlike popen and pclose). It only takes two functions to close down a connection (fclose() followed by waiting on the pid), but it is not uncommon to separate these two actions by large time intervals, so the function seems of little value. .PP If you are running on a Cray running Unicos (all I know for sure from experience), you must run your compiled program as root or setuid. The problem is that the Cray only allows root processes to open ptys. You should observe as much precautions as possible: If you don't need permissions, setuid(0) only immediately before calling one of the spawn functions and immediately set it back afterwards. .PP Normally, .B spawn takes little time to execute. If you notice spawn taking a significant amount of time, it is probably encountering ptys that are wedged. A number of tests are run on ptys to avoid entanglements with errant processes. (These take 10 seconds per wedged pty.) Running expect with the \-d option will show if .B expect is encountering many ptys in odd states. If you cannot kill the processes to which these ptys are attached, your only recourse may be to reboot. .SH BUGS The .B exp_fexpect functions don't work at all under HP-UX - it appears to be a bug in getc. Follow the advice (above) about using the .B exp_expect functions (which doesn't need to call getc). If you fix the problem (before I do - please check the latest release) let me know. .SH SEE ALSO An alternative to this library is the .B expect program. .B expect interprets scripts written in a high-level language which direct the dialogue. In addition, the user can take control and interact directly when desired. If it is not absolutely necessary to write your own C program, it is much easier to use .B expect to perform the entire interaction. It is described further in the following references: .PP .I "expect: Curing Those Uncontrollable Fits of Interactivity" \fRby Don Libes, Proceedings of the Summer 1990 USENIX Conference, Anaheim, California, June 11-15, 1990. .PP .I "Using expect to Automate System Administration Tasks" \fRby Don Libes, Proceedings of the 1990 USENIX Large Installation Systems Administration Conference, Colorado Springs, Colorado, October 17-19, 1990. .PP expect(1), alarm(3), read(2), write(2), fdopen(3), execve(2), execvp(3), longjmp(3), pty(4). .PP There are several examples C programs in the test directory of .BR expect 's source distribution which use the expect library. .PP .SH AUTHOR Don Libes, [email protected], National Institute of Standards and Technology .SH ACKNOWLEDGEMENTS Thanks to John Ousterhout (UCBerkeley) for supplying the pattern matcher. .PP Design and implementation of the .B expect library was paid for by the U.S. government and is therefore in the public domain. However the author and NIST would like credit if this program and documentation or portions of them are used. |
Changes to example/Makefile.
|
| < | < < < < < < < < < < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | EXPVERSION = 5.31 CC = gcc CPLUSPLUS = g++ CPLUSPLUSLIBDIR = -L/depot/gnu/arch/lib CPLUSPLUSLIB = -lg++ CFLAGS = -g -I.. LIBEXPECT = -L.. -lexpect$(EXPVERSION) LIBS = $(LIBEXPECT) -lm SCRIPTS = su2 noidle script.exp bonfield.exp all: chesslib chesslib2 chesslib++ # this can be compiled with either cc or gcc chesslib: chesslib.o |
︙ | ︙ |
Changes to example/autoexpect.
︙ | ︙ | |||
16 17 18 19 20 21 22 | set filename "script.exp" set verbose 1 set conservative 0 set promptmode 0 set option_keys "" proc check_for_following {type} { | | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | set filename "script.exp" set verbose 1 set conservative 0 set promptmode 0 set option_keys "" proc check_for_following {type} { if {![llength [uplevel set argv]]} { puts "autoexpect: [uplevel set flag] requires following $type" exit 1 } } while {[llength $argv]>0} { set flag [lindex $argv 0] if {0==[regexp "^-" $flag]} break set argv [lrange $argv 1 end] switch -- $flag \ "-c" { set conservative 1 } "-C" { check_for_following character lappend option_keys [lindex $argv 0] ctoggle |
︙ | ︙ | |||
80 81 82 83 84 85 86 | # Handle a null character from the keyboard proc input_null {} { global lastkey userbuf procbuf echoing send -null if {$lastkey == ""} { | | | | | | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | # Handle a null character from the keyboard proc input_null {} { global lastkey userbuf procbuf echoing send -null if {$lastkey == ""} { if {$echoing} { sendcmd "$userbuf" } if {$procbuf != ""} { expcmd "$procbuf" } } else { sendcmd "$userbuf" if {$echoing} { expcmd "$procbuf" sendcmd "$lastkey" } } cmd "send -null" set userbuf "" set procbuf "" set lastkey "" set echoing 0 } # Handle a character that came from the process proc output {s} { global lastkey procbuf userbuf echoing send_user -raw -- $s if {$lastkey == ""} { if {!$echoing} { append procbuf $s } else { sendcmd "$userbuf" expcmd "$procbuf" set echoing 0 set userbuf "" set procbuf $s } return } regexp (.)(.*) $s dummy c tail if {$c == $lastkey} { if {$echoing} { append userbuf $lastkey set lastkey "" } else { if {$procbuf != ""} { expcmd "$procbuf" set procbuf "" } set echoing 1 } append procbuf $s if {[string length $tail]} { sendcmd "$userbuf$lastkey" set userbuf "" set lastkey "" set echoing 0 } } else { if {!$echoing} { expcmd "$procbuf" } sendcmd "$userbuf$lastkey" set procbuf $s set userbuf "" set lastkey "" set echoing 0 |
︙ | ︙ | |||
168 169 170 171 172 173 174 | return $s } # generate an expect command proc expcmd {s} { global promptmode | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | return $s } # generate an expect command proc expcmd {s} { global promptmode if {$promptmode} { regexp ".*\[\r\n]+(.*)" $s dummy s } cmd "expect -exact \"[expand $s]\"" } # generate a send command |
︙ | ︙ | |||
195 196 197 198 199 200 201 | global fd puts $fd "$s" } proc verbose_send_user {s} { global verbose | | | | | | | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | global fd puts $fd "$s" } proc verbose_send_user {s} { global verbose if {$verbose} { send_user -- $s } } proc ctoggle {} { global conservative send_style if {$conservative} { cmd "# conservative mode off - adding no delays" verbose_send_user "conservative mode off\n" set conservative 0 set send_style "" } else { cmd "# prompt mode on - adding delays" verbose_send_user "conservative mode on\n" set conservative 1 set send_style " -s" } } proc ptoggle {} { global promptmode if {$promptmode} { cmd "# prompt mode off - now looking for complete output" verbose_send_user "prompt mode off\n" set promptmode 0 } else { cmd "# prompt mode on - now looking only for prompts" verbose_send_user "prompt mode on\n" set promptmode 1 } } # quote the next character from the user proc quote {} { expect_user -re . send -- $expect_out(buffer) } if {[catch {set fd [open $filename w]} msg]} { puts $msg exit } exec chmod +x $filename verbose_send_user "autoexpect started, file is $filename\n" # calculate a reasonable #! line set expectpath /usr/local/bin ;# prepare default foreach dir [split $env(PATH) :] { ;# now look for real location if {[file executable $dir/expect] && ![file isdirectory $dir/expect]} { set expectpath $dir break } } cmd "#![set expectpath]/expect -f # |
︙ | ︙ | |||
299 300 301 302 303 304 305 | # Read the man page for more info. # # -Don } cmd "set timeout -1" | | | | | < < < < | | | | | < | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | # Read the man page for more info. # # -Don } cmd "set timeout -1" if {$conservative} { set send_style " -s" cmd "set send_slow {1 .1}" } else { set send_style "" } if {[llength $argv]>0} { eval spawn -noecho $argv cmd "spawn $argv" } else { spawn -noecho $env(SHELL) cmd "spawn \$env(SHELL)" } cmd "match_max 100000" set lastkey "" set procbuf "" set userbuf "" set echoing 0 remove_nulls 0 eval interact $option_keys { -re . { input $interact_out(0,string) } -o -re .+ { output $interact_out(0,string) } eof { cmd "expect eof" return } } close $fd verbose_send_user "autoexpect done, file is $filename\n" |
Changes to example/beer.exp.
︙ | ︙ | |||
35 36 37 38 39 40 41 | proc line4 {i} { out $i "[bottles $i] on the wall.\n\n" } proc out {i s} { foreach c [split $s ""] { # don't touch punctuation; just looks too strange if you do | | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | proc line4 {i} { out $i "[bottles $i] on the wall.\n\n" } proc out {i s} { foreach c [split $s ""] { # don't touch punctuation; just looks too strange if you do if {[regexp "\[,. \n\]" $c]} { append d $c continue } # keep first couple of verses straight if {$i > 97} {append d $c; continue} # +3 prevents it from degenerating too far # /2 makes it degenerate faster though set r [rand [expr $i/2+3]] if {$r} {append d $c; continue} # do something strange switch [rand 3] { 0 { # substitute another letter if {[regexp \[aeiou\] $c]} { # if vowel, substitute another append d [string index aeiou [rand 5]] } elseif {[regexp \[0-9\] $c]} { # if number, substitute another append d [string index 123456789 [rand 9]] } else { # if consonant, substitute another append d [string index bcdfghjklmnpqrstvwxyz [rand 21]] } } 1 { |
︙ | ︙ |
Changes to example/carpal.
1 2 3 4 5 6 7 8 9 10 | # Script to enforce a 10 minute break every half hour from typing - # Written for someone (Uwe Hollerbach) with Carpal Tunnel Syndrome. # If you type for more than 20 minutes straight, the script rings # the bell after every character until you take a 10 minute break. # Author: Don Libes, NIST # Date: Feb 26, '95 spawn $env(SHELL) | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # Script to enforce a 10 minute break every half hour from typing - # Written for someone (Uwe Hollerbach) with Carpal Tunnel Syndrome. # If you type for more than 20 minutes straight, the script rings # the bell after every character until you take a 10 minute break. # Author: Don Libes, NIST # Date: Feb 26, '95 spawn $env(SHELL) set start [clock seconds] ;# when we started our current typing period set stop [clock seconds] ;# when we stopped typing set typing 1200 ;# twenty minutes, max typing time allowed set notyping 600 ;# ten minutes, min notyping time required interact -nobuffer -re . { set now [clock seconds] if {$now-$stop > $notyping} { set start [clock seconds] } elseif {$now-$start > $typing} { send_user "\007" } set stop [clock seconds] } |
Changes to example/chess.exp.
︙ | ︙ | |||
17 18 19 20 21 22 23 | # # n/kn1-kb3 (echo from first player) # 2. n/kn1-kb3 (reprint it as above, but differently - god knows why) # 2. ... p/k4-k5 (our new countermove - written differently, of course) set timeout -1; # wait forever expect_before { | | | | | | | | | | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # # n/kn1-kb3 (echo from first player) # 2. n/kn1-kb3 (reprint it as above, but differently - god knows why) # 2. ... p/k4-k5 (our new countermove - written differently, of course) set timeout -1; # wait forever expect_before { -i $any_spawn_id eof { send_user "player resigned!\n" exit } } # start things rolling spawn chess set id1 $spawn_id expect "Chess\r\n" send "first\r" # read_first_move expect -re "1. (.*)\n" spawn chess set id2 $spawn_id expect "Chess\r\n" send $expect_out(1,string) while {1} { expect { -i $id2 -re "\\.\\. (.*)\n" { send -i $id1 $expect_out(1,string) } -i $id1 -re "\\.\\. .*\\. (.*)\n" { send -i $id2 $expect_out(1,string) } } } |
Changes to example/chesslib++.c.
︙ | ︙ | |||
58 59 60 61 62 63 64 | main(){ int fd1, fd2; exp_loguser = 1; exp_timeout = 3600; | | > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | main(){ int fd1, fd2; exp_loguser = 1; exp_timeout = 3600; if (-1 == (fd1 = exp_spawnl("chess","chess",(char *)0))) { perror("chess"); exit(-1); } if (-1 == exp_expectl(fd1,exp_glob,"Chess\r\n",0,exp_end)) exit; if (-1 == write(fd1,"first\r",6)) exit; read_first_move(fd1); |
︙ | ︙ |
Changes to example/chesslib.c.
︙ | ︙ | |||
54 55 56 57 58 59 60 | main(){ int fd1, fd2; exp_loguser = 1; exp_timeout = 3600; | | > > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | main(){ int fd1, fd2; exp_loguser = 1; exp_timeout = 3600; if (-1 == (fd1 = exp_spawnl("chess","chess",(char *)0))) { perror("chess"); exit(-1); } if (-1 == exp_expectl(fd1,exp_glob,"Chess\r\n",0,exp_end)) exit; if (-1 == write(fd1,"first\r",6)) exit; read_first_move(fd1); |
︙ | ︙ |
Changes to example/chesslib2.c.
︙ | ︙ | |||
57 58 59 60 61 62 63 | int ec; /* exp_is_debugging = 1;*/ exp_loguser = 1; exp_timeout = 3600; if (0 == (fp1 = exp_popen("chess"))) { | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | int ec; /* exp_is_debugging = 1;*/ exp_loguser = 1; exp_timeout = 3600; if (0 == (fp1 = exp_popen("chess"))) { perror("chess"); exit(-1); } if (0 > exp_fexpectl(fp1,exp_glob,"Chess\r\n",0,exp_end)) exit(-1); fprintf(fp1,"first\r"); read_first_move(fp1); |
︙ | ︙ |
Changes to example/cryptdir.
1 2 3 4 5 6 7 8 9 10 11 | #!../expect -- # Name: cryptdir # Author: Don Libes, NIST # # Synopsis: # cryptdir [dir] # decryptdir [dir] # # Encrypt or decrypts the current directory or named directory if given. if {[llength $argv] > 0} { | | | < | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #!../expect -- # Name: cryptdir # Author: Don Libes, NIST # # Synopsis: # cryptdir [dir] # decryptdir [dir] # # Encrypt or decrypts the current directory or named directory if given. if {[llength $argv] > 0} { cd $argv } # encrypt or decrypt? set decrypt [regexp "decrypt" $argv0] set timeout -1 stty -echo send "Password:" expect -re "(.*)\n" send "\n" set passwd $expect_out(1,string) # Wouldn't want to encrypt/decrypt files with mistyped password! send "Again:" expect -re "(.*)\n" send "\n" if {![string match $passwd $expect_out(1,string)]} { send_user "mistyped password?\n" stty echo exit } stty echo log_user 0 foreach f [glob *] { # strip shell metachars from filename to avoid problems if {[regsub -all {[]['`~<>:-]} $f "" newf]} { exec mv $f $newf set f $newf } set strcmp [string compare .crypt [file extension $f]] if {$decrypt} { # skip files that don't end with ".crypt" if {0!=$strcmp} continue spawn sh -c "exec crypt < $f > [file root $f]" } else { # skip files that already end with ".crypt" if {0==$strcmp} continue spawn sh -c "exec crypt < $f > $f.crypt" } expect "key:" send "$passwd\r" expect wait exec rm -f $f send_tty "." } send_tty "\n" |
Changes to example/decryptdir.
1 2 3 4 5 6 7 8 9 10 11 | #!../expect -- # Name: cryptdir # Author: Don Libes, NIST # # Synopsis: # cryptdir [dir] # decryptdir [dir] # # Encrypt or decrypts the current directory or named directory if given. if {[llength $argv] > 0} { | | | < | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #!../expect -- # Name: cryptdir # Author: Don Libes, NIST # # Synopsis: # cryptdir [dir] # decryptdir [dir] # # Encrypt or decrypts the current directory or named directory if given. if {[llength $argv] > 0} { cd $argv } # encrypt or decrypt? set decrypt [regexp "decrypt" $argv0] set timeout -1 stty -echo send "Password:" expect -re "(.*)\n" send "\n" set passwd $expect_out(1,string) # Wouldn't want to encrypt/decrypt files with mistyped password! send "Again:" expect -re "(.*)\n" send "\n" if {![string match $passwd $expect_out(1,string)]} { send_user "mistyped password?\n" stty echo exit } stty echo log_user 0 foreach f [glob *] { # strip shell metachars from filename to avoid problems if {[regsub -all {[]['`~<>:-]} $f "" newf]} { exec mv $f $newf set f $newf } set strcmp [string compare .crypt [file extension $f]] if {$decrypt} { # skip files that don't end with ".crypt" if {0!=$strcmp} continue spawn sh -c "exec crypt < $f > [file root $f]" } else { # skip files that already end with ".crypt" if {0==$strcmp} continue spawn sh -c "exec crypt < $f > $f.crypt" } expect "key:" send "$passwd\r" expect wait exec rm -f $f send_tty "." } send_tty "\n" |
Changes to example/dislocate.
1 2 3 4 5 6 7 8 | #!../expect -- # dislocate - allow disconnection and reconnection to a background program # Author: Don Libes, NIST exp_version -exit 5.1 # The following code attempts to intuit whether cat buffers by default. # The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems. | | | | | | | | | | | | | | | | | | | | | | | < < | | < < < < | | | | > > > > > > > > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | > | > > | | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < < | | | | | | | < < | | | | | | | | | | | | | | | | | | | | > | > > > | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | > > > > > | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | #!../expect -- # dislocate - allow disconnection and reconnection to a background program # Author: Don Libes, NIST exp_version -exit 5.1 # The following code attempts to intuit whether cat buffers by default. # The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems. if {[file exists $exp_exec_library/cat-buffers]} { set catflags "-u" } else { set catflags "" } # If this fails, you can also force it by commenting in one of the following. # Or, you can use the -catu flag to the script. #set catflags "" #set catflags "-u" set escape \035 ;# control-right-bracket set escape_printable "^\]" set pidfile "~/.dislocate" set prefix "disc" set timeout -1 set debug_flag 0 while {$argc} { set flag [lindex $argv 0] switch -- $flag \ "-catu" { set catflags "-u" set argv [lrange $argv 1 end] incr argc -1 } "-escape" { set escape [lindex $argv 1] set escape_printable $escape set argv [lrange $argv 2 end] incr argc -2 } "-debug" { log_file [lindex $argv 1] set debug_flag 1 set argv [lrange $argv 2 end] incr argc -2 } default { break } } # These are correct from parent's point of view. # In child, we will reset these so that they appear backwards # thus allowing following two routines to be used by both parent and child set infifosuffix ".i" set outfifosuffix ".o" proc infifoname {pid} { return "/tmp/$::prefix$pid$::infifosuffix" } proc outfifoname {pid} { return "/tmp/$::prefix$pid$::outfifosuffix" } proc pid_remove {pid} { say "removing $pid $::proc($pid)" unset ::date($pid) unset ::proc($pid) } # lines in data file look like this: # pid#date-started#argv # allow element lookups on empty arrays set date(dummy) dummy; unset date(dummy) set proc(dummy) dummy; unset proc(dummy) proc say {msg} { if {!$::debug_flag} return if {[catch {puts "parent: $msg"}]} { send_log "child: $msg\n" } } # load pidfile into memory proc pidfile_read {} { global date proc pidfile say "opening $pidfile" if {[catch {open $pidfile} fp]} return # # read info from file # say "reading pidfile" set line 0 while {[gets $fp buf]!=-1} { # while pid and date can't have # in it, proc can if {[regexp "(\[^#]*)#(\[^#]*)#(.*)" $buf junk pid xdate xproc]} { set date($pid) $xdate set proc($pid) $xproc } else { puts "warning: inconsistency in $pidfile line $line" } incr line } close $fp say "read $line entries" # # see if pids and fifos are still around # foreach pid [array names date] { if {$pid && [catch {exec /bin/kill -0 $pid}]} { say "$pid no longer exists, removing" pid_remove $pid continue } # pid still there, see if fifos are if {![file exists [infifoname $pid]] || ![file exists [outfifoname $pid]]} { say "$pid fifos no longer exists, removing" pid_remove $pid continue } } } proc pidfile_write {} { global pidfile date proc say "writing pidfile" set fp [open $pidfile w] foreach pid [array names date] { puts $fp "$pid#$date($pid)#$proc($pid)" say "wrote $pid#$date($pid)#$proc($pid)" } close $fp } proc fifo_pair_remove {pid} { global date proc prefix pidfile_read pid_remove $pid pidfile_write file delete -force [infifoname $pid] [outfifoname $pid] } proc fifo_pair_create {pid argdate argv} { global prefix date proc pidfile_read set date($pid) $argdate set proc($pid) $argv pidfile_write mkfifo [infifoname $pid] mkfifo [outfifoname $pid] } proc mkfifo {f} { if {[file exists $f]} { say "uh, fifo already exists?" return } if {0==[catch {exec mkfifo $f}]} return ;# POSIX if {0==[catch {exec mknod $f p}]} return # some systems put mknod in wierd places if {0==[catch {exec /usr/etc/mknod $f p}]} return ;# Sun if {0==[catch {exec /etc/mknod $f p}]} return ;# AIX, Cray puts "Couldn't figure out how to make a fifo - where is mknod?" exit } proc child {argdate argv} { global infifosuffix outfifosuffix disconnect # these are backwards from the child's point of view so that # we can make everything else look "right" set infifosuffix ".o" set outfifosuffix ".i" set pid 0 eval spawn $argv set proc_spawn_id $spawn_id while {1} { say "opening [infifoname $pid] for read" set catfid [open "|cat $::catflags < [infifoname $pid]" "r"] set ::catpid $catfid spawn -open $catfid set in $spawn_id say "opening [outfifoname $pid] for write" spawn -open [open [outfifoname $pid] w] set out $spawn_id fifo_pair_remove $pid say "interacting" interact { -u $proc_spawn_id eof exit -output $out -input $in } # parent has closed connection say "parent closed connection" catch {close -i $in} catch {wait -i $in} catch {close -i $out} catch {wait -i $out} # switch to using real pid set pid [pid] # put entry back fifo_pair_create $pid $argdate $argv } } proc escape {} { # export process handles so that user can get at them global in out puts "\nto disconnect, enter: exit (or ^D)" puts "to suspend, press appropriate job control sequence" puts "to return to process, enter: return" interpreter -eof exit puts "returning ..." } # interactively query user to choose process, return pid proc choose {} { while {1} { send_user "enter # or pid: " expect_user -re "(.*)\n" {set buf $expect_out(1,string)} if {[info exists ::index($buf)]} { set pid $::index($buf) } elseif {[info exists ::date($buf)]} { set pid $buf } else { puts "no such # or pid" continue } return $pid } } if {$argc} { # initial creation occurs before fork because if we do it after # then either the child or the parent may have to spin retrying # the fifo open. Unfortunately, we cannot know the pid ahead of # time so use "0". This will be set to the real pid when the # parent does its initial disconnect. There is no collision # problem because the fifos are deleted immediately anyway. set datearg [clock format [clock seconds]] fifo_pair_create 0 $datearg $argv # to debug by faking child, comment out fork and set pid to a # non-zero int, then you can read/write to pipes manually set pid [fork] say "after fork, pid = $pid" if {$pid==0} { child $datearg $argv } # parent thinks of child as pid==0 for reason given earlier set pid 0 } say "examining pid" if {![info exists pid]} { global fifos date proc say "pid does not exist" pidfile_read set count 0 foreach pid [array names date] { incr count } if {$count==0} { puts "no connectable processes" exit } elseif {$count==1} { puts "one connectable process: $proc($pid)" puts "pid $pid, started $date($pid)" send_user "connect? \[y] " expect_user -re "(.*)\n" {set buf $expect_out(1,string)} if {$buf!="y" && $buf!=""} exit } else { puts "connectable processes:" set count 1 puts " # pid date started process" foreach pid [array names date] { puts [format "%2d %6d %.19s %s" \ $count $pid $date($pid) $proc($pid)] set index($count) $pid incr count } set pid [choose] } } say "opening [outfifoname $pid] for write" spawn -noecho -open [open [outfifoname $pid] w] set out $spawn_id say "opening [infifoname $pid] for read" set catfid [open "|cat $catflags < [infifoname $pid]" "r"] set catpid [pid $catfid] spawn -noecho -open $catfid set in $spawn_id puts "Escape sequence is $escape_printable" proc prompt1 {} { return "$::argv0[history nextid]> " } rename exit exitReal proc exit {} { exec /bin/kill $::catpid exitReal } interact { -reset $escape escape -output $out -input $in } |
Changes to example/dvorak.
︙ | ︙ | |||
22 23 24 25 26 27 28 | log_user 0 spawn $env(SHELL) log_user 1 send_user "~d for dvorak input\n" send_user "~q for qwerty input (default)\n" send_user "~e for expect interpreter\n" send_user "Enter ~ sequences using qwerty keys\n" | | | 22 23 24 25 26 27 28 29 | log_user 0 spawn $env(SHELL) log_user 1 send_user "~d for dvorak input\n" send_user "~q for qwerty input (default)\n" send_user "~e for expect interpreter\n" send_user "Enter ~ sequences using qwerty keys\n" interact ~d rot ~q {} ~e {interpreter -eof exit} |
Changes to example/ftp-inband.
︙ | ︙ | |||
18 19 20 21 22 23 24 | set timeout -1 set verbose_flag 0 proc send_verbose {msg} { global verbose_flag | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | set timeout -1 set verbose_flag 0 proc send_verbose {msg} { global verbose_flag if {$verbose_flag} { send_user $msg } } proc get {infile outfile} { global prompt verbose_flag if {!$verbose_flag} { log_user 0 } send_verbose "disabling echo: " send "stty -echo\r" expect -re $prompt |
︙ | ︙ | |||
76 77 78 79 80 81 82 | } -re "^(\[^\r]*)\r\n" { puts $out $expect_out(1,string) send_verbose "." exp_continue } } | | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | } -re "^(\[^\r]*)\r\n" { puts $out $expect_out(1,string) send_verbose "." exp_continue } } if {$verbose_flag} { send_user "\n" ;# after last "." log_user 1 } expect -re $prompt ;# wait for prompt from cat send_verbose "deleting temporary files\n" send "rm -f $infile_compressed $infile_encoded\r" expect -re $prompt send_verbose "switching attention to local system\nuudecoding\n" exec uudecode $outfile_encoded send_verbose "uncompressing\n" exec uncompress -f $outfile_compressed send_verbose "renaming\n" if {[catch "exec cp $outfile_plain $outfile" msg]} { send_user "could not move file in place, reason: $msg\n" send_user "left as $outfile_plain\n" exec rm -f $outfile_encoded } else { exec rm -f $outfile_plain $outfile_encoded } # restore echo and serendipitously reprompt send "stty echo\r" log_user 1 } proc put {infile outfile} { global prompt verbose_flag if {!$verbose_flag} { log_user 0 } send_verbose "disabling echo: " send "stty -echo\r" expect -re $prompt |
︙ | ︙ | |||
149 150 151 152 153 154 155 | send_verbose "copying\n" send "cat > $outfile_encoded\r" log_user 0 set fp [open $infile_encoded r] | | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | send_verbose "copying\n" send "cat > $outfile_encoded\r" log_user 0 set fp [open $infile_encoded r] while {1} { if {-1 == [gets $fp buf]} break send_verbose "." send -- "$buf\r" } if {$verbose_flag} { send_user "\n" ;# after last "." log_user 1 } send "\004" ;# eof close $fp |
︙ | ︙ | |||
246 247 248 249 250 251 252 | set verbose_flag [expr !$verbose_flag] send_user "verbose [verbose_status]\r\n" } proc verbose_status {} { global verbose_flag | | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | set verbose_flag [expr !$verbose_flag] send_user "verbose [verbose_status]\r\n" } proc verbose_status {} { global verbose_flag if {$verbose_flag} { return "on" } else { return "off" } } proc cmd {} { |
︙ | ︙ |
Changes to example/ftp-rfc.
1 2 3 4 5 6 7 8 9 | #!../expect -- # ftp-rfc <rfc-number> # ftp-rfc -index # retrieves an rfc (or the index) from uunet exp_version -exit 5.0 | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!../expect -- # ftp-rfc <rfc-number> # ftp-rfc -index # retrieves an rfc (or the index) from uunet exp_version -exit 5.0 if {$argc!=1} { send_user "usage: ftp-rfc \[#] \[-index]\n" exit } set file "rfc$argv.Z" set timeout 60 |
︙ | ︙ |
Changes to example/gethostbyaddr.
︙ | ︙ | |||
40 41 42 43 44 45 46 | send_user " -r reverse back to IP addr for verification true\n" send_user " -n query nic true\n" send_user " -d produce debugging output false\n" send_user "options must be separate.\n" exit } | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | send_user " -r reverse back to IP addr for verification true\n" send_user " -n query nic true\n" send_user " -d produce debugging output false\n" send_user "options must be separate.\n" exit } if {[file readable ~/.gethostbyaddr]} {source ~/.gethostbyaddr} while {[llength $argv]>0} { set flag [lindex $argv 0] switch -- $flag \ "-v" { set verbose [expr !$verbose] set argv [lrange $argv 1 end] |
︙ | ︙ | |||
68 69 70 71 72 73 74 | } default { break } } set IPaddress $argv | | | | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | } default { break } } set IPaddress $argv if {[llength $argv]!=1} usage if {4!=[scan $IPaddress "%d.%d.%d.%d" a b c d]} usage proc vprint {s} { global verbose if {!$verbose} return send_user $s\n } # dn==1 if domain name, 0 if text (from nic) proc printhost {name how dn} { global reverse tag IPaddress if {$dn && $reverse} { set verified [verify $name $IPaddress] } else {set verified 0} if {$verified || !$reverse || !$dn} { if {$tag} { send_user "$name ($how)\n" } else { send_user "$name\n" } if {$verified || !$reverse} { close |
︙ | ︙ | |||
116 117 118 119 120 121 122 | expect { -re "\\*\\*\\* (\[^\r]*)\r" { vprint $expect_out(1,string) } timeout { vprint "timed out" } -re "Address:.*Address: (\[^\r]*)\r" { set addr2 $expect_out(1,string) | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | expect { -re "\\*\\*\\* (\[^\r]*)\r" { vprint $expect_out(1,string) } timeout { vprint "timed out" } -re "Address:.*Address: (\[^\r]*)\r" { set addr2 $expect_out(1,string) if {[string match $IPaddress $addr2]} { vprint "verified" set rc 1 } else { vprint "not verified - $name is $addr2" } } } |
︙ | ︙ | |||
138 139 140 141 142 143 144 | proc telnet_error {s} { regexp ": (.*)\r" $s dontcare msg vprint $msg } proc guessHost {guess} { global guessHost | | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | proc telnet_error {s} { regexp ": (.*)\r" $s dontcare msg vprint $msg } proc guessHost {guess} { global guessHost if {[info exists guessHost]} return set guessHost $guess } proc guessDomain {guess} { global guessDomain if {[info exists guessDomain]} return set guessDomain $guess } proc guessFQDN {} { global guessHost guessDomain return $guessHost.$guessDomain } |
︙ | ︙ | |||
197 198 199 200 201 202 203 | vprint "timed out" } -re "\n220 (\[^\\. ]*).?(\[^ ]*)" { set host $expect_out(1,string) set domain $expect_out(2,string) printhost $host.$domain smtp 1 # if not valid FQDN, it's likely either host or domain | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | vprint "timed out" } -re "\n220 (\[^\\. ]*).?(\[^ ]*)" { set host $expect_out(1,string) set domain $expect_out(2,string) printhost $host.$domain smtp 1 # if not valid FQDN, it's likely either host or domain if {[string length $domain]} { guessDomain $host.$domain } else { guessHost $host } } } catch close |
︙ | ︙ | |||
279 280 281 282 283 284 285 | set host $expect_out(1,string) set domain $expect_out(2,string) printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1 # if not valid FQDN, it's likely either host or domain # don't bother recording host since it can't be for # original addr. | | | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | set host $expect_out(1,string) set domain $expect_out(2,string) printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1 # if not valid FQDN, it's likely either host or domain # don't bother recording host since it can't be for # original addr. if {[string length $domain]} { guessDomain $host.$domain } } } catch close wait } |
︙ | ︙ | |||
304 305 306 307 308 309 310 | set host $expect_out(1,string) set domain $expect_out(2,string) printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1 # if not valid FQDN, it's likely either host or domain # don't bother recording host since it can't be for # original addr. | | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | set host $expect_out(1,string) set domain $expect_out(2,string) printhost $guessHost.$domain "smtp - $a.$b.$c.$i is $host.$domain" 1 # if not valid FQDN, it's likely either host or domain # don't bother recording host since it can't be for # original addr. if {[string length $domain]} { guessDomain $host.$domain } } } catch close wait } |
︙ | ︙ |
Changes to example/kibitz.
︙ | ︙ | |||
23 24 25 26 27 28 29 | ;# this must end in "kibitz", but can have ;# things in front (like directory names). #set proxy "kibitz" ;# uncomment and set if you want kibitz to use ;# some other account on remote systems # The following code attempts to intuit whether cat buffers by default. # The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems. | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ;# this must end in "kibitz", but can have ;# things in front (like directory names). #set proxy "kibitz" ;# uncomment and set if you want kibitz to use ;# some other account on remote systems # The following code attempts to intuit whether cat buffers by default. # The -u flag is required on HPUX (8 and 9) and IBM AIX (3.2) systems. if {[file exists $exp_exec_library/cat-buffers]} { set catflags "-u" } else { set catflags "" } # If this fails, you can also force it by commenting in one of the following. # Or, you can use the -catu flag to the script. #set catflags "" #set catflags "-u" # Some flags must be passed onto the remote kibitz process. They are stored |
︙ | ︙ | |||
79 80 81 82 83 84 85 | exit } log_user 0 set timeout -1 set user [lindex $argv 0] | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | exit } log_user 0 set timeout -1 set user [lindex $argv 0] if {[string match -r $user]} { send_user "KRUN" ;# this tells user_number 1 that we're running ;# and to prepare for possible error messages set user_number 3 # need to check that it exists first! set user [lindex $argv 1] } else { set user_number [expr 1+(0==[string first - $user])] |
︙ | ︙ | |||
112 113 114 115 116 117 118 | # return true if x is a prefix of xjunk, given that prefixes are only # valid at . delimiters # if !do_if0, skip the whole thing - this is here just to make caller simpler proc is_prefix {do_if0 x xjunk} { if 0!=$do_if0 {return 0} set split [split $xjunk .] for {set i [expr [llength $split]-1]} {$i>=0} {incr i -1} { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | # return true if x is a prefix of xjunk, given that prefixes are only # valid at . delimiters # if !do_if0, skip the whole thing - this is here just to make caller simpler proc is_prefix {do_if0 x xjunk} { if 0!=$do_if0 {return 0} set split [split $xjunk .] for {set i [expr [llength $split]-1]} {$i>=0} {incr i -1} { if {[string match $x [join [lrange $split 0 $i] .]]} {return 1} } return 0 } # get domainname. Unfortunately, on some systems, domainname(1) # returns NIS domainname which is not the internet domainname. proc domainname {} { # open pops stack upon failure set rc [catch {open /etc/resolv.conf r} file] if {$rc==0} { while {-1!=[gets $file buf]} { if 1==[scan $buf "domain %s" name] { close $file return $name } } close $file } # fall back to using domainname if {0==[catch {exec domainname} name]} {return $name} error "could not figure out domainname" } if $user_number==1 { if $noproc==0 { if {[llength $argv]>1} { set pid [eval spawn [lrange $argv 1 end]] } else { # if running as CGI, shell may not be set! set shell /bin/sh catch {set shell $env(SHELL)} set pid [spawn $shell] } set shell $spawn_id } # is user2 remote? regexp (\[^@\]*)@*(.*) $user ignore tmp host set user $tmp if ![string match $host ""] { set h_rc [catch {exec hostname} hostname] set d_rc [catch domainname domainname] if {![is_prefix $h_rc $host $hostname] && ![is_prefix $d_rc $host $hostname.$domainname]} { set user2_islocal 0 } } if !$user2_islocal { if $verbose {send_user "connecting to $host\n"} if ![info exists proxy] { proc whoami {} { global env if {[info exists env(USER)]} {return $env(USER)} if {[info exists env(LOGNAME)]} {return $env(LOGNAME)} if {![catch {exec whoami} user]} {return $user} if {![catch {exec logname} user]} {return $user} # error "can't figure out who you are!" } set proxy [whoami] } spawn rlogin $host -l $proxy -8 set userin $spawn_id set userout $spawn_id catch {set prompt $env(EXPECT_PROMPT)} set timeout 120 expect { assword: { stty -echo send_user "password (for $proxy) on $host: " set old_timeout $timeout; set timeout -1 expect_user -re "(.*)\n" send_user "\n" set timeout $old_timeout send "$expect_out(1,string)\r" # bother resetting echo? exp_continue } incorrect* { send_user "invalid password or account\n" exit } "TERM = *) " { send "\r" exp_continue } timeout { send_user "connection to $host timed out\n" exit } eof { send_user "connection to host failed: $expect_out(buffer)" exit } -re $prompt } if {$verbose} {send_user "starting kibitz on $host\n"} # the kill protects user1 from receiving user3's # prompt if user2 exits via expect's exit. send "$kibitz $kibitz_flags -r $user;kill -9 $$\r" expect { -re "kibitz $kibitz_flags -r $user.*KRUN" {} -re "kibitz $kibitz_flags -r $user.*(kibitz\[^\r\]*)\r" { send_user "unable to start kibitz on $host: \"$expect_out(1,string)\"\n" send_user "try rlogin by hand followed by \"kibitz $user\"\n" exit } timeout { send_user "unable to start kibitz on $host: " set expect_out(buffer) "timed out" set timeout 0; expect -re .+ send_user $expect_out(buffer) exit } } expect { -re ".*\n" { # pass back diagnostics # should really strip out extra cr send_user $expect_out(buffer) exp_continue } KABORT exit default exit KDATA } } } if {$user_number==2} { set pid [string trimleft $user -] } set local_io [expr ($user_number==3)||$user2_islocal] if {$local_io||($user_number==2)} { if {0==[info exists pid]} {set pid [pid]} set userinfile /tmp/exp0.$pid set useroutfile /tmp/exp1.$pid } proc prompt1 {} { return "kibitz[info level].[history nextid]> " } set esc_match {} if {$allow_escape} { set esc_match { $escape_char { send_user "\nto exit kibitz, enter: exit\n" send_user "to suspend kibitz, press appropriate job control sequence\n" send_user "to return to kibitzing, enter: return\n" interpreter send_user "returning to kibitz\n" } } } proc prompt1 {} { return "kibitz[info level].[history nextid]> " } set timeout -1 # kibitzer executes following code if {$user_number==2} { # for readability, swap variables set tmp $userinfile set userinfile $useroutfile set useroutfile $tmp if ![file readable $userinfile] { send_user "Eh? No one is asking you to kibitz.\n" exit -1 } spawn -open [open "|cat $catflags < $userinfile" "r"] set userin $spawn_id spawn -open [open $useroutfile w] set userout $spawn_id # open will hang until other user's cat starts stty -echo raw if {$allow_escape} {send_user "Escape sequence is $escape_printable\r\n"} # While user is reading message, try to delete other fifo catch {exec rm -f $userinfile} eval interact $esc_match \ -output $userout \ -input $userin exit } # only user_numbers 1 and 3 execute remaining code proc abort {} { # KABORT tells user_number 1 that user_number 3 has run into problems # and is exiting, and diagnostics have been returned already if {$::user_number==3} {send_user KABORT} exit } if {$local_io} { proc mkfifo {f} { if 0==[catch {exec mkfifo $f}] return ;# POSIX if 0==[catch {exec mknod $f p}] return # some systems put mknod in wierd places if 0==[catch {exec /usr/etc/mknod $f p}] return ;# Sun if 0==[catch {exec /etc/mknod $f p}] return ;# AIX, Cray puts "Couldn't figure out how to make a fifo - where is mknod?" |
︙ | ︙ | |||
345 346 347 348 349 350 351 | # create 2 fifos to communicate with other user mkfifo $userinfile mkfifo $useroutfile # make sure other user can access despite umask exec chmod 666 $userinfile $useroutfile | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > | | | | | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | # create 2 fifos to communicate with other user mkfifo $userinfile mkfifo $useroutfile # make sure other user can access despite umask exec chmod 666 $userinfile $useroutfile if {$verbose} {send_user "asking $user to type: kibitz -$pid\n"} # can't use exec since write insists on being run from a tty! set rc [catch { system echo "Can we talk? Run: \"kibitz -$pid\"" | \ /bin/write $user $tty } ] if {$rc} {rmfifos;abort} spawn -open [open $useroutfile w] set userout $spawn_id # open will hang until other user's cat starts spawn -open [open "|cat $catflags < $userinfile" "r"] set userin $spawn_id catch {exec rm $userinfile} } stty -echo raw if {$user_number==3} { send_user "KDATA" ;# this tells user_number 1 to send data interact { -output $userout -input $userin eof { wait -i $userin return -tcl } -output $user_spawn_id } } else { if {$allow_escape} {send_user "Escape sequence is $escape_printable\r\n"} if {$noproc} { interact { -output $userout -input $userin eof {wait -i $userin; return} -output $user_spawn_id } } else { eval interact $esc_match { -output $shell \ -input $userin eof { wait -i $userin close -i $shell return } -output $shell \ -input $shell eof { close -i $userout wait -i $userout return } -output "$user_spawn_id $userout" } wait -i $shell } } if {$local_io} rmfifos |
Changes to example/lpunlock.
︙ | ︙ | |||
14 15 16 17 18 19 20 | proc usage {} { send_user "usage: lpunlock <printer> \[<server>\]\n" send_user "example: lpunlock lw-isg durer\n" exit } | | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | proc usage {} { send_user "usage: lpunlock <printer> \[<server>\]\n" send_user "example: lpunlock lw-isg durer\n" exit } if {$argc==0} usage set printer [lindex $argv 0] set client [exec hostname] if {$argc == 1} { # if no arg2, look in local printcap for info spawn ed /etc/printcap expect "\n" ;# discard character count send "/$printer/\r" for {} {1} {} { expect -re ".*:rm=(\[^:]*):.*\r\n" { set server $expect_out(1,string) break } "\r\n*\\\r\n" { ;# look at next line of entry send "\r" } "\r\n*\n" { ;# no more lines of entry - give up set server $client |
︙ | ︙ |
Changes to example/mkpasswd.
1 2 3 4 5 6 7 8 9 10 11 12 | #!/depot/path/expect -- # mkpasswd - make a password, if username given, set it. # Author: Don Libes, NIST # defaults set length 9 set minnum 2 set minlower 2 set minupper 2 set verbose 0 set distribute 0 | > > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/depot/path/expect -- # mkpasswd - make a password, if username given, set it. # Author: Don Libes, NIST # defaults set length 9 set minnum 2 set minlower 2 set minupper 2 set minspecial 1 set verbose 0 set distribute 0 if {[file executable /bin/nispasswd]} { set defaultprog /bin/nispasswd } elseif {[file executable /bin/yppasswd]} { set defaultprog /bin/yppasswd } elseif {[file executable /bin/passwd]} { set defaultprog /bin/passwd } else { set defaultprog passwd } set prog $defaultprog while {[llength $argv]>0} { |
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | set argv [lrange $argv 2 end] } "-c" { set minlower [lindex $argv 1] set argv [lrange $argv 2 end] } "-C" { set minupper [lindex $argv 1] set argv [lrange $argv 2 end] } "-v" { set verbose 1 set argv [lrange $argv 1 end] } "-p" { set prog [lindex $argv 1] set argv [lrange $argv 2 end] } "-2" { | > > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | set argv [lrange $argv 2 end] } "-c" { set minlower [lindex $argv 1] set argv [lrange $argv 2 end] } "-C" { set minupper [lindex $argv 1] set argv [lrange $argv 2 end] } "-s" { set minspecial [lindex $argv 1] set argv [lrange $argv 2 end] } "-v" { set verbose 1 set argv [lrange $argv 1 end] } "-p" { set prog [lindex $argv 1] set argv [lrange $argv 2 end] } "-2" { |
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 | if {[llength $argv]} { puts "usage: mkpasswd \[args] \[user]" puts " where arguments are:" puts " -l # (length of password, default = $length)" puts " -d # (min # of digits, default = $minnum)" puts " -c # (min # of lowercase chars, default = $minlower)" puts " -C # (min # of uppercase chars, default = $minupper)" puts " -v (verbose, show passwd interaction)" puts " -p prog (program to set password, default = $defaultprog)" exit 1 } | > | | > | | > | | < < < | < < < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | if {[llength $argv]} { puts "usage: mkpasswd \[args] \[user]" puts " where arguments are:" puts " -l # (length of password, default = $length)" puts " -d # (min # of digits, default = $minnum)" puts " -c # (min # of lowercase chars, default = $minlower)" puts " -C # (min # of uppercase chars, default = $minupper)" puts " -s # (min # of special chars, default = $minspecial)" puts " -v (verbose, show passwd interaction)" puts " -p prog (program to set password, default = $defaultprog)" exit 1 } if {$minnum + $minlower + $minupper + $minspecial > $length} { puts "impossible to generate $length-character password\ with $minnum numbers, $minlower lowercase letters,\ $minupper uppercase letters and\ $minspecial special characters." exit 1 } # if there is any underspecification, use additional lowercase letters set minlower [expr {$length - ($minnum + $minupper + $minspecial)}] set lpass "" ;# password chars typed by left hand set rpass "" ;# password chars typed by right hand # insert char into password at a random position, thereby spreading # the different kinds of characters throughout the password proc insert {pvar char} { upvar $pvar p set p [linsert $p [rand [expr {(1+[llength $p])}]] $char] } proc rand {m} { expr {int($m*rand())} } # choose left or right starting hand set initially_left [set isleft [rand 2]] # given a size, distribute between left and right hands # taking into account where we left off |
︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | } if {$distribute} { set lkeys {q w e r t a s d f g z x c v b} set rkeys {y u i o p h j k l n m} set lnums {1 2 3 4 5 6} set rnums {7 8 9 0} } else { set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set lnums {0 1 2 3 4 5 6 7 8 9} set rnums {0 1 2 3 4 5 6 7 8 9} } set lkeys_length [llength $lkeys] set rkeys_length [llength $rkeys] set lnums_length [llength $lnums] set rnums_length [llength $rnums] psplit $minnum left right for {set i 0} {$i<$left} {incr i} { insert lpass [lindex $lnums [rand $lnums_length]] } for {set i 0} {$i<$right} {incr i} { insert rpass [lindex $rnums [rand $rnums_length]] | > > > > > > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | } if {$distribute} { set lkeys {q w e r t a s d f g z x c v b} set rkeys {y u i o p h j k l n m} set lnums {1 2 3 4 5 6} set rnums {7 8 9 0} set lspec {! @ # \$ %} set rspec {^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /} } else { set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set lnums {0 1 2 3 4 5 6 7 8 9} set rnums {0 1 2 3 4 5 6 7 8 9} set lspec {! @ # \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /} set rspec {! @ # \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /} } set lkeys_length [llength $lkeys] set rkeys_length [llength $rkeys] set lnums_length [llength $lnums] set rnums_length [llength $rnums] set lspec_length [llength $lspec] set rspec_length [llength $rspec] psplit $minnum left right for {set i 0} {$i<$left} {incr i} { insert lpass [lindex $lnums [rand $lnums_length]] } for {set i 0} {$i<$right} {incr i} { insert rpass [lindex $rnums [rand $rnums_length]] |
︙ | ︙ | |||
148 149 150 151 152 153 154 155 | psplit $minupper left right for {set i 0} {$i<$left} {incr i} { insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]] } for {set i 0} {$i<$right} {incr i} { insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]] } | | | < | < < | | | | < < < < < | > | > | > > | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | psplit $minupper left right for {set i 0} {$i<$left} {incr i} { insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]] } for {set i 0} {$i<$right} {incr i} { insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]] } psplit $minspecial left right for {set i 0} {$i<$left} {incr i} { insert lpass [lindex $lspec [rand $lspec_length]] } for {set i 0} {$i<$right} {incr i} { insert rpass [lindex $rspec [rand $rspec_length]] } # merge results together foreach l $lpass r $rpass { if {$initially_left} { append password $l $r } else { append password $r $l } } if {[info exists user]} { if {!$verbose} { log_user 0 } |
︙ | ︙ |
Changes to example/mkpasswd.man.
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | The default is 2. The .B \-C flag defines the minimum number of uppercase alphabetic characters that must be in the password. The default is 2. The .B \-p flag names a program to set the password. By default, /etc/yppasswd is used if present, otherwise /bin/passwd is used. The .B \-2 | > > > > > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | The default is 2. The .B \-C flag defines the minimum number of uppercase alphabetic characters that must be in the password. The default is 2. The .B \-s flag defines the minimum number of special characters that must be in the password. The default is 1. The .B \-p flag names a program to set the password. By default, /etc/yppasswd is used if present, otherwise /bin/passwd is used. The .B \-2 |
︙ | ︙ |
Changes to example/passmass.
1 2 3 4 5 6 7 | #!../expect -- # passmass: change password on many machines # Synopsis: passmass host1 host2 host3 .... # Don Libes - March 11, 1991 # Description: Change passwords on the named machines. # | < < < < < < < < < < < < < < < < < < < < | < < < | | | | | | | | | | > | > > | | | | > | | | | | | | | > > > > > > > > > > > > > > > > > > > | | | < | | < | | | | | | | | | | | | | | | | | | | | | | | | > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > | | | | | | | | | | | | | | | | | | | | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | #!../expect -- # passmass: change password on many machines # Synopsis: passmass host1 host2 host3 .... # Don Libes - March 11, 1991 # Description: Change passwords on the named machines. # # See passmass.man for further info. exp_version -exit 5.0 if {$argc==0} { send_user "usage: $argv0 host1 host2 host3 . . .\n" exit } expect_before -i $user_spawn_id \003 exit proc badhost {host emsg} { global badhosts send_user "\r\n\007password not changed on $host - $emsg\n\n" if {0==[llength $badhosts]} { set badhosts $host } else { set badhosts [concat $badhosts $host] } } # set defaults set login "rlogin" set program "passwd" set user [exec whoami] set su 0 set timeout -1 stty -echo if {!$su} { send_user "old password: " expect_user -re "(.*)\n" send_user "\n" set password(old) $expect_out(1,string) set password(login) $expect_out(1,string) send_user "new password: " expect_user -re "(.*)\n" send_user "\n" set password(new) $expect_out(1,string) send_user "retype new password: " expect_user -re "(.*)\n" set password(newcheck) $expect_out(1,string) send_user "\n" } else { send_user "login password: " expect_user -re "(.*)\n" send_user "\n" set password(login) $expect_out(1,string) send_user "root password: " expect_user -re "(.*)\n" send_user "\n" set password(old) $expect_out(1,string) send_user "new password: " expect_user -re "(.*)\n" send_user "\n" set password(new) $expect_out(1,string) send_user "retype new password: " expect_user -re "(.*)\n" set password(newcheck) $expect_out(1,string) send_user "\n" } stty echo trap exit SIGINT if ![string match $password(new) $password(newcheck)] { send_user "mismatch - password unchanged\n" exit } #send_user "want to see new password you just typed? (y|n) " #expect_user "*\n" # #if {[string match "y" [lindex $expect_match 0 c]]} { # send_user "password is <$password(new)>\nproceed? (y|n) " # expect_user "*\n" # if ![string match "y" [lindex $expect_match 0 c]] exit #} set timeout 30 set badhosts {} for {set i 0} {$i<$argc} {incr i} { set arg [lindex $argv $i] switch -- $arg "-user" { incr i set user [lindex $argv $i] continue } "-prompt" { incr i set prompt [lindex $argv $i] continue } "-rlogin" { set login "rlogin" continue } "-slogin" { set login "slogin" continue } "-telnet" { set login "telnet" continue } "-program" { incr i set program [lindex $argv $i] continue } "-timeout" { incr i set timeout [lindex $argv $i] continue } "-su" { incr i set su [lindex $argv $i] continue } set host $arg if {[string match $login "rlogin"]} { set pid [spawn rlogin $host -l $user] } elseif {[string match $login "slogin"]} { set pid [spawn slogin $host -l $user] } elseif {[string match $login "ssh"]} { set pid [spawn ssh $host -l $user] } else { set pid [spawn telnet $host] expect -re "(login|Username):.*" { send "$user\r" } } if ![info exists prompt] { if {[string match $user "root"]} { set prompt "# " } else { set prompt "(%|\\\$|#) " } } set logged_in 0 while {1} { expect "Password*" { send "$password(login)\r" } eof { badhost $host "spawn failed" break } timeout { badhost $host "could not log in (or unrecognized prompt)" exec kill $pid expect eof break } -re "incorrect|invalid" { badhost $host "bad password or login" exec kill $pid expect eof break } -re $prompt { set logged_in 1 break } } if (!$logged_in) { wait continue } if ($su) { send "su -\r" expect "Password:" send "$password(old)\r" expect "# " send "$program root\r" } else { send "$program\r" } expect "Old password*" { send "$password(old)\r" expect "Sorry*" { badhost $host "old password is bad?" continue } "password:" } -re "(n|N)ew password:" send "$password(new)\r" expect -re "not changed|unchanged" { badhost $host "new password is bad?" continue } -re "(password|Verification|Verify|again):.*" send "$password(new)\r" expect -re "(not changed|incorrect|choose new).*" { badhost $host "password is bad?" continue } -re "$prompt" send_user "\n" close wait } if {[llength $badhosts]} { send_user "\nfailed to set password on $badhosts\n" } |
Changes to example/passmass.man.
︙ | ︙ | |||
41 42 43 44 45 46 47 | .TP 4 -telnet Use telnet to access host. .TP 4 -program | | | | > > > > > > > > | | | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | .TP 4 -telnet Use telnet to access host. .TP 4 -program Next argument is a program to run to set the password. Default is "passwd". Other common choices are "yppasswd" and "set passwd" (e.g., VMS hosts). A program name such as "password fred" can be used to create entries for new accounts (when run as root). .TP 4 -prompt Next argument is a prompt suffix pattern. This allows the script to know when the shell is prompting. The default is "# " for root and "% " for non-root accounts. .TP 4 -timeout Next argument is the number of seconds to wait for responses. Default is 30 but some systems can be much slower logging in. .TP 4 -su Next argument is 1 or 0. If 1, you are additionally prompted for a root password which is used to su after logging in. root's password is changed rather than the user's. This is useful for hosts which do not allow root to log in. .SH HOW TO USE The best way to run Passmass is to put the command in a one-line shell script or alias. Whenever you get a new account on a new machine, add the appropriate arguments to the command. Then run it whenever you want to change your passwords on all the hosts. .SH CAVEATS Using the same password on multiple hosts carries risks. In particular, if the password can be stolen, then all of your accounts are at risk. Thus, you should not use Passmass in situations where your password is visible, such as across a network which hackers are known to eavesdrop. On the other hand, if you have enough accounts with different passwords, you may end up writing them down somewhere - and .I that can be a security problem. Funny story: my college roommate had an 11"x13" piece of paper on which he had listed accounts and passwords all across the Internet. This was several years worth of careful work |
︙ | ︙ |
Changes to example/passwd.cgi.
︙ | ︙ | |||
95 96 97 98 99 100 101 | send "$var(new2)\r" expect -re (.*)\r\n { set error $expect_out(1,string) } close wait | | | 95 96 97 98 99 100 101 102 103 104 105 106 | send "$var(new2)\r" expect -re (.*)\r\n { set error $expect_out(1,string) } close wait if {[info exists error]} { errormsg "$error" } else { successmsg "Password changed successfully." } |
Changes to example/reprompt.
1 2 3 4 5 6 7 8 9 10 11 | #!/depot/path/expect -- # Name: reprompt # Description: reprompt every so often until user enters something # Usage: reprompt timeout prompt # Author: Don Libes, NIST foreach {timeout prompt} $argv {} send_error $prompt expect { | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/depot/path/expect -- # Name: reprompt # Description: reprompt every so often until user enters something # Usage: reprompt timeout prompt # Author: Don Libes, NIST foreach {timeout prompt} $argv {} send_error $prompt expect { timeout { send_error "\nwake up!!\a" send_error \n$prompt exp_continue } -re .+ { send_user $expect_out(buffer) } } |
Changes to example/rftp.
︙ | ︙ | |||
45 46 47 48 49 50 51 | ####################end of documentation############################### match_max -d 100000 ;# max size of a directory listing # return name of file from one line of directory listing proc getname {line} { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | < | > | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | < | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | ####################end of documentation############################### match_max -d 100000 ;# max size of a directory listing # return name of file from one line of directory listing proc getname {line} { # if it's a symbolic link, return local name set i [lsearch $line "->"] if {-1==$i} { # not a sym link, return last token of line as name return [lindex $line [expr [llength $line]-1]] } else { # sym link, return "a" of "a -> b" return [lindex $line [expr $i-1]] } } proc putfile {name} { global current_type default_type global binary ascii tenex global file_timeout switch -- $name $binary {set new_type binary} \ $ascii {set new_type ascii} \ $tenex {set new_type tenex} \ default {set new_type $default_type} if {$current_type != $new_type} { settype $new_type } set timeout $file_timeout send "put $name\r" expect timeout { send_user "ftp timed out in response to \"put $name\"\n" exit } "ftp>*" } proc getfile {name} { global current_type default_type global binary ascii tenex global file_timeout switch -- $name $binary {set new_type binary} \ $ascii {set new_type ascii} \ $tenex {set new_type tenex} \ default {set new_type $default_type} if {$current_type != $new_type} { settype $new_type } set timeout $file_timeout send "get $name\r" expect timeout { send_user "ftp timed out in response to \"get $name\"\n" exit } "ftp>*" } # returns 1 if successful, 0 otherwise proc putdirectory {name} { send "mkdir $name\r" expect "550*denied*ftp>*" { send_user "failed to make remote directory $name\n" return 0 } timeout { send_user "timed out on make remote directory $name\n" return 0 } -re "(257|550.*exists).*ftp>.*" # 550 is returned if directory already exists send "cd $name\r" expect "550*ftp>*" { send_user "failed to cd to remote directory $name\n" return 0 } timeout { send_user "timed out on cd to remote directory $name\n" return 0 } -re "2(5|0)0.*ftp>.*" # some ftp's return 200, some return 250 send "lcd $name\r" # hard to know what to look for, since my ftp doesn't return status # codes. It is evidentally very locale-dependent. # So, assume success. expect "ftp>*" putcurdirectory send "lcd ..\r" expect "ftp>*" send "cd ..\r" expect timeout { send_user "failed to cd to remote directory ..\n" return 0 } -re "2(5|0)0.*ftp>.*" return 1 } # returns 1 if successful, 0 otherwise proc getdirectory {name transfer} { send "cd $name\r" # this can fail normally if it's a symbolic link, and we are just # experimenting expect "550*ftp>*" { send_user "failed to cd to remote directory $name\n" return 0 } timeout { send_user "timed out on cd to remote directory $name\n" return 0 } -re "2(5|0)0.*ftp>.*" # some ftp's return 200, some return 250 if {$transfer} { send "!mkdir $name\r" expect "denied*" return timeout return "ftp>" send "lcd $name\r" # hard to know what to look for, since my ftp doesn't return # status codes. It is evidentally very locale-dependent. # So, assume success. expect "ftp>*" } getcurdirectory $transfer if {$transfer} { send "lcd ..\r" expect "ftp>*" } send "cd ..\r" expect timeout { send_user "failed to cd to remote directory ..\n" return 0 } -re "2(5|0)0.*ftp>.*" return 1 } proc putentry {name type} { switch -- $type d { # directory if {$name=="." || $name==".."} return putdirectory $name } - { # file putfile $name } l { # symlink, could be either file or directory # first assume it's a directory if {[putdirectory $name]} return putfile $name } default { send_user "can't figure out what $name is, skipping\n" } } proc getentry {name type transfer} { switch -- $type d { # directory if {$name=="." || $name==".."} return getdirectory $name $transfer } - { # file if {!$transfer} return getfile $name } l { # symlink, could be either file or directory # first assume it's a directory if {[getdirectory $name $transfer]} return if {!$transfer} return getfile $name } default { send_user "can't figure out what $name is, skipping\n" } } proc putcurdirectory {} { send "!/bin/ls -alg\r" expect timeout { send_user "failed to get directory listing\n" return } "ftp>*" set buf $expect_out(buffer) while {1} { # if end of listing, succeeded! if 0==[regexp "(\[^\n]*)\n(.*)" $buf dummy line buf] return set token [lindex $line 0] switch -- $token !/bin/ls { # original command } total { # directory header } . { # unreadable } default { # either file or directory set name [getname $line] set type [string index $line 0] putentry $name $type } } } # look at result of "dir". If transfer==1, get all files and directories proc getcurdirectory {transfer} { send "dir\r" expect timeout { send_user "failed to get directory listing\n" return } "ftp>*" set buf $expect_out(buffer) while {1} { regexp "(\[^\n]*)\n(.*)" $buf dummy line buf set token [lindex $line 0] switch -- $token dir { # original command } 200 { # command successful } 150 { # opening data connection } total { # directory header } 226 { # transfer complete, succeeded! return } ftp>* { # next prompt, failed! return } . { # unreadable } default { # either file or directory set name [getname $line] set type [string index $line 0] getentry $name $type $transfer } } } proc settype {t} { global current_type send "type $t\r" set current_type $t expect "200*ftp>*" } proc final_msg {} { # write over the previous prompt with our message send_user "\rQuit ftp or cd to another directory and press ~g, ~p, or ~l\n" # and then reprompt send_user "ftp> " } if {[file readable ~/.rftprc]} {source ~/.rftprc} set first_time 1 if {$argc>1} { send_user "usage: rftp [host]" exit } send_user "Once logged in, cd to the directory to be transferred and press:\n" send_user "~p to put the current directory from the local to the remote host\n" send_user "~g to get the current directory from the remote host to the local host\n" send_user "~l to list the current directory from the remote host\n" if {$argc==0} {spawn ftp} else {spawn ftp $argv} interact -echo ~g { if {$first_time} { set first_time 0 settype $default_type } getcurdirectory 1 final_msg } -echo ~p { if {$first_time} { set first_time 0 settype $default_type } putcurdirectory final_msg } -echo ~l { getcurdirectory 0 final_msg } |
Changes to example/robohunt.
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!../expect -f # Synopsis # robohunt player-name [-nodisplay] # Plays hunt automatically. Optional "-nodisplay" argument disables output. # by Don Libes expect_version -exit 5.0 set timeout 1 proc random {} { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #!../expect -f # Synopsis # robohunt player-name [-nodisplay] # Plays hunt automatically. Optional "-nodisplay" argument disables output. # by Don Libes expect_version -exit 5.0 set timeout 1 proc random {} { global ia ic im jran set jran [expr ($jran*$ia + $ic) % $im] return $jran } set ia 7141 set ic 54773 set im 259200 set jran [pid] # given a direction and number, moves that many spaces in that direction proc mv {dir num} { # first try firing a bullet (what the hell...open some walls to move!) send "f" for {set i 0} {$i<$num} {incr i} { send $dir } } # move a random distance/direction # 31 is arbitrarily used as a max distance to move in any one direction # this is a compromise between long horizontal and vertical moves # but since excess movement is good for stabbing, this is reasonable proc move {} { set num [random] set mask [expr $num&3] set num [expr $num&31] if $mask==0 {send "H"; mv "h" $num; return} if $mask==1 {send "L"; mv "l" $num; return} if $mask==2 {send "K"; mv "k" $num; return} send "J"; mv "j" $num; return } if {2==$argc} { set output 0 } {set output 1} if {1>$argc} { send_user "usage: robohunt name \[-nodisplay\]\n"; exit} spawn hunt -b -c -n [lindex $argv 0] expect "team" send "\r" set several_moves 5 expect "Monitor:" after 1000 expect ;# flush output log_user 0 # output is turned off so that we can first strip out ^Gs before they # are sent to the tty. It seems to drive xterms crazy - because our # rather stupid algorithm off not checking after every move can cause # the game to send a lot of them. for {} {1} {} { # make several moves at a time, before checking to see if we are dead # this is a compromise between just ignoring our status after each move # and looking at our status after each move for {set j $several_moves} {$j} {incr j -1} { move } expect { -re ^\007+ {exp_continue} -re "\\? " {send y} -re .+ } if $output {send_user -raw $expect_out(buffer)} } |
Changes to example/rogue.exp.
1 2 3 4 5 6 7 | #!../expect -f # Look for a GREAT game of rogue. # Idea is that any game with a Strength of 18 is unusually good. # Written by Don Libes - March, 1990 set timeout -1 while {1} { | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!../expect -f # Look for a GREAT game of rogue. # Idea is that any game with a Strength of 18 is unusually good. # Written by Don Libes - March, 1990 set timeout -1 while {1} { spawn rogue expect "Str: 18" break \ "Str: 16" send "Q" expect "quit?" send "y" close wait } interact |
Changes to example/telnet-in-bg.
1 2 3 4 5 6 7 8 9 | # Start telnet and when you press ^Z, put telnet in background and save any # remaining output in "telnet.log". You can actually apply this technique # to any interactive program - I just chose telnet here. # Author: Don Libes, NIST, 1/5/95 spawn -ignore HUP telnet $argv ;# start telnet interact \032 return ;# interact until ^Z | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Start telnet and when you press ^Z, put telnet in background and save any # remaining output in "telnet.log". You can actually apply this technique # to any interactive program - I just chose telnet here. # Author: Don Libes, NIST, 1/5/95 spawn -ignore HUP telnet $argv ;# start telnet interact \032 return ;# interact until ^Z if {[fork]} exit ;# disconnect from terminal disconnect set log [open logfile w] ;# open logfile expect -re .+ { ;# and record everything to it puts -nonewline $log $expect_out(buffer) exp_continue } |
︙ | ︙ |
Changes to example/term_expect.
︙ | ︙ | |||
108 109 110 111 112 113 114 | unset env(DISPLAY) set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | unset env(DISPLAY) set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" if {$termcap} { set env(TERMCAP) {tt: :cm=\E[%d;%dH: :up=\E[A: :nd=\E[C: :cl=\E[H\E[J: :ce=\E[K: :do=^J: |
︙ | ︙ | |||
130 131 132 133 134 135 136 | :k6=\EOU: :k7=\EOV: :k8=\EOW: :k9=\EOX: } } | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | :k6=\EOU: :k7=\EOV: :k8=\EOW: :k9=\EOX: } } if {$terminfo} { set env(TERMINFO) /tmp set ttsrc "/tmp/tt.src" set file [open $ttsrc w] puts $file {tt|textterm|Don Libes' tk text widget terminal emulator, cup=\E[%p1%d;%p2%dH, cuu1=\E[A, |
︙ | ︙ | |||
280 281 282 283 284 285 286 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row if {$newline} { term_down } ################## # write full lines ################## while {$chars_rem_to_write >= $cols} { |
︙ | ︙ |
Changes to example/tknewsbiff.
︙ | ︙ | |||
31 32 33 34 35 36 37 | # make sure that when we map it, it will be open (i.e., "normal") set _window_open 1 # PUBLIC proc mapwindow {} { global _window_open | | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # make sure that when we map it, it will be open (i.e., "normal") set _window_open 1 # PUBLIC proc mapwindow {} { global _window_open if {$_window_open} { wm deiconify . } else { wm iconify . } } proc _abort {msg} { global argv0 puts "$argv0: $msg" exit 1 } if {[info exists env(DOTDIR)]} { set home $env(DOTDIR) } else { set home [glob ~] } set delay 60 set width 27 |
︙ | ︙ | |||
72 73 74 75 76 77 78 | .scrollbar config -highlightthickness 0 pack .scrollbar -side left -fill y pack .list -side left -fill both -expand 1 while {[llength $argv]>0} { set arg [lindex $argv 0] | | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | .scrollbar config -highlightthickness 0 pack .scrollbar -side left -fill y pack .list -side left -fill both -expand 1 while {[llength $argv]>0} { set arg [lindex $argv 0] if {[file readable $arg]} { if {0==[string compare active [file tail $arg]]} { set active_file $arg set argv [lrange $argv 1 end] } else { # must be a config file set _config_file $arg set argv [lrange $argv 1 end] } |
︙ | ︙ | |||
102 103 104 105 106 107 108 | # remove previous user-provided proc in case user simply # deleted it from config file proc user {} {} set watch_list {} set ignore_list {} | | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | # remove previous user-provided proc in case user simply # deleted it from config file proc user {} {} set watch_list {} set ignore_list {} if {[file exists $_config_file]} { # uplevel allows user to set global variables if {[catch {uplevel source $_config_file} msg]} { _abort "error reading $_config_file\n$msg" } } if {[llength $watch_list]==0} { watch * } } # PUBLIC proc watch {args} { global watch_list |
︙ | ︙ | |||
133 134 135 136 137 138 139 | } # get time and server _read_config_file # if user didn't set newsrc, try ~/.newsrc-server convention. # if that fails, fall back to just plain ~/.newsrc | | | | | | | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | } # get time and server _read_config_file # if user didn't set newsrc, try ~/.newsrc-server convention. # if that fails, fall back to just plain ~/.newsrc if {![info exists newsrc]} { set newsrc $home/.newsrc-$server if {![file readable $newsrc]} { set newsrc $home/.newsrc if {![file readable $newsrc]} { _abort "cannot tell what newgroups you read found neither $home/.newsrc-$server nor $home/.newsrc" } } } # PRIVATE proc _read_newsrc {} { global db newsrc if {[catch {set file [open $newsrc]} msg]} { _abort $msg } while {-1 != [gets $file buf]} { if {[regexp "!" $buf]} continue if {[regexp "(\[^:]*):.*\[-, ](\[0-9]+)" $buf dummy ng seen]} { set db($ng,seen) $seen } # only way 2nd regexp can fail is on lines # that have a : but no number } close $file } proc _unknown_host {} { global server _default_server if {0==[string compare $_default_server $server]} { puts "tknewsbiff: default server <$server> is not known" } else { puts "tknewsbiff: server <$server> is not known" } puts "Give tknewsbiff an argument - either the name of your news server or active file. I.e., |
︙ | ︙ | |||
190 191 192 193 194 195 196 | # PRIVATE proc _read_active {} { global db server active_list active_file upvar #0 server_timeout timeout set active_list {} | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | # PRIVATE proc _read_active {} { global db server active_list active_file upvar #0 server_timeout timeout set active_list {} if {[info exists active_file]} { spawn -open [open $active_file] } else { spawn telnet $server nntp expect { "20*\n" { # should get 200 or 201 } "NNTP server*\n" { |
︙ | ︙ | |||
243 244 245 246 247 248 249 | # test in various ways for good newsgroups # return 1 if good, 0 if not good # PRIVATE proc _isgood {ng threshold} { global db seen_list ignore_list # skip if we don't subscribe to it | | | | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | # test in various ways for good newsgroups # return 1 if good, 0 if not good # PRIVATE proc _isgood {ng threshold} { global db seen_list ignore_list # skip if we don't subscribe to it if {![info exists db($ng,seen)]} {return 0} # skip if the threshold isn't exceeded if {$db($ng,hi) - $db($ng,seen) < $threshold} {return 0} # skip if it matches an ignore command foreach igpat $ignore_list { if {[string match $igpat $ng]} {return 0} } # skip if we've seen it before if {[lsearch -exact $seen_list $ng]!=-1} {return 0} # passed all tests, so remember that we've seen it lappend seen_list $ng return 1 } # return 1 if not seen on previous turn # PRIVATE proc _isnew {ng} { global previous_seen_list if {[lsearch -exact $previous_seen_list $ng]==-1} { return 1 } else { return 0 } } # schedule display of newsgroup in global variable "newsgroup" |
︙ | ︙ | |||
310 311 312 313 314 315 316 | set watch [lrange $watch 2 end] } default { _abort "watch: expecting -threshold -display or -new but found: [lindex $watch 0]" } } foreach ng $active_list { | | | | | | | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | set watch [lrange $watch 2 end] } default { _abort "watch: expecting -threshold -display or -new but found: [lindex $watch 0]" } } foreach ng $active_list { if {[string match $ngpat $ng]} { if {[_isgood $ng $threshold]} { if {[llength $display]} { set newsgroup $ng uplevel $display } if {[_isnew $ng]} { if {[llength $new]} { set newsgroup $ng uplevel $new } } } } } |
︙ | ︙ | |||
368 369 370 371 372 373 374 | } wm geometry . ${width}x$current_height wm maxsize . 999 [llength $display_list] _display_ngs $width | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | } wm geometry . ${width}x$current_height wm maxsize . 999 [llength $display_list] _display_ngs $width if {[string compare [wm state .] withdrawn]==0} { mapwindow } } # actually write all newsgroups to the window # PRIVATE proc _display_ngs {width} { |
︙ | ︙ | |||
452 453 454 455 456 457 458 | spawn cat -u; set _cat_spawn_id $spawn_id set _update_flag 0 # PUBLIC proc update-now {} { global _update_flag _cat_spawn_id | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | spawn cat -u; set _cat_spawn_id $spawn_id set _update_flag 0 # PUBLIC proc update-now {} { global _update_flag _cat_spawn_id if {$_update_flag} return ;# already set, do nothing set _update_flag 1 exp_send -i $_cat_spawn_id "\r" } bind .list <1> help bind .list <2> update-now |
︙ | ︙ | |||
498 499 500 501 502 503 504 | set display_list {} set seen_list {} catch {unset db} } | | | | 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | set display_list {} set seen_list {} catch {unset db} } for {} {1} {_sleep $delay} { _init_ngs _read_newsrc if {[_read_active]} continue _read_config_file _update_ngs user _update_window } |
Changes to example/tkpasswd.
1 2 3 4 5 6 7 8 9 10 | #!/depot/path/expectk -f # tkpasswd - Change passwords using Expectk # Author: Don Libes, NIST, October 1, 1993 # Version: 1.8 - Added support for Tk 4.1 # There is no man page. However, there is some on-line help when you run # the program. Technical details and insights are described in the # O'Reilly book "Exploring Expect". proc prog_exists {prog} { | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #!/depot/path/expectk -f # tkpasswd - Change passwords using Expectk # Author: Don Libes, NIST, October 1, 1993 # Version: 1.8 - Added support for Tk 4.1 # There is no man page. However, there is some on-line help when you run # the program. Technical details and insights are described in the # O'Reilly book "Exploring Expect". proc prog_exists {prog} { global env foreach dir [split $env(PATH) :] { if {[file executable $dir/$prog]} { return 1 } } return 0 } frame .type -relief raised -bd 1 radiobutton .passwd -text passwd -variable passwd_cmd \ -value {passwd {cat /etc/passwd}} \ -anchor w -command get_users -relief flat pack .passwd -in .type -fill x if {[prog_exists yppasswd]} { radiobutton .yppasswd -text yppasswd -variable passwd_cmd \ -value {yppasswd {ypcat passwd}} \ -anchor w -command get_users -relief flat pack .yppasswd -in .type -fill x } if {[prog_exists nispasswd]} { radiobutton .nispasswd -text nispasswd -variable passwd_cmd \ -value {nispasswd {niscat passwd}} \ -anchor w -command get_users -relief flat pack .nispasswd -in .type -fill x } pack .type -fill x frame .sort -relief raised -bd 1 radiobutton .unsorted -text unsorted -variable sort_cmd -value " " \ -anchor w -relief flat -command get_users radiobutton .name -text name -variable sort_cmd -value "| sort" \ -anchor w -relief flat -command get_users radiobutton .uid -text uid -variable sort_cmd -value "| sort -t: -n +2" \ -anchor w -relief flat -command get_users pack .unsorted .name .uid -in .sort -fill x pack .sort -fill x frame .users -relief raised -bd 1 # has to be wide enough for 8+1+5=14 text .names -yscrollcommand ".scroll set" -width 14 -height 1 \ -font "*-bold-o-normal-*-120-*-m-*" -setgrid 1 .names tag configure nopassword -relief raised .names tag configure selection -relief raised set iscolor 0 if {[winfo depth .] > 1} { set iscolor 1 } if {$iscolor} { .names tag configure nopassword -background red .names tag configure selection -background green } else { .names tag configure nopassword -background black -foreground white .names tag configure selection -background white -foreground black } scrollbar .scroll -command ".names yview" -relief raised pack .scroll -in .users -side left -fill y pack .names -in .users -side left -fill y pack .users -expand 1 -fill y wm minsize . 14 1 |
︙ | ︙ | |||
87 88 89 90 91 92 93 | button .generate_button -text "generate" -command password_generate pack .prompt .password -in .password_frame -fill x -padx 2 -pady 2 pack .password_set .generate_button -in .password_frame -side left -expand 1 -fill x -padx 2 -pady 2 pack .password_frame -fill x set dict_loaded 0 checkbutton .dict -text "test dictionary" -variable dict_check \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | < < < | | | | | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | button .generate_button -text "generate" -command password_generate pack .prompt .password -in .password_frame -fill x -padx 2 -pady 2 pack .password_set .generate_button -in .password_frame -side left -expand 1 -fill x -padx 2 -pady 2 pack .password_frame -fill x set dict_loaded 0 checkbutton .dict -text "test dictionary" -variable dict_check \ -command {if {!$dict_loaded} load_dict} \ -anchor w pack .dict -fill x -padx 2 -pady 2 button .quit -text quit -command exit button .help_button -text help -command help pack .quit .help_button -side left -expand 1 -fill x -padx 2 -pady 2 proc help {} { if {[catch {toplevel .help}]} return message .help.text -text \ "tkpasswd - written by Don Libes, NIST, 10/1/93. Click on passwd (local users) or yppasswd (NIS users).\ Select user using mouse (or keys - see below).\ Enter password or press ^G to generate a random password.\ (Press ^A to adjust the generation parameters.)\ Press return to set the password.\ If the dictionary is enabled and the password is in it,\ the password is rejected. You must be root to set local passwords besides your own.\ If you are not root, you must also enter an old password\ when requested. You do not have to move mouse into password field(s) to enter password.\ ^U clears password field.\ ^N and ^P select next/previous user.\ M-n and M-p select next/previous user with no password.\ (Users with no passwords are highlighted.)" button .help.ok -text "ok" -command {destroy .help} pack .help.text pack .help.ok -fill x -padx 2 -pady 2 } # get list of local users proc get_users {} { global sort_cmd passwd_cmd global nopasswords ;# line numbers of entries with no passwords global last_line ;# last line of text box global selection_line .names delete 1.0 end set file [open "|[lindex $passwd_cmd 1] $sort_cmd"] set last_line 1 set nopasswords {} while {[gets $file buf] != -1} { set buf [split $buf :] if {[llength $buf]>2} { # normal password entry .names insert end "[format "%-8.8s %5d" [lindex $buf 0] [lindex $buf 2]]\n" if {0==[string compare [lindex $buf 1] ""]} { .names tag add nopassword \ {end - 2 line linestart} \ {end - 2 line lineend} lappend nopasswords $last_line } } else { # +name style entry .names insert end "$buf\n" } incr last_line } incr last_line -1 close $file set selection_line 0 } proc feedback {msg} { global password set password $msg .password select from 0 .password select to end update } proc load_dict {} { global dict dict_loaded feedback "loading dictionary..." if {0==[catch {open /usr/dict/words} file]} { foreach w [split [read $file] "\n"] {set dict($w) ""} close $file set dict_loaded 1 feedback "dictionary loaded" } else { feedback "dictionary missing" .dict deselect } } # put whatever security checks you like in here proc weak_password {password} { global dict dict_check if {$dict_check} { feedback "checking password" if {[info exists dict($password)]} { feedback "sorry - in dictionary" return 1 } } return 0 } proc password_set {} { global password passwd_cmd selection_line set new_password $password if {$selection_line==0} { feedback "select a user first" return } set user [lindex [.names get selection.first selection.last] 0] if {[weak_password $password]} return feedback "setting password . . ." set cmd [lindex $passwd_cmd 0] spawn -noecho $cmd $user log_user 0 set last_msg "error in $cmd" while {1} { expect { -nocase "old password:" { exp_send "[get_old_password]\r" } "assword*:" { exp_send "$new_password\r" } -re "(.*)\r\n" { set last_msg $expect_out(1,string) } eof break } } set status [wait] if {[lindex $status 3]==0} { feedback "set successfully" } else { feedback $last_msg } } # defaults for generating passwords set length 9 set minnum 2 set minlower 5 set minupper 2 set distribute 0 proc parameter_filename {} { set file .tkpasswd.rc if {[info exists env(DOTDIR)]} { set file "$env(DOTDIR)/$file" } return ~/$file } catch {source [parameter_filename]} # save parameters in a file proc save_parameters {} { global minnum minlower minupper length if {[catch {open [parameter_filename] w} f]} { # should never happen, so don't bother with window code puts "tkpasswd: could not write [parameter_filename]" return } puts $f "# This is the .tkpasswd.rc file. Do not edit it by hand as" puts $f "# it is automatically maintained by tkpasswd. Any manual" puts $f "# modifications will be lost." puts $f "" puts $f "set length $length" puts $f "set minnum $minnum" puts $f "set minupper $minupper" puts $f "set minlower $minlower" close $f } # insert char into password at a random position proc insert {pvar char} { upvar $pvar p set p [linsert $p [rand [expr 1+[llength $p]]] $char] } # given a size, distribute between left and right hands # taking into account where we left off proc psplit {max lvar rvar} { upvar $lvar left $rvar right global isleft if {$isleft} { set right [expr $max/2] set left [expr $max-$right] set isleft [expr !($max%2)] } else { set left [expr $max/2] set right [expr $max-$left] set isleft [expr $max%2] } } proc password_generate {} { global password length minnum minlower minupper global lpass rpass initially_left isleft global distribute if {$distribute} { set lkeys {q w e r t a s d f g z x c v b} set rkeys {y u i o p h j k l n m} set lnums {1 2 3 4 5 6} set rnums {7 8 9 0} } else { set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z} set lnums {0 1 2 3 4 5 6 7 8 9} set rnums {0 1 2 3 4 5 6 7 8 9} } set lkeys_length [llength $lkeys] set rkeys_length [llength $rkeys] set lnums_length [llength $lnums] set rnums_length [llength $rnums] # if there is any underspecification, use additional lowercase letters set minlower [expr $length - ($minnum + $minupper)] set lpass "" ;# password chars typed by left hand set rpass "" ;# password chars typed by right hand set password "" ;# merged password # choose left or right starting hand set initially_left [set isleft [rand 2]] psplit $minnum left right for {set i 0} {$i<$left} {incr i} { insert lpass [lindex $lnums [rand $lnums_length]] } for {set i 0} {$i<$right} {incr i} { insert rpass [lindex $rnums [rand $rnums_length]] } psplit $minlower left right for {set i 0} {$i<$left} {incr i} { insert lpass [lindex $lkeys [rand $lkeys_length]] } for {set i 0} {$i<$right} {incr i} { insert rpass [lindex $rkeys [rand $rkeys_length]] } psplit $minupper left right for {set i 0} {$i<$left} {incr i} { insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]] } for {set i 0} {$i<$right} {incr i} { insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]] } # merge results together if {$initially_left} { regexp "(\[^ ]*) *(.*)" "$lpass" x password lpass while {[llength $lpass]} { regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass } if {[llength $rpass]} { append password $rpass } } else { regexp "(\[^ ]*) *(.*)" "$rpass" x password rpass while {[llength $rpass]} { regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass } if {[llength $lpass]} { append password $lpass } } } proc rand {m} { expr {int($m*rand())} } proc gen_bad_args {msg} { if {![llength [info commands .parameters.errmsg]]} { message .parameters.errmsg -aspect 300 pack .parameters.errmsg } .parameters.errmsg configure -text "$msg\ Please adjust the password generation arguments." } # tell tab what window to move between set parm_tabList {} # The procedure below is invoked in response to tabs in the entry |
︙ | ︙ | |||
420 421 422 423 424 425 426 | } } focus [lindex $list $i] } # adjust args used in password generation proc adjust_parameters {} { | | | | < < < | | | | | | | | | | | | | | | | | | | | | | | | | < | < | | < | < | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | } } focus [lindex $list $i] } # adjust args used in password generation proc adjust_parameters {} { global parm_tabList set parm_tabList {} toplevel [set w .parameters] message $w.text -aspect 300 -text \ "These parameters control generation of random passwords. It is not necessary to move the mouse into this window to operate it.\ Press <tab> to move to the next entry.\ Press <return> or click the <ok> button when you are done." foreach desc { {length {total length}} {minnum {minimum number of digits}} {minupper {minimum number of uppercase letters}} {minlower {minimum number of lowercase letters}}} { set name [lindex $desc 0] set text [lindex $desc 1] frame $w.$name -bd 1 entry $w.$name.entry -relief sunken -width 2 -textvar $name bind $w.$name.entry <Tab> "Tab \$parm_tabList" bind $w.$name.entry <Return> "destroy_parm_window" label $w.$name.text -text $text pack $w.$name.entry -side left pack $w.$name.text -side left lappend parm_tabList $w.$name.entry } frame $w.2 -bd 1 checkbutton $w.2.cb -text "alternate characters across hands" \ -relief flat -variable distribute pack $w.2.cb -side left button $w.ok -text "ok" -command "destroy_parm_window" pack $w.text -expand 1 -fill x pack $w.length $w.minnum $w.minupper $w.minlower $w.2 -expand 1 -fill x pack $w.ok -side left -fill x -expand 1 -padx 2 -pady 2 set oldfocus [focus] tkwait visibility $w.length.entry focus $w.length.entry tkwait window $w focus $oldfocus save_parameters } proc isnumber {n} { regexp "^\[0-9\]+$" $n } # destroy parm window IF all values are legal proc destroy_parm_window {} { global minnum minlower minupper length set mustbe "must be a number greater than or equal to zero." # check all variables if {![isnumber $length]} { gen_bad_args "The total length $mustbe" return } if {![isnumber $minlower]} { gen_bad_args "The minimum number of lowercase characters $mustbe" return } if {![isnumber $minupper]} { gen_bad_args "The minimum number of uppercase characters $mustbe" return } if {![isnumber $minnum]} { gen_bad_args "The minimum number of digits $mustbe" return } # check constraints if {$minnum + $minlower + $minupper > $length} { gen_bad_args \ "It is impossible to generate a $length-character password with\ $minnum number[pluralize $minnum],\ $minlower lowercase letter[pluralize $minlower], and\ $minupper uppercase letter[pluralize $minupper]." return } destroy .parameters } # return appropriate ending for a count of "n" nouns proc pluralize {n} { expr $n!=1?"s":"" } proc get_old_password {} { global old toplevel .old label .old.label -text "Old password:" catch {unset old} entry .old.entry -textvar old -relief sunken -width 1 pack .old.label pack .old.entry -fill x -padx 2 -pady 2 bind .old.entry <Return> {destroy .old} set oldfocus [focus] focus .old.entry tkwait visibility .old grab .old tkwait window .old focus $oldfocus return $old } .unsorted select .passwd invoke proc make_selection {} { global selection_line last_line .names tag remove selection 0.0 end # don't let selection go off top of screen if {$selection_line < 1} { set selection_line $last_line } elseif {$selection_line > $last_line} { set selection_line 1 } .names yview -pickplace [expr $selection_line-1] .names tag add selection $selection_line.0 [expr 1+$selection_line].0 } proc select_next_nopassword {direction} { global selection_line last_line global nopasswords if {0==[llength $nopasswords]} { feedback "no null passwords" return } if {$direction==1} { # is there a better way to get last element of list? if {$selection_line>=[lindex $nopasswords [expr [llength $nopasswords]-1]]} { set selection_line 0 } foreach i $nopasswords { if {$selection_line<$i} break } } else { if {$selection_line<=[lindex $nopasswords 0]} { set selection_line $last_line } set j [expr [llength $nopasswords]-1] for {} {$j>=0} {incr j -1} { set i [lindex $nopasswords $j] if {$selection_line>$i} break } } set selection_line $i make_selection } proc select {w coords} { global selection_line $w mark set insert "@$coords linestart" $w mark set anchor insert set first [$w index "anchor linestart"] set last [$w index "insert lineend + 1c"] scan $first %d selection_line $w tag remove selection 0.0 end $w tag add selection $first $last } bind Text <1> {select %W %x,%y} bind Text <Double-1> {select %W %x,%y} bind Text <Triple-1> {select %W %x,%y} bind Text <2> {select %W %x,%y} bind Text <3> {select %W %x,%y} |
︙ | ︙ |
Changes to example/tkterm.
︙ | ︙ | |||
113 114 115 116 117 118 119 | unset env(DISPLAY) set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" | | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | unset env(DISPLAY) set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" if {$termcap} { set env(TERMCAP) {tt: :cm=\E[%d;%dH: :up=\E[A: :nd=\E[C: :cl=\E[H\E[J: :do=^J: :so=\E[7m: :se=\E[m: :k1=\EOP: :k2=\EOQ: :k3=\EOR: :k4=\EOS: :k5=\EOT: :k6=\EOU: :k7=\EOV: :k8=\EOW: :k9=\EOX: } } if {$terminfo} { set env(TERMINFO) /tmp set ttsrc "/tmp/tt.src" set file [open $ttsrc w] puts $file {tt|textterm|Don Libes' tk text widget terminal emulator, cup=\E[%p1%d;%p2%dH, cuu1=\E[A, |
︙ | ︙ | |||
161 162 163 164 165 166 167 | kf7=\EOV, kf8=\EOW, kf9=\EOX, } close $file set oldpath $env(PATH) | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | kf7=\EOV, kf8=\EOW, kf9=\EOX, } close $file set oldpath $env(PATH) set env(PATH) "$env(PATH):/usr/5bin:/usr/lib/terminfo" if 1==[catch {exec tic $ttsrc} msg] { puts "WARNING: tic failed - if you don't have terminfo support on" puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"." puts "Here is the original error from running tic:" puts $msg } set env(PATH) $oldpath |
︙ | ︙ | |||
267 268 269 270 271 272 273 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row if {$newline} { term_down } ################## # write full lines ################## while {$chars_rem_to_write >= $cols} { |
︙ | ︙ |
Changes to example/virterm.
︙ | ︙ | |||
75 76 77 78 79 80 81 | ############################################# set blankline "" set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" | | | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | ############################################# set blankline "" set env(LINES) $rows set env(COLUMNS) $cols set env(TERM) "tt" if {$termcap} { set env(TERMCAP) {tt: :cm=\E[%d;%dH: :up=\E[A: :cl=\E[H\E[J: :do=^J: :so=\E[7m: :se=\E[m: :nd=\E[C: } } if {$terminfo} { set env(TERMINFO) /tmp set ttsrc "/tmp/tt.src" set file [open $ttsrc w] puts $file {tt|textterm|Don Libes' tk text widget terminal emulator, cup=\E[%p1%d;%p2%dH, cuu1=\E[A, cuf1=\E[C, clear=\E[H\E[J, ind=\n, cr=\r, smso=\E[7m, rmso=\E[m, } close $file set oldpath $env(PATH) set env(PATH) "/usr/5bin:/usr/lib/terminfo" if {1==[catch {exec tic $ttsrc} msg]} { puts "WARNING: tic failed - if you don't have terminfo support on" puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"." puts "Here is the original error from running tic:" puts $msg } set env(PATH) $oldpath |
︙ | ︙ | |||
231 232 233 234 235 236 237 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | # discard first line already written incr chars_rem_to_write -$chars_to_write set s [string range $s $chars_to_write end] # update cur_col incr cur_col $chars_to_write # update cur_row if {$newline} { term_down } ################## # write full lines ################## while {$chars_rem_to_write >= $cols} { |
︙ | ︙ | |||
321 322 323 324 325 326 327 | proc term_expect {args} { global cur_row cur_col # used by expect_background actions set desired_timeout [ uplevel { | | | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | proc term_expect {args} { global cur_row cur_col # used by expect_background actions set desired_timeout [ uplevel { if {[info exists timeout]} { set timeout } else { uplevel #0 { if {[info exists timeout]} { set timeout } else { expr 10 |
︙ | ︙ | |||
432 433 434 435 436 437 438 | exp_send_error "connected.\n\n" } proc dosearch {search} { global term exp_send_error "Searching for '$search'..." | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | exp_send_error "connected.\n\n" } proc dosearch {search} { global term exp_send_error "Searching for '$search'..." if {[string match ?=* "$search"]} {set typ ""} else {set typ "k="} sendcommand "$typ$search\r" waitfornext set countstr [$term get 2.17 2.35] if {![regsub { Entries Found *} $countstr "" number]} { set number 1 exp_send_error "one entry found.\n\n" return 1 |
︙ | ︙ |
Changes to example/weather.
1 2 3 4 5 6 7 8 9 10 11 12 | #!../expect -f # weather - Expect script to get the weather (courtesy University of Michigan) # Don Libes # Version 1.9 # local weather is retrieved if no argument # argument is the National Weather Service designation for an area # I.e., WBC = Washington DC (oh yeah, that's obvious) exp_version -exit 5.0 | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!../expect -f # weather - Expect script to get the weather (courtesy University of Michigan) # Don Libes # Version 1.9 # local weather is retrieved if no argument # argument is the National Weather Service designation for an area # I.e., WBC = Washington DC (oh yeah, that's obvious) exp_version -exit 5.0 if {$argc>0} {set code $argv} else {set code "WBC"} proc timedout {} { send_user "Weather server timed out. Try again later when weather server is not so busy.\n" exit 1 } # delete special weather statement question proc delete_special {s} { set x [string first " ******" $s] return [join [lrange [split $s ""] 0 $x] ""] } set timeout 60 #log_user 0 set env(TERM) vt100 ;# actual value doesn't matter, just has to be set spawn telnet cirrus.sprl.umich.edu 3000 match_max 100000 while {1} { expect timeout { send_user "failed to contact weather server\n" exit } "Press Return to continue*" { # this prompt used sometimes, eg, upon opening connection send "\r" } "Press Return for menu*" { |
︙ | ︙ | |||
57 58 59 60 61 62 63 | send "1\r" expect timeout timedout "Selection:" send "1\r" expect timeout timedout "city code:" send "$code\r" expect $code ;# discard this | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | send "1\r" expect timeout timedout "Selection:" send "1\r" expect timeout timedout "city code:" send "$code\r" expect $code ;# discard this while {1} { expect timeout { timedout } "Press Return to continue*:*" { send_user "\n[delete_special $expect_out(buffer)]\n" send "\r" } "Press Return to display statement, M for menu:*" { send_user "\n[delete_special $expect_out(buffer)]\n" |
︙ | ︙ |
Changes to example/xkibitz.
1 2 3 4 5 6 7 8 9 | #!../expect -- # share an xterm with other users # See xkibitz(1) man page for complete info. # Compare with kibitz. # Author: Don Libes, NIST # Version: 1.2 proc help {} { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | > > | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | #!../expect -- # share an xterm with other users # See xkibitz(1) man page for complete info. # Compare with kibitz. # Author: Don Libes, NIST # Version: 1.2 proc help {} { puts "Commands Meaning" puts "-------- -------" puts "return return to program" puts "= list" puts "+ <display> add" puts "- <tag> drop" puts "where <display> is an X display name such as nist.gov or nist.gov:0.0" puts "and <tag> is a tag from the = command." puts "+ and - require whitespace before argument." puts {return command must be spelled out ("r", "e", "t", ...).} } proc prompt1 {} { return "xkibitz> " } proc h {} help proc ? {} help # disable history processing - there seems to be some incestuous relationship # between history and unknown in Tcl 8.0 proc history {args} {} proc unknown {args} { puts "$args: invalid command" help } set tag2pid(0) [pid] set pid2tty([pid]) "/dev/tty" if {[info exists env(DISPLAY)]} { set pid2display([pid]) $env(DISPLAY) } else { set pid2display([pid]) "" } # small int allowing user to more easily identify display # maxtag always points at highest in use set maxtag 0 proc + {display} { global ids pid2display pid2tag tag2pid maxtag pid2sid global pid2tty env if {![string match *:* $display]} { append display :0.0 } if {![info exists env(XKIBITZ_XTERM_ARGS)]} { set env(XKIBITZ_XTERM_ARGS) "" } set dummy1 [open /dev/null] set dummy2 [open /dev/null] spawn -pty -noecho close $dummy1 close $dummy2 stty raw -echo < $spawn_out(slave,name) # Linux needs additional stty, sounds like a bug in its stty to me. # raw should imply this stuff, no? stty -icrnl -icanon < $spawn_out(slave,name) regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2 if {[string compare $c1 "/"] == 0} { # On Pyramid and AIX, ttynames such as /dev/pts/1 # requre suffix to be padded with a 0 set c1 0 } set pid [eval exec xterm \ -display $display \ -geometry [stty columns]x[stty rows] \ -S$c1$c2$spawn_out(slave,fd) \ $env(XKIBITZ_XTERM_ARGS) &] close -slave # xterm first sends back window id, discard log_user 0 expect { eof {wait;return} \n } log_user 1 lappend ids $spawn_id set pid2display($pid) $display incr maxtag set tag2pid($maxtag) $pid set pid2tag($pid) $maxtag set pid2sid($pid) $spawn_id set pid2tty($pid) $spawn_out(slave,name) return } proc = {} { global pid2display tag2pid pid2tty puts "Tag Size Display" foreach tag [lsort -integer [array names tag2pid]] { set pid $tag2pid($tag) set tty $pid2tty($pid) puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag] } } proc - {tag} { global tag2pid pid2tag pid2display maxtag ids pid2sid global pid2tty if {![info exists tag2pid($tag)]} { puts "no such tag" return } if {$tag == 0} { puts "cannot drop self" return } set pid $tag2pid($tag) # close and remove spawn_id from list set spawn_id $pid2sid($pid) set index [lsearch $ids $spawn_id] set ids [lreplace $ids $index $index] exec kill -9 $pid close wait unset tag2pid($tag) unset pid2tag($pid) unset pid2display($pid) unset pid2sid($pid) unset pid2tty($pid) # lower maxtag if possible while {![info exists tag2pid($maxtag)]} { incr maxtag -1 } } rename exit exitReal proc exit {} { global pid2display unset pid2display([pid]) ;# avoid killing self foreach pid [array names pid2display] { catch {exec kill -9 $pid} } exitReal } trap exit HUP trap { set r [stty rows] set c [stty columns] stty rows $r columns $c < $app_tty foreach pid [array names pid2tty] { if {$pid == [pid]} continue stty rows $r columns $c < $pid2tty($pid) } } WINCH set escape \035 ;# control-right-bracket set escape_printable "^\]" while {[llength $argv]>0} { set flag [lindex $argv 0] switch -- $flag \ "-escape" { set escape [lindex $argv 1] set escape_printable $escape set argv [lrange $argv 2 end] } "-display" { + [lindex $argv 1] set argv [lrange $argv 2 end] } default { break } } if {[llength $argv]>0} { eval spawn -noecho $argv } else { spawn -noecho $env(SHELL) } set prog $spawn_id set app_tty $spawn_out(slave,name) puts "Escape sequence is $escape_printable" interact { -input $user_spawn_id -reset $escape { puts "\nfor help enter: ? or h or help" interpreter -eof exit } -output $prog -input ids -output $prog -input $prog eof exit -output $user_spawn_id -output ids } |
Changes to example/xpstat.
︙ | ︙ | |||
130 131 132 133 134 135 136 | Pan the world/author text, player list, or your own alias by holding the middle mouse button down and moving the mouse." } # if user presses "update" try to update screen immediately proc prod {x y} { global cat_spawn_id updateflag | | < | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | Pan the world/author text, player list, or your own alias by holding the middle mouse button down and moving the mouse." } # if user presses "update" try to update screen immediately proc prod {x y} { global cat_spawn_id updateflag if {$updateflag} { show-help $x $y "I heard you, gimme a break. I'm waiting for the xpilot server to respond..." } set updateflag 1 exp_send -i $cat_spawn_id "\r" } proc display {host} { global world db alias max env set w .$host if {![winfo exists $w]} { # window does not exist, create it toplevel $w -class xpstat wm minsize $w 1 1 wm title $w "xpilot@$host" wm iconname $w "$host xpilot stats" |
︙ | ︙ | |||
199 200 201 202 203 204 205 | pack $w.world -expand 1 -fill x pack $w.msg pack $w.help $w.update $w.play -side left pack $w.alias -side left -expand 1 -fill x set max($host,was) 0 } | | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | pack $w.world -expand 1 -fill x pack $w.msg pack $w.help $w.update $w.play -side left pack $w.alias -side left -expand 1 -fill x set max($host,was) 0 } if {$max($host)==0} { # put up "no players" message? if {$max($host,was)>0} { pack $w.msg -after $w.world -fill x -side top pack forget $w.world } } else { # remove "no players" message? if {$max($host,was)==0} { pack $w.players -after $w.world -side top pack forget $w.msg } } $w.players delete 0 end |
︙ | ︙ | |||
233 234 235 236 237 238 239 | wm withdraw . set oldhosts {} set updateflag 0 ;# 1 if user pressed "update" button # look for desired alias in the .Xdefaults file set status [catch {exec egrep "xpilot.name:" [glob ~/.Xdefaults]} output] | | | | | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | wm withdraw . set oldhosts {} set updateflag 0 ;# 1 if user pressed "update" button # look for desired alias in the .Xdefaults file set status [catch {exec egrep "xpilot.name:" [glob ~/.Xdefaults]} output] if {$status==0} { regexp "xpilot.name:\[ \t]*(\[^\r]*)" $output dummy env(USER) } spawn cat -u; set cat_spawn_id $spawn_id while {1} { global xpilot hosts set hosts {} eval spawn $xpilot $argv while {[probe]} {exp_send "N\r"} catch {expect_before} ;# disable expect_before from inside probe # clean up hosts that no longer are running xpilots foreach host $oldhosts { # if host not in hosts if {-1==[lsearch $hosts $host]} { destroy .$host } } set oldhosts $hosts set updateflag 0 # sleep for a little while, subject to click from "update" button expect -i $cat_spawn_id -re "...." ;# two crlfs } |
Changes to example/xrlogin.
︙ | ︙ | |||
11 12 13 14 15 16 17 | set prompt "(%|#|\\$) $" ;# default prompt catch {set prompt $env(EXPECT_PROMPT)} set timeout -1 eval spawn rlogin $argv expect eof exit -re $prompt | | | 11 12 13 14 15 16 17 18 19 20 21 22 | set prompt "(%|#|\\$) $" ;# default prompt catch {set prompt $env(EXPECT_PROMPT)} set timeout -1 eval spawn rlogin $argv expect eof exit -re $prompt if {[string match "unix:0.0" $env(DISPLAY)]} { set env(DISPLAY) "[exec hostname].[exec domainname]:0.0\r" } send "setenv DISPLAY $env(DISPLAY)\r" interact |
Deleted exp_clib.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_closetcl.c.
|
| < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_command.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_command.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_console.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_event.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_event.h.
|
| < < < < < < < < < < < < < < < < < < < |
Deleted exp_glob.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_int.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_inter.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_log.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_log.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_main_exp.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_main_sub.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_main_tk.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_memmove.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_noevent.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_poll.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_printify.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_printify.h.
|
| < < < < < < |
Deleted exp_prog.h.
|
| < < < < < < < < < < < < < < < < < < < |
Deleted exp_pty.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_pty.h.
|
| < < < < < < < < < < < < < < < < < |
Deleted exp_regexp.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_regexp.h.
|
| < < < < < < < < |
Deleted exp_rename.h.
|
| < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_select.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_simple.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_strf.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_trap.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_tstamp.h.
|
| < < |
Deleted exp_tty.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_tty.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_tty_comm.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_tty_in.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_win.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_win.h.
|
| < < < < < < < < < < < < < < < < < < < < |
Deleted expect.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect.man.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect_cf.h.in.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect_comm.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect_tcl.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expectk.man.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted fixcat.
|
| < < < < < < < < < < < < < < < < < < < < < |
Deleted fixline1.
|
| < < < < < < < < < < < < < |
Added generic/Dbg.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 | /* Dbg.c - Tcl Debugger - See cmdHelp() for commands Written by: Don Libes, NIST, 3/23/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include <stdio.h> #include "Dbg_cf.h" #if 0 /* tclInt.h drags in stdlib. By claiming no-stdlib, force it to drag in */ /* Tcl's compat version. This avoids having to test for its presence */ /* which is too tricky - configure can't generate two cf files, so when */ /* Expect (or any app) uses the debugger, there's no way to get the info */ /* about whether stdlib exists or not, except pointing the debugger at */ /* an app-dependent .h file and I don't want to do that. */ #define NO_STDLIB_H #endif #include "tclInt.h" /*#include <varargs.h> tclInt.h drags in varargs.h. Since Pyramid */ /* objects to including varargs.h twice, just */ /* omit this one. */ /*#include "string.h" tclInt.h drags this in, too! */ #include "Dbg.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* * Declarations for local procedures defined in this file: */ static int cmdBreak _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int cmdDir _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int cmdHelp _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int cmdNext _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int cmdSimple _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int cmdWhere _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static int simple_interactor _ANSI_ARGS_((Tcl_Interp *interp, ClientData data)); static int zero _ANSI_ARGS_((Tcl_Interp *interp, char *string)); static void print _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); static void debugger_trap _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *cmdProc, ClientData cmdClientData, int argc, char **argv)); /* most of the static variables in this file may be */ /* moved into Tcl_Interp */ static Dbg_InterProc *interactor = simple_interactor; static ClientData interdata = 0; static Dbg_IgnoreFuncsProc *ignoreproc = zero; static Dbg_OutputProc *printproc = 0; static ClientData printdata = 0; static int debugger_active = FALSE; /* this is not externally documented anywhere as of yet */ char *Dbg_VarName = "dbg"; #define DEFAULT_COMPRESS 0 static int compress = DEFAULT_COMPRESS; #define DEFAULT_WIDTH 75 /* leave a little space for printing */ /* stack level */ static int buf_width = DEFAULT_WIDTH; static int main_argc = 1; static char *default_argv = "application"; static char **main_argv = &default_argv; static Tcl_Trace debug_handle; static int step_count = 1; /* count next/step */ #define FRAMENAMELEN 10 /* enough to hold strings like "#4" */ static char viewFrameName[FRAMENAMELEN];/* destination frame name for up/down */ static CallFrame *goalFramePtr; /* destination for next/return */ static int goalNumLevel; /* destination for Next */ static enum debug_cmd { none, step, next, ret, cont, up, down, where, Next } debug_cmd; /* info about last action to use as a default */ static enum debug_cmd last_action_cmd = next; static int last_step_count = 1; /* this acts as a strobe (while testing breakpoints). It is set to true */ /* every time a new debugger command is issued that is an action */ static debug_new_action; #define NO_LINE -1 /* if break point is not set by line number */ struct breakpoint { int id; char *file; /* file where breakpoint is */ int line; /* line where breakpoint is */ char *pat; /* pattern defining where breakpoint can be */ regexp *re; /* regular expression to trigger breakpoint */ char *expr; /* expr to trigger breakpoint */ char *cmd; /* cmd to eval at breakpoint */ struct breakpoint *next, *previous; }; static struct breakpoint *break_base = 0; static int breakpoint_max_id = 0; static struct breakpoint * breakpoint_new() { struct breakpoint *b = (struct breakpoint *)ckalloc(sizeof(struct breakpoint)); if (break_base) break_base->previous = b; b->next = break_base; b->previous = 0; b->id = breakpoint_max_id++; b->file = 0; b->line = NO_LINE; b->pat = 0; b->re = 0; b->expr = 0; b->cmd = 0; break_base = b; return(b); } static void breakpoint_print(interp,b) Tcl_Interp *interp; struct breakpoint *b; { print(interp,"breakpoint %d: ",b->id); if (b->re) { print(interp,"-re \"%s\" ",b->pat); } else if (b->pat) { print(interp,"-glob \"%s\" ",b->pat); } else if (b->line != NO_LINE) { if (b->file) { print(interp,"%s:",b->file); } print(interp,"%d ",b->line); } if (b->expr) print(interp,"if {%s} ",b->expr); if (b->cmd) print(interp,"then {%s}",b->cmd); print(interp,"\n"); } static void save_re_matches(interp,re) Tcl_Interp *interp; regexp *re; { int i; char name[20]; char match_char;/* place to hold char temporarily */ /* uprooted by a NULL */ for (i=0;i<NSUBEXP;i++) { if (re->startp[i] == 0) break; sprintf(name,"%d",i); /* temporarily null-terminate in middle */ match_char = *re->endp[i]; *re->endp[i] = 0; Tcl_SetVar2(interp,Dbg_VarName,name,re->startp[i],0); /* undo temporary null-terminator */ *re->endp[i] = match_char; } } /* return 1 to break, 0 to continue */ static int breakpoint_test(interp,cmd,bp) Tcl_Interp *interp; char *cmd; /* command about to be executed */ struct breakpoint *bp; /* breakpoint to test */ { if (bp->re) { if (0 == TclRegExec(bp->re,cmd,cmd)) return 0; save_re_matches(interp,bp->re); } else if (bp->pat) { if (0 == Tcl_StringMatch(cmd,bp->pat)) return 0; } else if (bp->line != NO_LINE) { /* not yet implemented - awaiting support from Tcl */ return 0; } if (bp->expr) { int value; /* ignore errors, since they are likely due to */ /* simply being out of scope a lot */ if (TCL_OK != Tcl_ExprBoolean(interp,bp->expr,&value) || (value == 0)) return 0; } if (bp->cmd) { Tcl_Eval(interp,bp->cmd); } else { breakpoint_print(interp,bp); } return 1; } static char *already_at_top_level = "already at top level"; /* similar to TclGetFrame but takes two frame ptrs and a direction. If direction is up, search up stack from curFrame If direction is down, simulate searching down stack by seaching up stack from origFrame */ static int TclGetFrame2(interp, origFramePtr, string, framePtrPtr, dir) Tcl_Interp *interp; CallFrame *origFramePtr; /* frame that is true top-of-stack */ char *string; /* String describing frame. */ CallFrame **framePtrPtr; /* Store pointer to frame here (or NULL * if global frame indicated). */ enum debug_cmd dir; /* look up or down the stack */ { Interp *iPtr = (Interp *) interp; int level, result; CallFrame *framePtr; /* frame currently being searched */ CallFrame *curFramePtr = iPtr->varFramePtr; /* * Parse string to figure out which level number to go to. */ result = 1; if (*string == '#') { if (Tcl_GetInt(interp, string+1, &level) != TCL_OK) { return TCL_ERROR; } if (level < 0) { levelError: Tcl_AppendResult(interp, "bad level \"", string, "\"", (char *) NULL); return TCL_ERROR; } framePtr = origFramePtr; /* start search here */ } else if (isdigit(*string)) { if (Tcl_GetInt(interp, string, &level) != TCL_OK) { return TCL_ERROR; } if (dir == up) { if (curFramePtr == 0) { Tcl_SetResult(interp,already_at_top_level,TCL_STATIC); return TCL_ERROR; } level = curFramePtr->level - level; framePtr = curFramePtr; /* start search here */ } else { if (curFramePtr != 0) { level = curFramePtr->level + level; } framePtr = origFramePtr; /* start search here */ } } else { level = curFramePtr->level - 1; result = 0; } /* * Figure out which frame to use. */ if (level == 0) { framePtr = NULL; } else { for (;framePtr != NULL; framePtr = framePtr->callerVarPtr) { if (framePtr->level == level) { break; } } if (framePtr == NULL) { goto levelError; } } *framePtrPtr = framePtr; return result; } static char *printify(s) char *s; { static int destlen = 0; char *d; /* ptr into dest */ int need; static char buf_basic[DEFAULT_WIDTH+1]; static char *dest = buf_basic; if (s == 0) return("<null>"); /* worst case is every character takes 4 to printify */ need = strlen(s)*4; if (need > destlen) { if (dest && (dest != buf_basic)) ckfree(dest); dest = (char *)ckalloc(need+1); destlen = need; } for (d = dest;*s;s++) { /* since we check at worst by every 4 bytes, play */ /* conservative and subtract 4 from the limit */ if (d-dest > destlen-4) break; if (*s == '\b') { strcpy(d,"\\b"); d += 2; } else if (*s == '\f') { strcpy(d,"\\f"); d += 2; } else if (*s == '\v') { strcpy(d,"\\v"); d += 2; } else if (*s == '\r') { strcpy(d,"\\r"); d += 2; } else if (*s == '\n') { strcpy(d,"\\n"); d += 2; } else if (*s == '\t') { strcpy(d,"\\t"); d += 2; } else if ((unsigned)*s < 0x20) { /* unsigned strips parity */ sprintf(d,"\\%03o",*s); d += 4; } else if (*s == 0177) { strcpy(d,"\\177"); d += 4; } else { *d = *s; d += 1; } } *d = '\0'; return(dest); } static char * print_argv(interp,argc,argv) Tcl_Interp *interp; int argc; char *argv[]; { static int buf_width_max = DEFAULT_WIDTH; static char buf_basic[DEFAULT_WIDTH+1]; /* basic buffer */ static char *buf = buf_basic; int space; /* space remaining in buf */ int len; char *bufp; int proc; /* if current command is "proc" */ int arg_index; if (buf_width > buf_width_max) { if (buf && (buf != buf_basic)) ckfree(buf); buf = (char *)ckalloc(buf_width + 1); buf_width_max = buf_width; } proc = (0 == strcmp("proc",argv[0])); sprintf(buf,"%.*s",buf_width,argv[0]); len = strlen(buf); space = buf_width - len; bufp = buf + len; argc--; argv++; arg_index = 1; while (argc && (space > 0)) { char *elementPtr; char *nextPtr; int wrap; /* braces/quotes have been stripped off arguments */ /* so put them back. We wrap everything except lists */ /* with one argument. One exception is to always wrap */ /* proc's 2nd arg (the arg list), since people are */ /* used to always seeing it this way. */ if (proc && (arg_index > 1)) wrap = TRUE; else { (void) TclFindElement(interp,*argv, #if TCL_MAJOR_VERSION >= 8 strlen(*argv), #endif &elementPtr, &nextPtr,(int *)0,(int *)0); if (*elementPtr == '\0') wrap = TRUE; else if (*nextPtr == '\0') wrap = FALSE; else wrap = TRUE; } /* wrap lists (or null) in braces */ if (wrap) { sprintf(bufp," {%.*s}",space-3,*argv); } else { sprintf(bufp," %.*s",space-1,*argv); } len = strlen(buf); space = buf_width - len; bufp = buf + len; argc--; argv++; arg_index++; } if (compress) { /* this copies from our static buf to printify's static buf */ /* and back to our static buf */ strncpy(buf,printify(buf),buf_width); } /* usually but not always right, but assume truncation if buffer is */ /* full. this avoids tiny but odd-looking problem of appending "}" */ /* to truncated lists during {}-wrapping earlier */ if (strlen(buf) == (size_t) buf_width) { buf[buf_width-1] = buf[buf_width-2] = buf[buf_width-3] = '.'; } return(buf); } static void PrintStackBelow(interp,curf,viewf) Tcl_Interp *interp; CallFrame *curf; /* current FramePtr */ CallFrame *viewf; /* view FramePtr */ { char ptr; /* graphically indicate where we are in the stack */ /* indicate where we are in the stack */ ptr = ((curf == viewf)?'*':' '); if (curf == 0) { print(interp,"%c0: %s\n", ptr,print_argv(interp,main_argc,main_argv)); } else { PrintStackBelow(interp,curf->callerVarPtr,viewf); #if TCL_MAJOR_VERSION < 8 print(interp,"%c%d: %s\n",ptr,curf->level, print_argv(interp,curf->argc,curf->argv)); #else if (1) { char **argv; int i, length; argv = (char **) ckalloc(curf->objc * sizeof(char *)); for (i = 0; i < curf->objc; i++) { argv[i] = Tcl_GetStringFromObj(curf->objv[i], &length); } print(interp,"%c%d: %s\n",ptr,curf->level, print_argv(interp,curf->objc, argv)); ckfree((char *) argv); } #endif } } static void PrintStack(interp,curf,viewf,argc,argv,level) Tcl_Interp *interp; CallFrame *curf; /* current FramePtr */ CallFrame *viewf; /* view FramePtr */ int argc; char *argv[]; char *level; { PrintStackBelow(interp,curf,viewf); print(interp," %s: %s\n",level,print_argv(interp,argc,argv)); } /* return 0 if goal matches current frame or goal can't be found */ /* anywere in frame stack */ /* else return 1 */ /* This catches things like a proc called from a Tcl_Eval which in */ /* turn was not called from a proc but some builtin such as source */ /* or Tcl_Eval. These builtin calls to Tcl_Eval lose any knowledge */ /* the FramePtr from the proc, so we have to search the entire */ /* stack frame to see if it's still there. */ static int GoalFrame(goal,iptr) CallFrame *goal; Interp *iptr; { CallFrame *cf = iptr->varFramePtr; /* if at current level, return success immediately */ if (goal == cf) return 0; while (cf) { cf = cf->callerVarPtr; if (goal == cf) { /* found, but since it's above us, fail */ return 1; } } return 0; } /* debugger's trace handler */ /*ARGSUSED*/ static void debugger_trap(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv) ClientData clientData; /* not used */ Tcl_Interp *interp; int level; /* positive number if called by Tcl, -1 if */ /* called by Dbg_On in which case we don't */ /* know the level */ char *command; Tcl_CmdProc *cmdProc; /* not used */ ClientData cmdClientData; int argc; char *argv[]; { char level_text[6]; /* textual representation of level */ int break_status; Interp *iPtr = (Interp *)interp; CallFrame *trueFramePtr; /* where the pc is */ CallFrame *viewFramePtr; /* where up/down are */ int print_command_first_time = TRUE; static int debug_suspended = FALSE; struct breakpoint *b; /* skip commands that are invoked interactively */ if (debug_suspended) return; /* skip debugger commands */ if (argv[0][1] == '\0') { switch (argv[0][0]) { case 'n': case 's': case 'c': case 'r': case 'w': case 'b': case 'u': case 'd': return; } } if ((*ignoreproc)(interp,argv[0])) return; /* if level is unknown, use "?" */ sprintf(level_text,(level == -1)?"?":"%d",level); /* save so we can restore later */ trueFramePtr = iPtr->varFramePtr; /* do not allow breaking while testing breakpoints */ debug_suspended = TRUE; /* test all breakpoints to see if we should break */ /* if any successful breakpoints, start interactor */ debug_new_action = FALSE; /* reset strobe */ break_status = FALSE; /* no successful breakpoints yet */ for (b = break_base;b;b=b->next) { break_status |= breakpoint_test(interp,command,b); } if (break_status) { if (!debug_new_action) goto start_interact; /* if s or n triggered by breakpoint, make "s 1" */ /* (and so on) refer to next command, not this one */ /* step_count++;*/ goto end_interact; } switch (debug_cmd) { case cont: goto finish; case step: step_count--; if (step_count > 0) goto finish; goto start_interact; case next: /* check if we are back at the same level where the next */ /* command was issued. Also test */ /* against all FramePtrs and if no match, assume that */ /* we've missed a return, and so we should break */ /* if (goalFramePtr != iPtr->varFramePtr) goto finish;*/ if (GoalFrame(goalFramePtr,iPtr)) goto finish; step_count--; if (step_count > 0) goto finish; goto start_interact; case Next: /* check if we are back at the same level where the next */ /* command was issued. */ if (goalNumLevel < iPtr->numLevels) goto finish; step_count--; if (step_count > 0) goto finish; goto start_interact; case ret: /* same comment as in "case next" */ if (goalFramePtr != iPtr->varFramePtr) goto finish; goto start_interact; } start_interact: if (print_command_first_time) { print(interp,"%s: %s\n", level_text,print_argv(interp,1,&command)); print_command_first_time = FALSE; } /* since user is typing a command, don't interrupt it immediately */ debug_cmd = cont; debug_suspended = TRUE; /* interactor won't return until user gives a debugger cmd */ (*interactor)(interp,interdata); end_interact: /* save this so it can be restored after "w" command */ viewFramePtr = iPtr->varFramePtr; if (debug_cmd == up || debug_cmd == down) { /* calculate new frame */ if (-1 == TclGetFrame2(interp,trueFramePtr,viewFrameName, &iPtr->varFramePtr,debug_cmd)) { print(interp,"%s\n",interp->result); Tcl_ResetResult(interp); } goto start_interact; } /* reset view back to normal */ iPtr->varFramePtr = trueFramePtr; #if 0 /* allow trapping */ debug_suspended = FALSE; #endif switch (debug_cmd) { case cont: case step: goto finish; case next: goalFramePtr = iPtr->varFramePtr; goto finish; case Next: goalNumLevel = iPtr->numLevels; goto finish; case ret: goalFramePtr = iPtr->varFramePtr; if (goalFramePtr == 0) { print(interp,"nowhere to return to\n"); break; } goalFramePtr = goalFramePtr->callerVarPtr; goto finish; case where: PrintStack(interp,iPtr->varFramePtr,viewFramePtr,argc,argv,level_text); break; } /* restore view and restart interactor */ iPtr->varFramePtr = viewFramePtr; goto start_interact; finish: debug_suspended = FALSE; } /*ARGSUSED*/ static int cmdNext(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { debug_new_action = TRUE; debug_cmd = *(enum debug_cmd *)clientData; last_action_cmd = debug_cmd; step_count = (argc == 1)?1:atoi(argv[1]); last_step_count = step_count; return(TCL_RETURN); } /*ARGSUSED*/ static int cmdDir(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { debug_cmd = *(enum debug_cmd *)clientData; if (argc == 1) argv[1] = "1"; strncpy(viewFrameName,argv[1],FRAMENAMELEN); return TCL_RETURN; } /*ARGSUSED*/ static int cmdSimple(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { debug_new_action = TRUE; debug_cmd = *(enum debug_cmd *)clientData; last_action_cmd = debug_cmd; return TCL_RETURN; } static void breakpoint_destroy(b) struct breakpoint *b; { if (b->file) ckfree(b->file); if (b->pat) ckfree(b->pat); if (b->re) ckfree((char *)b->re); if (b->cmd) ckfree(b->cmd); /* unlink from chain */ if ((b->previous == 0) && (b->next == 0)) { break_base = 0; } else if (b->previous == 0) { break_base = b->next; b->next->previous = 0; } else if (b->next == 0) { b->previous->next = 0; } else { b->previous->next = b->next; b->next->previous = b->previous; } ckfree((char *)b); } static void savestr(straddr,str) char **straddr; char *str; { *straddr = ckalloc(strlen(str)+1); strcpy(*straddr,str); } /* return 1 if a string is substring of a flag */ static int flageq(flag,string,minlen) char *flag; char *string; int minlen; /* at least this many chars must match */ { for (;*flag;flag++,string++,minlen--) { if (*string == '\0') break; if (*string != *flag) return 0; } if (*string == '\0' && minlen <= 0) return 1; return 0; } /*ARGSUSED*/ static int cmdWhere(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc == 1) { debug_cmd = where; return TCL_RETURN; } argc--; argv++; while (argc) { if (flageq("-width",*argv,2)) { argc--; argv++; if (*argv) { buf_width = atoi(*argv); argc--; argv++; } else print(interp,"%d\n",buf_width); } else if (flageq("-compress",*argv,2)) { argc--; argv++; if (*argv) { compress = atoi(*argv); argc--; argv++; } else print(interp,"%d\n",compress); } else { print(interp,"usage: w [-width #] [-compress 0|1]\n"); return TCL_ERROR; } } return TCL_OK; } #define breakpoint_fail(msg) {error_msg = msg; goto break_fail;} /*ARGSUSED*/ static int cmdBreak(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { struct breakpoint *b; char *error_msg; argc--; argv++; if (argc < 1) { for (b = break_base;b;b=b->next) breakpoint_print(interp,b); return(TCL_OK); } if (argv[0][0] == '-') { if (argv[0][1] == '\0') { while (break_base) { breakpoint_destroy(break_base); } breakpoint_max_id = 0; return(TCL_OK); } else if (isdigit(argv[0][1])) { int id = atoi(argv[0]+1); for (b = break_base;b;b=b->next) { if (b->id == id) { breakpoint_destroy(b); if (!break_base) breakpoint_max_id = 0; return(TCL_OK); } } Tcl_SetResult(interp,"no such breakpoint",TCL_STATIC); return(TCL_ERROR); } } b = breakpoint_new(); if (flageq("-regexp",argv[0],2)) { argc--; argv++; if ((argc > 0) && (b->re = TclRegComp(argv[0]))) { savestr(&b->pat,argv[0]); argc--; argv++; } else { breakpoint_fail("bad regular expression") } } else if (flageq("-glob",argv[0],2)) { argc--; argv++; if (argc > 0) { savestr(&b->pat,argv[0]); argc--; argv++; } else { breakpoint_fail("no pattern?"); } } else if ((!(flageq("if",*argv,1)) && (!(flageq("then",*argv,1))))) { /* look for [file:]line */ char *colon; char *linep; /* pointer to beginning of line number */ colon = strchr(argv[0],':'); if (colon) { *colon = '\0'; savestr(&b->file,argv[0]); *colon = ':'; linep = colon + 1; } else { linep = argv[0]; /* get file from current scope */ /* savestr(&b->file, ?); */ } if (TCL_OK == Tcl_GetInt(interp,linep,&b->line)) { argc--; argv++; print(interp,"setting breakpoints by line number is currently unimplemented - use patterns or expressions\n"); } else { /* not an int? - unwind & assume it is an expression */ if (b->file) ckfree(b->file); } } if (argc > 0) { int do_if = FALSE; if (flageq("if",argv[0],1)) { argc--; argv++; do_if = TRUE; } else if (!flageq("then",argv[0],1)) { do_if = TRUE; } if (do_if) { if (argc < 1) { breakpoint_fail("if what"); } savestr(&b->expr,argv[0]); argc--; argv++; } } if (argc > 0) { if (flageq("then",argv[0],1)) { argc--; argv++; } if (argc < 1) { breakpoint_fail("then what?"); } savestr(&b->cmd,argv[0]); } sprintf(interp->result,"%d",b->id); return(TCL_OK); break_fail: breakpoint_destroy(b); Tcl_SetResult(interp,error_msg,TCL_STATIC); return(TCL_ERROR); } static char *help[] = { "s [#] step into procedure", "n [#] step over procedure", "N [#] step over procedures, commands, and arguments", "c continue", "r continue until return to caller", "u [#] move scope up level", "d [#] move scope down level", " go to absolute frame if # is prefaced by \"#\"", "w show stack (\"where\")", "w -w [#] show/set width", "w -c [0|1] show/set compress", "b show breakpoints", "b [-r regexp-pattern] [if expr] [then command]", "b [-g glob-pattern] [if expr] [then command]", "b [[file:]#] [if expr] [then command]", " if pattern given, break if command resembles pattern", " if # given, break on line #", " if expr given, break if expr true", " if command given, execute command at breakpoint", "b -# delete breakpoint", "b - delete all breakpoints", 0}; /*ARGSUSED*/ static int cmdHelp(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char **hp; for (hp=help;*hp;hp++) { print(interp,"%s\n",*hp); } return(TCL_OK); } /* occasionally, we print things larger buf_max but not by much */ /* see print statements in PrintStack routines for examples */ #define PAD 80 /*VARARGS*/ static void print TCL_VARARGS_DEF(Tcl_Interp *,arg1) { Tcl_Interp *interp; char *fmt; va_list args; interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args); fmt = va_arg(args,char *); if (!printproc) vprintf(fmt,args); else { static int buf_width_max = DEFAULT_WIDTH+PAD; static char buf_basic[DEFAULT_WIDTH+PAD+1]; static char *buf = buf_basic; if (buf_width+PAD > buf_width_max) { if (buf && (buf != buf_basic)) ckfree(buf); buf = (char *)ckalloc(buf_width+PAD+1); buf_width_max = buf_width+PAD; } vsprintf(buf,fmt,args); (*printproc)(interp,buf,printdata); } va_end(args); } /*ARGSUSED*/ Dbg_InterStruct Dbg_Interactor(interp,inter_proc,data) Tcl_Interp *interp; Dbg_InterProc *inter_proc; ClientData data; { Dbg_InterStruct tmp; tmp.func = interactor; tmp.data = interdata; interactor = (inter_proc?inter_proc:simple_interactor); interdata = data; return tmp; } /*ARGSUSED*/ Dbg_IgnoreFuncsProc * Dbg_IgnoreFuncs(interp,proc) Tcl_Interp *interp; Dbg_IgnoreFuncsProc *proc; { Dbg_IgnoreFuncsProc *tmp = ignoreproc; ignoreproc = (proc?proc:zero); return tmp; } /*ARGSUSED*/ Dbg_OutputStruct Dbg_Output(interp,proc,data) Tcl_Interp *interp; Dbg_OutputProc *proc; ClientData data; { Dbg_OutputStruct tmp; tmp.func = printproc; tmp.data = printdata; printproc = proc; printdata = data; return tmp; } /*ARGSUSED*/ int Dbg_Active(interp) Tcl_Interp *interp; { return debugger_active; } char ** Dbg_ArgcArgv(argc,argv,copy) int argc; char *argv[]; int copy; { char **alloc; main_argc = argc; if (!copy) { main_argv = argv; alloc = 0; } else { main_argv = alloc = (char **)ckalloc((argc+1)*sizeof(char *)); while (argc-- >= 0) { *main_argv++ = *argv++; } main_argv = alloc; } return alloc; } static struct cmd_list { char *cmdname; Tcl_CmdProc *cmdproc; enum debug_cmd cmdtype; } cmd_list[] = { {"n", cmdNext, next}, {"s", cmdNext, step}, {"N", cmdNext, Next}, {"c", cmdSimple, cont}, {"r", cmdSimple, ret}, {"w", cmdWhere, none}, {"b", cmdBreak, none}, {"u", cmdDir, up}, {"d", cmdDir, down}, {"h", cmdHelp, none}, {0} }; /* this may seem excessive, but this avoids the explicit test for non-zero */ /* in the caller, and chances are that that test will always be pointless */ /*ARGSUSED*/ static int zero(interp,string) Tcl_Interp *interp; char *string; { return 0; } static int simple_interactor(interp, clientData) Tcl_Interp *interp; ClientData clientData; { int rc; char *ccmd; /* pointer to complete command */ char line[BUFSIZ+1]; /* space for partial command */ int newcmd = TRUE; Interp *iPtr = (Interp *)interp; Tcl_DString dstring; Tcl_DStringInit(&dstring); newcmd = TRUE; while (TRUE) { struct cmd_list *c; if (newcmd) { print(interp,"dbg%d> ",iPtr->numLevels); } else { print(interp,"dbg+> "); } fflush(stdout); #ifdef __WIN32__ if (1) { Tcl_Obj *objv[3]; char *end; objv[0] = Tcl_NewStringObj("gets", -1); objv[1] = Tcl_NewStringObj("stdin", -1); objv[2] = Tcl_NewStringObj("ExpectTmpDbgVarX0X0X0Y", -1); rc = Tcl_GetsObjCmd(NULL, interp, 3, objv); Tcl_DecrRefCount(objv[0]); Tcl_DecrRefCount(objv[1]); Tcl_DecrRefCount(objv[2]); if (rc == TCL_ERROR) { return TCL_ERROR; } if (interp->result[0] == '-') { Tcl_AppendResult(interp, "error: stdin is non-blocking, can't debug", NULL); return TCL_ERROR; } rc = strtoul(interp->result, &end, 10); strcpy(line, interp->result); } #else if (0 >= (rc = read(0,line,BUFSIZ))) { if (!newcmd) line[0] = 0; else exit(0); } else line[rc] = '\0'; #endif ccmd = Tcl_DStringAppend(&dstring,line,rc); if (!Tcl_CommandComplete(ccmd)) { newcmd = FALSE; continue; /* continue collecting command */ } newcmd = TRUE; /* if user pressed return with no cmd, use previous one */ if ((ccmd[0] == '\n' || ccmd[0] == '\r') && ccmd[1] == '\0') { /* this loop is guaranteed to exit through break */ for (c = cmd_list;c->cmdname;c++) { if (c->cmdtype == last_action_cmd) break; } /* recreate textual version of command */ Tcl_DStringAppend(&dstring,c->cmdname,-1); if (c->cmdtype == step || c->cmdtype == next || c->cmdtype == Next) { char num[10]; sprintf(num," %d",last_step_count); Tcl_DStringAppend(&dstring,num,-1); } } #if TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION < 4 rc = Tcl_RecordAndEval(interp,ccmd,0); #else rc = Tcl_RecordAndEval(interp,ccmd,TCL_NO_EVAL); rc = Tcl_Eval(interp,ccmd); #endif Tcl_DStringFree(&dstring); switch (rc) { case TCL_OK: if (*interp->result != 0) print(interp,"%s\n",interp->result); continue; case TCL_ERROR: print(interp,"%s\n",Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY)); /* since user is typing by hand, we expect lots of errors, and want to give another chance */ continue; case TCL_BREAK: case TCL_CONTINUE: #define finish(x) {rc = x; goto done;} finish(rc); case TCL_RETURN: finish(TCL_OK); default: /* note that ccmd has trailing newline */ print(interp,"error %d: %s\n",rc,ccmd); continue; } } /* cannot fall thru here, must jump to label */ done: Tcl_DStringFree(&dstring); return(rc); } static char init_auto_path[] = "lappend auto_path $dbg_library"; static void init_debugger(interp) Tcl_Interp *interp; { struct cmd_list *c; for (c = cmd_list;c->cmdname;c++) { Tcl_CreateCommand(interp,c->cmdname,c->cmdproc, (ClientData)&c->cmdtype,(Tcl_CmdDeleteProc *)0); } debug_handle = Tcl_CreateTrace(interp, 10000,debugger_trap,(ClientData)0); debugger_active = TRUE; Tcl_SetVar2(interp,Dbg_VarName,"active","1",0); #ifdef DBG_SCRIPTDIR Tcl_SetVar(interp,"dbg_library",DBG_SCRIPTDIR,0); #endif Tcl_Eval(interp,init_auto_path); } /* allows any other part of the application to jump to the debugger */ /*ARGSUSED*/ void Dbg_On(interp,immediate) Tcl_Interp *interp; int immediate; /* if true, stop immediately */ /* should only be used in safe places */ /* i.e., when Tcl_Eval can be called */ { if (!debugger_active) init_debugger(interp); debug_cmd = step; step_count = 1; if (immediate) { static char *fake_cmd = "--interrupted-- (command_unknown)"; debugger_trap((ClientData)0,interp,-1,fake_cmd,(Tcl_CmdProc *)0, (ClientData)0,1,&fake_cmd); /* (*interactor)(interp);*/ } } void Dbg_Off(interp) Tcl_Interp *interp; { struct cmd_list *c; if (!debugger_active) return; for (c = cmd_list;c->cmdname;c++) { Tcl_DeleteCommand(interp,c->cmdname); } Tcl_DeleteTrace(interp,debug_handle); debugger_active = FALSE; Tcl_UnsetVar(interp,Dbg_VarName,TCL_GLOBAL_ONLY); } |
Added generic/Dbg.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* Dbg.h - Tcl Debugger include file Written by: Don Libes, NIST, 3/23/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* _DEBUG or _DBG is just too likely, use something more unique */ #ifndef _NIST_DBG #define _NIST_DBG #include "tcl.h" typedef int (Dbg_InterProc) _ANSI_ARGS_((Tcl_Interp *interp, ClientData data)); typedef int (Dbg_IgnoreFuncsProc) _ANSI_ARGS_(( Tcl_Interp *interp, char *funcname)); typedef void (Dbg_OutputProc) _ANSI_ARGS_(( Tcl_Interp *interp, char *output, ClientData data)); typedef struct { Dbg_InterProc *func; ClientData data; } Dbg_InterStruct; typedef struct { Dbg_OutputProc *func; ClientData data; } Dbg_OutputStruct; EXTERN char *Dbg_VarName; EXTERN char *Dbg_DefaultCmdName; /* trivial interface, creates a "debug" command in your interp */ EXTERN int Dbg_Init _ANSI_ARGS_((Tcl_Interp *)); EXTERN void Dbg_On _ANSI_ARGS_((Tcl_Interp *interp, int immediate)); EXTERN void Dbg_Off _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN char **Dbg_ArgcArgv _ANSI_ARGS_((int argc,char *argv[], int copy)); EXTERN int Dbg_Active _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN Dbg_InterStruct Dbg_Interactor _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_InterProc *interactor, ClientData data)); EXTERN Dbg_IgnoreFuncsProc *Dbg_IgnoreFuncs _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_IgnoreFuncsProc *)); EXTERN Dbg_OutputStruct Dbg_Output _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_OutputProc *, ClientData data)); #endif /* _NIST_DBG */ |
Added generic/exp.decls.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | # ---------------------------------------------------------------------------- # exp.decls -- # # This file contains the declarations for all supported public # functions that are exported by the Expect library via the stubs table. # This file is used to generate the expDecls.h, expPlatDecls.h, # expIntDecls.h, and expStubLib.c files. # # ---------------------------------------------------------------------------- # # Written by: Don Libes, [email protected], NIST, 12/3/90 # # Design and implementation of this program was paid for by U.S. tax # dollars. Therefore it is public domain. However, the author and NIST # would appreciate credit if this program or parts of it are used. # # Copyright (c) 1997 Mitel Corporation # work by Gordon Chaffee <[email protected]> for the WinNT port. # # Copyright (c) 2001-2002 Telindustrie, LLC # work by David Gravereaux <[email protected]> for any Win32 OS. # # ---------------------------------------------------------------------------- # URLs: http://expect.nist.gov/ # http://expect.sf.net/ # http://bmrc.berkeley.edu/people/chaffee/expectnt.html # ---------------------------------------------------------------------------- # RCS: @(#) $Id: exp.decls,v 1.1.4.6 2002/03/07 02:49:36 davygrvy Exp $ # ---------------------------------------------------------------------------- library exp # Define the tcl interface with several sub interfaces: # expPlat - platform specific public # expInt - generic private # expIntPlat - platform specific private interface exp hooks {expPlat expInt expIntPlat} # Declare each of the functions in the public Expect interface. Note that # the an index should never be reused for a different function in order # to preserve backwards compatibility. declare 0 generic { int Expect_Init (Tcl_Interp *interp) } #declare 1 generic { # int Expect_SafeInit (Tcl_Interp *interp) #} ### The command procs. ### ### I'm not sure _exactly_ why, but I think they should be in the Stubs table as ### they are functions. #declare 2 generic { # int Exp_CloseObjCmd (ClientData clientData, Tcl_Interp *interp, # int argc, char *argv[]) #} declare 3 generic { int Exp_ExpInternalCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } #declare 4 generic { # int Exp_DisconnectCmd (ClientData clientData, Tcl_Interp *interp, # int argc, char *argv[]) #} declare 5 generic { int Exp_ExitCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 6 generic { int Exp_ExpContinueCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } #declare 7 generic { # int Exp_ForkCmd (ClientData clientData, Tcl_Interp *interp, # int argc, char *argv[]) #} declare 8 generic { int Exp_ExpPidCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 9 generic { int Exp_GetpidDeprecatedCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } #declare 10 generic { # int Exp_InterpreterObjCmd (ClientData clientData, # Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]) #} declare 11 generic { int Exp_LogFileCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 12 generic { int Exp_LogUserCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 13 generic { int Exp_OpenCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } #declare 14 generic { # int Exp_OverlayCmd (ClientData clientData, Tcl_Interp *interp, # int argc, char *argv[]) #} #declare 15 generic { # int Exp_InterReturnObjCmd (ClientData clientData, # Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]) #} #declare 16 generic { # int Exp_SendObjCmd (ClientData clientData, # Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST objv[]) #} declare 17 generic { int Exp_SendLogCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 18 generic { int Exp_SleepCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 19 generic { int Exp_SpawnCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 20 generic { int Exp_StraceCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 21 generic { int Exp_WaitCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 22 generic { int Exp_ExpVersionCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 23 generic { int Exp_Prompt1Cmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 24 generic { int Exp_Prompt2Cmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 25 generic { int Exp_TrapCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 26 generic { int Exp_SttyCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 27 generic { int Exp_SystemCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 28 generic { int Exp_ExpectCmd (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) } declare 29 generic { int Exp_ExpectGlobalCmd (ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *CONST objv[]) } declare 30 generic { int Exp_MatchMaxCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 31 generic { int Exp_RemoveNullsCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 32 generic { int Exp_ParityCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 33 generic { int Exp_TimestampCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 34 generic { int Exp_CloseCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 35 generic { int Exp_InterpreterCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 36 generic { int Exp_SendCmd (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) } declare 37 generic { int Exp_KillCmd (ClientData clientData,Tcl_Interp *interp, int argc, char *argv[]) } ### From the old exp_printify.h declare 40 generic { char *exp_printify (char *s) } ### From the old exp_log.h declare 50 generic { void exp_errorlog (char *fmt, ...) } declare 51 generic { void exp_log (int force_stdout, ...) } declare 52 generic { void exp_debuglog (char *fmt, ...) } declare 53 generic { void exp_nflog (char *buf, int force_stdout) } declare 54 generic { void exp_nferrorlog (char *buf, int force_stdout) } declare 55 generic { void exp_error (Tcl_Interp *interp, ...) } ## all below are NOT final -> declare 60 generic { void exp_parse_argv (Tcl_Interp *interp, int argc, char **argv) } declare 61 generic { int exp_interpreter (Tcl_Interp *interp) } declare 62 generic { int exp_interpret_cmdfile (Tcl_Interp *interp, Tcl_Channel cmdfile) } declare 63 generic { int exp_interpret_cmdfilename (Tcl_Interp *interp, char *filename) } declare 64 generic { void exp_interpret_rcfiles (Tcl_Interp *interp, int my_rc, int sys_rc) } declare 65 generic { char *exp_cook (CONST char *s, int *len) } #declare 66 generic { # void expCloseOnExec (int fd) #} declare 67 generic { int exp_getpidproc (void) } declare 68 generic { Tcl_Channel ExpCreateSpawnChannel (Tcl_Interp *interp, Tcl_Channel chan) } declare 69 generic { int ExpPlatformSpawnOutput (ClientData instanceData, CONST char *bufPtr, int toWrite, int *errorPtr) } declare 70 generic { void exp_init_main_cmds (Tcl_Interp *interp) } declare 71 generic { void exp_init_expect_cmds (Tcl_Interp *interp) } declare 72 generic { void exp_init_most_cmds (Tcl_Interp *interp) } declare 73 generic { void exp_init_trap_cmds (Tcl_Interp *interp) } declare 74 generic { void exp_init_interact_cmds (Tcl_Interp *interp) } declare 75 generic { int exp_init_tty_cmds (Tcl_Interp *interp) } #declare 76 generic { # int exp_getpidproc (void) #} #declare 77 generic { # void exp_busy (int fd) #} declare 78 generic { Tcl_Channel ExpCreatePairChannel (Tcl_Interp *interp, CONST char *chanInId, CONST char *chanOutId, CONST char *chanName) } declare 79 generic { int ExpSpawnOpen (Tcl_Interp *interp, char *chanId, int leaveopen) } declare 80 generic { struct exp_f * exp_update_master (Tcl_Interp *interp ,int opened, int adjust) } declare 81 generic { CONST char * exp_get_var (Tcl_Interp *interp, char *var) } declare 82 generic { void exp_exit (Tcl_Interp *interp, int status) } ### From exp_event.h declare 83 generic { int exp_dsleep (Tcl_Interp *interp, double sec) } declare 84 generic { void exp_init_event (void) } #declare 85 generic { # void exp_event_exit (Tcl_Interp *interp) #} declare 86 generic { void exp_background_filehandler (ClientData clientData, int mask) } declare 87 generic { void exp_exit_handlers (ClientData clientData) } declare 88 generic { void exp_close_on_exec (int fd) } declare 89 generic { int exp_flageq_code (char *flag, char *string, int minlen) } declare 90 generic { void exp_close_tcl_files (void) } declare 91 generic { void exp_lowmemcpy (char *dest, CONST char *src, int n) } declare 92 generic { void exp_timestamp (Tcl_Interp *interp, time_t *timeval, char *array) } interface expPlat interface expInt declare 1 generic { int Exp_StringMatch (CONST char *string, CONST char *pattern, int *offset) } declare 2 generic { int Exp_StringMatch2 (CONST char *string, CONST char *pattern) } #declare 3 generic { # void exp_console_set (void) #} declare 4 generic { struct exp_i *exp_new_i_complex (Tcl_Interp *interp, char *arg, int duration, Tcl_VarTraceProc *updateproc, CONST char *msg) } declare 5 generic { struct exp_i *exp_new_i_simple (struct exp_f *fd, int duration) } declare 6 generic { struct exp_fs_list *exp_new_fs (struct exp_f *f) } declare 7 generic { void exp_free_i (Tcl_Interp *interp ,struct exp_i *i, Tcl_VarTraceProc *updateproc) } declare 8 generic { void exp_free_fs (struct exp_fs_list *fs_first) } declare 9 generic { void exp_free_fs_single (struct exp_fs_list *fs) } declare 10 generic { void exp_i_update (Tcl_Interp *interp, struct exp_i *i) } declare 11 generic { void exp_pty_exit (void) } declare 12 generic { void exp_init_spawn_ids (Tcl_Interp *interp) } declare 13 generic { void exp_init_pty (Tcl_Interp *interp) } declare 14 generic { void exp_init_tty (Tcl_Interp *interp) } declare 15 generic { void exp_init_stdio (void) } declare 16 generic { void exp_init_sig (void) } declare 17 generic { void exp_init_trap (void) } declare 18 generic { void exp_init_unit_random (void) } declare 19 generic { void exp_init_spawn_id_vars (Tcl_Interp *interp) } declare 20 generic { void exp_adjust (struct exp_f *f) } declare 21 generic { void exp_ecmd_remove_f_direct_and_indirect (Tcl_Interp *interp, struct exp_f *f) } declare 22 generic { void exp_rearm_sigchld (Tcl_Interp *interp) } declare 23 generic { struct exp_f * exp_chan2f (Tcl_Interp *interp, CONST char *chan, int opened, int adjust, CONST char *msg) } declare 24 generic { int exp_fcheck (Tcl_Interp *interp, struct exp_f *f, int opened, int adjust, CONST char *msg) } declare 25 generic { int exp_close (Tcl_Interp *interp, struct exp_f *f) } declare 26 generic { void exp_strftime (char *format, const struct tm *timeptr, Tcl_DString *dstring) } declare 27 generic { void exp_create_commands (Tcl_Interp *interp, struct exp_cmd_data *c) } declare 28 generic { void exp_tty_break (Tcl_Interp *interp, struct exp_f *f) } declare 29 generic { void exp_event_disarm (struct exp_f *f) } declare 30 generic { void exp_arm_background_filehandler (struct exp_f *f) } declare 31 generic { void exp_disarm_background_filehandler (struct exp_f *f) } declare 32 generic { void exp_disarm_background_filehandler_force (struct exp_f *f) } declare 33 generic { void exp_unblock_background_filehandler (struct exp_f *f) } declare 34 generic { void exp_block_background_filehandler (struct exp_f *f) } declare 35 generic { int exp_get_next_event (Tcl_Interp *interp, struct exp_f **masters, int n, struct exp_f **master_out, int timeout, int key) } declare 36 generic { int exp_get_next_event_info (Tcl_Interp *interp, struct exp_f *fd, int ready_mask) } declare 37 generic { struct exp_f * exp_f_find (Tcl_Interp *interp, char *spawnId) } declare 38 generic { struct exp_f * exp_f_new (Tcl_Interp *interp, Tcl_Channel chan, char *spawnId, int pid) } declare 39 generic { int exp_f_new_platform (struct exp_f *f) } declare 40 generic { void exp_f_free (struct exp_f *f) } declare 41 generic { void exp_f_free_platform (struct exp_f *f) } declare 42 generic { int exp_exact_write (struct exp_f * f, char *buffer, int rembytes) } #declare 43 generic { # void exp_sys_close (int fd, struct exp_f *f) #} interface expIntPlat #==================================================================================== # UNIX specific publics. #==================================================================================== # WIN32 specific privates. declare 0 win { DWORD ExpWinApplicationType(const char *originalName, Tcl_DString *fullPath) } declare 1 win { DWORD ExpWinCreateProcess (int argc, char *const *argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, HANDLE *processPtr, PDWORD globalPidPtr) } declare 2 win { void ExpWinSyslog (DWORD errId, ...) } declare 3 win { char *ExpSyslogGetSysMsg (DWORD errId) } declare 4 win { Tcl_Pid Exp_WaitPid (Tcl_Pid pid, int *statPtr, int options) } declare 5 win { void Exp_KillProcess (Tcl_Pid pid) } declare 6 win { void ExpWinInit (void) } declare 7 win { void BuildCommandLine (CONST char *executable, int argc, char *const *argv, Tcl_DString *linePtr) } #==================================================================================== # MAC specific publics. ### We aren't doing Mac... sorry.. |
Added generic/exp.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | /* ---------------------------------------------------------------------------- * exp.h -- * * Public include file for using the Expect extension. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.8 2002/03/06 02:18:20 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXP #define _EXP #ifndef _TCL # include "tcl.h" #endif /* * Version stuff. */ #define EXP_MAJOR_VERSION 6 #define EXP_MINOR_VERSION 0 #define EXP_RELEASE_LEVEL TCL_ALPHA_RELEASE #define EXP_RELEASE_SERIAL 0 #define EXP_VERSION STRINGIFY(JOIN(EXP_MAJOR_VERSION,JOIN(.,EXP_MINOR_VERSION))) #if EXP_RELEASE_LEVEL == TCL_ALPHA_RELEASE # define EXP_PATCH_LEVEL \ STRINGIFY( \ JOIN(JOIN(EXP_MAJOR_VERSION, \ JOIN(., EXP_MINOR_VERSION)), \ JOIN(a, EXP_RELEASE_SERIAL))) #elif EXP_RELEASE_LEVEL == TCL_BETA_RELEASE # define EXP_PATCH_LEVEL \ STRINGIFY( \ JOIN(JOIN(EXP_MAJOR_VERSION, \ JOIN(., EXP_MINOR_VERSION)), \ JOIN(b, EXP_RELEASE_SERIAL))) #elif EXP_RELEASE_LEVEL == TCL_FINAL_RELEASE # define EXP_PATCH_LEVEL \ STRINGIFY( \ JOIN(JOIN(EXP_MAJOR_VERSION, \ JOIN(., EXP_MINOR_VERSION)), \ JOIN(., EXP_RELEASE_SERIAL))) #else # include "bad/release/level/used" #endif /* * The windows resource compiler defines this by default. Skip the rest of this * file when included from an rc script. */ #ifndef RC_INVOKED #undef TCL_STORAGE_CLASS #if defined(BUILD_spawndriver) # define TCL_STORAGE_CLASS #elif defined(BUILD_exp) # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_EXP_STUBS # define TCL_STORAGE_CLASS # else # define TCL_STORAGE_CLASS DLLIMPORT # endif #endif /* Fix the Borland bug in tcl.h */ #ifndef TCL_EXTERN # undef DLLIMPORT # undef DLLEXPORT # if (defined(__WIN32__) && (defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) \ || (defined(__GNUC__) && defined(__DECLSPEC_SUPPORTED)))) \ || (defined(MAC_TCL) && FUNCTION_DECLSPEC) # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # elif defined(__BORLANDC__) # define OLD_BORLAND 1 # define DLLIMPORT __import # define DLLEXPORT __export # else # define DLLIMPORT # define DLLEXPORT # endif /* Avoid name mangling. */ # ifdef __cplusplus # define TCL_CPP "C" # else # define TCL_CPP # endif /* Pre 5.5 Borland requires the attributes be placed after the return type. */ # if OLD_BORLAND # define TCL_EXTERN(rtnType) extern TCL_CPP rtnType TCL_STORAGE_CLASS # else # define TCL_EXTERN(rtnType) extern TCL_CPP TCL_STORAGE_CLASS rtnType # endif #endif /* needed by some exports */ #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # ifdef HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #define SCRIPTDIR "example/" #define EXECSCRIPTDIR "example/" /* common return codes for Expect functions */ /* The library actually only uses TIMEOUT and EOF */ #define EXP_ABEOF -1 /* abnormal eof in Expect */ /* when in library, this define is not used. */ /* Instead "-1" is used literally in the */ /* usual sense to check errors in system */ /* calls */ #define EXP_TIMEOUT -2 #define EXP_TCLERROR -3 #define EXP_FULLBUFFER -5 #define EXP_MATCH -6 #define EXP_NOMATCH -7 /*#define EXP_CANTMATCH EXP_NOMATCH #define EXP_CANMATCH -8*/ #define EXP_DATA_NEW -9 /* if select says there is new data */ #define EXP_DATA_OLD -10 /* if we already read data in another cmd */ #define EXP_EOF -11 #define EXP_RECONFIGURE -12 /* changes to indirect spawn id lists */ /* require us to reconfigure things */ /* in the unlikely event that a signal handler forces us to return this */ /* through expect's read() routine, we temporarily convert it to this. */ #define EXP_TCLRET -20 #define EXP_TCLCNT -21 #define EXP_TCLCNTTIMER -22 #define EXP_TCLBRK -23 #define EXP_TCLCNTEXP -24 #define EXP_TCLRETTCL -25 /* yet more TCL return codes */ /* Tcl does not safely provide a way to define the values of these, so */ /* use ridiculously different numbers for safety */ #define EXP_CONTINUE -101 /* continue expect command */ /* and restart timer */ #define EXP_CONTINUE_TIMER -102 /* continue expect command */ /* and continue timer */ #define EXP_TCL_RETURN -103 /* converted by interact */ /* and interpeter from */ /* inter_return into */ /* TCL_RETURN*/ #define EXP_TIME_INFINITY -1 #define EXP_SPAWN_ID_BAD -1 /* * Include the public function declarations that are accessible via * the stubs table. */ #include "expDecls.h" /* * Include platform specific public function declarations that are * accessible via the stubs table. */ #include "expPlatDecls.h" /* * Exp_InitStubs is used by apps/extensions that want to link * against the expect stubs library. If we are not using stubs, * then this won't be declared. */ #ifdef USE_EXP_STUBS extern TCL_CPP CONST char *Exp_InitStubs _ANSI_ARGS_((Tcl_Interp *interp, char *version, int exact)); #endif #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* RC_INVOKED */ #endif /* _EXP */ |
Added generic/expChan.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | /* ---------------------------------------------------------------------------- * expChan.c -- * * Implements the exp_pair channel id. What this really does * is wrap the input and output channels into a single, duplex * channel. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" static void ExpPairInputCloseHandler _ANSI_ARGS_((ClientData clientData)); static void ExpPairOutputCloseHandler _ANSI_ARGS_((ClientData clientData)); static Tcl_DriverCloseProc ExpPairClose; static Tcl_DriverInputProc ExpPairInput; static Tcl_DriverOutputProc ExpPairOutput; static Tcl_DriverSetOptionProc ExpPairSetOption; static Tcl_DriverGetOptionProc ExpPairGetOption; static Tcl_DriverWatchProc ExpPairWatch; static Tcl_DriverGetHandleProc ExpPairGetHandle; static Tcl_DriverBlockModeProc ExpPairBlock; static void ExpPairReadable _ANSI_ARGS_((ClientData clientData, int mask)); static void ExpPairWritable _ANSI_ARGS_((ClientData clientData, int mask)); static Tcl_ChannelType ExpPairChannelType = { "exp_pair", TCL_CHANNEL_VERSION_2, ExpPairClose, ExpPairInput, ExpPairOutput, NULL, /* Can't seek! */ ExpPairSetOption, ExpPairGetOption, ExpPairWatch, ExpPairGetHandle, 0, ExpPairBlock, 0, 0 }; typedef struct { Tcl_Channel thisChannelPtr; /* The toplevel channel */ Tcl_Channel inChannelPtr; /* The input child channel */ Tcl_Channel outChannelPtr; /* The output child channel */ int watchMask; /* Events that are being checked for */ int blockingPropagate; /* Propagate a blocking option to children */ } ExpPairState; static int expPairCount = 0; static int initialized = 0; /* *---------------------------------------------------------------------- * * ExpPairInit -- * * Initialize the pair event mechanism. Currently, it * does nothing because it may not be needed. If it is * needed, it will need to call platform specific event * code. * * Results: * None * * Side Effects: * None currently * *---------------------------------------------------------------------- */ static void ExpPairInit() { initialized = 1; } /* *---------------------------------------------------------------------- * * ExpCreatePairChannel -- * * Routine that wraps an input channel and an output channel * into a single channel. By default, no translation or buffering * occurs in this channel. * * Results: * A Tcl_Channel. * * Side Effects: * Allocates memory. * *---------------------------------------------------------------------- */ Tcl_Channel ExpCreatePairChannel(interp, chanInId, chanOutId, chanName) Tcl_Interp *interp; CONST char *chanInId; CONST char *chanOutId; CONST char *chanName; /* Name of resulting channel to create. * If NULL, it gets created here */ { Tcl_Channel chanIn, chanOut, chan; ExpPairState *ssPtr; char channelNameStr[10]; int mode; chanIn = Tcl_GetChannel(interp, chanInId, &mode); if (chanIn) { if ((mode & TCL_READABLE) == 0) { Tcl_AppendResult(interp, chanInId, " is not a readable channel", (char *) NULL); return NULL; } } else { return NULL; } chanOut = Tcl_GetChannel(interp, chanOutId, &mode); if (chanOut) { if ((mode & TCL_WRITABLE) == 0) { Tcl_AppendResult(interp, chanInId, " is not a writable channel", (char *) NULL); return NULL; } } else { return NULL; } if (chanName == NULL) { sprintf(channelNameStr, "exp_pair%d", expPairCount++); chanName = channelNameStr; } ssPtr = (ExpPairState *) ckalloc(sizeof(ExpPairState)); ssPtr->inChannelPtr = chanIn; ssPtr->outChannelPtr = chanOut; /* * Setup the expect channel to always flush immediately */ if (chanName == NULL) { sprintf(channelNameStr, "exp_pair%d", expPairCount++); chanName = channelNameStr; } chan = Tcl_CreateChannel(&ExpPairChannelType, chanName, (ClientData) ssPtr, TCL_READABLE|TCL_WRITABLE); if (chan == NULL) { free(ssPtr); return NULL; } ssPtr->thisChannelPtr = chan; ssPtr->watchMask = 0; ssPtr->blockingPropagate = 0; Tcl_CreateCloseHandler(chanIn, ExpPairInputCloseHandler, (ClientData) ssPtr); Tcl_CreateCloseHandler(chanOut, ExpPairOutputCloseHandler, (ClientData) ssPtr); Tcl_SetChannelOption(interp, chan, "-buffering", "none"); Tcl_SetChannelOption(interp, chan, "-translation","binary"); Tcl_SetChannelOption(interp, chan, "-blockingpropagate", "off"); Tcl_SetChannelOption(interp, chan, "-blocking", "off"); return chan; } /* *---------------------------------------------------------------------- * * ExpPairInputCloseHandler -- * * This gets called when the underlying input channel is closed. * * Results: * None * *---------------------------------------------------------------------- */ static void ExpPairInputCloseHandler(clientData) ClientData clientData; { ExpPairState *ssPtr = (ExpPairState *) clientData; ssPtr->inChannelPtr = NULL; } /* *---------------------------------------------------------------------- * * ExpPairOutputCloseHandler -- * * This gets called when the underlying output channel is closed. * * Results: * None * *---------------------------------------------------------------------- */ static void ExpPairOutputCloseHandler(clientData) ClientData clientData; { ExpPairState *ssPtr = (ExpPairState *) clientData; ssPtr->outChannelPtr = NULL; } /* *---------------------------------------------------------------------- * * ExpPairBlock -- * * Generic routine to set I/O to blocking or non-blocking. * * Results: * TCL_OK or TCL_ERROR. * * Side Effects: * None. * *---------------------------------------------------------------------- */ static int ExpPairBlock(instanceData, mode) ClientData instanceData; int mode; /* (in) Block or not */ { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel inChannelPtr = ssPtr->inChannelPtr; Tcl_Channel outChannelPtr = ssPtr->outChannelPtr; int ret; if (! ssPtr->blockingPropagate) { return TCL_OK; } if (inChannelPtr && Tcl_GetChannelType(inChannelPtr)->blockModeProc) { ret = (Tcl_GetChannelType(inChannelPtr)->blockModeProc) (Tcl_GetChannelInstanceData(inChannelPtr), mode); if (ret == TCL_ERROR) { return ret; } } if (outChannelPtr && Tcl_GetChannelType(outChannelPtr)->blockModeProc) { return (Tcl_GetChannelType(outChannelPtr)->blockModeProc) (Tcl_GetChannelInstanceData(outChannelPtr), mode); } return TCL_OK; } /* *---------------------------------------------------------------------- * * ExpPairInput -- * * Generic read routine for expect console * * Returns: * Amount read or -1 with errorcode in errorPtr. * * Side Effects: * Buffer is updated. * *---------------------------------------------------------------------- */ static int ExpPairInput(instanceData, bufPtr, bufSize, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int bufSize; /* (in) sizeof buffer */ int *errorPtr; /* (out) error code */ { ExpPairState *ssPtr = (ExpPairState *)instanceData; Tcl_Channel channelPtr = ssPtr->inChannelPtr; if (! channelPtr) { *errorPtr = EPIPE; return -1; } if (channelPtr && Tcl_GetChannelType(channelPtr)->inputProc) { return (Tcl_GetChannelType(channelPtr)->inputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, bufSize, errorPtr); } *errorPtr = EINVAL; return -1; } /* *---------------------------------------------------------------------- * * ExpPairOutput -- * * Write routine for expect console * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ static int ExpPairOutput(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; CONST char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { ExpPairState *ssPtr = (ExpPairState *)instanceData; Tcl_Channel channelPtr = ssPtr->outChannelPtr; if (! channelPtr) { *errorPtr = EPIPE; return -1; } if (channelPtr && (Tcl_GetChannelType(channelPtr)->outputProc)) { return (Tcl_GetChannelType(channelPtr)->outputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, toWrite, errorPtr); } *errorPtr = EINVAL; return -1; } /* *---------------------------------------------------------------------- * * ExpPairClose -- * * Generic routine to close the expect console * * Results: * 0 if successful or a POSIX errorcode with * interp updated. * * Side Effects: * Channel is deleted. * *---------------------------------------------------------------------- */ static int ExpPairClose(instanceData, interp) ClientData instanceData; Tcl_Interp *interp; { ExpPairState *ssPtr = (ExpPairState *) instanceData; if (ssPtr->inChannelPtr) { Tcl_DeleteCloseHandler(ssPtr->inChannelPtr, ExpPairOutputCloseHandler, (ClientData) ssPtr); } if (ssPtr->outChannelPtr) { Tcl_DeleteCloseHandler(ssPtr->inChannelPtr, ExpPairOutputCloseHandler, (ClientData) ssPtr); } ckfree((char *)ssPtr); return TCL_OK; } /* *---------------------------------------------------------------------- * * ExpPairSetOption -- * * Set the value of an ExpPair channel option * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ static int ExpPairSetOption(instanceData, interp, nameStr, valStr) ClientData instanceData; Tcl_Interp *interp; CONST char *nameStr; /* (in) Name of option */ CONST char *valStr; /* (in) New value of option */ { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel inChannelPtr = ssPtr->inChannelPtr; Tcl_Channel outChannelPtr = ssPtr->outChannelPtr; int ret1, ret2; Tcl_DString dString; int len; int newMode; len = strlen(nameStr); if (strcmp(nameStr, "-blockingpropagate") == 0) { if (Tcl_GetBoolean(interp, valStr, &newMode) == TCL_ERROR) { return TCL_ERROR; } ssPtr->blockingPropagate = newMode; return TCL_OK; } /* * If the option can be applied to either channel, the result is OK. */ ret1 = ret2 = TCL_OK; if (inChannelPtr && (Tcl_GetChannelType(inChannelPtr)->setOptionProc)) { ret1 = (Tcl_GetChannelType(inChannelPtr)->setOptionProc) (Tcl_GetChannelInstanceData(inChannelPtr), interp, nameStr, valStr); } if (outChannelPtr && (Tcl_GetChannelType(outChannelPtr)->setOptionProc)) { Tcl_DStringInit(&dString); Tcl_DStringGetResult(interp, &dString); ret2 = (Tcl_GetChannelType(outChannelPtr)->setOptionProc) (Tcl_GetChannelInstanceData(outChannelPtr), interp, nameStr, valStr); if (ret1 == TCL_OK && ret2 != TCL_OK) { Tcl_DStringResult(interp, &dString); } Tcl_DStringFree(&dString); } if (ret1 == TCL_OK && ret2 == TCL_OK) { return TCL_OK; } return TCL_ERROR; } /* *---------------------------------------------------------------------- * * ExpPairGetOption -- * * Queries ExpPair channel for the current value of * the given option. * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ static int ExpPairGetOption(instanceData, interp, nameStr, dsPtr) ClientData instanceData; Tcl_Interp *interp; CONST char *nameStr; /* (in) Name of option to retrieve */ Tcl_DString *dsPtr; /* (in) String to place value */ { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel inChannelPtr = ssPtr->inChannelPtr; Tcl_Channel outChannelPtr = ssPtr->outChannelPtr; int ret; int len; len = nameStr ? strlen(nameStr) : 0; if (strcmp(nameStr, "-blockingpropagate") == 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-blockingpropagate"); } Tcl_DStringAppendElement(dsPtr, (ssPtr->blockingPropagate) ? "0" : "1"); if (len > 0) { return TCL_OK; } } if (inChannelPtr && (Tcl_GetChannelType(inChannelPtr)->getOptionProc)) { ret = (Tcl_GetChannelType(inChannelPtr)->getOptionProc) (Tcl_GetChannelInstanceData(inChannelPtr), interp, nameStr, dsPtr); if (ret == TCL_OK) { return ret; } } if (outChannelPtr && (Tcl_GetChannelType(outChannelPtr)->getOptionProc)) { return (Tcl_GetChannelType(outChannelPtr)->getOptionProc) (Tcl_GetChannelInstanceData(outChannelPtr), interp, nameStr, dsPtr); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * * ExpPairGetHandle -- * * Get the Tcl_File for the appropriate direction in from the * Tcl_Channel. * * Results: * NULL because ExpPair ids are handled through other channel * types. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpPairGetHandle(instanceData, direction, handlePtr) ClientData instanceData; int direction; ClientData *handlePtr; { Tcl_Channel inChannelPtr = ((ExpPairState *)instanceData)->inChannelPtr; Tcl_Channel outChannelPtr = ((ExpPairState *)instanceData)->outChannelPtr; if (direction == TCL_READABLE) { if (inChannelPtr && (Tcl_GetChannelType(inChannelPtr)->getHandleProc)) { return (Tcl_GetChannelType(inChannelPtr)->getHandleProc) (Tcl_GetChannelInstanceData(inChannelPtr), direction, handlePtr); } else { *handlePtr = NULL; return TCL_ERROR; } } else { if (outChannelPtr && (Tcl_GetChannelType(outChannelPtr)->getHandleProc)) { return (Tcl_GetChannelType(outChannelPtr)->getHandleProc) (Tcl_GetChannelInstanceData(outChannelPtr), direction, handlePtr); } else { *handlePtr = NULL; return TCL_ERROR; } } } /* *---------------------------------------------------------------------- * * ExpPairWatch -- * * Sets up event handling on a expect console Tcl_Channel using * the underlying channel type. * * Results: * Nothing * * Side Effects * None. * *---------------------------------------------------------------------- */ void ExpPairWatch(instanceData, mask) ClientData instanceData; int mask; { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel inChannelPtr = ssPtr->inChannelPtr; Tcl_Channel outChannelPtr = ssPtr->outChannelPtr; int old_mask = ssPtr->watchMask; if (mask & TCL_READABLE) { if (inChannelPtr && (Tcl_GetChannelType(inChannelPtr)->watchProc)) { (Tcl_GetChannelType(inChannelPtr)->watchProc) (Tcl_GetChannelInstanceData(inChannelPtr), mask & (~TCL_WRITABLE)); } if (! (old_mask & TCL_READABLE)) { Tcl_CreateChannelHandler(inChannelPtr, TCL_READABLE, ExpPairReadable, instanceData); } } else if (old_mask & TCL_READABLE) { Tcl_DeleteChannelHandler(inChannelPtr, ExpPairReadable, instanceData); } if (mask & TCL_WRITABLE) { if (outChannelPtr && (Tcl_GetChannelType(outChannelPtr)->watchProc)) { (Tcl_GetChannelType(outChannelPtr)->watchProc) (Tcl_GetChannelInstanceData(outChannelPtr), mask & (~TCL_READABLE)); } if (! (old_mask & TCL_WRITABLE)) { Tcl_CreateChannelHandler(outChannelPtr, TCL_WRITABLE, ExpPairWritable, instanceData); } } else if (old_mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChannelPtr, ExpPairWritable, instanceData); } ssPtr->watchMask = mask; return; } /* *---------------------------------------------------------------------- * * ExpPairReadable -- * * Callback when an event occurs in the input channel. * * Results: * None * * Side Effects: * An event is generated for this channel. * *---------------------------------------------------------------------- */ static void ExpPairReadable(ClientData instanceData, int mask) { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel channel = ssPtr->thisChannelPtr; if (! initialized) { initialized = 1; ExpPairInit(); } Tcl_NotifyChannel(channel, mask); } /* *---------------------------------------------------------------------- * * ExpPairWritable -- * * Callback when an event occurs in the output channel. * * Results: * None * * Side Effects: * An event is generated for this channel. * *---------------------------------------------------------------------- */ static void ExpPairWritable(ClientData instanceData, int mask) { ExpPairState *ssPtr = (ExpPairState *) instanceData; Tcl_Channel channel = ssPtr->thisChannelPtr; if (!initialized) { initialized = 1; ExpPairInit(); } Tcl_NotifyChannel(channel, mask); } |
Added generic/expChannel.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | /* * expChannel.c -- * * Implements the Expect_Channel * * XXX: This has not been implemented yet but the idea is this: * Change expect to use channel ids instead of just expect ids. * This allows more flexibility. * * Copyright (c) 1997 by Mitel Corporation * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "exp_port.h" #include "tclInt.h" #include "tclPort.h" int ExpectBlock _ANSI_ARGS_((ClientData instanceData, int mode)); int ExpectInput _ANSI_ARGS_((ClientData instanceData, char *bufPtr, int bufSize, int *errorPtr)); int ExpectOutput _ANSI_ARGS_((ClientData instanceData, char *bufPtr, int toWrite, int *errorPtr)); int ExpectClose _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp)); int ExpectSetOption _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp, char *nameStr, char *val)); int ExpectGetOption _ANSI_ARGS_((ClientData instanceData, char *nameStr, Tcl_DString *dsPtr)); Tcl_File ExpectGetFile _ANSI_ARGS_((ClientData instanceData, int direction)); int ExpectReady _ANSI_ARGS_((ClientData instanceData, int direction)); void ExpectWatch _ANSI_ARGS_((ClientData instanceData, int mask)); static Tcl_ChannelType expectChannelType = { "expect", ExpectBlock, ExpectClose, ExpectInput, ExpectOutput, NULL, /* Can't seek! */ ExpectSetOption, ExpectGetOption, ExpectWatch, ExpectReady, ExpectGetFile }; /* *---------------------------------------------------------------------- * * ExpOpenExpectChannel -- * * Generic routine to open a expect channel * * Results: * A Tcl_Channel. * * Side Effects: * Allocates memory. * * Notes: * XXX: This will be called from Exp_SpawnCmd() to create a new * channel. * *---------------------------------------------------------------------- */ Tcl_Channel ExpOpenExpectChannel(interp, argc, argv) Tcl_Interp *interp; int argc; char **argv; { Tcl_Channel chan; ExpectState *ssPtr; char devStr[15]; char channelNameStr[10]; /* * XXX: A bunch of other stuff should be done here first */ ssPtr = (ExpectState *) ckalloc(sizeof(ExpectState)); if (ExppOpenExpectChannel(interp, (ClientData)ssPtr, devStr, flags) != TCL_OK) { ckfree((char *)ssPtr); return NULL; } ssPtr->theFile = Tcl_GetFile((ClientData)ssPtr->fd, EXPECT_HANDLE); /* * Setup the expect channel to always flush immediately */ sprintf(channelNameStr, "expect%d", expectCount++); chan = Tcl_CreateChannel(&expectChannelType, channelNameStr, (ClientData) ssPtr, mode); if (Tcl_SetChannelOption(interp, chan, "-buffering", "none") != TCL_OK) { ExpClose(interp, chan); return NULL; } return chan; arg_missing: Tcl_AppendResult(interp, "Value for \"", argv[i], "\" missing", NULL); return NULL; } /* *---------------------------------------------------------------------- * * ExpectBlock -- * * Generic routine to set I/O to blocking or non-blocking. * * Results: * TCL_OK or TCL_ERROR. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpectBlock(instanceData, mode) ClientData instanceData; int mode; /* (in) Block or not */ { return ExppExpectBlock(instanceData, mode); } /* *---------------------------------------------------------------------- * * ExpectInput -- * * Generic read routine for expect ports * * Returns: * Amount read or -1 with errorcode in errorPtr. * * Side Effects: * Buffer is updated. * *---------------------------------------------------------------------- */ int ExpectInput(instanceData, bufPtr, bufSize, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int bufSize; /* (in) sizeof buffer */ int *errorPtr; /* (out) error code */ { Tcl_Channel channelPtr = ((PlugFInfo *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->inputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, bufSize, errorPtr); } /* *---------------------------------------------------------------------- * * ExpectOutput -- * * Generic write routine for expect ports * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpectOutput(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { Tcl_Channel channelPtr = ((PlugFInfo *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->outputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, toWrite, errorPtr); } /* *---------------------------------------------------------------------- * * ExpectClose -- * * Generic routine to close the expect port * * Results: * 0 if successful or a POSIX errorcode with * interp updated. * * Side Effects: * Channel is deleted. * *---------------------------------------------------------------------- */ int ExpectClose(instanceData, interp) ClientData instanceData; Tcl_Interp *interp; { ExpectState *ssPtr = (ExpectState *) instanceData; int rc = TCL_OK; rc = ExppExpectClose(instanceData); if ((rc != 0) && (interp != NULL)) { Tcl_SetErrno(rc); Tcl_SetResult(interp, Tcl_PosixError(interp), TCL_VOLATILE); } Tcl_FreeFile(ssPtr->theFile); ckfree((char *)ssPtr); return rc; } /* *---------------------------------------------------------------------- * * ExpectSetOption -- * * Set the value of an expect channel option * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpectSetOption(instanceData, interp, nameStr, valStr) ClientData instanceData; Tcl_Interp *interp; char *nameStr; /* (in) Name of option */ char *valStr; /* (in) New value of option */ { ExpectState *ssPtr = (ExpectState *) instanceData; int optVal, option; char errorStr[80]; int optBool; Tcl_AppendResult (interp, "Illegal option \"", nameStr, "\" -- must be a standard channel option", NULL); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * ExpectGetOption -- * * Queries expect channel for the current value of * the given option. * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpectGetOption(instanceData, nameStr, dsPtr) ClientData instanceData; char *nameStr; /* (in) Name of option to retrieve */ Tcl_DString *dsPtr; /* (in) String to place value */ { ExpectState *ssPtr = (ExpectState *) instanceData; return TCL_OK; } /* *---------------------------------------------------------------------- * * ExpectGetFile -- * * Get the Tcl_File for the appropriate direction in from the * Tcl_Channel. * * Results: * NULL because expect ids are handled through other channel * types. * * Side Effects * None. * *---------------------------------------------------------------------- */ Tcl_File ExpectGetFile(instanceData, direction) ClientData instanceData; int direction; { return (Tcl_File)NULL; } /* *---------------------------------------------------------------------- * * ExpectReady -- * * Determines whether expect port has data to be * read or is OK for writing. * * Results: * A bitmask of the events that were found by checking the * underlying channel. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpectReady(instanceData, direction) ClientData instanceData; int direction; { Tcl_Channel channelPtr = ((PlugFInfo *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->channelReadyProc) (Tcl_GetChannelInstanceData(channelPtr), mask); } /* *---------------------------------------------------------------------- * * ExpectWatch -- * * Sets up event handling on a expect port Tcl_Channel using * the underlying channel type. * * Results: * Nothing * * Side Effects * None. * *---------------------------------------------------------------------- */ void ExpectWatch(instanceData, mask) ClientData instanceData; int mask; { Tcl_Channel channelPtr = ((PlugFInfo *)instanceData)->channelPtr; (Tcl_GetChannelType(channelPtr)->watchChannelProc) (Tcl_GetChannelInstanceData(channelPtr), mask); return; } |
Added generic/expCommand.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 | /* ---------------------------------------------------------------------------- * expCommand.c -- * * The bulk of the Expect commands, platform generic. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expCommand.c,v 1.1.2.1.2.4 2002/02/10 12:04:22 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #include <math.h> /* Tcl needs commands in writable space (or at least used to) */ static char close_cmd[] = "close"; /* * exp_configure_count is incremented whenever a spawned process is closed * or an indirect list is modified. This forces any (stack of) expect or * interact commands to reexamine the state of the world and adjust * accordingly. */ int exp_configure_count = 0; /* this message is required because fopen sometimes fails to set errno */ /* Apparently, it "does the user a favor" and doesn't even call open */ /* if the file name is bizarre enough. This means we can't handle fopen */ /* with the obvious trivial logic. */ static char *open_failed = "could not open - odd file name?"; /* * expect_key is just a source for generating a unique stamp. As each * expect/interact command begins, it generates a new key and marks all * the spawn ids of interest with it. Then, if someone comes along and * marks them with yet a newer key, the old command will recognize this * reexamine the state of the spawned process. */ int expect_key = 0; /* * The table is used to map channels to exp_f structures. */ Tcl_HashTable *exp_f_table = NULL; /* * The 'exp_any' spawn identifier */ struct exp_f *exp_f_any = NULL; static void tcl_tracer _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *cmdProc, ClientData cmdClientData, int argc, char *argv[])); static void exp_i_add_f _ANSI_ARGS_((struct exp_i *, struct exp_f *fs)); static void exp_f_closed _ANSI_ARGS_((struct exp_f *)); /* *---------------------------------------------------------------------- * * exp_error -- * * Formats an error message into the interp. Do not terminate * format strings with \n!!!. * * Results: * None * * Side Effects: * An error message is written into interp->result * *---------------------------------------------------------------------- */ void exp_error TCL_VARARGS_DEF(Tcl_Interp *,arg1) { Tcl_Interp *interp; char *fmt; va_list args; interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args); fmt = va_arg(args,char *); vsprintf(interp->result,fmt,args); va_end(args); } /* *---------------------------------------------------------------------- * * exp_wait_zero -- * * Zero out the wait status field * * Results: * None * *---------------------------------------------------------------------- */ static void exp_wait_zero(status) WAIT_STATUS_TYPE *status; { int i; for (i=0;i<sizeof(WAIT_STATUS_TYPE);i++) { ((char *)status)[i] = 0; } } /* *---------------------------------------------------------------------- * * exp_fcheck -- * * Check and possibly adjust the status of the exp_f. * * Results: * 0 if not valid, 1 if good. * * Side Effects: * None * *---------------------------------------------------------------------- */ int exp_fcheck(interp,f,opened,adjust,msg) Tcl_Interp *interp; struct exp_f *f; int opened; /* check not closed */ int adjust; /* adjust buffer sizes */ CONST char *msg; { if ((!opened) || (!f->user_closed)) { if (adjust) { exp_adjust(f); } return 1; } exp_error(interp,"%s: invalid spawn id (%s)", msg, f->spawnId); return(0); } /* *---------------------------------------------------------------------- * * exp_chan2f -- * * For a given channel name, returns the exp_f structure * for that channel. * * Results: * An exp_f structure if found and usable, NULL if not. * * Side Effects: * None * *---------------------------------------------------------------------- */ struct exp_f * exp_chan2f(interp,chan,opened,adjust,msg) Tcl_Interp *interp; CONST char *chan; /* Channel name */ int opened; /* check not closed */ int adjust; /* adjust buffer sizes */ CONST char *msg; { Tcl_HashEntry *hPtr; struct exp_f *f; hPtr = Tcl_FindHashEntry(exp_f_table, chan); if (hPtr != NULL) { f = (struct exp_f *) Tcl_GetHashValue(hPtr); if ((!opened) || !f->user_closed) { if (adjust) { exp_adjust(f); } return f; } } exp_error(interp,"%s: invalid spawn id (%s)",msg,chan); return NULL; } /* *---------------------------------------------------------------------- * * exp_close -- * * Close a connection. * * Results: * None * * Side Effects: * A native file handle is closed * *---------------------------------------------------------------------- */ int exp_close(interp, f) Tcl_Interp *interp; struct exp_f *f; { /* * Check if this is an id that should never be deleted */ if (f->alwaysopen) { exp_error(interp, "cannot close permanent id %s", f->spawnId); return TCL_ERROR; } f->user_closed = TRUE; if (! f->leaveopen) { /* * Tcl_UnregisterChannel() will call Tcl_Close() if needed */ if (f->channel) { return Tcl_UnregisterChannel(interp, f->channel); } return TCL_OK; } else { if (--f->leaveopen >= 0) { return TCL_OK; } if (f->channel) { Tcl_DeleteCloseHandler(f->channel, (Tcl_CloseProc *) exp_f_closed, (ClientData) f); } exp_f_closed(f); } return(TCL_OK); } /* *---------------------------------------------------------------------- * * exp_f_find -- * * Try to find an existing exp_f structure in the spawn id table. * * Results: * The structure if found, NULL if not. * *---------------------------------------------------------------------- */ struct exp_f * exp_f_find(interp,spawnId) Tcl_Interp *interp; char *spawnId; { Tcl_HashEntry *hPtr; hPtr = Tcl_FindHashEntry(exp_f_table, spawnId); if (! hPtr) { return NULL; } return (struct exp_f *) Tcl_GetHashValue(hPtr); } /* *---------------------------------------------------------------------- * * exp_f_new -- * * Create a new exp_f structure for a given channel and enter * it into the spawn id hash table. If spawnId is given, it * is entered under that name. If not, it is entered under * the channel identifier. This means that either a channel * and/or a spawnId must be passed in. * * Results: * The new structure if successful, NULL if not. * *---------------------------------------------------------------------- */ struct exp_f * exp_f_new(interp,chan,spawnId,pid) Tcl_Interp *interp; Tcl_Channel chan; char *spawnId; int pid; { struct exp_f *f; Tcl_HashEntry *hPtr; int new; if (!chan && !spawnId) { return NULL; } spawnId = spawnId ? spawnId : Tcl_GetChannelName(chan); hPtr = Tcl_CreateHashEntry(exp_f_table, spawnId, &new); if (!new) { panic("Exp_SpawnCmd: old entry found in table"); f = (struct exp_f *) Tcl_GetHashValue(hPtr); return f; } f = (struct exp_f *) ckalloc(sizeof(struct exp_f)); f->interp = interp; f->pid = pid; f->size = 0; f->msize = 0; f->buffer = 0; f->printed = 0; f->echoed = 0; f->rm_nulls = exp_default_rm_nulls; f->parity = exp_default_parity; f->key = expect_key++; f->force_read = FALSE; f->fg_armed = FALSE; f->umsize = exp_default_match_max; f->valid = TRUE; f->user_closed = FALSE; f->user_waited = (EXP_NOPID == pid) ? TRUE : FALSE; f->sys_waited = (EXP_NOPID == pid) ? TRUE : FALSE; if (f->sys_waited) { exp_wait_zero(&f->wait); } f->bg_interp = 0; f->bg_status = unarmed; f->bg_ecount = 0; f->channel = chan; f->leaveopen = 0; f->alwaysopen = 0; f->matched = 0; /* Used only by expectlib */ f->Master = NULL; f->event_proc = NULL; f->event_data = 0; exp_f_new_platform(f); Tcl_SetHashValue(hPtr, f); f->hashPtr = hPtr; f->spawnId = ckalloc(strlen(spawnId) + 1); strcpy(f->spawnId, spawnId); if (chan) { Tcl_CreateCloseHandler(chan, (Tcl_CloseProc *) exp_f_closed, (ClientData) f); } return f; } /* *---------------------------------------------------------------------- * * exp_f_free -- * * Frees an exp_f structure. * * Results: * None * *---------------------------------------------------------------------- */ void exp_f_free(f) struct exp_f *f; { if (f->buffer) { ckfree(f->buffer); f->buffer = 0; f->msize = 0; f->size = 0; f->printed = 0; f->echoed = 0; if (f->fg_armed) { exp_event_disarm(f); f->fg_armed = FALSE; } ckfree(f->lower); } ckfree(f->spawnId); f->fg_armed = FALSE; Tcl_DeleteHashEntry(f->hashPtr); exp_f_free_platform(f); ckfree((char *) f); } /* *---------------------------------------------------------------------- * * exp_f_closed -- * * A channel was closed, so we need to make it unavailable * for anything except the wait command. * * Results: * None * *---------------------------------------------------------------------- */ static void exp_f_closed(f) struct exp_f *f; { exp_ecmd_remove_f_direct_and_indirect(f->interp,f); exp_configure_count++; f->fg_armed = FALSE; f->valid = FALSE; if (f->user_waited) { exp_f_free(f); } } /* *---------------------------------------------------------------------- * * Exp_ExpPidCmd -- * * Implements the "exp_pid" command * * Results: * A standard Tcl result * * Side Effects: * None * * Notes: * OS independent * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_ExpPidCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { struct exp_f *f; char *chanId = NULL; char *argv0 = argv[0]; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) goto usage; chanId = *argv; } else goto usage; } if (chanId == NULL) { f = exp_update_master(interp,0,0); } else { f = exp_chan2f(interp, chanId, 1, 0, argv0); } if (f == NULL) { return(TCL_ERROR); } sprintf(interp->result,"%d",f->pid); return TCL_OK; usage: exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Exp_GetpidDeprecatedCmd -- * * Implements the old 'getpid' command. This command is has * been deprecated and may not be supported in the future * * Results: * A standard Tcl result * * Side Effects: * None * * Notes: * OS independent * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_GetpidDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { exp_debuglog("getpid is deprecated, use pid\r\n"); sprintf(interp->result,"%d",exp_getpidproc()); return(TCL_OK); } /* *---------------------------------------------------------------------- * * exp_update_master -- * * Get the current master (via out-parameter) * * Results: * An exp_f structure or NULL if not found * * Note: Since exp_chan2f calls tcl_error, this may be * immediately followed by a "return(TCL_ERROR)"!!! * * Notes: * OS independent * *---------------------------------------------------------------------- */ struct exp_f * exp_update_master(interp,opened,adjust) Tcl_Interp *interp; int opened; int adjust; { CONST char *s = exp_get_var(interp,EXP_SPAWN_ID_VARNAME); if (s == NULL) { s = EXP_SPAWN_ID_USER; } return exp_chan2f(interp,s,opened,adjust,s); } /* *---------------------------------------------------------------------- * * Exp_SleepCmd -- * * Implements the 'sleep' (alias 'exp_sleep') command. * Can sleep for fractional seconds. * * Results: * A standard Tcl result * * Side Effects: * May not return immediately, and it may service other * events during the sleep period * * Notes: * OS independent * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_SleepCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { argc--; argv++; if (argc != 1) { exp_error(interp,"must have one arg: seconds"); return TCL_ERROR; } return(exp_dsleep(interp,(double)atof(*argv))); } struct slow_arg { int size; double time; }; /* *---------------------------------------------------------------------- * * get_slow_args -- * * Get the arguments the the 'send -s' command * * Results: * 0 on success, -1 on failure * * Side Effects: * The slow_arg structure is filled in * *---------------------------------------------------------------------- */ /* returns 0 for success, -1 for failure */ static int get_slow_args(interp,x) Tcl_Interp *interp; struct slow_arg *x; { int sc; /* return from scanf */ CONST char *s = exp_get_var(interp,"send_slow"); if (!s) { exp_error(interp,"send -s: send_slow has no value"); return(-1); } if (2 != (sc = sscanf(s,"%d %lf",&x->size,&x->time))) { exp_error(interp,"send -s: found %d value(s) in send_slow but need 2",sc); return(-1); } if (x->size <= 0) { exp_error(interp,"send -s: size (%d) in send_slow must be positive", x->size); return(-1); } if (x->time <= 0) { exp_error(interp,"send -s: time (%f) in send_slow must be larger",x->time); return(-1); } return(0); } /* *---------------------------------------------------------------------- * * slow_write -- * * Write some bytes s l o w l y * * Results: * 0 on success, -1 on failure, positive for standard Tcl result * * Side Effects: * Data is written to an output object * * Notes: * OS independent * *---------------------------------------------------------------------- */ static int slow_write(interp,f,buffer,rembytes,arg) Tcl_Interp *interp; struct exp_f *f; char *buffer; int rembytes; struct slow_arg *arg; { int rc; while (rembytes > 0) { int len; len = (arg->size<rembytes?arg->size:rembytes); if (0 > exp_exact_write(f,buffer,len)) return(-1); rembytes -= arg->size; buffer += arg->size; /* skip sleep after last write */ if (rembytes > 0) { rc = exp_dsleep(interp,arg->time); if (rc>0) return rc; } } return(0); } struct human_arg { float alpha; /* average interarrival time in seconds */ float alpha_eow; /* as above but for eow transitions */ float c; /* shape */ float min, max; }; /* *---------------------------------------------------------------------- * * get_human_args -- * * Get the arguments the the 'send -h' command * * Results: * 0 on success, -1 on failure * * Side Effects: * The human_arg structure is filled in * * Notes: * OS independent * *---------------------------------------------------------------------- */ static int get_human_args(interp,x) Tcl_Interp *interp; struct human_arg *x; { int sc; /* return from scanf */ CONST char *s = exp_get_var(interp,"send_human"); if (!s) { exp_error(interp,"send -h: send_human has no value"); return(-1); } if (5 != (sc = sscanf(s,"%f %f %f %f %f", &x->alpha,&x->alpha_eow,&x->c,&x->min,&x->max))) { if (sc == EOF) sc = 0; /* make up for overloaded return */ exp_error(interp,"send -h: found %d value(s) in send_human but need 5",sc); return(-1); } if (x->alpha < 0 || x->alpha_eow < 0) { exp_error(interp,"send -h: average interarrival times (%f %f) must be non-negative in send_human", x->alpha,x->alpha_eow); return(-1); } if (x->c <= 0) { exp_error(interp,"send -h: variability (%f) in send_human must be positive",x->c); return(-1); } x->c = 1/x->c; if (x->min < 0) { exp_error(interp,"send -h: minimum (%f) in send_human must be non-negative",x->min); return(-1); } if (x->max < 0) { exp_error(interp,"send -h: maximum (%f) in send_human must be non-negative",x->max); return(-1); } if (x->max < x->min) { exp_error(interp,"send -h: maximum (%f) must be >= minimum (%f) in send_human",x->max,x->min); return(-1); } return(0); } /* *---------------------------------------------------------------------- * * unit_random -- * * Compute random numbers from 0 to 1, for expect's send -h * This implementation sacrifices beauty for portability. * Current implementation is pathetic but works * * Results: * A floating point number between 0 and 1 * * Side Effects: * None * * Notes: * OS independent * *---------------------------------------------------------------------- */ static float unit_random() { /* 99991 is largest prime in my CRC - can't hurt, eh? */ return((float)(1+(rand()%99991))/(float) 99991.0); } /* *---------------------------------------------------------------------- * * exp_init_unit_random -- * * Initialize the random number generator * * Results: * None * * Side Effects: * None * * Notes: * OS independent * *---------------------------------------------------------------------- */ void exp_init_unit_random() { srand(exp_getpidproc()); } /* *---------------------------------------------------------------------- * * exp_init_unit_random -- * * This function is my implementation of the Weibull distribution. * I've added a max time and an "alpha_eow" that captures the slight * but noticable change in human typists when hitting end-of-word * transitions. * * Results: * 0 for success, -1 for failure, positive for standard Tcl result * * Side Effects: * None * *---------------------------------------------------------------------- */ static int human_write(interp,f,buffer,arg) Tcl_Interp *interp; struct exp_f *f; char *buffer; struct human_arg *arg; { char *sp; float t; float alpha; int in_word = TRUE; int wc; exp_debuglog("human_write: avg_arr=%f/%f 1/shape=%f min=%f max=%f\r\n", arg->alpha,arg->alpha_eow,arg->c,arg->min,arg->max); for (sp = buffer;*sp;sp++) { /* use the end-of-word alpha at eow transitions */ if (in_word && (ispunct(*sp) || isspace(*sp))) alpha = arg->alpha_eow; else alpha = arg->alpha; in_word = !(ispunct(*sp) || isspace(*sp)); t = alpha * (float) pow(-log((double)unit_random()),arg->c); /* enforce min and max times */ if (t<arg->min) t = arg->min; else if (t>arg->max) t = arg->max; /*fprintf(stderr,"\nwriting <%c> but first sleep %f seconds\n",*sp,t);*/ /* skip sleep before writing first character */ if (sp != buffer) { wc = exp_dsleep(interp,(double)t); if (wc > 0) return wc; } wc = exp_exact_write(f, sp, 1); if (wc == -1) { return -1; } } return(0); } struct exp_i *exp_i_pool = 0; struct exp_fs_list *exp_fs_list_pool = 0; #define EXP_I_INIT_COUNT 10 #define EXP_FS_INIT_COUNT 10 struct exp_i * exp_new_i() { int n; struct exp_i *i; if (!exp_i_pool) { /* none avail, generate some new ones */ exp_i_pool = i = (struct exp_i *)ckalloc( EXP_I_INIT_COUNT * sizeof(struct exp_i)); for (n=0;n<EXP_I_INIT_COUNT-1;n++,i++) { i->next = i+1; } i->next = 0; } /* now that we've made some, unlink one and give to user */ i = exp_i_pool; exp_i_pool = exp_i_pool->next; i->value = 0; i->variable = 0; i->fs_list = 0; i->ecount = 0; i->next = 0; return i; } /* *---------------------------------------------------------------------- * * exp_new_fs -- * * Get a new exp_f structure. * * Results: * A structure pointer if successful. * * Side Effects: * Removes one from the pool if there are any in the pool. * If none are in pool, more are allocated for the pool. * *---------------------------------------------------------------------- */ struct exp_fs_list * exp_new_fs(f) struct exp_f *f; { int n; struct exp_fs_list *fs; if (!exp_fs_list_pool) { exp_fs_list_pool = fs = (struct exp_fs_list *) ckalloc(EXP_FS_INIT_COUNT * sizeof(struct exp_fs_list)); for (n=0;n<EXP_FS_INIT_COUNT-1;n++,fs++) { fs->next = fs+1; } fs->next = 0; } fs = exp_fs_list_pool; exp_fs_list_pool = exp_fs_list_pool->next; fs->f = f; return fs; } /* *---------------------------------------------------------------------- * * exp_free_fs -- * * Add an exp_f structure list to the free pool. * * Results: * None * *---------------------------------------------------------------------- */ void exp_free_fs(fs_first) struct exp_fs_list *fs_first; { struct exp_fs_list *fs, *penultimate; if (!fs_first) return; /* * link entire chain back in at once by first finding last pointer * making that point back to pool, and then resetting pool to this */ /* run to end */ for (fs = fs_first;fs;fs=fs->next) { penultimate = fs; } penultimate->next = exp_fs_list_pool; exp_fs_list_pool = fs_first; } /* *---------------------------------------------------------------------- * * exp_free_fs_single -- * * Remove an exp_f structure from the list and put it back * in the free pool * * Results: * None * *---------------------------------------------------------------------- */ void exp_free_fs_single(fs) struct exp_fs_list *fs; { fs->next = exp_fs_list_pool; exp_fs_list_pool = fs; } void exp_free_i(interp,i,updateproc) Tcl_Interp *interp; struct exp_i *i; Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */ { if (i->next) exp_free_i(interp,i->next,updateproc); exp_free_fs(i->fs_list); if (i->direct == EXP_INDIRECT) { Tcl_UntraceVar(interp,i->variable, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES, updateproc,(ClientData)i); } /* * here's the long form * if duration & direct free(var) free(val) * PERM DIR 1 * PERM INDIR 1 1 * TMP DIR * TMP INDIR 1 * Also if i->variable was a bogus variable name, i->value might not be * set, so test i->value to protect this * TMP in this case does NOT mean from the "expect" command. Rather * it means "an implicit spawn id from any expect or expect_XXX * command". In other words, there was no variable name provided. */ if (i->value && (((i->direct == EXP_DIRECT) && (i->duration == EXP_PERMANENT)) || ((i->direct == EXP_INDIRECT) && (i->duration == EXP_TEMPORARY)))) { ckfree(i->value); } else if (i->duration == EXP_PERMANENT) { if (i->value) ckfree(i->value); if (i->variable) ckfree(i->variable); } i->next = exp_i_pool; exp_i_pool = i; } /* *---------------------------------------------------------------------- * * exp_new_i_complex -- * * Generate a descriptor for a "-i" flag. This tries to * be backward compatible, but it can't be perfect. If * a channel exists, it assumes that the channel is what * was intended. If it doesn't, it checks the identifier * as a variable. If the variable exists, the it uses * the variable name as an indirect pointer to the channel * to use. If the variable doesn't exist, it falls back * to assuming the identifier is a channel identifier. * * Results: * A new descriptor structure. Cannot fail currently. * * Side Effects: * Memory is allocated and a Tcl variable trace may be setup * *---------------------------------------------------------------------- */ struct exp_i * exp_new_i_complex(interp,arg,duration,updateproc,msg) Tcl_Interp *interp; char *arg; /* spawn id list or a variable containing a list */ int duration; /* if we have to copy the args */ /* should only need do this in expect_before/after */ Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */ CONST char *msg;/* Error message identifier */ { struct exp_i *i; char **stringp; Tcl_DString dString; if (!exp_chan2f(interp, arg, 1, 0, msg)) { Tcl_DStringInit(&dString); Tcl_DStringGetResult(interp, &dString); if (Tcl_GetVar(interp, arg, 0)) { Tcl_DStringFree(&dString); i = exp_new_i(); i->direct = EXP_INDIRECT; stringp = &i->variable; } else { Tcl_DStringResult(interp, &dString); Tcl_DStringFree(&dString); return NULL; } } else { i = exp_new_i(); i->direct = EXP_DIRECT; stringp = &i->value; } i->duration = duration; if (duration == EXP_PERMANENT) { *stringp = ckalloc(strlen(arg)+1); strcpy(*stringp,arg); } else { *stringp = arg; } i->fs_list = 0; exp_i_update(interp,i); /* if indirect, ask Tcl to tell us when variable is modified */ if (i->direct == EXP_INDIRECT) { Tcl_TraceVar(interp, i->variable, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES, updateproc, (ClientData) i); } return i; } /* *---------------------------------------------------------------------- * * exp_i_add_f -- * * Add to a list of descriptors * * Results: * None * * Side Effects: * A list grows * *---------------------------------------------------------------------- */ static void exp_i_add_f(i,f) struct exp_i *i; struct exp_f *f; { struct exp_fs_list *new_fs; new_fs = exp_new_fs(f); new_fs->next = i->fs_list; i->fs_list = new_fs; } /* *---------------------------------------------------------------------- * * exp_i_parse_channels * * Parses a string containing a list of channel identifiers and * adds the resulting exp_f structures to a list. * * Results: * None * * Side Effects: * A list grows * *---------------------------------------------------------------------- */ void exp_i_parse_channels(interp, i) Tcl_Interp *interp; struct exp_i *i; { char *p = i->value; char *b; char s; struct exp_f *f; while (1) { while (isspace(*p)) { p++; } if (*p == 0) break; b = p; while (*p && !isspace(*p)) { p++; } s = *p; *p = 0; f = exp_chan2f(interp, b, 1, 0, ""); if (f) { exp_i_add_f(i,f); } *p = s; } } /* *---------------------------------------------------------------------- * * exp_i_update -- * * updates a single exp_i struct * * Results: * None * *---------------------------------------------------------------------- */ void exp_i_update(interp,i) Tcl_Interp *interp; struct exp_i *i; { CONST char *p; /* string representation of list of spawn ids*/ if (i->direct == EXP_INDIRECT) { p = Tcl_GetVar(interp,i->variable,TCL_GLOBAL_ONLY); if (!p) { p = ""; exp_debuglog("warning: indirect variable %s undefined",i->variable); } if (i->value) { if (streq(p,i->value)) return; /* replace new value with old */ ckfree(i->value); } i->value = ckalloc(strlen(p)+1); strcpy(i->value,p); exp_free_fs(i->fs_list); i->fs_list = 0; } else { /* no free, because this should only be called on */ /* "direct" i's once */ i->fs_list = 0; } exp_i_parse_channels(interp, i); } /* *---------------------------------------------------------------------- * * exp_new_i_simple -- * * Not quite sure what this does (GCC) * * Results: * An exp_i structure * *---------------------------------------------------------------------- */ struct exp_i * exp_new_i_simple(f,duration) struct exp_f *f; int duration; /* if we have to copy the args */ /* should only need do this in expect_before/after */ { struct exp_i *i; i = exp_new_i(); i->direct = EXP_DIRECT; i->duration = duration; exp_i_add_f(i,f); return i; } /* *---------------------------------------------------------------------- * * exp_exact_write -- * * Write exactly this many bytes, i.e. retry partial writes. * * Results: * 0 on success, -1 on failure * * Side Effects: * Data is written to an output object * *---------------------------------------------------------------------- */ int exp_exact_write(f,buffer,rembytes) struct exp_f *f; char *buffer; int rembytes; { int n; while (rembytes) { n = Tcl_Write(f->channel, buffer, rembytes); if (-1 == n) { return -1; } if (0 == n) { Tcl_Sleep(1000); exp_debuglog("write() failed to write anything but returned - sleeping and retrying...\n"); } buffer += n; rembytes -= n; } return(0); } /* *---------------------------------------------------------------------- * * ExpSpawnOpen -- * * Handle the 'spawn -open' command. Called from Exp_SpawnCmd. * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ int ExpSpawnOpen(interp, chanId, leaveopen) Tcl_Interp *interp; char *chanId; int leaveopen; { Tcl_Channel chan; int mode; struct exp_f *f; if (!(chan = Tcl_GetChannel(interp, chanId, &mode))) { return TCL_ERROR; } if (!mode) { exp_error(interp,"%s: channel is neither readable nor writable", chanId); return TCL_ERROR; } f = exp_f_find(interp, chanId); if (! f) { f = exp_f_new(interp, chan, NULL, EXP_NOPID); f->leaveopen = leaveopen; exp_wait_zero(&f->wait); } else { /* * Reference count this thing */ f->leaveopen += leaveopen; } /* tell user id of new process */ Tcl_SetVar(interp,EXP_SPAWN_ID_VARNAME,chanId,0); sprintf(interp->result,"%d",EXP_NOPID); exp_debuglog("spawn: returns {%s}\r\n",interp->result); return TCL_OK; } /* *---------------------------------------------------------------------- * * Exp_SendLogCmd -- * * Implements the send_log command. * * Results: * A standard Tcl result * * Side Effects: * Messages are written to a log file * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_SendLogCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *string; int len; argv++; argc--; if (argc) { if (streq(*argv,"--")) { argc--; argv++; } } if (argc != 1) { exp_error(interp,"usage: send [args] string"); return TCL_ERROR; } string = *argv; len = strlen(string); if (exp_debugfile) Tcl_Write(exp_debugfile, string, len); if (exp_logfile) Tcl_Write(exp_logfile, string, len); return(TCL_OK); } /* *---------------------------------------------------------------------- * * Exp_SendCmd -- * * Sends data to a subprocess or over some channel * * Results: * Standard Tcl result * * Notes: * (Don) I've rewritten this to be unbuffered. I did this so you * could shove large files through "send". If you are concerned * about efficiency, you should quote all your send args to make * them one single argument. * * (GCC) This uses Tcl channels. By default, the channel * translation will be binary for channels created with * spawn <program>. The clientData argument, if non-NULL, * holds the name of the channel to use. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_SendCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int rc; /* final result of this procedure */ struct human_arg human_args; struct slow_arg slow_args; #define SEND_STYLE_STRING_MASK 0x07 /* mask to detect a real string arg */ #define SEND_STYLE_PLAIN 0x01 #define SEND_STYLE_HUMAN 0x02 #define SEND_STYLE_SLOW 0x04 #define SEND_STYLE_ZERO 0x10 #define SEND_STYLE_BREAK 0x20 int send_style = SEND_STYLE_PLAIN; int want_cooked = TRUE; char *string; /* string to send */ int len; /* length of string to send */ int zeros; /* count of how many ascii zeros to send */ char *i_masters = 0; struct exp_fs_list *fs; struct exp_i *i; char *arg; struct exp_f *f = NULL; char *argv0 = argv[0]; argv++; argc--; while (argc) { arg = *argv; if (arg[0] != '-') break; arg++; if (exp_flageq1('-',arg)) { /* "--" */ argc--; argv++; break; } else if (exp_flageq1('i',arg)) { /* "-i" */ argc--; argv++; if (argc==0) { exp_error(interp,"usage: %s -i spawn_id", argv0); return(TCL_ERROR); } i_masters = *argv; argc--; argv++; continue; } else if (exp_flageq1('h',arg)) { /* "-h" */ argc--; argv++; if (-1 == get_human_args(interp,&human_args)) return(TCL_ERROR); send_style = SEND_STYLE_HUMAN; continue; } else if (exp_flageq1('s',arg)) { /* "-s" */ argc--; argv++; if (-1 == get_slow_args(interp,&slow_args)) return(TCL_ERROR); send_style = SEND_STYLE_SLOW; continue; } else if (exp_flageq("null",arg,1) || exp_flageq1('0',arg)) { argc--; argv++; /* "-null" */ if (!*argv) zeros = 1; else { zeros = atoi(*argv); argc--; argv++; if (zeros < 1) return TCL_OK; } send_style = SEND_STYLE_ZERO; string = "<zero(s)>"; continue; } else if (exp_flageq("raw",arg,1)) { /* "-raw" */ argc--; argv++; want_cooked = FALSE; continue; } else if (exp_flageq("break",arg,1)) { /* "-break" */ argc--; argv++; send_style = SEND_STYLE_BREAK; string = "<break>"; continue; } else { exp_error(interp,"usage: unrecognized flag <-%.80s>",arg); return TCL_ERROR; } } if (send_style & SEND_STYLE_STRING_MASK) { if (argc != 1) { exp_error(interp,"usage: %s [args] string", argv0); return TCL_ERROR; } string = *argv; } len = strlen(string); if (clientData != NULL) { f = exp_chan2f(interp, (char *) clientData, 1, 0, argv0); } else if (!i_masters) { /* * we really do want to check if it is open * but since stdin could be closed, we have to first * get the fs and then convert it from 0 to 1 if necessary */ f = exp_update_master(interp,0,0); if (f == NULL) { return(TCL_ERROR); } } /* * if f != NULL, then it holds desired master, else i_masters does */ if (f) { i = exp_new_i_simple(f,EXP_TEMPORARY); } else { i = exp_new_i_complex(interp,i_masters,FALSE, (Tcl_VarTraceProc *)NULL,argv0); if (i == NULL) { return TCL_ERROR; } } if (clientData == NULL) { /* This seems to be the standard send call (send_to_proc) */ want_cooked = FALSE; exp_debuglog("send: sending \"%s\" to {",dprintify(string)); /* if closing brace doesn't appear, that's because an error */ /* was encountered before we could send it */ } else { if (exp_debugfile) { Tcl_Write(exp_debugfile, string, len); } /* send_to_user ? */ if (((strcmp((char *) clientData, "exp_user") == 0 || strcmp((char *) clientData, exp_dev_tty_id) == 0 || strcmp((char *) clientData, "exp_tty") == 0) && exp_logfile_all) || exp_logfile) { if (exp_logfile) { Tcl_Write(exp_logfile, string, len); } } } for (fs=i->fs_list;fs;fs=fs->next) { f = fs->f; if (clientData == NULL) { /* send_to_proc */ exp_debuglog(" %s ", f->spawnId); } /* check validity of each - i.e., are they open */ if (! exp_fcheck(interp, f, 1, 0, "send")) { rc = TCL_ERROR; goto finish; } if (want_cooked) string = exp_cook(string,&len); switch (send_style) { case SEND_STYLE_PLAIN: rc = exp_exact_write(f,string,len); break; case SEND_STYLE_SLOW: rc = slow_write(interp,f,string,len,&slow_args); break; case SEND_STYLE_HUMAN: rc = human_write(interp,f,string,&human_args); break; case SEND_STYLE_ZERO: for (;zeros>0;zeros--) rc = exp_exact_write(f, "", 1); /* catching error on last write is sufficient */ break; case SEND_STYLE_BREAK: exp_tty_break(interp,f); rc = 0; break; } if (rc != 0) { if (rc == -1) { exp_error(interp,"write(spawn_id=%s): %s", f->spawnId, Tcl_PosixError(interp)); rc = TCL_ERROR; } goto finish; } } if (clientData == NULL) { /* send_to_proc */ exp_debuglog("}\r\n"); } rc = TCL_OK; finish: exp_free_i(interp,i,(Tcl_VarTraceProc *)0); return rc; } /* *---------------------------------------------------------------------- * * Exp_LogFileCmd -- * * Implements the 'log_file' and 'exp_log_file' commands. * Opens a logfile. * * Results: * A standard Tcl result. * * Side Effects: * A file may be opened, or a currently open file may be * changed to unbuffered * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_LogFileCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static Tcl_DString dstring; static int first_time = TRUE; static int current_append; /* true if currently appending */ static char *openarg = 0; /* Tcl file identifier from -open */ static int leaveopen = FALSE; /* true if -leaveopen was used */ int old_logfile_all = exp_logfile_all; Tcl_Channel old_logfile = exp_logfile; char *old_openarg = openarg; int old_leaveopen = leaveopen; int aflag = FALSE; int append = TRUE; char *filename = 0; char *type; int usage_error_occurred = FALSE; openarg = 0; leaveopen = FALSE; if (first_time) { Tcl_DStringInit(&dstring); first_time = FALSE; } #define usage_error {usage_error_occurred = TRUE; goto error; } /* when this function returns, we guarantee that if logfile_all */ /* is TRUE, then logfile is non-zero */ argv++; argc--; for (;argc>0;argc--,argv++) { if (streq(*argv,"-open")) { if (!argv[1]) usage_error; openarg = ckalloc(strlen(argv[1])+1); strcpy(openarg,argv[1]); argc--; argv++; } else if (streq(*argv,"-leaveopen")) { if (!argv[1]) usage_error; openarg = ckalloc(strlen(argv[1])+1); strcpy(openarg,argv[1]); leaveopen = TRUE; argc--; argv++; } else if (streq(*argv,"-a")) { aflag = TRUE; } else if (streq(*argv,"-info")) { if (exp_logfile) { if (exp_logfile_all) strcat(interp->result,"-a "); if (!current_append) strcat(interp->result,"-noappend "); strcat(interp->result,Tcl_DStringValue(&dstring)); } return TCL_OK; } else if (streq(*argv,"-noappend")) { append = FALSE; } else break; } if (argc == 1) { filename = argv[0]; } else if (argc > 1) { /* too many arguments */ usage_error } if (openarg && filename) { usage_error } if (aflag && !(openarg || filename)) { usage_error } exp_logfile = 0; exp_logfile_all = aflag; current_append = append; type = (append?"a":"w"); if (filename) { exp_logfile = Tcl_OpenFileChannel(interp, filename, type, O_CREAT|S_IWRITE); if (exp_logfile == (Tcl_Channel) NULL) { exp_error(interp,"%s: %s",filename,Tcl_PosixError(interp)); goto error; } } else if (openarg) { int mode; Tcl_DStringTrunc(&dstring,0); if (!(exp_logfile = Tcl_GetChannel(interp,openarg,&mode))) { return TCL_ERROR; } if (!(mode & TCL_WRITABLE)) { exp_error(interp,"channel is not writable"); } if (leaveopen) { Tcl_DStringAppend(&dstring,"-leaveopen ",-1); } else { Tcl_DStringAppend(&dstring,"-open ",-1); } Tcl_DStringAppend(&dstring,openarg,-1); /* * It would be convenient now to tell Tcl to close its * file descriptor. Alas, if involved in a pipeline, Tcl * will be unable to complete a wait on the process. * So simply remember that we meant to close it. We will * do so later in our own close routine. */ } if (exp_logfile) { Tcl_SetChannelOption(interp, exp_logfile, "-buffering", "none"); } if (old_logfile) { if (!old_openarg || !old_leaveopen) { Tcl_Close(interp, old_logfile); } if (old_openarg) { ckfree(old_openarg); } } return TCL_OK; error: if (old_logfile) { exp_logfile = old_logfile; exp_logfile_all = old_logfile_all; } if (openarg) ckfree(openarg); openarg = old_openarg; leaveopen = old_leaveopen; if (usage_error_occurred) { exp_error(interp,"usage: log_file [-info] [-noappend] [[-a] file] [-[leave]open [open ...]]"); } return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Exp_LogUserCmd -- * * Implements the 'loguser' and 'exp_loguser' commands. * Can turn logging to stdout on or off, and returns the * previous logging status. * * Results: * A standard TCL result * * Side Effects: * Logging can be enabled or disabled. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_LogUserCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int old_loguser = exp_loguser; if (argc == 0 || (argc == 2 && streq(argv[1],"-info"))) { /* do nothing */ } else if (argc == 2) { if (0 == atoi(argv[1])) exp_loguser = FALSE; else exp_loguser = TRUE; } else { exp_error(interp, "usage: [-info|1|0]"); } Tcl_SetObjResult(interp, Tcl_NewIntObj(old_loguser)); return(TCL_OK); } #ifdef TCL_DEBUGGER /* *---------------------------------------------------------------------- * * Exp_DebugCmd -- * * Implements the 'debug' and 'exp_debug' commands * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_DebugCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int now = FALSE; /* soon if FALSE, now if TRUE */ int exp_tcl_debugger_was_available = exp_tcl_debugger_available; if (argc > 3) goto usage; if (argc == 1) { sprintf(interp->result,"%d",exp_tcl_debugger_available); return TCL_OK; } argv++; while (*argv) { if (streq(*argv,"-now")) { now = TRUE; argv++; } else break; } if (!*argv) { if (now) { Dbg_On(interp,1); exp_tcl_debugger_available = 1; } else { goto usage; } } else if (streq(*argv,"0")) { Dbg_Off(interp); exp_tcl_debugger_available = 0; } else { Dbg_On(interp,now); exp_tcl_debugger_available = 1; } sprintf(interp->result,"%d",exp_tcl_debugger_was_available); return(TCL_OK); usage: exp_error(interp,"usage: [[-now] 1|0]"); return TCL_ERROR; } #endif /* TCL_DEBUGGER */ /*ARGSUSED*/ static int Exp_ExpInternalCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static Tcl_DString dstring; static int first_time = TRUE; int fopened = FALSE; if (first_time) { Tcl_DStringInit(&dstring); first_time = FALSE; } if (argc > 1 && streq(argv[1],"-info")) { if (exp_debugfile) { sprintf(interp->result,"-f %s ", Tcl_DStringValue(&dstring)); } strcat(interp->result,((exp_is_debugging==0)?"0":"1")); return TCL_OK; } argv++; argc--; while (argc) { if (!streq(*argv,"-f")) break; argc--;argv++; if (argc < 1) goto usage; if (exp_debugfile) { Tcl_Close(interp, exp_debugfile); } exp_debugfile = Tcl_OpenFileChannel(interp, argv[0], "a", O_APPEND|S_IWRITE); if (exp_debugfile == (Tcl_Channel) NULL) { exp_error(interp,"%s: %s",argv[0],Tcl_PosixError(interp)); goto error; } Tcl_DStringAppend(&dstring,argv[0],-1); Tcl_SetChannelOption(interp, exp_debugfile, "-buffering", "none"); fopened = TRUE; argc--;argv++; } if (argc != 1) goto usage; /* if no -f given, close file */ if (fopened == FALSE && exp_debugfile) { Tcl_Close(interp, exp_debugfile); exp_debugfile = NULL; Tcl_DStringFree(&dstring); } exp_is_debugging = atoi(*argv); return(TCL_OK); usage: exp_error(interp,"usage: [-f file] expr"); error: Tcl_DStringFree(&dstring); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Exp_ExitCmd -- * * Called on exit to do cleanup. * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ char *exp_onexit_action = 0; /*ARGSUSED*/ static int Exp_ExitCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int value = 0; argv++; if (*argv) { if (exp_flageq(*argv,"-onexit",3)) { argv++; if (*argv) { int len = strlen(*argv); if (exp_onexit_action) ckfree(exp_onexit_action); exp_onexit_action = ckalloc(len + 1); strcpy(exp_onexit_action,*argv); } else if (exp_onexit_action) { Tcl_AppendResult(interp,exp_onexit_action,(char *)0); } return TCL_OK; } else if (exp_flageq(*argv,"-noexit",3)) { argv++; exp_exit_handlers((ClientData)interp); return TCL_OK; } } if (*argv) { if (Tcl_GetInt(interp, *argv, &value) != TCL_OK) { return TCL_ERROR; } } exp_exit(interp,value); /*NOTREACHED*/ return TCL_OK; } /* *---------------------------------------------------------------------- * * Exp_CloseCmd -- * * Currently closes a channel or sets up handlers for * when the channel closes. * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_CloseCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *close_onexec = NULL; int slave_flag = FALSE; char *argv0 = argv[0]; struct exp_f *f; #if 0 int slave; #endif char *chanId = NULL; int argc_orig = argc; char **argv_orig = argv; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } chanId = *argv; } else if (streq(*argv,"-slave")) { slave_flag = TRUE; } else if (streq(*argv,"-onexec")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -onexec channelId"); return(TCL_ERROR); } close_onexec = *argv; } else break; } if (argc) { /* doesn't look like our format, it must be a Tcl-style file */ /* handle. Lucky that formats are easily distinguishable. */ /* Historical note: we used "close" long before there was a */ /* Tcl builtin by the same name. */ /* So what! the global namespace belongs to the core. */ /*Tcl_Obj **objv; int i, result; Tcl_CmdInfo info; Tcl_ResetResult(interp); objv = (Tcl_Obj **) ckalloc((argc+1)*sizeof(Tcl_Obj *)); objv[0] = Tcl_NewStringObj("close", -1); for (i = 0; i < argc; i++) { objv[i+1] = Tcl_NewStringObj(argv[i], -1); } if (0 == Tcl_GetCommandInfo(interp,"close",&info)) { info.clientData = 0; } result = Tcl_CloseObjCmd(info.objClientData,interp,argc+1,objv); for (i = 0; i < argc+1; i++) { Tcl_DecrRefCount(objv[i]); } ckfree((char *) objv); return result;*/ Tcl_SetResult(interp, "Cannot close the channel as it isn't an expect channel.", TCL_STATIC); return TCL_ERROR; } if (chanId == NULL) { f = exp_update_master(interp, 1, 0); } else if (slave_flag) { f = exp_chan2f(interp, chanId, 1, 0, "-slave"); } else { f = exp_chan2f(interp, chanId, 1, 0, argv0); } if (f == NULL) { return TCL_ERROR; } if (slave_flag) { if (f->slave_fd) { #ifndef __WIN32__ /* XXX: This still needs some looking at */ close(f->slave_fd); f->slave_fd = EXP_NOFD; exp_slave_control(f,1); #endif return TCL_OK; } exp_error(interp,"no such slave"); return TCL_ERROR; } #ifdef XXX /* I'm not sure this is a good idea to support */ if (onexec_flag) { /* heck, don't even bother to check if fd is open or a real */ /* spawn id, nothing else depends on it */ fcntl(m,F_SETFD,close_onexec); return TCL_OK; } #endif return exp_close(interp, f); } /*ARGSUSED*/ static void tcl_tracer(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv) ClientData clientData; Tcl_Interp *interp; int level; char *command; Tcl_CmdProc *cmdProc; ClientData cmdClientData; int argc; char *argv[]; { int i; /* come out on stderr, by using errorlog */ exp_errorlog("%2d",level); for (i = 0;i<level;i++) exp_nferrorlog(" ",0/*ignored - satisfy lint*/); exp_errorlog("%s\r\n",command); } /*ARGSUSED*/ static int Exp_StraceCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static int trace_level = 0; static Tcl_Trace trace_handle; if (argc > 1 && streq(argv[1],"-info")) { sprintf(interp->result,"%d",trace_level); return TCL_OK; } if (argc != 2) { exp_error(interp,"usage: trace level"); return(TCL_ERROR); } /* tracing already in effect, undo it */ if (trace_level > 0) Tcl_DeleteTrace(interp,trace_handle); /* get and save new trace level */ trace_level = atoi(argv[1]); if (trace_level > 0) trace_handle = Tcl_CreateTrace(interp, trace_level,tcl_tracer,(ClientData)0); return(TCL_OK); } /* *---------------------------------------------------------------------- * * Exp_WaitCmd -- * * Implements the 'wait' and 'exp_wait' commands. When a process * has been spawned, the wait call must be made before it will * go away. * * Results: * A standard Tcl result * * Notes: * XXX: This might need to go into the platform specific file. * Need to make sure that we do the right thing when exp_open * has been called on an identifier. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_WaitCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int master_supplied = FALSE; struct exp_f *f; /* ditto */ Tcl_HashEntry *hPtr; Tcl_HashSearch search; struct forked_proc *fp = 0; /* handle to a pure forked proc */ #ifdef XXX struct exp_f ftmp; /* temporary memory for either f or fp */ #endif int nowait = FALSE; int nohang = FALSE; char *chanId = NULL; char *argv0 = argv[0]; Tcl_Pid result = 0; /* 0 means child was successfully waited on */ /* -1 means an error occurred */ /* -2 means no eligible children to wait on */ #define NO_CHILD ((Tcl_Pid) -2) argv++; argc--; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (argc==0) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } chanId = *argv; } else if (streq(*argv,"-nowait")) { nowait = TRUE; } else if (streq(*argv,"-nohang")) { nohang = TRUE; } } if (chanId == NULL) { f = exp_update_master(interp, 0, 0); } else { f = exp_chan2f(interp, chanId, 0, 0, argv0); } if (f == NULL) { return TCL_ERROR; } if (f != exp_f_any) { /* * Check if waited on already. Things opened by "open", set * with -nowait, or are special expect ids are marked sys_waited * already */ if (!f->sys_waited) { if (nowait) { /* * should probably generate an error * if SIGCHLD is trapped. */ /* * pass to Tcl, so it can do wait in background. */ Tcl_DetachPids(1,&f->tclPid); exp_wait_zero(&f->wait); f->sys_waited = 1; f->user_waited = 1; } else if (nohang) { exp_wait_zero(&f->wait); result = Tcl_WaitPid(f->tclPid,&f->wait,WNOHANG); } else { while (1) { if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(rc); } exp_wait_zero(&f->wait); result = Tcl_WaitPid(f->tclPid,&f->wait,0); if (result == f->tclPid) break; if (result == (Tcl_Pid) -1) { if (errno == EINTR) continue; else break; } } } } /* * Now have Tcl reap anything we just detached. * This also allows procs user has created with "exec &" * and and associated with an "exec &" process to be reaped. */ Tcl_ReapDetachedProcs(); exp_rearm_sigchld(interp); /* new */ } else { /* * Wait for any of our own spawned processes. We call waitpid * rather than wait to avoid running into someone else's processes. * Yes, according to Ousterhout this is the best way to do it. */ hPtr = Tcl_FirstHashEntry(exp_f_table, &search); while (hPtr) { f = (struct exp_f *) Tcl_GetHashValue(hPtr); if (!f->valid) continue; if (f->pid == EXP_NOPID) continue; if (f->pid == exp_getpid) continue; /* skip ourself */ if (f->user_waited) continue; /* one wait only! */ if (f->sys_waited) break; restart: exp_wait_zero(&f->wait); result = Tcl_WaitPid(f->tclPid,&f->wait,WNOHANG); if (result == f->tclPid) break; if (result == 0) continue; /* busy, try next */ if (result == (Tcl_Pid) -1) { if (errno == EINTR) goto restart; else break; } hPtr = Tcl_NextHashEntry(&search); } #ifdef XXX /* if it's not a spawned process, maybe its a forked process */ for (fp=forked_proc_base;fp;fp=fp->next) { if (fp->link_status == not_in_use) continue; restart2: result = waitpid(fp->pid,&fp->wait_status,WNOHANG); if (result == fp->pid) { m = -1; /* DOCUMENT THIS! */ break; } if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart2; else break; } } #endif /* XXX */ if (hPtr == NULL && fp == NULL) { result = NO_CHILD; /* no children */ Tcl_ReapDetachedProcs(); } exp_rearm_sigchld(interp); } #ifdef XXX /* sigh, wedge forked_proc into an exp_f structure so we don't * have to rewrite remaining code (too much) */ if (fp) { f = &ftmp; f->tclPid = fp->pid; f->wait = fp->wait_status; } #endif /* non-portable assumption that pid_t can be printed with %d */ if (result == (Tcl_Pid) -1) { sprintf(interp->result,"%d %s -1 %d POSIX %s %s", f->pid,f->spawnId,errno,Tcl_ErrnoId(),Tcl_ErrnoMsg(errno)); result = TCL_OK; f->sys_waited = TRUE; f->user_waited = TRUE; } else if (result == NO_CHILD) { interp->result = "no children"; return TCL_ERROR; } else { sprintf(interp->result,"%d %s 0 %d", f->pid,f->spawnId,WEXITSTATUS(f->wait)); if (WIFSIGNALED(f->wait)) { Tcl_AppendElement(interp,"CHILDKILLED"); Tcl_AppendElement(interp,Tcl_SignalId((int)(WTERMSIG(f->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WTERMSIG(f->wait)))); } else if (WIFSTOPPED(f->wait)) { Tcl_AppendElement(interp,"CHILDSUSP"); Tcl_AppendElement(interp,Tcl_SignalId((int) (WSTOPSIG(f->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WSTOPSIG(f->wait)))); } if (nohang && result == 0) { Tcl_AppendElement(interp,"NOEXIT"); } if (result > 0 && WIFEXITED(f->wait)) { f->sys_waited = TRUE; f->user_waited = TRUE; } } #ifdef XXX if (fp) { fp->link_status = not_in_use; return ((result == -1)?TCL_ERROR:TCL_OK); } #endif /* * if user has already called close, make sure fd really is closed * and forget about this entry entirely */ if (f->user_closed) { exp_f_free(f); } return ((result == (Tcl_Pid) -1)?TCL_ERROR:TCL_OK); } /*ARGSUSED*/ int Exp_InterpreterCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc != 1) { exp_error(interp,"no arguments allowed"); return(TCL_ERROR); } #ifdef __WIN32__ exp_error(interp, "not implemented on Windows NT"); return TCL_ERROR; #endif return(exp_interpreter(interp)); /* errors and ok, are caught by exp_interpreter() and discarded */ /* to return TCL_OK, type "return" */ } /* this command supercede's Tcl's builtin CONTINUE command */ /*ARGSUSED*/ int Exp_ExpContinueDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc == 1) return(TCL_CONTINUE); else if (argc == 2) { if (streq(argv[1],"-expect")) { exp_debuglog("continue -expect is deprecated, use exp_continue\r\n"); return(EXP_CONTINUE); } } exp_error(interp,"usage: continue [-expect]\n"); return(TCL_ERROR); } /* this command supercede's Tcl's builtin CONTINUE command */ /*ARGSUSED*/ int Exp_ExpContinueCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc == 1) { return EXP_CONTINUE; } else if ((argc == 2) && (streq(argv[1],"-continue_timer"))) { return EXP_CONTINUE_TIMER; } exp_error(interp,"usage: exp::continue [-continue_timer]\n"); return(TCL_ERROR); } /* most of this is directly from Tcl's definition for return */ /*ARGSUSED*/ /* Why is this here? int Exp_InterReturnCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { /* let Tcl's return command worry about args */ /* if successful (i.e., TCL_RETURN is returned) */ /* modify the result, so that we will handle it specially */ /* int result; #if TCL_MAJOR_VERSION >= 8 Tcl_Obj **objv; int i; objv = (Tcl_Obj **) ckalloc(argc*sizeof(Tcl_Obj *)); for (i = 0; i < argc; i++) { objv[i] = Tcl_NewStringObj(argv[i], -1); } result = Tcl_ReturnObjCmd(clientData,interp,argc,objv); for (i = 0; i < argc; i++) { Tcl_DecrRefCount(objv[i]); } ckfree((char *) objv); #else result = Tcl_ReturnCmd(clientData,interp,argc,argv); #endif if (result == TCL_RETURN) result = EXP_TCL_RETURN; return result; }*/ /* *---------------------------------------------------------------------- * * Exp_OpenCmd -- * * Implements the exp_open command. Makes a spawn id available * to Tcl. Since this happens by default, we don't have to do * anything in the -leaveopen case. In the normal case, we * need to clean up the spawn identifier and that is all. * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int Exp_OpenCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { struct exp_f *f; int leaveopen = FALSE; char *chanId = NULL; char *argv0 = argv[0]; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } chanId = *argv; } else if (streq(*argv,"-leaveopen")) { leaveopen = TRUE; argc--; argv++; } else break; } if (chanId == NULL) { f = exp_update_master(interp,0,0); } else { f = exp_chan2f(interp, chanId, 1, 0, argv0); } if (f == NULL) { return(TCL_ERROR); } if (f->channel == NULL) { exp_error(interp, "%s: %s is an internal spawn id that cannot be expected as a channel id", argv0, chanId); return TCL_ERROR; } if (! leaveopen) { /* * Don't do any reference count check on f->leaveopen. Just force * the spawn id closed */ if (f->channel) { Tcl_DeleteCloseHandler(f->channel, (Tcl_CloseProc *) exp_f_free, (ClientData) f); } exp_f_free(f); } Tcl_AppendResult(interp, Tcl_GetChannelName(f->channel), (char *) NULL); return TCL_OK; } /* return 1 if a string is substring of a flag */ /* this version is the code used by the macro that everyone calls */ int exp_flageq_code(flag,string,minlen) char *flag; char *string; int minlen; /* at least this many chars must match */ { for (;*flag;flag++,string++,minlen--) { if (*string == '\0') break; if (*string != *flag) return 0; } if (*string == '\0' && minlen <= 0) return 1; return 0; } void exp_create_commands(interp,c) Tcl_Interp *interp; struct exp_cmd_data *c; { Namespace *expNsPtr = (Namespace *) Tcl_FindNamespace(interp, "::exp", NULL, 0); //char cmdnamebuf[80]; for (;c->name;c++) { /* if already defined, don't redefine */ if (!expNsPtr || !(Tcl_FindHashEntry(&expNsPtr->cmdTable,c->name))) { //sprintf(cmdnamebuf, "::exp::%s",c->name); if (c->objproc) { Tcl_CreateObjCommand(interp,c->name,c->objproc,c->data,NULL); } else { Tcl_CreateCommand(interp,c->name,c->proc,c->data,NULL); } } } } static struct exp_cmd_data cmd_data[] = { {"exp_close", 0, Exp_CloseCmd, 0, 0}, #ifdef TCL_DEBUGGER {"debug", 0, Exp_DebugCmd, 0, 0}, #endif {"exp_internal", 0, Exp_ExpInternalCmd, 0, 0}, #ifdef XXX {"::exp::disconnect", 0, Exp_DisconnectCmd, 0, 0}, #endif {"exp_exit", 0, Exp_ExitCmd, 0, 0}, /*{"exp::_continue", 0, Exp_ExpContinueDeprecatedCmd,0,0},*/ {"exp_continue",0,Exp_ExpContinueCmd,0, 0}, #ifdef XXX {"::exp::fork", 0, Exp_ForkCmd, 0, 0}, #endif {"exp_pid", 0, Exp_ExpPidCmd, 0, 0}, {"exp_getpid", 0, Exp_GetpidDeprecatedCmd,0, 0}, {"exp_interpreter", 0, Exp_InterpreterCmd, 0, 0}, {"kill", 0, Exp_KillCmd, 0, 0}, {"log_file", 0, Exp_LogFileCmd, 0, 0}, {"log_user", 0, Exp_LogUserCmd, 0, 0}, {"exp_open", 0, Exp_OpenCmd, 0, 0}, #ifdef XXX {"overlay", 0, Exp_OverlayCmd, 0, 0}, #endif /*{"::exp::inter_return",0, Exp_InterReturnCmd, 0, 0}, why is this here?*/ {"send", 0, Exp_SendCmd, (ClientData)NULL, 0}, /*{"exp::send_spawn", 0, Exp_SendCmd, (ClientData)NULL, 0},deprecat*/ {"send_error", 0, Exp_SendCmd, (ClientData)"stderr", 0}, {"send_log", 0, Exp_SendLogCmd, 0, 0}, {"send_tty", 0, Exp_SendCmd, (ClientData)"exp_tty", 0}, {"send_user", 0, Exp_SendCmd, (ClientData)"exp_user", 0}, {"sleep", 0, Exp_SleepCmd, 0, 0}, {"spawn", 0, Exp_SpawnCmd, 0, 0}, {"strace", 0, Exp_StraceCmd, 0, 0}, {"wait", 0, Exp_WaitCmd, 0, 0}, {0} }; /* *---------------------------------------------------------------------- * * exp_init_most_cmds -- * * Initialize the large majority of commands that are used * in expect * * Results: * None * *---------------------------------------------------------------------- */ void exp_init_most_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); exp_close_in_child = exp_close_tcl_files; } void exp_init_spawn_id_vars(interp) Tcl_Interp *interp; { Tcl_SetVar(interp,"::exp::user_spawn_id",EXP_SPAWN_ID_USER,0); Tcl_SetVar(interp,"::exp::error_spawn_id",EXP_SPAWN_ID_ERROR,0); Tcl_SetVar(interp,"::exp::tty_spawn_id","exp_tty",0); } /* *---------------------------------------------------------------------- * * exp_init_spawn_ids -- * * Create the structures for the standard spawn ids. * * Results: * None * *---------------------------------------------------------------------- */ void exp_init_spawn_ids(interp) Tcl_Interp *interp; { Tcl_Channel chan, chanIn, chanOut; struct exp_f *f; exp_f_table = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(exp_f_table, TCL_STRING_KEYS); chan = ExpCreatePairChannel(interp, "stdin", "stdout", "exp_user"); f = exp_f_new(interp, chan, NULL, EXP_NOPID); Tcl_RegisterChannel(interp, chan); chan = Tcl_GetStdChannel(TCL_STDIN); f = exp_f_new(interp, chan, NULL, (isatty(0) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; if (strcmp(Tcl_GetChannelName(chan), "stdin") != 0) { f = exp_f_new(interp, chan, "stdin", (isatty(0) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; } chanIn = chan; chan = Tcl_GetStdChannel(TCL_STDOUT); if (chan != chanIn) { f = exp_f_new(interp, chan, NULL, (isatty(1) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; } if (strcmp(Tcl_GetChannelName(chan), "stdout") != 0) { f = exp_f_new(interp, chan, "stdout", (isatty(1) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; } chanOut = chan; chan = Tcl_GetStdChannel(TCL_STDERR); if ((chan != chanIn) && (chan != chanOut)) { f = exp_f_new(interp, chan, NULL, (isatty(2) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; } if (strcmp(Tcl_GetChannelName(chan), "stderr") != 0) { f = exp_f_new(interp, chan, "stderr", (isatty(2) ? exp_getpid : EXP_NOPID)); f->leaveopen = 1; } /* * Create the 'exp_any' spawn id that is meant to many any spawn ids. */ f = exp_f_new(interp, NULL, "exp_any", exp_getpid); f->alwaysopen = 1; exp_f_any = f; #ifdef XXX /* really should be in interpreter() but silly to do on every call */ exp_adjust(&exp_fs[0]); #endif } |
Added generic/expDecls.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 | /* ---------------------------------------------------------------------------- * expDecls.h -- * * Declarations of functions in the platform independent public * Expect API. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expDecls.h,v 1.1.4.2 2002/02/10 12:04:22 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPDECLS #define _EXPDECLS /* * WARNING: This file is automatically generated by the $(TCLROOT)/tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/exp.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 0 */ TCL_EXTERN(int) Expect_Init _ANSI_ARGS_((Tcl_Interp * interp)); /* Slot 1 is reserved */ /* Slot 2 is reserved */ /* 3 */ TCL_EXTERN(int) Exp_ExpInternalCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* Slot 4 is reserved */ /* 5 */ TCL_EXTERN(int) Exp_ExitCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 6 */ TCL_EXTERN(int) Exp_ExpContinueCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* Slot 7 is reserved */ /* 8 */ TCL_EXTERN(int) Exp_ExpPidCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 9 */ TCL_EXTERN(int) Exp_GetpidDeprecatedCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* Slot 10 is reserved */ /* 11 */ TCL_EXTERN(int) Exp_LogFileCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 12 */ TCL_EXTERN(int) Exp_LogUserCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 13 */ TCL_EXTERN(int) Exp_OpenCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* Slot 14 is reserved */ /* Slot 15 is reserved */ /* Slot 16 is reserved */ /* 17 */ TCL_EXTERN(int) Exp_SendLogCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 18 */ TCL_EXTERN(int) Exp_SleepCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 19 */ TCL_EXTERN(int) Exp_SpawnCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 20 */ TCL_EXTERN(int) Exp_StraceCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 21 */ TCL_EXTERN(int) Exp_WaitCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 22 */ TCL_EXTERN(int) Exp_ExpVersionCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 23 */ TCL_EXTERN(int) Exp_Prompt1Cmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 24 */ TCL_EXTERN(int) Exp_Prompt2Cmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 25 */ TCL_EXTERN(int) Exp_TrapCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 26 */ TCL_EXTERN(int) Exp_SttyCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 27 */ TCL_EXTERN(int) Exp_SystemCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 28 */ TCL_EXTERN(int) Exp_ExpectCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 29 */ TCL_EXTERN(int) Exp_ExpectGlobalCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, Tcl_Obj *CONST objv[])); /* 30 */ TCL_EXTERN(int) Exp_MatchMaxCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 31 */ TCL_EXTERN(int) Exp_RemoveNullsCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 32 */ TCL_EXTERN(int) Exp_ParityCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 33 */ TCL_EXTERN(int) Exp_TimestampCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 34 */ TCL_EXTERN(int) Exp_CloseCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 35 */ TCL_EXTERN(int) Exp_InterpreterCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 36 */ TCL_EXTERN(int) Exp_SendCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 37 */ TCL_EXTERN(int) Exp_KillCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* Slot 38 is reserved */ /* Slot 39 is reserved */ /* 40 */ TCL_EXTERN(char *) exp_printify _ANSI_ARGS_((char * s)); /* Slot 41 is reserved */ /* Slot 42 is reserved */ /* Slot 43 is reserved */ /* Slot 44 is reserved */ /* Slot 45 is reserved */ /* Slot 46 is reserved */ /* Slot 47 is reserved */ /* Slot 48 is reserved */ /* Slot 49 is reserved */ /* 50 */ TCL_EXTERN(void) exp_errorlog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); /* 51 */ TCL_EXTERN(void) exp_log _ANSI_ARGS_(TCL_VARARGS(int,force_stdout)); /* 52 */ TCL_EXTERN(void) exp_debuglog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); /* 53 */ TCL_EXTERN(void) exp_nflog _ANSI_ARGS_((char * buf, int force_stdout)); /* 54 */ TCL_EXTERN(void) exp_nferrorlog _ANSI_ARGS_((char * buf, int force_stdout)); /* 55 */ TCL_EXTERN(void) exp_error _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* Slot 58 is reserved */ /* Slot 59 is reserved */ /* 60 */ TCL_EXTERN(void) exp_parse_argv _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 61 */ TCL_EXTERN(int) exp_interpreter _ANSI_ARGS_((Tcl_Interp * interp)); /* 62 */ TCL_EXTERN(int) exp_interpret_cmdfile _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel cmdfile)); /* 63 */ TCL_EXTERN(int) exp_interpret_cmdfilename _ANSI_ARGS_(( Tcl_Interp * interp, char * filename)); /* 64 */ TCL_EXTERN(void) exp_interpret_rcfiles _ANSI_ARGS_(( Tcl_Interp * interp, int my_rc, int sys_rc)); /* 65 */ TCL_EXTERN(char *) exp_cook _ANSI_ARGS_((CONST char * s, int * len)); /* Slot 66 is reserved */ /* 67 */ TCL_EXTERN(int) exp_getpidproc _ANSI_ARGS_((void)); /* 68 */ TCL_EXTERN(Tcl_Channel) ExpCreateSpawnChannel _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel chan)); /* 69 */ TCL_EXTERN(int) ExpPlatformSpawnOutput _ANSI_ARGS_(( ClientData instanceData, CONST char * bufPtr, int toWrite, int * errorPtr)); /* 70 */ TCL_EXTERN(void) exp_init_main_cmds _ANSI_ARGS_((Tcl_Interp * interp)); /* 71 */ TCL_EXTERN(void) exp_init_expect_cmds _ANSI_ARGS_(( Tcl_Interp * interp)); /* 72 */ TCL_EXTERN(void) exp_init_most_cmds _ANSI_ARGS_((Tcl_Interp * interp)); /* 73 */ TCL_EXTERN(void) exp_init_trap_cmds _ANSI_ARGS_((Tcl_Interp * interp)); /* 74 */ TCL_EXTERN(void) exp_init_interact_cmds _ANSI_ARGS_(( Tcl_Interp * interp)); /* 75 */ TCL_EXTERN(int) exp_init_tty_cmds _ANSI_ARGS_((Tcl_Interp * interp)); /* Slot 76 is reserved */ /* Slot 77 is reserved */ /* 78 */ TCL_EXTERN(Tcl_Channel) ExpCreatePairChannel _ANSI_ARGS_(( Tcl_Interp * interp, CONST char * chanInId, CONST char * chanOutId, CONST char * chanName)); /* 79 */ TCL_EXTERN(int) ExpSpawnOpen _ANSI_ARGS_((Tcl_Interp * interp, char * chanId, int leaveopen)); /* 80 */ TCL_EXTERN(struct exp_f *) exp_update_master _ANSI_ARGS_(( Tcl_Interp * interp, int opened, int adjust)); /* 81 */ TCL_EXTERN(CONST char *) exp_get_var _ANSI_ARGS_((Tcl_Interp * interp, char * var)); /* 82 */ TCL_EXTERN(void) exp_exit _ANSI_ARGS_((Tcl_Interp * interp, int status)); /* 83 */ TCL_EXTERN(int) exp_dsleep _ANSI_ARGS_((Tcl_Interp * interp, double sec)); /* 84 */ TCL_EXTERN(void) exp_init_event _ANSI_ARGS_((void)); /* Slot 85 is reserved */ /* 86 */ TCL_EXTERN(void) exp_background_filehandler _ANSI_ARGS_(( ClientData clientData, int mask)); /* 87 */ TCL_EXTERN(void) exp_exit_handlers _ANSI_ARGS_((ClientData clientData)); /* 88 */ TCL_EXTERN(void) exp_close_on_exec _ANSI_ARGS_((int fd)); /* 89 */ TCL_EXTERN(int) exp_flageq_code _ANSI_ARGS_((char * flag, char * string, int minlen)); /* 90 */ TCL_EXTERN(void) exp_close_tcl_files _ANSI_ARGS_((void)); /* 91 */ TCL_EXTERN(void) exp_lowmemcpy _ANSI_ARGS_((char * dest, CONST char * src, int n)); /* 92 */ TCL_EXTERN(void) exp_timestamp _ANSI_ARGS_((Tcl_Interp * interp, time_t * timeval, char * array)); typedef struct ExpStubHooks { struct ExpPlatStubs *expPlatStubs; struct ExpIntStubs *expIntStubs; struct ExpIntPlatStubs *expIntPlatStubs; } ExpStubHooks; typedef struct ExpStubs { int magic; struct ExpStubHooks *hooks; int (*expect_Init) _ANSI_ARGS_((Tcl_Interp * interp)); /* 0 */ void *reserved1; void *reserved2; int (*exp_ExpInternalCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 3 */ void *reserved4; int (*exp_ExitCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 5 */ int (*exp_ExpContinueCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 6 */ void *reserved7; int (*exp_ExpPidCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 8 */ int (*exp_GetpidDeprecatedCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 9 */ void *reserved10; int (*exp_LogFileCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 11 */ int (*exp_LogUserCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 12 */ int (*exp_OpenCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 13 */ void *reserved14; void *reserved15; void *reserved16; int (*exp_SendLogCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 17 */ int (*exp_SleepCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 18 */ int (*exp_SpawnCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 19 */ int (*exp_StraceCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 20 */ int (*exp_WaitCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 21 */ int (*exp_ExpVersionCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 22 */ int (*exp_Prompt1Cmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 23 */ int (*exp_Prompt2Cmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 24 */ int (*exp_TrapCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 25 */ int (*exp_SttyCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 26 */ int (*exp_SystemCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 27 */ int (*exp_ExpectCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 28 */ int (*exp_ExpectGlobalCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, Tcl_Obj *CONST objv[])); /* 29 */ int (*exp_MatchMaxCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 30 */ int (*exp_RemoveNullsCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 31 */ int (*exp_ParityCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 32 */ int (*exp_TimestampCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 33 */ int (*exp_CloseCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 34 */ int (*exp_InterpreterCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 35 */ int (*exp_SendCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 36 */ int (*exp_KillCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 37 */ void *reserved38; void *reserved39; char * (*exp_printify) _ANSI_ARGS_((char * s)); /* 40 */ void *reserved41; void *reserved42; void *reserved43; void *reserved44; void *reserved45; void *reserved46; void *reserved47; void *reserved48; void *reserved49; void (*exp_errorlog) _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); /* 50 */ void (*exp_log) _ANSI_ARGS_(TCL_VARARGS(int,force_stdout)); /* 51 */ void (*exp_debuglog) _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); /* 52 */ void (*exp_nflog) _ANSI_ARGS_((char * buf, int force_stdout)); /* 53 */ void (*exp_nferrorlog) _ANSI_ARGS_((char * buf, int force_stdout)); /* 54 */ void (*exp_error) _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); /* 55 */ void *reserved56; void *reserved57; void *reserved58; void *reserved59; void (*exp_parse_argv) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 60 */ int (*exp_interpreter) _ANSI_ARGS_((Tcl_Interp * interp)); /* 61 */ int (*exp_interpret_cmdfile) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel cmdfile)); /* 62 */ int (*exp_interpret_cmdfilename) _ANSI_ARGS_((Tcl_Interp * interp, char * filename)); /* 63 */ void (*exp_interpret_rcfiles) _ANSI_ARGS_((Tcl_Interp * interp, int my_rc, int sys_rc)); /* 64 */ char * (*exp_cook) _ANSI_ARGS_((CONST char * s, int * len)); /* 65 */ void *reserved66; int (*exp_getpidproc) _ANSI_ARGS_((void)); /* 67 */ Tcl_Channel (*expCreateSpawnChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 68 */ int (*expPlatformSpawnOutput) _ANSI_ARGS_((ClientData instanceData, CONST char * bufPtr, int toWrite, int * errorPtr)); /* 69 */ void (*exp_init_main_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 70 */ void (*exp_init_expect_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 71 */ void (*exp_init_most_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 72 */ void (*exp_init_trap_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 73 */ void (*exp_init_interact_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 74 */ int (*exp_init_tty_cmds) _ANSI_ARGS_((Tcl_Interp * interp)); /* 75 */ void *reserved76; void *reserved77; Tcl_Channel (*expCreatePairChannel) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * chanInId, CONST char * chanOutId, CONST char * chanName)); /* 78 */ int (*expSpawnOpen) _ANSI_ARGS_((Tcl_Interp * interp, char * chanId, int leaveopen)); /* 79 */ struct exp_f * (*exp_update_master) _ANSI_ARGS_((Tcl_Interp * interp, int opened, int adjust)); /* 80 */ CONST char * (*exp_get_var) _ANSI_ARGS_((Tcl_Interp * interp, char * var)); /* 81 */ void (*exp_exit) _ANSI_ARGS_((Tcl_Interp * interp, int status)); /* 82 */ int (*exp_dsleep) _ANSI_ARGS_((Tcl_Interp * interp, double sec)); /* 83 */ void (*exp_init_event) _ANSI_ARGS_((void)); /* 84 */ void *reserved85; void (*exp_background_filehandler) _ANSI_ARGS_((ClientData clientData, int mask)); /* 86 */ void (*exp_exit_handlers) _ANSI_ARGS_((ClientData clientData)); /* 87 */ void (*exp_close_on_exec) _ANSI_ARGS_((int fd)); /* 88 */ int (*exp_flageq_code) _ANSI_ARGS_((char * flag, char * string, int minlen)); /* 89 */ void (*exp_close_tcl_files) _ANSI_ARGS_((void)); /* 90 */ void (*exp_lowmemcpy) _ANSI_ARGS_((char * dest, CONST char * src, int n)); /* 91 */ void (*exp_timestamp) _ANSI_ARGS_((Tcl_Interp * interp, time_t * timeval, char * array)); /* 92 */ } ExpStubs; #ifdef __cplusplus extern "C" { #endif extern ExpStubs *expStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) /* * Inline function declarations: */ #ifndef Expect_Init #define Expect_Init \ (expStubsPtr->expect_Init) /* 0 */ #endif /* Slot 1 is reserved */ /* Slot 2 is reserved */ #ifndef Exp_ExpInternalCmd #define Exp_ExpInternalCmd \ (expStubsPtr->exp_ExpInternalCmd) /* 3 */ #endif /* Slot 4 is reserved */ #ifndef Exp_ExitCmd #define Exp_ExitCmd \ (expStubsPtr->exp_ExitCmd) /* 5 */ #endif #ifndef Exp_ExpContinueCmd #define Exp_ExpContinueCmd \ (expStubsPtr->exp_ExpContinueCmd) /* 6 */ #endif /* Slot 7 is reserved */ #ifndef Exp_ExpPidCmd #define Exp_ExpPidCmd \ (expStubsPtr->exp_ExpPidCmd) /* 8 */ #endif #ifndef Exp_GetpidDeprecatedCmd #define Exp_GetpidDeprecatedCmd \ (expStubsPtr->exp_GetpidDeprecatedCmd) /* 9 */ #endif /* Slot 10 is reserved */ #ifndef Exp_LogFileCmd #define Exp_LogFileCmd \ (expStubsPtr->exp_LogFileCmd) /* 11 */ #endif #ifndef Exp_LogUserCmd #define Exp_LogUserCmd \ (expStubsPtr->exp_LogUserCmd) /* 12 */ #endif #ifndef Exp_OpenCmd #define Exp_OpenCmd \ (expStubsPtr->exp_OpenCmd) /* 13 */ #endif /* Slot 14 is reserved */ /* Slot 15 is reserved */ /* Slot 16 is reserved */ #ifndef Exp_SendLogCmd #define Exp_SendLogCmd \ (expStubsPtr->exp_SendLogCmd) /* 17 */ #endif #ifndef Exp_SleepCmd #define Exp_SleepCmd \ (expStubsPtr->exp_SleepCmd) /* 18 */ #endif #ifndef Exp_SpawnCmd #define Exp_SpawnCmd \ (expStubsPtr->exp_SpawnCmd) /* 19 */ #endif #ifndef Exp_StraceCmd #define Exp_StraceCmd \ (expStubsPtr->exp_StraceCmd) /* 20 */ #endif #ifndef Exp_WaitCmd #define Exp_WaitCmd \ (expStubsPtr->exp_WaitCmd) /* 21 */ #endif #ifndef Exp_ExpVersionCmd #define Exp_ExpVersionCmd \ (expStubsPtr->exp_ExpVersionCmd) /* 22 */ #endif #ifndef Exp_Prompt1Cmd #define Exp_Prompt1Cmd \ (expStubsPtr->exp_Prompt1Cmd) /* 23 */ #endif #ifndef Exp_Prompt2Cmd #define Exp_Prompt2Cmd \ (expStubsPtr->exp_Prompt2Cmd) /* 24 */ #endif #ifndef Exp_TrapCmd #define Exp_TrapCmd \ (expStubsPtr->exp_TrapCmd) /* 25 */ #endif #ifndef Exp_SttyCmd #define Exp_SttyCmd \ (expStubsPtr->exp_SttyCmd) /* 26 */ #endif #ifndef Exp_SystemCmd #define Exp_SystemCmd \ (expStubsPtr->exp_SystemCmd) /* 27 */ #endif #ifndef Exp_ExpectCmd #define Exp_ExpectCmd \ (expStubsPtr->exp_ExpectCmd) /* 28 */ #endif #ifndef Exp_ExpectGlobalCmd #define Exp_ExpectGlobalCmd \ (expStubsPtr->exp_ExpectGlobalCmd) /* 29 */ #endif #ifndef Exp_MatchMaxCmd #define Exp_MatchMaxCmd \ (expStubsPtr->exp_MatchMaxCmd) /* 30 */ #endif #ifndef Exp_RemoveNullsCmd #define Exp_RemoveNullsCmd \ (expStubsPtr->exp_RemoveNullsCmd) /* 31 */ #endif #ifndef Exp_ParityCmd #define Exp_ParityCmd \ (expStubsPtr->exp_ParityCmd) /* 32 */ #endif #ifndef Exp_TimestampCmd #define Exp_TimestampCmd \ (expStubsPtr->exp_TimestampCmd) /* 33 */ #endif #ifndef Exp_CloseCmd #define Exp_CloseCmd \ (expStubsPtr->exp_CloseCmd) /* 34 */ #endif #ifndef Exp_InterpreterCmd #define Exp_InterpreterCmd \ (expStubsPtr->exp_InterpreterCmd) /* 35 */ #endif #ifndef Exp_SendCmd #define Exp_SendCmd \ (expStubsPtr->exp_SendCmd) /* 36 */ #endif #ifndef Exp_KillCmd #define Exp_KillCmd \ (expStubsPtr->exp_KillCmd) /* 37 */ #endif /* Slot 38 is reserved */ /* Slot 39 is reserved */ #ifndef exp_printify #define exp_printify \ (expStubsPtr->exp_printify) /* 40 */ #endif /* Slot 41 is reserved */ /* Slot 42 is reserved */ /* Slot 43 is reserved */ /* Slot 44 is reserved */ /* Slot 45 is reserved */ /* Slot 46 is reserved */ /* Slot 47 is reserved */ /* Slot 48 is reserved */ /* Slot 49 is reserved */ #ifndef exp_errorlog #define exp_errorlog \ (expStubsPtr->exp_errorlog) /* 50 */ #endif #ifndef exp_log #define exp_log \ (expStubsPtr->exp_log) /* 51 */ #endif #ifndef exp_debuglog #define exp_debuglog \ (expStubsPtr->exp_debuglog) /* 52 */ #endif #ifndef exp_nflog #define exp_nflog \ (expStubsPtr->exp_nflog) /* 53 */ #endif #ifndef exp_nferrorlog #define exp_nferrorlog \ (expStubsPtr->exp_nferrorlog) /* 54 */ #endif #ifndef exp_error #define exp_error \ (expStubsPtr->exp_error) /* 55 */ #endif /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* Slot 58 is reserved */ /* Slot 59 is reserved */ #ifndef exp_parse_argv #define exp_parse_argv \ (expStubsPtr->exp_parse_argv) /* 60 */ #endif #ifndef exp_interpreter #define exp_interpreter \ (expStubsPtr->exp_interpreter) /* 61 */ #endif #ifndef exp_interpret_cmdfile #define exp_interpret_cmdfile \ (expStubsPtr->exp_interpret_cmdfile) /* 62 */ #endif #ifndef exp_interpret_cmdfilename #define exp_interpret_cmdfilename \ (expStubsPtr->exp_interpret_cmdfilename) /* 63 */ #endif #ifndef exp_interpret_rcfiles #define exp_interpret_rcfiles \ (expStubsPtr->exp_interpret_rcfiles) /* 64 */ #endif #ifndef exp_cook #define exp_cook \ (expStubsPtr->exp_cook) /* 65 */ #endif /* Slot 66 is reserved */ #ifndef exp_getpidproc #define exp_getpidproc \ (expStubsPtr->exp_getpidproc) /* 67 */ #endif #ifndef ExpCreateSpawnChannel #define ExpCreateSpawnChannel \ (expStubsPtr->expCreateSpawnChannel) /* 68 */ #endif #ifndef ExpPlatformSpawnOutput #define ExpPlatformSpawnOutput \ (expStubsPtr->expPlatformSpawnOutput) /* 69 */ #endif #ifndef exp_init_main_cmds #define exp_init_main_cmds \ (expStubsPtr->exp_init_main_cmds) /* 70 */ #endif #ifndef exp_init_expect_cmds #define exp_init_expect_cmds \ (expStubsPtr->exp_init_expect_cmds) /* 71 */ #endif #ifndef exp_init_most_cmds #define exp_init_most_cmds \ (expStubsPtr->exp_init_most_cmds) /* 72 */ #endif #ifndef exp_init_trap_cmds #define exp_init_trap_cmds \ (expStubsPtr->exp_init_trap_cmds) /* 73 */ #endif #ifndef exp_init_interact_cmds #define exp_init_interact_cmds \ (expStubsPtr->exp_init_interact_cmds) /* 74 */ #endif #ifndef exp_init_tty_cmds #define exp_init_tty_cmds \ (expStubsPtr->exp_init_tty_cmds) /* 75 */ #endif /* Slot 76 is reserved */ /* Slot 77 is reserved */ #ifndef ExpCreatePairChannel #define ExpCreatePairChannel \ (expStubsPtr->expCreatePairChannel) /* 78 */ #endif #ifndef ExpSpawnOpen #define ExpSpawnOpen \ (expStubsPtr->expSpawnOpen) /* 79 */ #endif #ifndef exp_update_master #define exp_update_master \ (expStubsPtr->exp_update_master) /* 80 */ #endif #ifndef exp_get_var #define exp_get_var \ (expStubsPtr->exp_get_var) /* 81 */ #endif #ifndef exp_exit #define exp_exit \ (expStubsPtr->exp_exit) /* 82 */ #endif #ifndef exp_dsleep #define exp_dsleep \ (expStubsPtr->exp_dsleep) /* 83 */ #endif #ifndef exp_init_event #define exp_init_event \ (expStubsPtr->exp_init_event) /* 84 */ #endif /* Slot 85 is reserved */ #ifndef exp_background_filehandler #define exp_background_filehandler \ (expStubsPtr->exp_background_filehandler) /* 86 */ #endif #ifndef exp_exit_handlers #define exp_exit_handlers \ (expStubsPtr->exp_exit_handlers) /* 87 */ #endif #ifndef exp_close_on_exec #define exp_close_on_exec \ (expStubsPtr->exp_close_on_exec) /* 88 */ #endif #ifndef exp_flageq_code #define exp_flageq_code \ (expStubsPtr->exp_flageq_code) /* 89 */ #endif #ifndef exp_close_tcl_files #define exp_close_tcl_files \ (expStubsPtr->exp_close_tcl_files) /* 90 */ #endif #ifndef exp_lowmemcpy #define exp_lowmemcpy \ (expStubsPtr->exp_lowmemcpy) /* 91 */ #endif #ifndef exp_timestamp #define exp_timestamp \ (expStubsPtr->exp_timestamp) /* 92 */ #endif #endif /* defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _EXPDECLS */ |
Added generic/expInt.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | /* ---------------------------------------------------------------------------- * expInt.h -- * * Declarations of things used internally by Expect. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expInt.h,v 1.1.4.4 2002/02/13 02:39:41 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPINT #define _EXPINT #ifndef _EXP # include "exp.h" #endif #ifndef _TCLPORT # include "tclPort.h" #endif #undef TCL_STORAGE_CLASS #if defined(BUILD_slavedriver) # define TCL_STORAGE_CLASS #elif defined(BUILD_exp) # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_EXP_STUBS # define TCL_STORAGE_CLASS # else # define TCL_STORAGE_CLASS DLLIMPORT # endif #endif /* * This is a convenience macro used to initialize a thread local storage ptr. * Stolen from tclInt.h */ #ifndef TCL_TSD_INIT #define TCL_TSD_INIT(keyPtr) (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) #endif #define EXP_SPAWN_ID_VARNAME "spawn_id" #define EXP_SPAWN_OUT "spawn_out" #define EXP_SPAWN_ID_ANY_VARNAME "any_spawn_id" #define EXP_SPAWN_ID_ANY "exp_any" #define EXP_SPAWN_ID_ERROR "stderr" #define EXP_SPAWN_ID_USER "exp_user" #define EXP_NOPID 0 /* Used when there is no associated pid to */ /* wait for. For example: */ /* 1) When fd opened by someone else, e.g., */ /* Tcl's open */ /* 2) When entry not in use */ /* 3) To tell user pid of "spawn -open" */ /* 4) stdin, out, error */ #define EXP_NOFD -1 /* these are occasionally useful to distinguish between various expect */ /* commands and are also used as array indices into the per-fd eg[] arrays */ #define EXP_CMD_BEFORE 0 #define EXP_CMD_AFTER 1 #define EXP_CMD_BG 2 #define EXP_CMD_FG 3 #define streq(x,y) (0 == strcmp((x),(y))) #define dprintify(x) ((exp_is_debugging || exp_debugfile)?exp_printify(x):0) #define exp_flageq(flag,string,minlen) \ (((string)[0] == (flag)[0]) && (exp_flageq_code(((flag)+1),((string)+1),((minlen)-1)))) /* exp_flageq for single char flags */ #define exp_flageq1(flag,string) \ ((string[0] == flag) && (string[1] == '\0')) /* each process is associated with a 'struct exp_f'. An array of these */ /* ('exp_fs') keeps track of all processes. They are indexed by the true fd */ /* to the master side of the pty */ struct exp_f { char *spawnId; /* Spawn identifier name */ Tcl_HashEntry *hashPtr; /* The hash entry with this structure */ Tcl_Interp *interp; int pid; /* pid or EXP_NOPID if no pid */ Tcl_Pid tclPid; /* The pid that tcl wants */ char *buffer; /* input buffer */ char *lower; /* input buffer in lowercase */ int size; /* current size of data */ int msize; /* size of buffer (true size is one greater * for trailing null) */ int umsize; /* user view of size of buffer */ int rm_nulls; /* if nulls should be stripped before pat matching */ int valid; /* if any of the other fields should be believed */ int user_closed; /* if user has issued "close" command or close has */ /* occurred implicitly */ int user_waited; /* if user has issued "wait" command */ int sys_waited; /* if wait() (or variant) has been called */ WAIT_STATUS_TYPE wait; /* raw status from wait() */ int parity; /* strip parity if false */ int printed; /* # of characters written to stdout (if logging on) */ /* but not actually returned via a match yet */ int echoed; /* additional # of chars (beyond "printed" above) */ /* echoed back but not actually returned via a match */ /* yet. This supports interact -echo */ int key; /* unique id that identifies what command instance */ /* last touched this buffer */ int force_read; /* force read to occur (even if buffer already has */ /* data). This supports interact CAN_MATCH */ int fg_armed; /* If Tk_CreateFileHandler is active for responding */ /* to foreground events */ #ifdef __WIN32__ OVERLAPPED over; /* Overlapped result */ #endif Tcl_Channel channel;/* Tcl channel */ Tcl_Channel Master; /* corresponds to master fd */ /* * explicit fds aren't necessary now, but since the code is already * here from before Tcl required TclFile, we'll continue using * the old fds. If we ever port this code to a non-UNIX system, * we'll dump the fds totally. */ int slave_fd; /* slave fd if "spawn -pty" used */ #ifdef HAVE_PTYTRAP char *slave_name; /* Full name of slave, i.e., /dev/ttyp0 */ #endif int leaveopen; /* If we should not call Tcl's close when we close - * only relevant if Tcl does the original open. It * also serves as a ref count to how many times this * channel has been opened with spawn -leaveopen */ int alwaysopen; /* Set if this is identifier that should always exist */ Tcl_Interp *bg_interp; /* interp to process the bg cases */ int bg_ecount; /* number of background ecases */ enum { blocked, /* blocked because we are processing the */ /* file handler */ armed, /* normal state when bg handler in use */ unarmed, /* no bg handler in use */ disarm_req_while_blocked /* while blocked, a request */ /* was received to disarm it. Rather than */ /* processing the request immediately, defer */ /* it so that when we later try to unblock */ /* we will see at that time that it should */ /* instead be disarmed */ } bg_status; int matched; /* Chars matched. Used by expectlib */ Tcl_ChannelProc *event_proc; /* Currently installed channel handler */ ClientData event_data; /* Argument that was installed */ }; struct exp_fs_list { struct exp_f *f; struct exp_fs_list *next; }; /* describes a -i flag */ struct exp_i { int cmdtype; /* EXP_CMD_XXX. When an indirect update is */ /* triggered by Tcl, this helps tell us in what */ /* exp_i list to look in. */ int direct; /* if EXP_DIRECT, then the spawn ids have been given */ /* literally, else indirectly through a variable */ int duration; /* if EXP_PERMANENT, char ptrs here had to be */ /* malloc'd because Tcl command line went away - */ /* i.e., in expect_before/after */ char *variable; char *value; /* if type == direct, this is the string that the */ /* user originally supplied to the -i flag. It may */ /* lose relevance as the fd_list is manipulated */ /* over time. If type == direct, this is the */ /* cached value of variable use this to tell if it */ /* has changed or not, and ergo whether it's */ /* necessary to reparse. */ int ecount; /* # of ecases this is used by */ struct exp_fs_list *fs_list; struct exp_i *next; }; #define EXP_TEMPORARY 1 /* expect */ #define EXP_PERMANENT 2 /* expect_after, expect_before, expect_bg */ #define EXP_DIRECT 1 #define EXP_INDIRECT 2 /* * definitions for creating commands */ #define EXP_NOPREFIX 1 /* don't define with "exp_" prefix */ #define EXP_REDEFINE 2 /* stomp on old commands with same name */ #define exp_proc(cmdproc) 0, cmdproc #define exp_deleteProc ((Tcl_CmdDeleteProc *) NULL) #define exp_deleteProc ((Tcl_CmdDeleteProc *) NULL) struct exp_cmd_data { char *name; Tcl_ObjCmdProc *objproc; Tcl_CmdProc *proc; ClientData data; int flags; }; #define EXP_TEMPORARY 1 /* expect */ #define EXP_PERMANENT 2 /* expect_after, expect_before, expect_bg */ #define EXP_DIRECT 1 #define EXP_INDIRECT 2 typedef struct { Tcl_Channel channelPtr; int toWrite; } ExpSpawnState; /* * ---------------------------------------- * Global variables that are externalized. * ---------------------------------------- */ /* Table of struct exp_f */ TCL_EXTERN(Tcl_HashTable *) exp_f_table; TCL_EXTERN(char *) exp_onexit_action; TCL_EXTERN(Tcl_Channel) exp_debugfile; TCL_EXTERN(Tcl_Channel) exp_logfile; TCL_EXTERN(int) exp_logfile_all; TCL_EXTERN(int) exp_loguser; /* useful to know to avoid debug calls */ TCL_EXTERN(int) exp_is_debugging; TCL_EXTERN(struct exp_f *) exp_f_any; TCL_EXTERN(int) exp_default_match_max; TCL_EXTERN(int) exp_default_parity; TCL_EXTERN(int) exp_default_rm_nulls; TCL_EXTERN(struct exp_f *) exp_dev_tty; TCL_EXTERN(char *) exp_dev_tty_id; TCL_EXTERN(int) exp_stdin_is_tty; TCL_EXTERN(int) exp_stdout_is_tty; /* procedure to close files in child */ TCL_EXTERN(void) (*exp_close_in_child) _ANSI_ARGS_((void)); /* place to pass a string generated */ TCL_EXTERN(char *) exp_pty_error; /* pid of Expect itself */ TCL_EXTERN(int) exp_getpid; TCL_EXTERN(Tcl_Interp *) exp_interp; TCL_EXTERN(void) (*exp_event_exit) _ANSI_ARGS_((Tcl_Interp *interp)); /* # of times descriptors have been closed * or indirect lists have been changed */ TCL_EXTERN(int) exp_configure_count; /* TRUE if user has requested unrolling of * stack with no trace */ TCL_EXTERN(int) exp_nostack_dump; TCL_EXTERN(int) expect_key; /* protos not yet moved to the Stubs table */ //TCL_EXTERN(int) exp_fcheck _ANSI_ARGS_((Tcl_Interp *, struct exp_f *,int,int,char *)); //TCL_EXTERN(void) exp_buffer_shuffle _ANSI_ARGS_((Tcl_Interp *,struct exp_f *,int,char *,char *)); //TCL_EXTERN(int) exp_close_fd _ANSI_ARGS_((Tcl_Interp *,int)); //TCL_EXTERN(void) exp_close_all _ANSI_ARGS_((Tcl_Interp *)); //TCL_EXTERN(void) exp_trap_on _ANSI_ARGS_((int)); //TCL_EXTERN(int) exp_trap_off _ANSI_ARGS_((char *)); /*EXTERN(void) exp_init_expect _ANSI_ARGS_((Tcl_Interp *));*/ //TCL_EXTERN(int) exp_tcl2_returnvalue _ANSI_ARGS_((int)); //TCL_EXTERN(int) exp_2tcl_returnvalue _ANSI_ARGS_((int)); //TCL_EXTERN(int) exp_string_to_signal _ANSI_ARGS_((Tcl_Interp *,char *)); #include "expIntDecls.h" #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _EXPINT */ |
Added generic/expIntDecls.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | /* * expIntDecls.h -- * * Declarations of functions in the platform independent internal * Expect API. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expIntDecls.h,v 1.1.4.4 2002/02/10 13:40:47 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPINTDECLS #define _EXPINTDECLS /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the exp.decls script. */ /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* Slot 0 is reserved */ /* 1 */ TCL_EXTERN(int) Exp_StringMatch _ANSI_ARGS_((CONST char * string, CONST char * pattern, int * offset)); /* 2 */ TCL_EXTERN(int) Exp_StringMatch2 _ANSI_ARGS_((CONST char * string, CONST char * pattern)); /* Slot 3 is reserved */ /* 4 */ TCL_EXTERN(struct exp_i *) exp_new_i_complex _ANSI_ARGS_(( Tcl_Interp * interp, char * arg, int duration, Tcl_VarTraceProc * updateproc, CONST char * msg)); /* 5 */ TCL_EXTERN(struct exp_i *) exp_new_i_simple _ANSI_ARGS_((struct exp_f * fd, int duration)); /* 6 */ TCL_EXTERN(struct exp_fs_list *) exp_new_fs _ANSI_ARGS_((struct exp_f * f)); /* 7 */ TCL_EXTERN(void) exp_free_i _ANSI_ARGS_((Tcl_Interp * interp, struct exp_i * i, Tcl_VarTraceProc * updateproc)); /* 8 */ TCL_EXTERN(void) exp_free_fs _ANSI_ARGS_(( struct exp_fs_list * fs_first)); /* 9 */ TCL_EXTERN(void) exp_free_fs_single _ANSI_ARGS_(( struct exp_fs_list * fs)); /* 10 */ TCL_EXTERN(void) exp_i_update _ANSI_ARGS_((Tcl_Interp * interp, struct exp_i * i)); /* 11 */ TCL_EXTERN(void) exp_pty_exit _ANSI_ARGS_((void)); /* 12 */ TCL_EXTERN(void) exp_init_spawn_ids _ANSI_ARGS_((Tcl_Interp * interp)); /* 13 */ TCL_EXTERN(void) exp_init_pty _ANSI_ARGS_((Tcl_Interp * interp)); /* 14 */ TCL_EXTERN(void) exp_init_tty _ANSI_ARGS_((Tcl_Interp * interp)); /* 15 */ TCL_EXTERN(void) exp_init_stdio _ANSI_ARGS_((void)); /* 16 */ TCL_EXTERN(void) exp_init_sig _ANSI_ARGS_((void)); /* 17 */ TCL_EXTERN(void) exp_init_trap _ANSI_ARGS_((void)); /* 18 */ TCL_EXTERN(void) exp_init_unit_random _ANSI_ARGS_((void)); /* 19 */ TCL_EXTERN(void) exp_init_spawn_id_vars _ANSI_ARGS_(( Tcl_Interp * interp)); /* 20 */ TCL_EXTERN(void) exp_adjust _ANSI_ARGS_((struct exp_f * f)); /* 21 */ TCL_EXTERN(void) exp_ecmd_remove_f_direct_and_indirect _ANSI_ARGS_(( Tcl_Interp * interp, struct exp_f * f)); /* 22 */ TCL_EXTERN(void) exp_rearm_sigchld _ANSI_ARGS_((Tcl_Interp * interp)); /* 23 */ TCL_EXTERN(struct exp_f *) exp_chan2f _ANSI_ARGS_((Tcl_Interp * interp, CONST char * chan, int opened, int adjust, CONST char * msg)); /* 24 */ TCL_EXTERN(int) exp_fcheck _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f, int opened, int adjust, CONST char * msg)); /* 25 */ TCL_EXTERN(int) exp_close _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f)); /* 26 */ TCL_EXTERN(void) exp_strftime _ANSI_ARGS_((char * format, const struct tm * timeptr, Tcl_DString * dstring)); /* 27 */ TCL_EXTERN(void) exp_create_commands _ANSI_ARGS_((Tcl_Interp * interp, struct exp_cmd_data * c)); /* 28 */ TCL_EXTERN(void) exp_tty_break _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f)); /* 29 */ TCL_EXTERN(void) exp_event_disarm _ANSI_ARGS_((struct exp_f * f)); /* 30 */ TCL_EXTERN(void) exp_arm_background_filehandler _ANSI_ARGS_(( struct exp_f * f)); /* 31 */ TCL_EXTERN(void) exp_disarm_background_filehandler _ANSI_ARGS_(( struct exp_f * f)); /* 32 */ TCL_EXTERN(void) exp_disarm_background_filehandler_force _ANSI_ARGS_(( struct exp_f * f)); /* 33 */ TCL_EXTERN(void) exp_unblock_background_filehandler _ANSI_ARGS_(( struct exp_f * f)); /* 34 */ TCL_EXTERN(void) exp_block_background_filehandler _ANSI_ARGS_(( struct exp_f * f)); /* 35 */ TCL_EXTERN(int) exp_get_next_event _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f ** masters, int n, struct exp_f ** master_out, int timeout, int key)); /* 36 */ TCL_EXTERN(int) exp_get_next_event_info _ANSI_ARGS_(( Tcl_Interp * interp, struct exp_f * fd, int ready_mask)); /* 37 */ TCL_EXTERN(struct exp_f *) exp_f_find _ANSI_ARGS_((Tcl_Interp * interp, char * spawnId)); /* 38 */ TCL_EXTERN(struct exp_f *) exp_f_new _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, char * spawnId, int pid)); /* 39 */ TCL_EXTERN(int) exp_f_new_platform _ANSI_ARGS_((struct exp_f * f)); /* 40 */ TCL_EXTERN(void) exp_f_free _ANSI_ARGS_((struct exp_f * f)); /* 41 */ TCL_EXTERN(void) exp_f_free_platform _ANSI_ARGS_((struct exp_f * f)); /* 42 */ TCL_EXTERN(int) exp_exact_write _ANSI_ARGS_((struct exp_f * f, char * buffer, int rembytes)); typedef struct ExpIntStubs { int magic; struct ExpIntStubHooks *hooks; void *reserved0; int (*exp_StringMatch) _ANSI_ARGS_((CONST char * string, CONST char * pattern, int * offset)); /* 1 */ int (*exp_StringMatch2) _ANSI_ARGS_((CONST char * string, CONST char * pattern)); /* 2 */ void *reserved3; struct exp_i * (*exp_new_i_complex) _ANSI_ARGS_((Tcl_Interp * interp, char * arg, int duration, Tcl_VarTraceProc * updateproc, CONST char * msg)); /* 4 */ struct exp_i * (*exp_new_i_simple) _ANSI_ARGS_((struct exp_f * fd, int duration)); /* 5 */ struct exp_fs_list * (*exp_new_fs) _ANSI_ARGS_((struct exp_f * f)); /* 6 */ void (*exp_free_i) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_i * i, Tcl_VarTraceProc * updateproc)); /* 7 */ void (*exp_free_fs) _ANSI_ARGS_((struct exp_fs_list * fs_first)); /* 8 */ void (*exp_free_fs_single) _ANSI_ARGS_((struct exp_fs_list * fs)); /* 9 */ void (*exp_i_update) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_i * i)); /* 10 */ void (*exp_pty_exit) _ANSI_ARGS_((void)); /* 11 */ void (*exp_init_spawn_ids) _ANSI_ARGS_((Tcl_Interp * interp)); /* 12 */ void (*exp_init_pty) _ANSI_ARGS_((Tcl_Interp * interp)); /* 13 */ void (*exp_init_tty) _ANSI_ARGS_((Tcl_Interp * interp)); /* 14 */ void (*exp_init_stdio) _ANSI_ARGS_((void)); /* 15 */ void (*exp_init_sig) _ANSI_ARGS_((void)); /* 16 */ void (*exp_init_trap) _ANSI_ARGS_((void)); /* 17 */ void (*exp_init_unit_random) _ANSI_ARGS_((void)); /* 18 */ void (*exp_init_spawn_id_vars) _ANSI_ARGS_((Tcl_Interp * interp)); /* 19 */ void (*exp_adjust) _ANSI_ARGS_((struct exp_f * f)); /* 20 */ void (*exp_ecmd_remove_f_direct_and_indirect) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f)); /* 21 */ void (*exp_rearm_sigchld) _ANSI_ARGS_((Tcl_Interp * interp)); /* 22 */ struct exp_f * (*exp_chan2f) _ANSI_ARGS_((Tcl_Interp * interp, CONST char * chan, int opened, int adjust, CONST char * msg)); /* 23 */ int (*exp_fcheck) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f, int opened, int adjust, CONST char * msg)); /* 24 */ int (*exp_close) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f)); /* 25 */ void (*exp_strftime) _ANSI_ARGS_((char * format, const struct tm * timeptr, Tcl_DString * dstring)); /* 26 */ void (*exp_create_commands) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_cmd_data * c)); /* 27 */ void (*exp_tty_break) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * f)); /* 28 */ void (*exp_event_disarm) _ANSI_ARGS_((struct exp_f * f)); /* 29 */ void (*exp_arm_background_filehandler) _ANSI_ARGS_((struct exp_f * f)); /* 30 */ void (*exp_disarm_background_filehandler) _ANSI_ARGS_((struct exp_f * f)); /* 31 */ void (*exp_disarm_background_filehandler_force) _ANSI_ARGS_((struct exp_f * f)); /* 32 */ void (*exp_unblock_background_filehandler) _ANSI_ARGS_((struct exp_f * f)); /* 33 */ void (*exp_block_background_filehandler) _ANSI_ARGS_((struct exp_f * f)); /* 34 */ int (*exp_get_next_event) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f ** masters, int n, struct exp_f ** master_out, int timeout, int key)); /* 35 */ int (*exp_get_next_event_info) _ANSI_ARGS_((Tcl_Interp * interp, struct exp_f * fd, int ready_mask)); /* 36 */ struct exp_f * (*exp_f_find) _ANSI_ARGS_((Tcl_Interp * interp, char * spawnId)); /* 37 */ struct exp_f * (*exp_f_new) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan, char * spawnId, int pid)); /* 38 */ int (*exp_f_new_platform) _ANSI_ARGS_((struct exp_f * f)); /* 39 */ void (*exp_f_free) _ANSI_ARGS_((struct exp_f * f)); /* 40 */ void (*exp_f_free_platform) _ANSI_ARGS_((struct exp_f * f)); /* 41 */ int (*exp_exact_write) _ANSI_ARGS_((struct exp_f * f, char * buffer, int rembytes)); /* 42 */ } ExpIntStubs; #ifdef __cplusplus extern "C" { #endif extern ExpIntStubs *expIntStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) /* * Inline function declarations: */ /* Slot 0 is reserved */ #ifndef Exp_StringMatch #define Exp_StringMatch \ (expIntStubsPtr->exp_StringMatch) /* 1 */ #endif #ifndef Exp_StringMatch2 #define Exp_StringMatch2 \ (expIntStubsPtr->exp_StringMatch2) /* 2 */ #endif /* Slot 3 is reserved */ #ifndef exp_new_i_complex #define exp_new_i_complex \ (expIntStubsPtr->exp_new_i_complex) /* 4 */ #endif #ifndef exp_new_i_simple #define exp_new_i_simple \ (expIntStubsPtr->exp_new_i_simple) /* 5 */ #endif #ifndef exp_new_fs #define exp_new_fs \ (expIntStubsPtr->exp_new_fs) /* 6 */ #endif #ifndef exp_free_i #define exp_free_i \ (expIntStubsPtr->exp_free_i) /* 7 */ #endif #ifndef exp_free_fs #define exp_free_fs \ (expIntStubsPtr->exp_free_fs) /* 8 */ #endif #ifndef exp_free_fs_single #define exp_free_fs_single \ (expIntStubsPtr->exp_free_fs_single) /* 9 */ #endif #ifndef exp_i_update #define exp_i_update \ (expIntStubsPtr->exp_i_update) /* 10 */ #endif #ifndef exp_pty_exit #define exp_pty_exit \ (expIntStubsPtr->exp_pty_exit) /* 11 */ #endif #ifndef exp_init_spawn_ids #define exp_init_spawn_ids \ (expIntStubsPtr->exp_init_spawn_ids) /* 12 */ #endif #ifndef exp_init_pty #define exp_init_pty \ (expIntStubsPtr->exp_init_pty) /* 13 */ #endif #ifndef exp_init_tty #define exp_init_tty \ (expIntStubsPtr->exp_init_tty) /* 14 */ #endif #ifndef exp_init_stdio #define exp_init_stdio \ (expIntStubsPtr->exp_init_stdio) /* 15 */ #endif #ifndef exp_init_sig #define exp_init_sig \ (expIntStubsPtr->exp_init_sig) /* 16 */ #endif #ifndef exp_init_trap #define exp_init_trap \ (expIntStubsPtr->exp_init_trap) /* 17 */ #endif #ifndef exp_init_unit_random #define exp_init_unit_random \ (expIntStubsPtr->exp_init_unit_random) /* 18 */ #endif #ifndef exp_init_spawn_id_vars #define exp_init_spawn_id_vars \ (expIntStubsPtr->exp_init_spawn_id_vars) /* 19 */ #endif #ifndef exp_adjust #define exp_adjust \ (expIntStubsPtr->exp_adjust) /* 20 */ #endif #ifndef exp_ecmd_remove_f_direct_and_indirect #define exp_ecmd_remove_f_direct_and_indirect \ (expIntStubsPtr->exp_ecmd_remove_f_direct_and_indirect) /* 21 */ #endif #ifndef exp_rearm_sigchld #define exp_rearm_sigchld \ (expIntStubsPtr->exp_rearm_sigchld) /* 22 */ #endif #ifndef exp_chan2f #define exp_chan2f \ (expIntStubsPtr->exp_chan2f) /* 23 */ #endif #ifndef exp_fcheck #define exp_fcheck \ (expIntStubsPtr->exp_fcheck) /* 24 */ #endif #ifndef exp_close #define exp_close \ (expIntStubsPtr->exp_close) /* 25 */ #endif #ifndef exp_strftime #define exp_strftime \ (expIntStubsPtr->exp_strftime) /* 26 */ #endif #ifndef exp_create_commands #define exp_create_commands \ (expIntStubsPtr->exp_create_commands) /* 27 */ #endif #ifndef exp_tty_break #define exp_tty_break \ (expIntStubsPtr->exp_tty_break) /* 28 */ #endif #ifndef exp_event_disarm #define exp_event_disarm \ (expIntStubsPtr->exp_event_disarm) /* 29 */ #endif #ifndef exp_arm_background_filehandler #define exp_arm_background_filehandler \ (expIntStubsPtr->exp_arm_background_filehandler) /* 30 */ #endif #ifndef exp_disarm_background_filehandler #define exp_disarm_background_filehandler \ (expIntStubsPtr->exp_disarm_background_filehandler) /* 31 */ #endif #ifndef exp_disarm_background_filehandler_force #define exp_disarm_background_filehandler_force \ (expIntStubsPtr->exp_disarm_background_filehandler_force) /* 32 */ #endif #ifndef exp_unblock_background_filehandler #define exp_unblock_background_filehandler \ (expIntStubsPtr->exp_unblock_background_filehandler) /* 33 */ #endif #ifndef exp_block_background_filehandler #define exp_block_background_filehandler \ (expIntStubsPtr->exp_block_background_filehandler) /* 34 */ #endif #ifndef exp_get_next_event #define exp_get_next_event \ (expIntStubsPtr->exp_get_next_event) /* 35 */ #endif #ifndef exp_get_next_event_info #define exp_get_next_event_info \ (expIntStubsPtr->exp_get_next_event_info) /* 36 */ #endif #ifndef exp_f_find #define exp_f_find \ (expIntStubsPtr->exp_f_find) /* 37 */ #endif #ifndef exp_f_new #define exp_f_new \ (expIntStubsPtr->exp_f_new) /* 38 */ #endif #ifndef exp_f_new_platform #define exp_f_new_platform \ (expIntStubsPtr->exp_f_new_platform) /* 39 */ #endif #ifndef exp_f_free #define exp_f_free \ (expIntStubsPtr->exp_f_free) /* 40 */ #endif #ifndef exp_f_free_platform #define exp_f_free_platform \ (expIntStubsPtr->exp_f_free_platform) /* 41 */ #endif #ifndef exp_exact_write #define exp_exact_write \ (expIntStubsPtr->exp_exact_write) /* 42 */ #endif #endif /* defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _EXPINTDECLS */ |
Added generic/expIntPlatDecls.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | /* ---------------------------------------------------------------------------- * expPlatIntDecls.h -- * * Declarations of platform specific internal Expect APIs. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expIntPlatDecls.h,v 1.1.4.4 2002/03/07 02:49:36 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPPLATINTDECLS #define _EXPPLATINTDECLS /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ #ifdef __WIN32__ /* 0 */ TCL_EXTERN(DWORD) ExpWinApplicationType _ANSI_ARGS_(( const char * originalName, Tcl_DString * fullPath)); /* 1 */ TCL_EXTERN(DWORD) ExpWinCreateProcess _ANSI_ARGS_((int argc, char *const * argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, HANDLE * processPtr, PDWORD globalPidPtr)); /* 2 */ TCL_EXTERN(void) ExpWinSyslog _ANSI_ARGS_(TCL_VARARGS(DWORD,errId)); /* 3 */ TCL_EXTERN(char *) ExpSyslogGetSysMsg _ANSI_ARGS_((DWORD errId)); /* 4 */ TCL_EXTERN(Tcl_Pid) Exp_WaitPid _ANSI_ARGS_((Tcl_Pid pid, int * statPtr, int options)); /* 5 */ TCL_EXTERN(void) Exp_KillProcess _ANSI_ARGS_((Tcl_Pid pid)); /* 6 */ TCL_EXTERN(void) ExpWinInit _ANSI_ARGS_((void)); /* 7 */ TCL_EXTERN(void) BuildCommandLine _ANSI_ARGS_(( CONST char * executable, int argc, char *const * argv, Tcl_DString * linePtr)); #endif /* __WIN32__ */ typedef struct ExpIntPlatStubs { int magic; struct ExpIntPlatStubHooks *hooks; #ifdef __WIN32__ DWORD (*expWinApplicationType) _ANSI_ARGS_((const char * originalName, Tcl_DString * fullPath)); /* 0 */ DWORD (*expWinCreateProcess) _ANSI_ARGS_((int argc, char *const * argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, HANDLE * processPtr, PDWORD globalPidPtr)); /* 1 */ void (*expWinSyslog) _ANSI_ARGS_(TCL_VARARGS(DWORD,errId)); /* 2 */ char * (*expSyslogGetSysMsg) _ANSI_ARGS_((DWORD errId)); /* 3 */ Tcl_Pid (*exp_WaitPid) _ANSI_ARGS_((Tcl_Pid pid, int * statPtr, int options)); /* 4 */ void (*exp_KillProcess) _ANSI_ARGS_((Tcl_Pid pid)); /* 5 */ void (*expWinInit) _ANSI_ARGS_((void)); /* 6 */ void (*buildCommandLine) _ANSI_ARGS_((CONST char * executable, int argc, char *const * argv, Tcl_DString * linePtr)); /* 7 */ #endif /* __WIN32__ */ } ExpIntPlatStubs; #ifdef __cplusplus extern "C" { #endif extern ExpIntPlatStubs *expIntPlatStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) /* * Inline function declarations: */ #ifdef __WIN32__ #ifndef ExpWinApplicationType #define ExpWinApplicationType \ (expIntPlatStubsPtr->expWinApplicationType) /* 0 */ #endif #ifndef ExpWinCreateProcess #define ExpWinCreateProcess \ (expIntPlatStubsPtr->expWinCreateProcess) /* 1 */ #endif #ifndef ExpWinSyslog #define ExpWinSyslog \ (expIntPlatStubsPtr->expWinSyslog) /* 2 */ #endif #ifndef ExpSyslogGetSysMsg #define ExpSyslogGetSysMsg \ (expIntPlatStubsPtr->expSyslogGetSysMsg) /* 3 */ #endif #ifndef Exp_WaitPid #define Exp_WaitPid \ (expIntPlatStubsPtr->exp_WaitPid) /* 4 */ #endif #ifndef Exp_KillProcess #define Exp_KillProcess \ (expIntPlatStubsPtr->exp_KillProcess) /* 5 */ #endif #ifndef ExpWinInit #define ExpWinInit \ (expIntPlatStubsPtr->expWinInit) /* 6 */ #endif #ifndef BuildCommandLine #define BuildCommandLine \ (expIntPlatStubsPtr->buildCommandLine) /* 7 */ #endif #endif /* __WIN32__ */ #endif /* defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _EXPPLATINTDECLS */ |
Added generic/expPlatDecls.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /* ---------------------------------------------------------------------------- * expPlatDecls.h -- * * Declarations of platform specific Expect APIs. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expPlatDecls.h,v 1.1.4.1 2002/02/10 02:58:53 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPPLATDECLS #define _EXPPLATDECLS /* * Pull in the definition of TCHAR. Hopefully the compile flags * of the core are matching against your project build for these * public functions. BE AWARE. */ #ifdef __WIN32__ # ifndef _TCHAR_DEFINED # include <tchar.h> # ifndef _TCHAR_DEFINED /* Borland seems to forget to set this. */ typedef _TCHAR TCHAR; # define _TCHAR_DEFINED # endif # endif #endif /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ typedef struct ExpPlatStubs { int magic; struct ExpPlatStubHooks *hooks; } ExpPlatStubs; #ifdef __cplusplus extern "C" { #endif extern ExpPlatStubs *expPlatStubsPtr; #ifdef __cplusplus } #endif #if defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) /* * Inline function declarations: */ #endif /* defined(USE_EXP_STUBS) && !defined(USE_EXP_STUB_PROCS) */ /* !END!: Do not edit above this line. */ #endif /* _EXPPLATDECLS */ |
Added generic/expPort.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * expPort.h -- * * This header file handles porting issues that occur because * of differences between systems. It reads in platform specific * portability files. * * RCS: @(#) $Id: expPort.h,v 1.1.2.1 2001/10/28 01:02:39 davygrvy Exp $ */ #ifndef _EXPPORT_H__ #define _EXPPORT_H__ #define HAVE_MEMCPY #ifdef __WIN32__ # include "../win/expWinPort.h" #else # if defined(MAC_TCL) # include "../mac/expPort.h" # else # include "../unix/expUnixPort.h" # endif #endif #endif /* _EXPPORT_H__ */ |
Added generic/expSpawnChan.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | /* ---------------------------------------------------------------------------- * expWinChan.c -- * * Implements the exp_spawn channel id. This wraps a normal * file channel in another channel so we can close the file * channel normally but still have another id to wait on. * The file channel is not exposed in any interps. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" static Tcl_DriverCloseProc ExpSpawnClose; static Tcl_DriverInputProc ExpSpawnInput; static Tcl_DriverOutputProc ExpSpawnOutput; /*static Tcl_DriverSeekProc ExpSpawnSeek;*/ static Tcl_DriverSetOptionProc ExpSpawnSetOption; static Tcl_DriverGetOptionProc ExpSpawnGetOption; static Tcl_DriverWatchProc ExpSpawnWatch; static Tcl_DriverGetHandleProc ExpSpawnGetHandle; static Tcl_DriverBlockModeProc ExpSpawnBlock; /*static Tcl_DriverFlushProc ExpSpawnFlush;*/ /*static Tcl_DriverHandlerProc ExpSpawnHandler;*/ static Tcl_ChannelType ExpSpawnChannelType = { "exp_spawn", TCL_CHANNEL_VERSION_2, ExpSpawnClose, ExpSpawnInput, ExpSpawnOutput, NULL, /* no seek! */ ExpSpawnSetOption, ExpSpawnGetOption, ExpSpawnWatch, ExpSpawnGetHandle, NULL, /* no close2 */ ExpSpawnBlock, NULL, /* no flush */ NULL /* no handler */ }; /* *---------------------------------------------------------------------- * * ExpCreateSpawnChannel -- * * Create an expect spawn identifier * * Results: * A Tcl channel * * Side Effects: * Allocates and registers a channel * *---------------------------------------------------------------------- */ Tcl_Channel ExpCreateSpawnChannel(interp, chan) Tcl_Interp *interp; Tcl_Channel chan; { Tcl_Channel chan2; ExpSpawnState *ssPtr; ssPtr = (ExpSpawnState *) ckalloc(sizeof(ExpSpawnState)); ssPtr->channelPtr = chan; ssPtr->toWrite = 0; chan2 = Tcl_StackChannel(interp, &ExpSpawnChannelType, (ClientData) ssPtr, TCL_READABLE|TCL_WRITABLE, chan); /* * Setup the expect channel to always flush immediately */ Tcl_SetChannelOption(interp, chan2, "-buffering", "none"); Tcl_SetChannelOption(interp, chan2, "-blocking", "0"); Tcl_SetChannelOption(interp, chan2, "-translation","binary"); return chan2; } /* *---------------------------------------------------------------------- * * ExpSpawnClose -- * * Generic routine to close the expect spawn channel and child. * * Results: * 0 if successful or a POSIX errorcode with * interp updated. * * Side Effects: * Channel is deleted. * *---------------------------------------------------------------------- */ static int ExpSpawnClose(instanceData, interp) ClientData instanceData; Tcl_Interp *interp; { ckfree((char *)(ExpSpawnState *)instanceData); return TCL_OK; } /* *---------------------------------------------------------------------- * * ExpSpawnInput -- * * Generic read routine for expect console * * Returns: * Amount read or -1 with errorcode in errorPtr. * * Side Effects: * Buffer is updated. * *---------------------------------------------------------------------- */ static int ExpSpawnInput(instanceData, bufPtr, bufSize, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int bufSize; /* (in) sizeof buffer */ int *errorPtr; /* (out) error code */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->inputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, bufSize, errorPtr); } /* *---------------------------------------------------------------------- * * ExpSpawnOutput -- * * Write routine for expect console * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ static int ExpSpawnOutput(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; CONST char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { return ExpPlatformSpawnOutput(instanceData, bufPtr, toWrite, errorPtr); } /* *---------------------------------------------------------------------- * * ExpSpawnSetOption -- * * Set the value of an ExpSpawn channel option * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ static int ExpSpawnSetOption(instanceData, interp, nameStr, valStr) ClientData instanceData; Tcl_Interp *interp; CONST char *nameStr; /* (in) Name of option */ CONST char *valStr; /* (in) New value of option */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; Tcl_DriverSetOptionProc *setOpt; setOpt = Tcl_GetChannelType(channelPtr)->setOptionProc; if (setOpt) { return (setOpt)(Tcl_GetChannelInstanceData(channelPtr), interp, nameStr, valStr); } else { return Tcl_BadChannelOption(interp, nameStr, ""); } } /* *---------------------------------------------------------------------- * * ExpSpawnGetOption -- * * Queries ExpSpawn channel for the current value of * the given option. * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ static int ExpSpawnGetOption(instanceData, interp, nameStr, dsPtr) ClientData instanceData; Tcl_Interp *interp; CONST char *nameStr; /* (in) Name of option to retrieve */ Tcl_DString *dsPtr; /* (in) String to place value */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; Tcl_DriverGetOptionProc *getOpt; getOpt = Tcl_GetChannelType(channelPtr)->getOptionProc; if (getOpt) { return (getOpt)(Tcl_GetChannelInstanceData(channelPtr), interp, nameStr, dsPtr); } else if (nameStr != NULL) { return Tcl_BadChannelOption(interp, nameStr, ""); } else { return TCL_OK; } } /* *---------------------------------------------------------------------- * * ExpSpawnWatch -- * * Sets up event handling on a expect console Tcl_Channel using * the underlying channel type. * * Results: * Nothing * * Side Effects * None. * *---------------------------------------------------------------------- */ void ExpSpawnWatch(instanceData, mask) ClientData instanceData; int mask; { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; (Tcl_GetChannelType(channelPtr)->watchProc) (Tcl_GetChannelInstanceData(channelPtr), mask); return; } /* *---------------------------------------------------------------------- * * ExpSpawnGetHandle -- * * Get the Tcl_File for the appropriate direction in from the * Tcl_Channel. * * Results: * NULL because ExpSpawn ids are handled through other channel * types. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpSpawnGetHandle(instanceData, direction, handlePtr) ClientData instanceData; int direction; ClientData *handlePtr; { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return Tcl_GetChannelHandle(channelPtr, direction, handlePtr); } /* *---------------------------------------------------------------------- * * ExpSpawnBlock -- * * Generic routine to set I/O to blocking or non-blocking. * * Results: * TCL_OK or TCL_ERROR. * * Side Effects: * None. * *---------------------------------------------------------------------- */ static int ExpSpawnBlock(instanceData, mode) ClientData instanceData; int mode; /* (in) Block or not */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->blockModeProc) (Tcl_GetChannelInstanceData(channelPtr), mode); } |
Added generic/expStubInit.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | /* ---------------------------------------------------------------------------- * expStubInit.c -- * * This file contains the initializers for the Expect stub vectors. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expStubInit.c,v 1.1.4.4 2002/02/10 13:40:47 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #include "expPort.h" /* * WARNING: The contents of this file are automatically generated by the * $(TCLROOT)/tools/genStubs.tcl script. Any modifications to the function declarations * below should be made in the generic/exp.decls script. */ /* !BEGIN!: Do not edit below this line. */ ExpIntStubs expIntStubs = { TCL_STUB_MAGIC, NULL, NULL, /* 0 */ Exp_StringMatch, /* 1 */ Exp_StringMatch2, /* 2 */ NULL, /* 3 */ exp_new_i_complex, /* 4 */ exp_new_i_simple, /* 5 */ exp_new_fs, /* 6 */ exp_free_i, /* 7 */ exp_free_fs, /* 8 */ exp_free_fs_single, /* 9 */ exp_i_update, /* 10 */ exp_pty_exit, /* 11 */ exp_init_spawn_ids, /* 12 */ exp_init_pty, /* 13 */ exp_init_tty, /* 14 */ exp_init_stdio, /* 15 */ exp_init_sig, /* 16 */ exp_init_trap, /* 17 */ exp_init_unit_random, /* 18 */ exp_init_spawn_id_vars, /* 19 */ exp_adjust, /* 20 */ exp_ecmd_remove_f_direct_and_indirect, /* 21 */ exp_rearm_sigchld, /* 22 */ exp_chan2f, /* 23 */ exp_fcheck, /* 24 */ exp_close, /* 25 */ exp_strftime, /* 26 */ exp_create_commands, /* 27 */ exp_tty_break, /* 28 */ exp_event_disarm, /* 29 */ exp_arm_background_filehandler, /* 30 */ exp_disarm_background_filehandler, /* 31 */ exp_disarm_background_filehandler_force, /* 32 */ exp_unblock_background_filehandler, /* 33 */ exp_block_background_filehandler, /* 34 */ exp_get_next_event, /* 35 */ exp_get_next_event_info, /* 36 */ exp_f_find, /* 37 */ exp_f_new, /* 38 */ exp_f_new_platform, /* 39 */ exp_f_free, /* 40 */ exp_f_free_platform, /* 41 */ exp_exact_write, /* 42 */ }; ExpIntPlatStubs expIntPlatStubs = { TCL_STUB_MAGIC, NULL, #ifdef __WIN32__ ExpWinApplicationType, /* 0 */ ExpWinCreateProcess, /* 1 */ ExpWinSyslog, /* 2 */ ExpSyslogGetSysMsg, /* 3 */ Exp_WaitPid, /* 4 */ Exp_KillProcess, /* 5 */ ExpWinInit, /* 6 */ BuildCommandLine, /* 7 */ #endif /* __WIN32__ */ }; ExpPlatStubs expPlatStubs = { TCL_STUB_MAGIC, NULL, }; static ExpStubHooks expStubHooks = { &expPlatStubs, &expIntStubs, &expIntPlatStubs }; ExpStubs expStubs = { TCL_STUB_MAGIC, &expStubHooks, Expect_Init, /* 0 */ NULL, /* 1 */ NULL, /* 2 */ Exp_ExpInternalCmd, /* 3 */ NULL, /* 4 */ Exp_ExitCmd, /* 5 */ Exp_ExpContinueCmd, /* 6 */ NULL, /* 7 */ Exp_ExpPidCmd, /* 8 */ Exp_GetpidDeprecatedCmd, /* 9 */ NULL, /* 10 */ Exp_LogFileCmd, /* 11 */ Exp_LogUserCmd, /* 12 */ Exp_OpenCmd, /* 13 */ NULL, /* 14 */ NULL, /* 15 */ NULL, /* 16 */ Exp_SendLogCmd, /* 17 */ Exp_SleepCmd, /* 18 */ Exp_SpawnCmd, /* 19 */ Exp_StraceCmd, /* 20 */ Exp_WaitCmd, /* 21 */ Exp_ExpVersionCmd, /* 22 */ Exp_Prompt1Cmd, /* 23 */ Exp_Prompt2Cmd, /* 24 */ Exp_TrapCmd, /* 25 */ Exp_SttyCmd, /* 26 */ Exp_SystemCmd, /* 27 */ Exp_ExpectCmd, /* 28 */ Exp_ExpectGlobalCmd, /* 29 */ Exp_MatchMaxCmd, /* 30 */ Exp_RemoveNullsCmd, /* 31 */ Exp_ParityCmd, /* 32 */ Exp_TimestampCmd, /* 33 */ Exp_CloseCmd, /* 34 */ Exp_InterpreterCmd, /* 35 */ Exp_SendCmd, /* 36 */ Exp_KillCmd, /* 37 */ NULL, /* 38 */ NULL, /* 39 */ exp_printify, /* 40 */ NULL, /* 41 */ NULL, /* 42 */ NULL, /* 43 */ NULL, /* 44 */ NULL, /* 45 */ NULL, /* 46 */ NULL, /* 47 */ NULL, /* 48 */ NULL, /* 49 */ exp_errorlog, /* 50 */ exp_log, /* 51 */ exp_debuglog, /* 52 */ exp_nflog, /* 53 */ exp_nferrorlog, /* 54 */ exp_error, /* 55 */ NULL, /* 56 */ NULL, /* 57 */ NULL, /* 58 */ NULL, /* 59 */ exp_parse_argv, /* 60 */ exp_interpreter, /* 61 */ exp_interpret_cmdfile, /* 62 */ exp_interpret_cmdfilename, /* 63 */ exp_interpret_rcfiles, /* 64 */ exp_cook, /* 65 */ NULL, /* 66 */ exp_getpidproc, /* 67 */ ExpCreateSpawnChannel, /* 68 */ ExpPlatformSpawnOutput, /* 69 */ exp_init_main_cmds, /* 70 */ exp_init_expect_cmds, /* 71 */ exp_init_most_cmds, /* 72 */ exp_init_trap_cmds, /* 73 */ exp_init_interact_cmds, /* 74 */ exp_init_tty_cmds, /* 75 */ NULL, /* 76 */ NULL, /* 77 */ ExpCreatePairChannel, /* 78 */ ExpSpawnOpen, /* 79 */ exp_update_master, /* 80 */ exp_get_var, /* 81 */ exp_exit, /* 82 */ exp_dsleep, /* 83 */ exp_init_event, /* 84 */ NULL, /* 85 */ exp_background_filehandler, /* 86 */ exp_exit_handlers, /* 87 */ exp_close_on_exec, /* 88 */ exp_flageq_code, /* 89 */ exp_close_tcl_files, /* 90 */ exp_lowmemcpy, /* 91 */ exp_timestamp, /* 92 */ }; /* !END!: Do not edit above this line. */ |
Added generic/expStubLib.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | /* * expStubLib.c -- * * Stub object that will be statically linked into extensions that wish * to access Expect. * * Copyright (c) 2002 by Telindustrie, LLC * Copyright (c) 1998 Paul Duffin. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: $Id: expStubLib.c,v 1.1.2.1 2002/02/10 08:35:44 davygrvy Exp $ */ /* * We need to ensure that we use the stub macros so that this file contains * no references to any of the stub functions. This will make it possible * to build an extension that references Tcl_InitStubs but doesn't end up * including the rest of the stub functions. */ #ifndef USE_TCL_STUBS #define USE_TCL_STUBS #endif #undef USE_TCL_STUB_PROCS /* * This ensures that the Exp_InitStubs has a prototype in * exp.h and is not the macro that turns it into Tcl_PkgRequire */ #ifndef USE_EXP_STUBS #define USE_EXP_STUBS #endif #include "expInt.h" ExpStubs *expStubsPtr; ExpIntStubs *expIntStubsPtr; ExpPlatStubs *expPlatStubsPtr; ExpIntPlatStubs *expIntPlatStubsPtr; /* *---------------------------------------------------------------------- * * Exp_InitStubs -- * * Tries to initialise the stub table pointers and ensures that * the correct version of Expect is loaded. * * Results: * The actual version of Expect that satisfies the request, or * NULL to indicate that an error occurred. * * Side effects: * Sets the stub table pointers. * *---------------------------------------------------------------------- */ CONST char * Exp_InitStubs (interp, version, exact) Tcl_Interp *interp; char *version; int exact; { CONST char *actualVersion; actualVersion = Tcl_PkgRequireEx(interp, "Expect", version, exact, (ClientData *) &expStubsPtr); if (actualVersion == NULL) { expStubsPtr = NULL; return NULL; } if (expStubsPtr->hooks) { expIntStubsPtr = expStubsPtr->hooks->expIntStubs; expPlatStubsPtr = expStubsPtr->hooks->expPlatStubs; expIntPlatStubsPtr = expStubsPtr->hooks->expIntPlatStubs; } else { expIntStubsPtr = NULL; expPlatStubsPtr = NULL; expIntPlatStubsPtr = NULL; } return actualVersion; } |
Added generic/expTrap.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | /* ---------------------------------------------------------------------------- * exp_trap.c -- * * Expect's trap command. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #ifdef TCL_DEBUGGER #include "Dbg.h" #endif #define NO_SIG 0 #define SIGNAL_DEFAULT 0 #define SIGNAL_IGNORE 1 #define SIGNAL_ENABLED 2 static struct trap { char *action; /* Tcl command to execute upon sig */ /* Each is handled by the eval_trap_action */ int mark; /* TRUE if signal has occurred */ Tcl_Interp *interp; /* interp to use or 0 if we should use the */ /* interpreter active at the time the sig */ /* is processed */ int code; /* return our new code instead of code */ /* available when signal is processed */ CONST char *name; /* name of signal */ int reserved; /* if unavailable for trapping */ int enabled; /* set on Win32 if we are trapping signal */ } traps[NSIG]; int sigchld_count = 0; /* # of sigchlds caught but not yet processed */ static int eval_trap_action(); static int got_sig; /* this records the last signal received */ /* it is only a hint and can be wiped out */ /* by multiple signals, but it will always */ /* be left with a valid signal that is */ /* pending */ static Tcl_AsyncHandler async_handler; static CONST char * signal_to_string(sig) int sig; { if (sig <= 0 || sig > NSIG) return("SIGNAL OUT OF RANGE"); return(traps[sig].name); } /* current sig being processed by user sig handler */ static int current_sig = NO_SIG; int exp_nostack_dump = FALSE; /* TRUE if user has requested unrolling of */ /* stack with no trace */ /*ARGSUSED*/ static int tophalf(ClientData clientData, Tcl_Interp *interp, int code) { struct trap *trap; /* last trap processed */ int rc; int i; Tcl_Interp *sig_interp; /* extern Tcl_Interp *exp_interp;*/ exp_debuglog("sighandler: handling signal(%d)\r\n",got_sig); if (got_sig <= 0 || got_sig >= NSIG) { exp_errorlog("caught impossible signal %d\r\n",got_sig); abort(); } /* start to work on this sig. got_sig can now be overwritten */ /* and it won't cause a problem */ current_sig = got_sig; trap = &traps[current_sig]; trap->mark = FALSE; #ifdef SIGCHLD /* decrement below looks dangerous */ /* Don't we need to temporarily block bottomhalf? */ if (current_sig == SIGCHLD) { sigchld_count--; exp_debuglog("sigchld_count-- == %d\n",sigchld_count); } #endif if (!trap->action) { /* In this one case, we let ourselves be called when no */ /* signaler predefined, since we are calling explicitly */ /* from another part of the program, and it is just simpler */ if (current_sig == 0) return code; exp_errorlog("caught unexpected signal: %s (%d)\r\n", signal_to_string(current_sig),current_sig); abort(); } if (trap->interp) { /* if trap requested original interp, use it */ sig_interp = trap->interp; } else if (!interp) { /* else if another interp is available, use it */ sig_interp = interp; } else { /* fall back to exp_interp */ sig_interp = exp_interp; } rc = eval_trap_action(sig_interp,current_sig,trap,code); current_sig = NO_SIG; /* * scan for more signals to process */ /* first check for additional SIGCHLDs */ if (sigchld_count) { #ifdef SIGCHLD got_sig = SIGCHLD; traps[SIGCHLD].mark = TRUE; Tcl_AsyncMark(async_handler); #endif } else { got_sig = -1; for (i=1;i<NSIG;i++) { if (traps[i].mark) { got_sig = i; Tcl_AsyncMark(async_handler); break; } } } return rc; } #ifdef REARM_SIG int sigchld_sleep; static int rearm_sigchld = FALSE; /* TRUE if sigchld needs to be */ /* rearmed (i.e., because it has /* just gone off) */ static int rearming_sigchld = FALSE; #endif /* called upon receipt of a user-declared signal */ static void bottomhalf(int sig) { #ifdef REARM_SIG /* * tiny window of death if same signal should arrive here * before we've reinstalled it */ /* In SV, sigchld must be rearmed after wait to avoid recursion */ if (sig != SIGCHLD) { signal(sig,bottomhalf); } else { /* request rearm */ rearm_sigchld = TRUE; if (rearming_sigchld) sigchld_sleep = TRUE; } #endif traps[sig].mark = TRUE; got_sig = sig; /* just a hint - can be wiped out by another */ Tcl_AsyncMark(async_handler); /* if we are called while this particular async is being processed */ /* original async_proc will turn off "mark" so that when async_proc */ /* is recalled, it will see that nothing was left to do */ /* In case of SIGCHLD though, we must recall it as many times as * we have received it. */ #ifdef SIGCHLD if (sig == SIGCHLD) { sigchld_count++; /* exp_debuglog(stderr,"sigchld_count++ == %d\n",sigchld_count);*/ } #endif #if 0 /* if we are doing an i_read, restart it */ if (env_valid && (sig != 0)) longjmp(env,2); #endif } /*ARGSUSED*/ void exp_rearm_sigchld(interp) Tcl_Interp *interp; { #ifdef REARM_SIG if (rearm_sigchld) { rearm_sigchld = FALSE; rearming_sigchld = TRUE; signal(SIGCHLD,bottomhalf); } rearming_sigchld = FALSE; /* if the rearming immediately caused another SIGCHLD, slow down */ /* It's probably one of Tcl's intermediary pipeline processes that */ /* Tcl hasn't caught up with yet. */ if (sigchld_sleep) { exp_dsleep(interp,0.2); sigchld_sleep = FALSE; } #endif } #ifdef WIN32 static BOOL WINAPI ctrl_event(DWORD event) { int sig = 0; exp_debuglog("trap: ctrl_event %d\r\n", event); if (event == CTRL_C_EVENT) { sig = 2; } else if (event == CTRL_BREAK_EVENT) { sig = 3; } if (sig) { switch (traps[sig].enabled) { case SIGNAL_IGNORE: return TRUE; case SIGNAL_DEFAULT: return FALSE; case SIGNAL_ENABLED: bottomhalf(sig); return TRUE; } } return FALSE; } #endif void exp_init_trap() { int i; for (i=1;i<NSIG;i++) { traps[i].name = Tcl_SignalId(i); traps[i].action = 0; traps[i].reserved = FALSE; traps[i].enabled = SIGNAL_DEFAULT; } #ifdef WIN32 traps[3].name = "SIGQUIT"; #endif /* * fix up any special cases */ #if defined(SIGCLD) /* Tcl names it SIGCLD, not good for portable scripts */ traps[SIGCLD].name = "SIGCHLD"; #endif #if defined(SIGALRM) traps[SIGALRM].reserved = TRUE; #endif #if defined(SIGKILL) traps[SIGKILL].reserved = TRUE; #endif #if defined(SIGSTOP) traps[SIGSTOP].reserved = TRUE; #endif async_handler = Tcl_AsyncCreate(tophalf,(ClientData)NULL); } /* given signal index or name as string, */ /* returns signal index or -1 if bad arg */ int exp_string_to_signal(interp,s) Tcl_Interp *interp; char *s; { int sig; CONST char *name; /* try interpreting as an integer */ if (1 == sscanf(s,"%d",&sig)) { if (sig > 0 && sig < NSIG) return sig; } else { /* try interpreting as a string */ for (sig=1;sig<NSIG;sig++) { name = traps[sig].name; if (streq(s,name) || streq(s,name+3)) return(sig); } } exp_error(interp,"invalid signal %s",s); return -1; } /*ARGSUSED*/ int Exp_TrapCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *action = 0; int n; /* number of signals in list */ char **list = NULL; /* list of signals */ int len; /* length of action */ int i; int show_name = FALSE; /* if user asked for current sig by name */ int show_number = FALSE;/* if user asked for current sig by number */ int show_max = FALSE; /* if user asked for NSIG-1 */ int rc = TCL_OK; int new_code = FALSE; /* if action result should overwrite orig */ Tcl_Interp *new_interp = interp;/* interp in which to evaluate */ /* action when signal occurs */ argc--; argv++; while (*argv) { if (streq(*argv,"-code")) { argc--; argv++; new_code = TRUE; } else if (streq(*argv,"-interp")) { argc--; argv++; new_interp = 0; } else if (streq(*argv,"-name")) { argc--; argv++; show_name = TRUE; } else if (streq(*argv,"-number")) { argc--; argv++; show_number = TRUE; } else if (streq(*argv,"-max")) { argc--; argv++; show_max = TRUE; } else break; } if (show_name || show_number || show_max) { if (argc > 0) goto usage_error; if (show_max) { Tcl_SetObjResult(interp, Tcl_NewIntObj(NSIG-1)); return TCL_OK; } if (current_sig == NO_SIG) { exp_error(interp,"no signal in progress"); return TCL_ERROR; } if (show_name) { /* skip over "SIG" */ Tcl_SetObjResult(interp, Tcl_NewStringObj(signal_to_string(current_sig) + 3, -1)); } else { Tcl_SetObjResult(interp, Tcl_NewIntObj(current_sig)); } return TCL_OK; } if (argc == 0 || argc > 2) goto usage_error; if (argc == 1) { int sig = exp_string_to_signal(interp,*argv); if (sig == -1) return TCL_ERROR; if (traps[sig].action) { Tcl_AppendResult(interp,traps[sig].action,(char *)0); } else { interp->result = "SIG_DFL"; } return TCL_OK; } action = *argv; /* argv[1] is the list of signals - crack it open */ if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) { exp_errorlog("%s\r\n",interp->result); goto usage_error; } for (i=0;i<n;i++) { int sig = exp_string_to_signal(interp,list[i]); if (sig == -1) { rc = TCL_ERROR; break; } if (traps[sig].reserved) { exp_error(interp,"cannot trap %s",signal_to_string(sig)); rc = TCL_ERROR; break; } #if 0 #ifdef TCL_DEBUGGER if (sig == SIGINT && exp_tcl_debugger_available) { exp_debuglog("trap: cannot trap SIGINT while using debugger\r\n"); continue; } #endif /* TCL_DEBUGGER */ #endif exp_debuglog("trap: setting up signal %d (\"%s\")\r\n",sig,list[i]); if (traps[sig].action) ckfree(traps[sig].action); if (streq(action,"SIG_DFL")) { /* should've been free'd by now if nec. */ traps[sig].action = 0; traps[sig].enabled = SIGNAL_DEFAULT; #ifndef WIN32 signal(sig,SIG_DFL); #endif #ifdef REARM_SIG if (sig == SIGCHLD) rearm_sigchld = FALSE; #endif /*REARM_SIG*/ } else { len = 1 + strlen(action); traps[sig].action = ckalloc(len); memcpy(traps[sig].action,action,len); traps[sig].interp = new_interp; traps[sig].code = new_code; if (streq(action,"SIG_IGN")) { #ifdef WIN32 traps[sig].enabled = SIGNAL_IGNORE; #else signal(sig,SIG_IGN); #endif } else { #ifdef WIN32 if (sig == 2 || sig == 3) { traps[sig].enabled = SIGNAL_ENABLED; SetConsoleCtrlHandler(ctrl_event, TRUE); } #else signal(sig,bottomhalf); #endif } } } if (list) { ckfree((char *)list); } return(rc); usage_error: exp_error(interp,"usage: trap [command or SIG_DFL or SIG_IGN] {list of signals}"); return TCL_ERROR; } /* called by tophalf() to process the given signal */ static int eval_trap_action(interp,sig,trap,oldcode) Tcl_Interp *interp; int sig; struct trap *trap; int oldcode; { int code_flag; int newcode; Tcl_DString ei; /* errorInfo */ CONST char *eip; Tcl_DString ec; /* errorCode */ CONST char *ecp; Tcl_DString ir; /* interp->result */ exp_debuglog("async event handler: Tcl_Eval(%s)\r\n",trap->action); /* save to prevent user from redefining trap->code while trap */ /* is executing */ code_flag = trap->code; if (!code_flag) { /* * save return values */ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY); if (eip) { Tcl_DStringInit(&ei); eip = (char *) Tcl_DStringAppend(&ei,eip,-1); } ecp = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY); if (ecp) { Tcl_DStringInit(&ec); ecp = (char *) Tcl_DStringAppend(&ec,ecp,-1); } /* I assume interp->result is always non-zero, right? */ Tcl_DStringInit(&ir); Tcl_DStringAppend(&ir,interp->result,-1); } newcode = Tcl_GlobalEval(interp,trap->action); /* * if new code is to be ignored (usual case - see "else" below) * allow only OK/RETURN from trap, otherwise complain */ if (code_flag) { exp_debuglog("return value = %d for trap %s, action %s\r\n", newcode,signal_to_string(sig),trap->action); if (*interp->result != 0) { exp_errorlog("%s\r\n",interp->result); /* * Check errorinfo and see if it contains -nostack. * This shouldn't be necessary, but John changed the * top level interp so that it distorts arbitrary * return values into TCL_ERROR, so by the time we * get back, we'll have lost the value of errorInfo */ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY); exp_nostack_dump = (eip && (0 == strncmp("-nostack",eip,8))); } } else if (newcode != TCL_OK && newcode != TCL_RETURN) { if (newcode != TCL_ERROR) { exp_error(interp,"return value = %d for trap %s, action %s\r\n",newcode,signal_to_string(sig),trap->action); } Tcl_BackgroundError(interp); } if (!code_flag) { /* * restore values */ Tcl_ResetResult(interp); /* turns off Tcl's internal */ /* flags: ERR_IN_PROGRESS, ERROR_CODE_SET */ if (eip) { Tcl_AddErrorInfo(interp,eip); Tcl_DStringFree(&ei); } else { Tcl_UnsetVar(interp,"errorInfo",0); } /* restore errorCode. Note that Tcl_AddErrorInfo (above) */ /* resets it to NONE. If the previous value is NONE, it's */ /* important to avoid calling Tcl_SetErrorCode since this */ /* with cause Tcl to set its internal ERROR_CODE_SET flag. */ if (ecp) { if (!streq("NONE",ecp)) Tcl_SetErrorCode(interp,ecp,(char *)0); Tcl_DStringFree(&ec); } else { Tcl_UnsetVar(interp,"errorCode",0); } Tcl_DStringResult(interp,&ir); Tcl_DStringFree(&ir); newcode = oldcode; /* note that since newcode gets overwritten here by old code */ /* it is possible to return in the middle of a trap by using */ /* "return" (or "continue" for that matter)! */ } return newcode; } static struct exp_cmd_data cmd_data[] = { {"trap", 0, Exp_TrapCmd, NULL, 0}, {0} }; void exp_init_trap_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } |
Added generic/exp_closetcl.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* ---------------------------------------------------------------------------- * exp_closetcl.c -- * * close tcl files. Isolated in it's own file since it has hooks into * Tcl and exp_clib user might like to avoid dragging it in. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ void (*exp_close_in_child)() = 0; void exp_close_tcl_files() { /* So much for close-on-exec. Tcl doesn't mark its files that way */ /* everything has to be closed explicitly. */ #if 0 int i; /* Not necessary with Tcl 7.5? */ for (i=3; i<tclNumFiles;i++) close(i); #endif } |
Added generic/exp_event.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | /* ---------------------------------------------------------------------------- * exp_event.c -- * * event interface for Expect. * * Notes: * I'm only a little worried because Tk does not check for errno == EBADF * after calling select. I imagine that if the user passes in a bad file * descriptor, we'll never get called back, and thus, we'll hang forever * - it would be better to at least issue a diagnostic to the user. * * Another possible problem: Tk does not do file callbacks round-robin. * * Another possible problem: Calling Create/DeleteChannelHandler * before/after every Tcl_Eval... in expect/interact could be very * expensive. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" /* Tcl_DoOneEvent will call our filehandler which will set the following */ /* vars enabling us to know where and what kind of I/O we can do */ /*#define EXP_SPAWN_ID_BAD -1*/ /*#define EXP_SPAWN_ID_TIMEOUT -2*/ /* really indicates a timeout */ static struct exp_f *ready_fs = NULL; /* static int ready_fd = EXP_SPAWN_ID_BAD; */ static int ready_mask; static int default_mask = TCL_READABLE | TCL_EXCEPTION; void (*exp_event_exit) _ANSI_ARGS_((Tcl_Interp *interp)); /* * Declarations for functions used only in this file. */ static void exp_timehandler _ANSI_ARGS_ ((ClientData clientData)); static void exp_filehandler _ANSI_ARGS_ ((ClientData clientData, int mask)); static void exp_event_exit_real _ANSI_ARGS_ ((Tcl_Interp *interp)); /* *---------------------------------------------------------------------- * * exp_event_disarm -- * * Completely remove the filehandler for this process * * Results: * None * * Side Effects: * Events will no longer be reported for this process * *---------------------------------------------------------------------- */ void exp_event_disarm(f) struct exp_f *f; { Tcl_Channel channel; channel = f->Master; if (! channel) { channel = f->channel; } Tcl_DeleteChannelHandler(channel, f->event_proc, f->event_data); f->event_proc = NULL; /* remember that filehandler has been disabled so that */ /* it can be turned on for fg expect's as well as bg */ f->fg_armed = FALSE; } /* *---------------------------------------------------------------------- * * exp_event_disarm_fast -- * * Temporarily disable the filehandler for this process. This * is quicker than calling exp_event_disasrm as it reduces the * calls to malloc() and free() inside Tcl_...FileHandler. * * Results: * None * * Side Effects: * Events will no longer be reported for this process * *---------------------------------------------------------------------- */ static void exp_event_disarm_fast(f,filehandler) struct exp_f *f; Tcl_ChannelProc *filehandler; { Tcl_Channel channel; channel = f->Master; if (! channel) { channel = f->channel; } /* Tk insists on having a valid proc here even though it isn't used */ if (f->event_proc) { Tcl_DeleteChannelHandler(channel,f->event_proc,f->event_data); } Tcl_CreateChannelHandler(channel,0,filehandler,(ClientData)0); f->event_proc = filehandler; f->event_data = 0; /* remember that filehandler has been disabled so that */ /* it can be turned on for fg expect's as well as bg */ f->fg_armed = FALSE; } /* *---------------------------------------------------------------------- * * exp_arm_background_filehandler_force -- * * Always installs a background filehander * * Results: * None * * Side Effects: * Background events will be reported for this process * *---------------------------------------------------------------------- */ static void exp_arm_background_filehandler_force(f) struct exp_f *f; { Tcl_Channel channel; channel = f->Master; if (! channel) { channel = f->channel; } if (f->event_proc) { Tcl_DeleteChannelHandler(channel,f->event_proc,f->event_data); } Tcl_CreateChannelHandler(channel, TCL_READABLE|TCL_EXCEPTION, exp_background_filehandler, (ClientData) f); f->event_proc = exp_background_filehandler; f->event_data = (ClientData) f; f->bg_status = armed; } /* *---------------------------------------------------------------------- * * exp_arm_background_filehandler -- * * Installs a background filehandler if it hasn't already been * installed or if it was disabled. * * Results: * None * * Side Effects: * Background events will be reported for this process * *---------------------------------------------------------------------- */ void exp_arm_background_filehandler(f) struct exp_f *f; { switch (f->bg_status) { case unarmed: exp_arm_background_filehandler_force(f); break; case disarm_req_while_blocked: f->bg_status = blocked; /* forget request */ break; case armed: case blocked: /* do nothing */ break; } } /* *---------------------------------------------------------------------- * * exp_disarm_background_filehandler -- * * Removes a background filehandler if it was previously installed * and armed. * * Results: * None * * Side Effects: * Background events will no longer be reported for this process * *---------------------------------------------------------------------- */ void exp_disarm_background_filehandler(f) struct exp_f *f; { switch (f->bg_status) { case blocked: f->bg_status = disarm_req_while_blocked; break; case armed: f->bg_status = unarmed; exp_event_disarm(f); break; case disarm_req_while_blocked: case unarmed: /* do nothing */ break; } } /* *---------------------------------------------------------------------- * * exp_disarm_background_filehandler_force -- * * Removes a background filehandler if it was previously installed, * ignoring block status. Called from exp_close(). After exp_close * returns, we will not have an opportunity to disarm because the fd * will be invalid, so we force it here. * * Results: * None * * Side Effects: * Background events will no longer be reported for this process * *---------------------------------------------------------------------- */ void exp_disarm_background_filehandler_force(f) struct exp_f *f; { switch (f->bg_status) { case blocked: case disarm_req_while_blocked: case armed: f->bg_status = unarmed; exp_event_disarm(f); break; case unarmed: /* do nothing */ break; } } /* *---------------------------------------------------------------------- * * exp_unblock_background_filehandler -- * * Unblocks the background filehandler. * This can only be called at the end of the bg handler in which * case we know the status is some kind of "blocked" * * Results: * None * * Side Effects: * * *---------------------------------------------------------------------- */ void exp_unblock_background_filehandler(f) struct exp_f *f; { switch (f->bg_status) { case blocked: exp_arm_background_filehandler_force(f); break; case disarm_req_while_blocked: exp_disarm_background_filehandler_force(f); break; } } /* *---------------------------------------------------------------------- * * exp_block_background_filehandler -- * * Blocks the background filehandler. * This can only be called at the end of the bg handler in which * case we know the status is some kind of "armed" * * Results: * None * * Side Effects: * Temporarily removes the filehandler, so events will stop * being reported for this process. * *---------------------------------------------------------------------- */ void exp_block_background_filehandler(f) struct exp_f *f; { f->bg_status = blocked; exp_event_disarm_fast(f,exp_background_filehandler); } /* *---------------------------------------------------------------------- * * exp_timehandler -- * * Tcl calls this routine when timer we have set has expired. * * Results: * None * * Side Effects: * A flag is set. * *---------------------------------------------------------------------- */ static void exp_timehandler(clientData) ClientData clientData; { *(int *)clientData = TRUE; } /* *---------------------------------------------------------------------- * * exp_filehandler -- * * Tcl calls this routine when some data is available on a * channel. * * Results: * None * * Side Effects: * Sets the global value of what process is ready. This is * checked at the return of Tcl_DoOneEvent(). * *---------------------------------------------------------------------- */ static void exp_filehandler(clientData,mask) ClientData clientData; int mask; { /* * if input appears, record the fd on which it appeared */ ready_fs = (struct exp_f *) clientData; /* ready_fd = *(int *)clientData; */ ready_mask = mask; exp_event_disarm_fast(ready_fs,exp_filehandler); } /* *---------------------------------------------------------------------- * * exp_get_next_event -- * * Waits for the next event that expect is registered an * interest in. * * Results: * Returns status, one of EOF, TIMEOUT, ERROR, DATA or RECONFIGURE * * Side Effects: * Other event handlers outside of Expect may be run as well * * Notes: * This still needs some work to run properly under NT * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; struct exp_f **masters; /* Array of expect process structures */ int n; /* # of masters */ struct exp_f **master_out; /* 1st ready master, not set if none */ int timeout; /* seconds */ int key; { static rr = 0; /* round robin ptr */ int i; /* index into in-array */ #ifdef HAVE_PTYTRAP struct request_info ioctl_info; #endif int old_configure_count = exp_configure_count; int timer_created = FALSE; int timer_fired = FALSE; Tcl_TimerToken timetoken;/* handle to Tcl timehandler descriptor */ for (;;) { struct exp_f *f; /* if anything has been touched by someone else, report that */ /* an event has been received */ for (i=0;i<n;i++) { rr++; if (rr >= n) rr = 0; f = masters[rr]; if (f->key != key) { f->key = key; f->force_read = FALSE; *master_out = f; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { *master_out = f; return(EXP_DATA_OLD); } } if (!timer_created) { if (timeout >= 0) { timetoken = Tcl_CreateTimerHandler(1000*timeout, exp_timehandler, (ClientData)&timer_fired); timer_created = TRUE; } } for (;;) { int j; /* make sure that all fds that should be armed are */ for (j=0;j<n;j++) { f = masters[j]; if (!f->fg_armed) { Tcl_Channel channel; channel = f->Master; if (! channel) { channel = f->channel; } if (f->event_proc) { Tcl_DeleteChannelHandler(channel,f->event_proc, f->event_data); } Tcl_CreateChannelHandler(channel, default_mask, exp_filehandler, (ClientData)f); f->event_proc = exp_filehandler; f->event_data = (ClientData) f; f->fg_armed = TRUE; } } Tcl_DoOneEvent(0); /* do any event */ if (timer_fired) return(EXP_TIMEOUT); if (old_configure_count != exp_configure_count) { if (timer_created) Tcl_DeleteTimerHandler(timetoken); return EXP_RECONFIGURE; } if (ready_fs == NULL) continue; /* if it was from something we're not looking for at */ /* the moment, ignore it */ for (j=0;j<n;j++) { if (ready_fs == masters[j]) goto found; } /* not found */ exp_event_disarm_fast(ready_fs,exp_filehandler); ready_fs = NULL; continue; found: *master_out = ready_fs; ready_fs = NULL; if (timer_created) Tcl_DeleteTimerHandler(timetoken); /* this test should be redundant but SunOS */ /* raises both READABLE and EXCEPTION (for no */ /* apparent reason) when selecting on a plain file */ if (ready_mask & TCL_READABLE) { return EXP_DATA_NEW; } /* ready_mask must contain TCL_EXCEPTION */ #ifndef HAVE_PTYTRAP return(EXP_EOF); #else if (ioctl(*master_out,TIOCREQCHECK,&ioctl_info) < 0) { exp_debuglog("ioctl error on TIOCREQCHECK: %s", Tcl_PosixError(interp)); return(EXP_TCLERROR); } if (ioctl_info.request == TIOCCLOSE) { return(EXP_EOF); } if (ioctl(*master_out, TIOCREQSET, &ioctl_info) < 0) { exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno)); } /* presumably, we trapped an open here */ continue; #endif /* !HAVE_PTYTRAP */ } } } /* *---------------------------------------------------------------------- * * exp_get_next_event_info -- * * Having been told there was an event for a specific fd, get it * returns status, one of EOF, TIMEOUT, ERROR or DATA * * Results: * Returns EXP_DATA_NEW, EXP_EOF, of EXP_TCLERROR * * Side Effects: * None on NT or most Unices. On HPUX, it looks like there might * be some. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int exp_get_next_event_info(interp,f,ready_mask) Tcl_Interp *interp; struct exp_f *f; int ready_mask; { #ifdef HAVE_PTYTRAP struct request_info ioctl_info; #endif if (ready_mask & TCL_READABLE) return EXP_DATA_NEW; /* ready_mask must contain TCL_EXCEPTION */ #ifndef HAVE_PTYTRAP return(EXP_EOF); #else if (ioctl(f->fd,TIOCREQCHECK,&ioctl_info) < 0) { exp_debuglog("ioctl error on TIOCREQCHECK: %s", Tcl_PosixError(interp)); return(EXP_TCLERROR); } if (ioctl_info.request == TIOCCLOSE) { return(EXP_EOF); } if (ioctl(f->fd, TIOCREQSET, &ioctl_info) < 0) { exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno)); } /* presumably, we trapped an open here */ /* call it an error for lack of anything more descriptive */ /* it will be thrown away by caller anyway */ return EXP_TCLERROR; #endif } /* *---------------------------------------------------------------------- * * exp_dsleep -- * * Waits for at least a certain amount of time. In general, * the length of time will be a little bit longer. * * Results: * Returns TCL_OK; * * Side Effects: * Event handlers can fire during this period, so other actions * are taken. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { int timer_fired = FALSE; Tcl_CreateTimerHandler((int)(sec*1000),exp_timehandler,(ClientData)&timer_fired); while (1) { Tcl_DoOneEvent(0); if (timer_fired) return TCL_OK; if (ready_fs == NULL) continue; exp_event_disarm_fast(ready_fs,exp_filehandler); ready_fs = NULL; } } /* * Tcl used to require commands to be in writeable memory. This * probably doesn't apply anymore */ static char destroy_cmd[] = "destroy ."; /* *---------------------------------------------------------------------- * * exp_event_exit_real -- * * Function to call to destroy the main window, causing * the program to exit. * * Results: * None * * Side Effects: * Program exits. * *---------------------------------------------------------------------- */ static void exp_event_exit_real(interp) Tcl_Interp *interp; { Tcl_Eval(interp,destroy_cmd); } /* *---------------------------------------------------------------------- * * exp_init_event -- * * Set things up for later calls to the event handler * * Results: * None * * Side Effects: * None * *---------------------------------------------------------------------- */ void exp_init_event() { exp_event_exit = exp_event_exit_real; } |
Added generic/exp_glob.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | /* ---------------------------------------------------------------------------- * exp_glob.c -- * * expect functions for doing glob. Based on Tcl's glob functions but * modified to support anchors and to return information about the * possibility of future matches. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <string.h> #include "expInt.h" /* *---------------------------------------------------------------------- * * Exp_StringMatch -- * * Implement expect's glob-style string matching. * Exp_StringMatch allow's implements the unanchored front * (or conversely the '^') feature. Exp_StringMatch2 does * the rest of the work. * * Results: * Number of characters that matched * * Side Effects: * None * *---------------------------------------------------------------------- */ int Exp_StringMatch(string, pattern,offset) CONST char *string; CONST char *pattern; int *offset; /* offset from beginning of string where * pattern matches */ { CONST char *s; int sm; /* count of chars matched or -1 */ int caret = FALSE; int star = FALSE; *offset = 0; if (pattern[0] == '^') { caret = TRUE; pattern++; } else if (pattern[0] == '*') { star = TRUE; } /* * test if pattern matches in initial position. * This handles front-anchor and 1st iteration of non-front-anchor. * Note that 1st iteration must be tried even if string is empty. */ sm = Exp_StringMatch2(string,pattern); if (sm >= 0) return(sm); if (caret) return -1; if (star) return -1; if (*string == '\0') return -1; for (s = string+1;*s;s++) { sm = Exp_StringMatch2(s,pattern); if (sm != -1) { *offset = s-string; return(sm); } } return -1; } /* *---------------------------------------------------------------------- * * Exp_StringMatch2 -- * * Like Tcl_StringMatch except that * 1) returns number of characters matched, -1 if failed. * (Can return 0 on patterns like "" or "$") * 2) does not require pattern to match to end of string * 3) much of code is stolen from Tcl_StringMatch * 4) front-anchor is assumed (Tcl_StringMatch retries for * non-front-anchor) * * Results: * Number of characters that matched * * Side Effects: * None * *---------------------------------------------------------------------- */ int Exp_StringMatch2(string,pattern) CONST register char *string; /* String. */ CONST register char *pattern; /* Pattern, which may contain * special characters. */ { char c2; int match = 0; /* # of chars matched */ while (1) { /* If at end of pattern, success! */ if (*pattern == 0) { return match; } /* If last pattern character is '$', verify that entire * string has been matched. */ if ((*pattern == '$') && (pattern[1] == 0)) { if (*string == 0) return(match); else return(-1); } /* Check for a "*" as the next pattern character. It matches * any substring. We handle this by calling ourselves * recursively for each postfix of string, until either we * match or we reach the end of the string. */ if (*pattern == '*') { #if 1 int head_len; CONST char *tail; #endif pattern += 1; if (*pattern == 0) { return(strlen(string)+match); /* DEL */ } #if 1 /* find longest match - switched to this on 12/31/93 */ head_len = strlen(string); /* length before tail */ tail = string + head_len; while (head_len >= 0) { int rc; if (-1 != (rc = Exp_StringMatch2(tail, pattern))) { return rc + match + head_len; /* DEL */ } tail--; head_len--; } #else /* find shortest match */ while (*string != 0) { int rc; /* DEL */ if (-1 != (rc = Exp_StringMatch2(string, pattern))) { return rc+match; /* DEL */ } string += 1; match++; /* DEL */ } if (*pattern == '$') return 0; /* handle *$ */ #endif return -1; /* DEL */ } /* * after this point, all patterns must match at least one * character, so check this */ if (*string == 0) return -1; /* Check for a "?" as the next pattern character. It matches * any single character. */ if (*pattern == '?') { goto thisCharOK; } /* Check for a "[" as the next pattern character. It is followed * by a list of characters that are acceptable, or by a range * (two characters separated by "-"). */ if (*pattern == '[') { pattern += 1; while (1) { if ((*pattern == ']') || (*pattern == 0)) { return -1; /* was 0; DEL */ } if (*pattern == *string) { break; } if (pattern[1] == '-') { c2 = pattern[2]; if (c2 == 0) { return -1; /* DEL */ } if ((*pattern <= *string) && (c2 >= *string)) { break; } if ((*pattern >= *string) && (c2 <= *string)) { break; } pattern += 2; } pattern += 1; } /* OOPS! Found a bug in vanilla Tcl - have sent back to Ousterhout */ /* but he hasn't integrated it yet. - DEL */ #if 0 while ((*pattern != ']') && (*pattern != 0)) { #else while (*pattern != ']') { if (*pattern == 0) { pattern--; break; } #endif pattern += 1; } goto thisCharOK; } /* If the next pattern character is backslash, strip it off * so we do exact matching on the character that follows. */ if (*pattern == '\\') { pattern += 1; if (*pattern == 0) { return -1; } } /* There's no special character. Just make sure that the next * characters of each string match. */ if (*pattern != *string) { return -1; } thisCharOK: pattern += 1; string += 1; match++; } } |
Added generic/exp_inter.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 | /* ---------------------------------------------------------------------------- * exp_inter.c -- * * interact (using select) - give user keyboard control. * * Notes: * Has no working implimentation (yet) on windows. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #ifndef __WIN32__ extern char *TclGetRegError(); extern void TclRegError(); #define INTER_OUT "interact_out" /* * tests if we are running this using a real tty * * these tests are currently only used to control what gets written to the * logfile. Note that removal of the test of "..._is_tty" means that stdin * or stdout could be redirected and yet stdout would still be logged. * However, it's not clear why anyone would use log_file when these are * redirected in the first place. On the other hand, it is reasonable to * run expect as a daemon in which case, stdin/out do not appear to be * ttys, yet it makes sense for them to be logged with log_file as if they * were. */ #if 0 #define real_tty_output(x) (exp_stdout_is_tty && (((x)==1) || ((x)==exp_dev_tty))) #define real_tty_input(x) (exp_stdin_is_tty && (((x)==0) || ((x)==exp_dev_tty))) #endif #define real_tty_output(x) (((x)==1) || ((x)==exp_dev_tty)) #define real_tty_input(x) (((x)==0) || ((x)==exp_dev_tty)) #define new(x) (x *)ckalloc(sizeof(x)) struct action { char *statement; int tty_reset; /* if true, reset tty mode upon action */ int iread; /* if true, reread indirects */ int iwrite; /* if true, write spawn_id element */ int timestamp; /* if true, generate timestamp */ struct action *next; /* chain only for later for freeing */ }; struct keymap { char *keys; /* original pattern provided by user */ regexp *re; int null; /* true if looking to match 0 byte */ int case_sensitive; int echo; /* if keystrokes should be echoed */ int writethru; /* if keystrokes should go through to process */ int indices; /* true if should write indices */ struct action action; struct keymap *next; }; struct output { struct exp_i *i_list; struct action *action_eof; struct output *next; }; struct input { struct exp_i *i_list; struct output *output; struct action *action_eof; struct action *action_timeout; struct keymap *keymap; int timeout_nominal; /* timeout nominal */ int timeout_remaining; /* timeout remaining */ struct input *next; }; static void free_input(); static void free_keymap(); static void free_output(); static void free_action(); static struct action *new_action(); static int inter_eval(); /* in_keymap() accepts user keystrokes and returns one of MATCH, CANMATCH, or CANTMATCH. These describe whether the keystrokes match a key sequence, and could or can't if more characters arrive. The function assigns a matching keymap if there is a match or can-match. A matching keymap is assigned on can-match so we know whether to echo or not. in_keymap is optimized (if you can call it that) towards a small number of key mappings, but still works well for large maps, since no function calls are made, and we stop as soon as there is a single-char mismatch, and go on to the next one. A hash table or compiled DFA probably would not buy very much here for most maps. The basic idea of how this works is it does a smart sequential search. At each position of the input string, we attempt to match each of the keymaps. If at least one matches, the first match is returned. If there is a CANMATCH and there are more keymaps to try, we continue trying. If there are no more keymaps to try, we stop trying and return with an indication of the first keymap that can match. Note that I've hacked up the regexp pattern matcher in two ways. One is to force the pattern to always be anchored at the front. That way, it doesn't waste time attempting to match later in the string (before we're ready). The other is to return can-match. */ static int in_keymap(string,stringlen,keymap,km_match,match_length,skip,rm_nulls) char *string; int stringlen; struct keymap *keymap; /* linked list of keymaps */ struct keymap **km_match; /* keymap that matches or can match */ int *match_length; /* # of chars that matched */ int *skip; /* # of chars to skip */ int rm_nulls; /* skip nulls if true */ { struct keymap *km; char *ks; /* string from a keymap */ char *start_search; /* where in the string to start searching */ char *string_end; /* assert (*km == 0) */ /* a shortcut that should help master output which typically */ /* is lengthy and has no key maps. Otherwise it would mindlessly */ /* iterate on each character anyway. */ if (!keymap) { *skip = stringlen; return(EXP_CANTMATCH); } string_end = string + stringlen; /* Mark beginning of line for ^ . */ regbol = string; /* skip over nulls - Pascal Meheut, [email protected] 18-May-1993 */ /* for (start_search = string;*start_search;start_search++) {*/ for (start_search = string;start_search<string_end;start_search++) { if (*km_match) break; /* if we've already found a CANMATCH */ /* don't bother starting search from positions */ /* further along the string */ for (km=keymap;km;km=km->next) { char *s; /* current character being examined */ if (km->null) { if (*start_search == 0) { *skip = start_search-string; *match_length = 1; /* s - start_search == 1 */ *km_match = km; return(EXP_MATCH); } } else if (!km->re) { /* fixed string */ for (s = start_search,ks = km->keys ;;s++,ks++) { /* if we hit the end of this map, must've matched! */ if (*ks == 0) { *skip = start_search-string; *match_length = s-start_search; *km_match = km; return(EXP_MATCH); } /* if we ran out of user-supplied characters, and */ /* still haven't matched, it might match if the user */ /* supplies more characters next time */ if (s == string_end) { /* skip to next key entry, but remember */ /* possibility that this entry might match */ if (!*km_match) *km_match = km; break; } if ((*s & 0x7f) == *ks) continue; if ((*s == '\0') && rm_nulls) { ks--; continue; } break; } } else { /* regexp */ int r; /* regtry status */ regexp *prog = km->re; /* if anchored, but we're not at beginning, skip pattern */ if (prog->reganch) { if (string != start_search) continue; } /* known starting char - quick test 'fore lotta work */ if (prog->regstart) { if ((*start_search & 0x7f) != prog->regstart) continue; } r = exp_regtry(prog,start_search,match_length); if (r == EXP_MATCH) { *km_match = km; *skip = start_search-string; return(EXP_MATCH); } if (r == EXP_CANMATCH) { if (!*km_match) *km_match = km; } } } } if (*km_match) { /* report a can-match */ char *p; *skip = (start_search-string)-1; #if 0 *match_length = stringlen - *skip; #else /* * there may be nulls in the string in which case * the pattern matchers can report CANMATCH when * the null is hit. So find the null and compute * the length of the possible match. * * Later, after we squeeze out the nulls, we will * retry the match, but for now, go along with * calling it a CANMATCH */ p = start_search; while (*p) { p++; } *match_length = (p - start_search) + 1; /*printf(" match_length = %d\n",*match_length);*/ #endif return(EXP_CANMATCH); } *skip = start_search-string; return(EXP_CANTMATCH); } #ifdef SIMPLE_EVENT /* The way that the "simple" interact works is that the original Expect process reads from the tty and writes to the spawned process. A child process is forked to read from the spawned process and write to the tty. It looks like this: user --> tty >-- / \ ^ v child original process Expect ^ process | v \ / < spawned < process */ #ifndef WEXITSTATUS #define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #include <setjmp.h> static jmp_buf env; /* for interruptable read() */ static int reading; /* while we are reading */ /* really, while "env" is valid */ static int deferred_interrupt = FALSE; /* if signal is received, but not */ /* in i_read record this here, so it will */ /* be handled next time through i_read */ void sigchld_handler() { if (reading) longjmp(env,1); deferred_interrupt = TRUE; } #define EXP_CHILD_EOF -100 /* interruptable read */ static int i_read(fd,buffer,length) int fd; char *buffer; int length; { int cc = EXP_CHILD_EOF; if (deferred_interrupt) return(cc); if (0 == setjmp(env)) { reading = TRUE; cc = read(fd,buffer,length); } reading = FALSE; return(cc); } /* exit status for the child process created by cmdInteract */ #define CHILD_DIED -2 #define SPAWNED_PROCESS_DIED -3 static void clean_up_after_child(interp,master) Tcl_Interp *interp; int master; { /* should really be recoded using the common wait code in command.c */ int status; int pid; int i; pid = wait(&status); /* for slave */ for (i=0;i<=exp_fd_max;i++) { if (exp_fs[i].pid == pid) { exp_fs[i].sys_waited = TRUE; exp_fs[i].wait = status; } } pid = wait(&status); /* for child */ for (i=0;i<=exp_fd_max;i++) { if (exp_fs[i].pid == pid) { exp_fs[i].sys_waited = TRUE; exp_fs[i].wait = status; } } deferred_interrupt = FALSE; exp_close(interp,master); master = -1; } #endif /*SIMPLE_EVENT*/ static int update_interact_fds(interp,fd_count,fd_to_input,fd_list,input_base, do_indirect,config_count,real_tty_caller) Tcl_Interp *interp; int *fd_count; struct input ***fd_to_input; /* map from fd's to "struct input"s */ int **fd_list; struct input *input_base; int do_indirect; /* if true do indirects */ int *config_count; int *real_tty_caller; { struct input *inp; struct output *outp; struct exp_fd_list *fdp; int count; int real_tty = FALSE; *config_count = exp_configure_count; count = 0; for (inp = input_base;inp;inp=inp->next) { if (do_indirect) { /* do not update "direct" entries (again) */ /* they were updated upon creation */ if (inp->i_list->direct == EXP_INDIRECT) { exp_i_update(interp,inp->i_list); } for (outp = inp->output;outp;outp=outp->next) { if (outp->i_list->direct == EXP_INDIRECT) { exp_i_update(interp,outp->i_list); } } } /* revalidate all input descriptors */ for (fdp = inp->i_list->fd_list;fdp;fdp=fdp->next) { count++; /* have to "adjust" just in case spawn id hasn't had */ /* a buffer sized yet */ if (!exp_fd2f(interp,fdp->fd,1,1,"interact")) return(TCL_ERROR); } /* revalidate all output descriptors */ for (outp = inp->output;outp;outp=outp->next) { for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) { /* make user_spawn_id point to stdout */ if (fdp->fd == 0) { fdp->fd = 1; } else if (fdp->fd == 1) { /* do nothing */ } else if (!exp_fd2f(interp,fdp->fd,1,0,"interact")) return(TCL_ERROR); } } } if (!do_indirect) return TCL_OK; if (*fd_to_input == 0) { *fd_to_input = (struct input **)ckalloc( (exp_fd_max+1) * sizeof(struct input *)); *fd_list = (int *)ckalloc(count * sizeof(int)); } else { *fd_to_input = (struct input **)ckrealloc((char *)*fd_to_input, (exp_fd_max+1) * sizeof(struct input *)); *fd_list = (int *)ckrealloc((char *)*fd_list,count * sizeof(int)); } count = 0; for (inp = input_base;inp;inp=inp->next) { for (fdp = inp->i_list->fd_list;fdp;fdp=fdp->next) { /* build map to translate from spawn_id to struct input */ (*fd_to_input)[fdp->fd] = inp; /* build input to ready() */ (*fd_list)[count] = fdp->fd; if (real_tty_input(fdp->fd)) real_tty = TRUE; count++; } } *fd_count = count; *real_tty_caller = real_tty; /* tell caller if we have found that */ /* we are using real tty */ return TCL_OK; } /*ARGSUSED*/ static char * inter_updateproc(clientData, interp, name1, name2, flags) ClientData clientData; Tcl_Interp *interp; /* Interpreter containing variable. */ char *name1; /* Name of variable. */ char *name2; /* Second part of variable name. */ int flags; /* Information about what happened. */ { exp_configure_count++; return 0; } #define finish(x) { status = x; goto done; } static char return_cmd[] = "return"; static char interpreter_cmd[] = "interpreter"; /*ARGSUSED*/ int Exp_InteractCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *arg; /* shorthand for current argv */ #ifdef SIMPLE_EVENT int pid; #endif /*SIMPLE_EVENT*/ /*declarations*/ int input_count; /* count of struct input descriptors */ struct input **fd_to_input; /* map from fd's to "struct input"s */ int *fd_list; struct keymap *km; /* ptr for above while parsing */ /* extern char *tclRegexpError; /* declared in tclInt.h */ int master = EXP_SPAWN_ID_BAD; char *master_string = 0;/* string representation of master */ int need_to_close_master = FALSE; /* if an eof is received */ /* we use this to defer close until later */ int next_tty_reset = FALSE; /* if we've seen a single -reset */ int next_iread = FALSE;/* if we've seen a single -iread */ int next_iwrite = FALSE;/* if we've seen a single -iread */ int next_re = FALSE; /* if we've seen a single -re */ int next_null = FALSE; /* if we've seen the null keyword */ int next_writethru = FALSE;/*if macros should also go to proc output */ int next_indices = FALSE;/* if we should write indices */ int next_echo = FALSE; /* if macros should be echoed */ int next_timestamp = FALSE; /* if we should generate a timestamp */ /* int next_case_sensitive = TRUE;*/ char **oldargv = 0; /* save original argv here if we split it */ int status = TCL_OK; /* final return value */ int i; /* trusty temp */ int timeout_simple = TRUE; /* if no or global timeout */ int real_tty; /* TRUE if we are interacting with real tty */ int tty_changed = FALSE;/* true if we had to change tty modes for */ /* interact to work (i.e., to raw, noecho) */ int was_raw; int was_echo; exp_tty tty_old; char *replace_user_by_process = 0; /* for -u flag */ struct input *input_base; #define input_user input_base struct input *input_default; struct input *inp; /* overused ptr to struct input */ struct output *outp; /* overused ptr to struct output */ int dash_input_count = 0; /* # of "-input"s seen */ int arbitrary_timeout; int default_timeout; struct action action_timeout; /* common to all */ struct action action_eof; /* common to all */ struct action **action_eof_ptr; /* allow -input/ouput to */ /* leave their eof-action assignable by a later */ /* -eof */ struct action *action_base = 0; struct keymap **end_km; int key; int configure_count; /* monitor reconfigure events */ char *argv0; if ((argc == 2) && exp_one_arg_braced(argv[1])) { return(exp_eval_with_one_arg(clientData,interp,argv)); } else if ((argc == 3) && streq(argv[1],"-brace")) { char *new_argv[2]; new_argv[0] = argv[0]; new_argv[1] = argv[2]; return(exp_eval_with_one_arg(clientData,interp,new_argv)); } argv0 = argv[0]; argv++; argc--; default_timeout = EXP_TIME_INFINITY; arbitrary_timeout = EXP_TIME_INFINITY; /* if user specifies */ /* a bunch of timeouts with EXP_TIME_INFINITY, this will be */ /* left around for us to find. */ input_user = new(struct input); input_user->i_list = exp_new_i_simple(0,EXP_TEMPORARY); /* stdin by default */ input_user->output = 0; input_user->action_eof = &action_eof; input_user->timeout_nominal = EXP_TIME_INFINITY; input_user->action_timeout = 0; input_user->keymap = 0; end_km = &input_user->keymap; inp = input_user; action_eof_ptr = &input_user->action_eof; input_default = new(struct input); input_default->i_list = exp_new_i_simple(EXP_SPAWN_ID_BAD,EXP_TEMPORARY); /* fix up later */ input_default->output = 0; input_default->action_eof = &action_eof; input_default->timeout_nominal = EXP_TIME_INFINITY; input_default->action_timeout = 0; input_default->keymap = 0; input_default->next = 0; /* no one else */ input_user->next = input_default; /* default and common -eof action */ action_eof.statement = return_cmd; action_eof.tty_reset = FALSE; action_eof.iread = FALSE; action_eof.iwrite = FALSE; action_eof.timestamp = FALSE; for (;argc>0;argc--,argv++) { arg = *argv; if (exp_flageq("eof",arg,3)) { struct action *action; argc--;argv++; *action_eof_ptr = action = new_action(&action_base); action->statement = *argv; action->tty_reset = next_tty_reset; next_tty_reset = FALSE; action->iwrite = next_iwrite; next_iwrite = FALSE; action->iread = next_iread; next_iread = FALSE; action->timestamp = next_timestamp; next_timestamp = FALSE; continue; } else if (exp_flageq("timeout",arg,7)) { int t; struct action *action; argc--;argv++; if (argc < 1) { exp_error(interp,"timeout needs time"); return(TCL_ERROR); } t = atoi(*argv); argc--;argv++; /* we need an arbitrary timeout to start */ /* search for lowest one later */ if (t != -1) arbitrary_timeout = t; timeout_simple = FALSE; action = inp->action_timeout = new_action(&action_base); inp->timeout_nominal = t; action->statement = *argv; action->tty_reset = next_tty_reset; next_tty_reset = FALSE; action->iwrite = next_iwrite; next_iwrite = FALSE; action->iread = next_iread; next_iread = FALSE; action->timestamp = next_timestamp; next_timestamp = FALSE; continue; } else if (exp_flageq("null",arg,4)) { next_null = TRUE; } else if (arg[0] == '-') { arg++; if (exp_flageq1('-',arg) /* "--" */ || (exp_flageq("exact",arg,3))) { argc--;argv++; } else if (exp_flageq("regexp",arg,2)) { if (argc < 1) { exp_error(interp,"-re needs pattern"); return(TCL_ERROR); } next_re = TRUE; argc--; argv++; } else if (exp_flageq("input",arg,2)) { dash_input_count++; if (dash_input_count == 2) { inp = input_default; input_user->next = input_default; } else if (dash_input_count > 2) { struct input *previous_input = inp; inp = new(struct input); previous_input->next = inp; } inp->output = 0; inp->action_eof = &action_eof; action_eof_ptr = &inp->action_eof; inp->timeout_nominal = default_timeout; inp->action_timeout = &action_timeout; inp->keymap = 0; end_km = &inp->keymap; inp->next = 0; argc--;argv++; if (argc < 1) { exp_error(interp,"-input needs argument"); return(TCL_ERROR); } /* inp->spawn_id = atoi(*argv);*/ inp->i_list = exp_new_i_complex(interp,*argv, EXP_TEMPORARY,inter_updateproc, argv0); if (inp->i_list == NULL) { return(TCL_ERROR); } continue; } else if (exp_flageq("output",arg,3)) { struct output *tmp; /* imply a "-input" */ if (dash_input_count == 0) dash_input_count = 1; outp = new(struct output); /* link new output in front of others */ tmp = inp->output; inp->output = outp; outp->next = tmp; argc--;argv++; if (argc < 1) { exp_error(interp,"-output needs argument"); return(TCL_ERROR); } outp->i_list = exp_new_i_complex(interp,*argv, EXP_TEMPORARY,inter_updateproc,argv0); if (outp->i_list == NULL) { return TCL_ERROR; } outp->action_eof = &action_eof; action_eof_ptr = &outp->action_eof; continue; } else if (exp_flageq1('u',arg)) { /* treat process as user */ argc--;argv++; if (argc < 1) { exp_error(interp,"-u needs argument"); return(TCL_ERROR); } replace_user_by_process = *argv; /* imply a "-input" */ if (dash_input_count == 0) dash_input_count = 1; continue; } else if (exp_flageq1('o',arg)) { /* apply following patterns to opposite side */ /* of interaction */ end_km = &input_default->keymap; /* imply two "-input" */ if (dash_input_count < 2) { dash_input_count = 2; inp = input_default; action_eof_ptr = &inp->action_eof; } continue; } else if (exp_flageq1('i',arg)) { /* substitute master */ argc--;argv++; /* master = atoi(*argv);*/ master_string = *argv; /* will be used later on */ end_km = &input_default->keymap; /* imply two "-input" */ if (dash_input_count < 2) { dash_input_count = 2; inp = input_default; action_eof_ptr = &inp->action_eof; } continue; /* } else if (exp_flageq("nocase",arg,3)) {*/ /* next_case_sensitive = FALSE;*/ /* continue;*/ } else if (exp_flageq("echo",arg,4)) { next_echo = TRUE; continue; } else if (exp_flageq("nobuffer",arg,3)) { next_writethru = TRUE; continue; } else if (exp_flageq("indices",arg,3)) { next_indices = TRUE; continue; } else if (exp_flageq1('f',arg)) { /* leftover from "fast" days */ continue; } else if (exp_flageq("reset",arg,5)) { next_tty_reset = TRUE; continue; } else if (exp_flageq1('F',arg)) { /* leftover from "fast" days */ continue; } else if (exp_flageq("iread",arg,2)) { next_iread = TRUE; continue; } else if (exp_flageq("iwrite",arg,2)) { next_iwrite = TRUE; continue; } else if (exp_flageq("eof",arg,3)) { struct action *action; argc--;argv++; exp_debuglog("-eof is deprecated, use eof\r\n"); *action_eof_ptr = action = new_action(&action_base); action->statement = *argv; action->tty_reset = next_tty_reset; next_tty_reset = FALSE; action->iwrite = next_iwrite; next_iwrite = FALSE; action->iread = next_iread; next_iread = FALSE; action->timestamp = next_timestamp; next_timestamp = FALSE; continue; } else if (exp_flageq("timeout",arg,7)) { int t; struct action *action; exp_debuglog("-timeout is deprecated, use timeout\r\n"); argc--;argv++; if (argc < 1) { exp_error(interp,"-timeout needs time"); return(TCL_ERROR); } t = atoi(*argv); argc--;argv++; if (t != -1) arbitrary_timeout = t; /* we need an arbitrary timeout to start */ /* search for lowest one later */ #if 0 /* if -timeout comes before "-input", then applies */ /* to all descriptors, else just the current one */ if (dash_input_count > 0) { timeout_simple = FALSE; action = inp->action_timeout = new_action(&action_base); inp->timeout_nominal = t; } else { action = &action_timeout; default_timeout = t; } #endif timeout_simple = FALSE; action = inp->action_timeout = new_action(&action_base); inp->timeout_nominal = t; action->statement = *argv; action->tty_reset = next_tty_reset; next_tty_reset = FALSE; action->iwrite = next_iwrite; next_iwrite = FALSE; action->iread = next_iread; next_iread = FALSE; action->timestamp = next_timestamp; next_timestamp = FALSE; continue; } else if (exp_flageq("timestamp",arg,2)) { exp_debuglog("-timestamp is deprecated, use exp_timestamp command\r\n"); next_timestamp = TRUE; continue; } else if (exp_flageq("nobrace",arg,7)) { /* nobrace does nothing but take up space */ /* on the command line which prevents */ /* us from re-expanding any command lines */ /* of one argument that looks like it should */ /* be expanded to multiple arguments. */ continue; } } /* * pick up the pattern */ km = new(struct keymap); /* so that we can match in order user specified */ /* link to end of keymap list */ *end_km = km; km->next = 0; end_km = &km->next; km->echo = next_echo; km->writethru = next_writethru; km->indices = next_indices; km->action.tty_reset = next_tty_reset; km->action.iwrite = next_iwrite; km->action.iread = next_iread; km->action.timestamp = next_timestamp; /* km->case_sensitive = next_case_sensitive;*/ next_indices = next_echo = next_writethru = FALSE; next_tty_reset = FALSE; next_iwrite = next_iread = FALSE; /* next_case_sensitive = TRUE;*/ km->keys = *argv; km->null = FALSE; km->re = 0; if (next_re) { TclRegError((char *)0); if (0 == (km->re = TclRegComp(*argv))) { exp_error(interp,"bad regular expression: %s", TclGetRegError()); return(TCL_ERROR); } next_re = FALSE; } if (next_null) { km->null = TRUE; next_null = FALSE; } argc--;argv++; km->action.statement = *argv; exp_debuglog("defining key %s, action %s\r\n", km->keys, km->action.statement?(dprintify(km->action.statement)) :interpreter_cmd); /* imply a "-input" */ if (dash_input_count == 0) dash_input_count = 1; } /* if the user has not supplied either "-output" for the */ /* default two "-input"s, fix them up here */ if (!input_user->output) { struct output *o = new(struct output); if (master_string == 0) { if (0 == exp_update_master(interp,&master,1,1)) { return(TCL_ERROR); } o->i_list = exp_new_i_simple(master,EXP_TEMPORARY); } else { o->i_list = exp_new_i_complex(interp,master_string, EXP_TEMPORARY,inter_updateproc,argv0); if (o->i_list == NULL) { return(TCL_ERROR); } } #if 0 if (master == EXP_SPAWN_ID_BAD) { if (0 == exp_update_master(interp,&master,1,1)) { return(TCL_ERROR); } } o->i_list = exp_new_i_simple(master,EXP_TEMPORARY); #endif o->next = 0; /* no one else */ o->action_eof = &action_eof; input_user->output = o; } if (!input_default->output) { struct output *o = new(struct output); o->i_list = exp_new_i_simple(1,EXP_TEMPORARY);/* stdout by default */ o->next = 0; /* no one else */ o->action_eof = &action_eof; input_default->output = o; } /* if user has given "-u" flag, substitute process for user */ /* in first two -inputs */ if (replace_user_by_process) { /* through away old ones */ exp_free_i(interp,input_user->i_list, inter_updateproc); exp_free_i(interp,input_default->output->i_list,inter_updateproc); /* replace with arg to -u */ input_user->i_list = exp_new_i_complex(interp, replace_user_by_process, EXP_TEMPORARY,inter_updateproc,argv0); if (input_user->i_list == NULL) { return(TCL_ERROR); } input_default->output->i_list = exp_new_i_complex(interp, replace_user_by_process, EXP_TEMPORARY,inter_updateproc,argv0); } /* * now fix up for default spawn id */ /* user could have replaced it with an indirect, so force update */ if (input_default->i_list->direct == EXP_INDIRECT) { exp_i_update(interp,input_default->i_list); } if (input_default->i_list->fd_list && (input_default->i_list->fd_list->fd == EXP_SPAWN_ID_BAD)) { if (master_string == 0) { if (0 == exp_update_master(interp,&master,1,1)) { return(TCL_ERROR); } input_default->i_list->fd_list->fd = master; } else { /* discard old one and install new one */ exp_free_i(interp,input_default->i_list,inter_updateproc); input_default->i_list = exp_new_i_complex(interp,master_string, EXP_TEMPORARY,inter_updateproc,argv0); if (input_default->i_list == NULL) { return(TCL_ERROR); } } #if 0 if (master == EXP_SPAWN_ID_BAD) { if (0 == exp_update_master(interp,&master,1,1)) { return(TCL_ERROR); } } input_default->i_list->fd_list->fd = master; #endif } /* * check for user attempting to interact with self * they're almost certainly just fooling around */ /* user could have replaced it with an indirect, so force update */ if (input_user->i_list->direct == EXP_INDIRECT) { exp_i_update(interp,input_user->i_list); } if (input_user->i_list->fd_list && input_default->i_list->fd_list && (input_user->i_list->fd_list->fd == input_default->i_list->fd_list->fd)) { exp_error(interp,"cannot interact with self - set spawn_id to a spawned process"); return(TCL_ERROR); } fd_list = 0; fd_to_input = 0; /***************************************************************/ /* all data structures are sufficiently set up that we can now */ /* "finish()" to terminate this procedure */ /***************************************************************/ status = update_interact_fds(interp,&input_count,&fd_to_input,&fd_list,input_base,1,&configure_count,&real_tty); if (status == TCL_ERROR) finish(TCL_ERROR); if (real_tty) { tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo); } for (inp = input_base,i=0;inp;inp=inp->next,i++) { struct exp_fd_list *fdp; for (fdp = inp->i_list->fd_list;fdp;fdp=fdp->next) { /* start timers */ inp->timeout_remaining = inp->timeout_nominal; } } key = expect_key++; /* declare ourselves "in sync" with external view of close/indirect */ configure_count = exp_configure_count; #ifndef SIMPLE_EVENT /* loop waiting (in event handler) for input */ for (;;) { int te; /* result of Tcl_Eval */ struct exp_f *u; int rc; /* return code from ready. This is further */ /* refined by matcher. */ int cc; /* chars count from read() */ int m; /* master */ int m_out; /* where master echoes to */ struct action *action = 0; time_t previous_time; time_t current_time; int match_length, skip; int change; /* if action requires cooked mode */ int attempt_match = TRUE; struct input *soonest_input; int print; /* # of chars to print */ int oldprinted; /* old version of u->printed */ int timeout; /* current as opposed to default_timeout */ /* calculate how long to wait */ /* by finding shortest remaining timeout */ if (timeout_simple) { timeout = default_timeout; } else { timeout = arbitrary_timeout; for (inp=input_base;inp;inp=inp->next) { if ((inp->timeout_remaining != EXP_TIME_INFINITY) && (inp->timeout_remaining <= timeout)) { soonest_input = inp; timeout = inp->timeout_remaining; } } time(&previous_time); /* timestamp here rather than simply saving old */ /* current time (after ready()) to account for */ /* possibility of slow actions */ /* timeout can actually be EXP_TIME_INFINITY here if user */ /* explicitly supplied it in a few cases (or */ /* the count-down code is broken) */ } /* update the world, if necessary */ if (configure_count != exp_configure_count) { status = update_interact_fds(interp,&input_count, &fd_to_input,&fd_list,input_base,1, &configure_count,&real_tty); if (status) finish(status); } rc = exp_get_next_event(interp,fd_list,input_count,&m,timeout,key); if (rc == EXP_TCLERROR) return(TCL_ERROR); if (rc == EXP_RECONFIGURE) continue; if (rc == EXP_TIMEOUT) { if (timeout_simple) { action = &action_timeout; goto got_action; } else { action = soonest_input->action_timeout; /* arbitrarily pick first fd out of list */ m = soonest_input->i_list->fd_list->fd; } } if (!timeout_simple) { int time_diff; time(¤t_time); time_diff = current_time - previous_time; /* update all timers */ for (inp=input_base;inp;inp=inp->next) { if (inp->timeout_remaining != EXP_TIME_INFINITY) { inp->timeout_remaining -= time_diff; if (inp->timeout_remaining < 0) inp->timeout_remaining = 0; } } } /* at this point, we have some kind of event which can be */ /* immediately processed - i.e. something that doesn't block */ /* figure out who we are */ inp = fd_to_input[m]; /* u = inp->f;*/ u = exp_fs+m; /* reset timer */ inp->timeout_remaining = inp->timeout_nominal; switch (rc) { case EXP_DATA_NEW: if (u->size == u->msize) { /* In theory, interact could be invoked when this situation */ /* already exists, hence the "probably" in the warning below */ exp_debuglog("WARNING: interact buffer is full, probably because your\r\n"); exp_debuglog("patterns have matched all of it but require more chars\r\n"); exp_debuglog("in order to complete the match.\r\n"); exp_debuglog("Dumping first half of buffer in order to continue\r\n"); exp_debuglog("Recommend you enlarge the buffer or fix your patterns.\r\n"); exp_buffer_shuffle(interp,u,0,INTER_OUT,"interact"); } cc = read(m, u->buffer + u->size, u->msize - u->size); if (cc > 0) { u->key = key; u->size += cc; u->buffer[u->size] = '\0'; /* strip parity if requested */ if (u->parity == 0) { /* do it from end backwards */ char *p = u->buffer + u->size - 1; int count = cc; while (count--) { *p-- &= 0x7f; } } /* avoid another function call if possible */ if (debugfile || is_debugging) { exp_debuglog("spawn id %d sent <%s>\r\n",m, exp_printify(u->buffer + u->size - cc)); } break; } rc = EXP_EOF; /* Most systems have read() return 0, allowing */ /* control to fall thru and into this code. On some */ /* systems (currently HP and new SGI), read() does */ /* see eof, and it must be detected earlier. Then */ /* control jumps directly to this EXP_EOF label. */ /*FALLTHRU*/ case EXP_EOF: action = inp->action_eof; attempt_match = FALSE; skip = u->size; exp_debuglog("interact: received eof from spawn_id %d\r\n",m); /* actual close is done later so that we have a */ /* chance to flush out any remaining characters */ need_to_close_master = TRUE; #if EOF_SO /* should really check for remaining chars and */ /* flush them but this will only happen in the */ /* unlikely scenario that there are partially */ /* matched buffered chars. */ /* So for now, indicate no chars to skip. */ skip = 0; exp_close(interp,m); #endif break; case EXP_DATA_OLD: cc = 0; break; case EXP_TIMEOUT: action = inp->action_timeout; attempt_match = FALSE; skip = u->size; break; } km = 0; if (attempt_match) { rc = in_keymap(u->buffer,u->size,inp->keymap, &km,&match_length,&skip,u->rm_nulls); } else { attempt_match = TRUE; } /* put regexp result in variables */ if (km && km->re) { #define out(var,val) exp_debuglog("expect: set %s(%s) \"%s\"\r\n",INTER_OUT,var, \ dprintify(val)); \ Tcl_SetVar2(interp,INTER_OUT,var,val,0); char name[20], value[20]; regexp *re = km->re; char match_char;/* place to hold char temporarily */ /* uprooted by a NULL */ for (i=0;i<NSUBEXP;i++) { int offset; if (re->startp[i] == 0) continue; if (km->indices) { /* start index */ sprintf(name,"%d,start",i); offset = re->startp[i]-u->buffer; sprintf(value,"%d",offset); out(name,value); /* end index */ sprintf(name,"%d,end",i); sprintf(value,"%d",re->endp[i]-u->buffer-1); out(name,value); } /* string itself */ sprintf(name,"%d,string",i); /* temporarily null-terminate in */ /* middle */ match_char = *re->endp[i]; *re->endp[i] = 0; out(name,re->startp[i]); *re->endp[i] = match_char; } } /* * dispose of chars that should be skipped * i.e., chars that cannot possibly be part of a match. */ /* "skip" is count of chars not involved in match */ /* "print" is count with chars involved in match */ if (km && km->writethru) { print = skip + match_length; } else print = skip; /* * echo chars if appropriate */ if (km && km->echo) { int seen; /* either printed or echoed */ /* echo to stdout rather than stdin */ m_out = (m == 0)?1:m; /* write is unlikely to fail, since we just read */ /* from same descriptor */ seen = u->printed + u->echoed; if (skip >= seen) { write(m_out,u->buffer+skip,match_length); } else if ((match_length + skip - seen) > 0) { write(m_out,u->buffer+seen,match_length+skip-seen); } u->echoed = match_length + skip - u->printed; } oldprinted = u->printed; /* If expect has left characters in buffer, it has */ /* already echoed them to the screen, thus we must */ /* prevent them being rewritten. Unfortunately this */ /* gives the possibility of matching chars that have */ /* already been output, but we do so since the user */ /* could have avoided it by flushing the output */ /* buffers directly. */ if (print > u->printed) { /* usual case */ int wc; /* return code from write() */ for (outp = inp->output;outp;outp=outp->next) { struct exp_fd_list *fdp; for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) { int od; /* output descriptor */ /* send to logfile if open */ /* and user is seeing it */ if (logfile && real_tty_output(fdp->fd)) { fwrite(u->buffer+u->printed,1, print - u->printed,logfile); } /* send to each output descriptor */ od = fdp->fd; /* if opened by Tcl, it may use a different */ /* output descriptor */ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od); wc = write(od,u->buffer+u->printed, print - u->printed); if (wc <= 0) { exp_debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp)); action = outp->action_eof; change = (action && action->tty_reset); if (change && tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); te = inter_eval(interp,action,m); if (change && real_tty) tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } } u->printed = print; } /* u->printed is now accurate with respect to the buffer */ /* However, we're about to shift the old data out of the */ /* buffer. Thus, u->size, printed, and echoed must be */ /* updated */ /* first update size based on skip information */ /* then set skip to the total amount skipped */ if (rc == EXP_MATCH) { action = &km->action; skip += match_length; u->size -= skip; if (u->size) { memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } } else { if (skip) { u->size -= skip; memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } } #if EOF_SO /* as long as buffer is still around, null terminate it */ if (rc != EXP_EOF) { u->buffer[u->size] = '\0'; u->lower [u->size] = '\0'; } #else u->buffer[u->size] = '\0'; u->lower [u->size] = '\0'; #endif /* now update printed based on total amount skipped */ u->printed -= skip; /* if more skipped than printed (i.e., keymap encountered) */ /* for printed positive */ if (u->printed < 0) u->printed = 0; /* if we are in the middle of a match, force the next event */ /* to wait for more data to arrive */ u->force_read = (rc == EXP_CANMATCH); /* finally reset echoed if necessary */ if (rc != EXP_CANMATCH) { if (skip >= oldprinted + u->echoed) u->echoed = 0; } if (rc == EXP_EOF) { exp_close(interp,m); need_to_close_master = FALSE; } if (action) { got_action: change = (action && action->tty_reset); if (change && tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); te = inter_eval(interp,action,m); if (change && real_tty) tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } #else /* SIMPLE_EVENT */ /* deferred_interrupt = FALSE;*/ { int te; /* result of Tcl_Eval */ struct exp_f *u; int rc; /* return code from ready. This is further */ /* refined by matcher. */ int cc; /* chars count from read() */ int m; /* master */ struct action *action = 0; time_t previous_time; time_t current_time; int match_length, skip; int change; /* if action requires cooked mode */ int attempt_match = TRUE; struct input *soonest_input; int print; /* # of chars to print */ int oldprinted; /* old version of u->printed */ int timeout; /* current as opposed to default_timeout */ if (-1 == (pid = fork())) { exp_error(interp,"fork: %s",Tcl_PosixError(interp)); finish(TCL_ERROR); } if (pid == 0) { /* child - send process output to user */ exp_close(interp,0); m = fd_list[1]; /* get 2nd fd */ input_count = 1; while (1) { /* calculate how long to wait */ /* by finding shortest remaining timeout */ if (timeout_simple) { timeout = default_timeout; } else { timeout = arbitrary_timeout; for (inp=input_base;inp;inp=inp->next) { if ((inp->timeout_remaining != EXP_TIME_INFINITY) && (inp->timeout_remaining < timeout)) soonest_input = inp; timeout = inp->timeout_remaining; } time(&previous_time); /* timestamp here rather than simply saving old */ /* current time (after ready()) to account for */ /* possibility of slow actions */ /* timeout can actually be EXP_TIME_INFINITY here if user */ /* explicitly supplied it in a few cases (or */ /* the count-down code is broken) */ } /* +1 so we can look at the "other" file descriptor */ rc = exp_get_next_event(interp,fd_list+1,input_count,&m,timeout,key); if (!timeout_simple) { int time_diff; time(¤t_time); time_diff = current_time - previous_time; /* update all timers */ for (inp=input_base;inp;inp=inp->next) { if (inp->timeout_remaining != EXP_TIME_INFINITY) { inp->timeout_remaining -= time_diff; if (inp->timeout_remaining < 0) inp->timeout_remaining = 0; } } } /* at this point, we have some kind of event which can be */ /* immediately processed - i.e. something that doesn't block */ /* figure out who we are */ inp = fd_to_input[m]; /* u = inp->f;*/ u = exp_fs+m; switch (rc) { case EXP_DATA_NEW: cc = read(m, u->buffer + u->size, u->msize - u->size); if (cc > 0) { u->key = key; u->size += cc; u->buffer[u->size] = '\0'; /* strip parity if requested */ if (u->parity == 0) { /* do it from end backwards */ char *p = u->buffer + u->size - 1; int count = cc; while (count--) { *p-- &= 0x7f; } } /* avoid another function call if possible */ if (debugfile || is_debugging) { exp_debuglog("spawn id %d sent <%s>\r\n",m, exp_printify(u->buffer + u->size - cc)); } break; } /*FALLTHRU*/ /* Most systems have read() return 0, allowing */ /* control to fall thru and into this code. On some */ /* systems (currently HP and new SGI), read() does */ /* see eof, and it must be detected earlier. Then */ /* control jumps directly to this EXP_EOF label. */ case EXP_EOF: action = inp->action_eof; attempt_match = FALSE; skip = u->size; rc = EXP_EOF; exp_debuglog("interact: child received eof from spawn_id %d\r\n",m); exp_close(interp,m); break; case EXP_DATA_OLD: cc = 0; break; } km = 0; if (attempt_match) { rc = in_keymap(u->buffer,u->size,inp->keymap, &km,&match_length,&skip); } else { attempt_match = TRUE; } /* put regexp result in variables */ if (km && km->re) { #define INTER_OUT "interact_out" #define out(i,val) exp_debuglog("expect: set %s(%s) \"%s\"\r\n",INTER_OUT,i, \ dprintify(val)); \ Tcl_SetVar2(interp,INTER_OUT,i,val,0); char name[20], value[20]; regexp *re = km->re; char match_char;/* place to hold char temporarily */ /* uprooted by a NULL */ for (i=0;i<NSUBEXP;i++) { int offset; if (re->startp[i] == 0) continue; if (km->indices) { /* start index */ sprintf(name,"%d,start",i); offset = re->startp[i]-u->buffer; sprintf(value,"%d",offset); out(name,value); /* end index */ sprintf(name,"%d,end",i); sprintf(value,"%d",re->endp[i]-u->buffer-1); out(name,value); } /* string itself */ sprintf(name,"%d,string",i); /* temporarily null-terminate in */ /* middle */ match_char = *re->endp[i]; *re->endp[i] = 0; out(name,re->startp[i]); *re->endp[i] = match_char; } } /* dispose of chars that should be skipped */ /* skip is chars not involved in match */ /* print is with chars involved in match */ if (km && km->writethru) { print = skip + match_length; } else print = skip; /* figure out if we should echo any chars */ if (km && km->echo) { int seen; /* either printed or echoed */ /* echo to stdout rather than stdin */ if (m == 0) m = 1; /* write is unlikely to fail, since we just read */ /* from same descriptor */ seen = u->printed + u->echoed; if (skip >= seen) { write(m,u->buffer+skip,match_length); } else if ((match_length + skip - seen) > 0) { write(m,u->buffer+seen,match_length+skip-seen); } u->echoed = match_length + skip - u->printed; } oldprinted = u->printed; /* If expect has left characters in buffer, it has */ /* already echoed them to the screen, thus we must */ /* prevent them being rewritten. Unfortunately this */ /* gives the possibility of matching chars that have */ /* already been output, but we do so since the user */ /* could have avoided it by flushing the output */ /* buffers directly. */ if (print > u->printed) { /* usual case */ int wc; /* return code from write() */ for (outp = inp->output;outp;outp=outp->next) { struct exp_fd_list *fdp; for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) { int od; /* output descriptor */ /* send to logfile if open */ /* and user is seeing it */ if (logfile && real_tty_output(fdp->fd)) { fwrite(u->buffer+u->printed,1, print - u->printed,logfile); } /* send to each output descriptor */ od = fdp->fd; /* if opened by Tcl, it may use a different */ /* output descriptor */ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od); wc = write(od,u->buffer+u->printed, print - u->printed); if (wc <= 0) { exp_debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp)); action = outp->action_eof; te = inter_eval(interp,action,m); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } } u->printed = print; } /* u->printed is now accurate with respect to the buffer */ /* However, we're about to shift the old data out of the */ /* buffer. Thus, u->size, printed, and echoed must be */ /* updated */ /* first update size based on skip information */ /* then set skip to the total amount skipped */ if (rc == EXP_MATCH) { action = &km->action; skip += match_length; u->size -= skip; if (u->size) memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } else { if (skip) { u->size -= skip; memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } } /* as long as buffer is still around, null terminate it */ if (rc != EXP_EOF) { u->buffer[u->size] = '\0'; u->lower [u->size] = '\0'; } /* now update printed based on total amount skipped */ u->printed -= skip; /* if more skipped than printed (i.e., keymap encountered) */ /* for printed positive */ if (u->printed < 0) u->printed = 0; /* if we are in the middle of a match, force the next event */ /* to wait for more data to arrive */ u->force_read = (rc == EXP_CANMATCH); /* finally reset echoed if necessary */ if (rc != EXP_CANMATCH) { if (skip >= oldprinted + u->echoed) u->echoed = 0; } if (action) { te = inter_eval(interp,action,m); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } } else { /* parent - send user keystrokes to process */ #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif exp_debuglog("fork = %d\r\n",pid); signal(SIGCHLD,sigchld_handler); /* restart:*/ /* tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo);*/ m = fd_list[0]; /* get 1st fd */ input_count = 1; while (1) { /* calculate how long to wait */ /* by finding shortest remaining timeout */ if (timeout_simple) { timeout = default_timeout; } else { timeout = arbitrary_timeout; for (inp=input_base;inp;inp=inp->next) { if ((inp->timeout_remaining != EXP_TIME_INFINITY) && (inp->timeout_remaining < timeout)) soonest_input = inp; timeout = inp->timeout_remaining; } time(&previous_time); /* timestamp here rather than simply saving old */ /* current time (after ready()) to account for */ /* possibility of slow actions */ /* timeout can actually be EXP_TIME_INFINITY here if user */ /* explicitly supplied it in a few cases (or */ /* the count-down code is broken) */ } rc = exp_get_next_event(interp,fd_list,input_count,&m,timeout,key); if (!timeout_simple) { int time_diff; time(¤t_time); time_diff = current_time - previous_time; /* update all timers */ for (inp=input_base;inp;inp=inp->next) { if (inp->timeout_remaining != EXP_TIME_INFINITY) { inp->timeout_remaining -= time_diff; if (inp->timeout_remaining < 0) inp->timeout_remaining = 0; } } } /* at this point, we have some kind of event which can be */ /* immediately processed - i.e. something that doesn't block */ /* figure out who we are */ inp = fd_to_input[m]; /* u = inp->f;*/ u = exp_fs+m; switch (rc) { case EXP_DATA_NEW: cc = i_read(m, u->buffer + u->size, u->msize - u->size); if (cc > 0) { u->key = key; u->size += cc; u->buffer[u->size] = '\0'; /* strip parity if requested */ if (u->parity == 0) { /* do it from end backwards */ char *p = u->buffer + u->size - 1; int count = cc; while (count--) { *p-- &= 0x7f; } } /* avoid another function call if possible */ if (debugfile || is_debugging) { exp_debuglog("spawn id %d sent <%s>\r\n",m, exp_printify(u->buffer + u->size - cc)); } break; } else if (cc == EXP_CHILD_EOF) { /* user could potentially have two outputs in which */ /* case we might be looking at the wrong one, but */ /* the likelihood of this is nil */ action = inp->output->action_eof; attempt_match = FALSE; skip = u->size; rc = EXP_EOF; exp_debuglog("interact: process died/eof\r\n"); clean_up_after_child(interp,fd_list[1]); break; } /*FALLTHRU*/ /* Most systems have read() return 0, allowing */ /* control to fall thru and into this code. On some */ /* systems (currently HP and new SGI), read() does */ /* see eof, and it must be detected earlier. Then */ /* control jumps directly to this EXP_EOF label. */ case EXP_EOF: action = inp->action_eof; attempt_match = FALSE; skip = u->size; rc = EXP_EOF; exp_debuglog("user sent EOF or disappeared\n\n"); break; case EXP_DATA_OLD: cc = 0; break; } km = 0; if (attempt_match) { rc = in_keymap(u->buffer,u->size,inp->keymap, &km,&match_length,&skip); } else { attempt_match = TRUE; } /* put regexp result in variables */ if (km && km->re) { char name[20], value[20]; regexp *re = km->re; char match_char;/* place to hold char temporarily */ /* uprooted by a NULL */ for (i=0;i<NSUBEXP;i++) { int offset; if (re->startp[i] == 0) continue; if (km->indices) { /* start index */ sprintf(name,"%d,start",i); offset = re->startp[i]-u->buffer; sprintf(value,"%d",offset); out(name,value); /* end index */ sprintf(name,"%d,end",i); sprintf(value,"%d",re->endp[i]-u->buffer-1); out(name,value); } /* string itself */ sprintf(name,"%d,string",i); /* temporarily null-terminate in */ /* middle */ match_char = *re->endp[i]; *re->endp[i] = 0; out(name,re->startp[i]); *re->endp[i] = match_char; } } /* dispose of chars that should be skipped */ /* skip is chars not involved in match */ /* print is with chars involved in match */ if (km && km->writethru) { print = skip + match_length; } else print = skip; /* figure out if we should echo any chars */ if (km && km->echo) { int seen; /* either printed or echoed */ /* echo to stdout rather than stdin */ if (m == 0) m = 1; /* write is unlikely to fail, since we just read */ /* from same descriptor */ seen = u->printed + u->echoed; if (skip >= seen) { write(m,u->buffer+skip,match_length); } else if ((match_length + skip - seen) > 0) { write(m,u->buffer+seen,match_length+skip-seen); } u->echoed = match_length + skip - u->printed; } oldprinted = u->printed; /* If expect has left characters in buffer, it has */ /* already echoed them to the screen, thus we must */ /* prevent them being rewritten. Unfortunately this */ /* gives the possibility of matching chars that have */ /* already been output, but we do so since the user */ /* could have avoided it by flushing the output */ /* buffers directly. */ if (print > u->printed) { /* usual case */ int wc; /* return code from write() */ for (outp = inp->output;outp;outp=outp->next) { struct exp_fd_list *fdp; for (fdp = outp->i_list->fd_list;fdp;fdp=fdp->next) { int od; /* output descriptor */ /* send to logfile if open */ /* and user is seeing it */ if (logfile && real_tty_output(fdp->fd)) { fwrite(u->buffer+u->printed,1, print - u->printed,logfile); } /* send to each output descriptor */ od = fdp->fd; /* if opened by Tcl, it may use a different */ /* output descriptor */ od = (exp_fs[od].tcl_handle?exp_fs[od].tcl_output:od); wc = write(od,u->buffer+u->printed, print - u->printed); if (wc <= 0) { exp_debuglog("interact: write on spawn id %d failed (%s)\r\n",fdp->fd,Tcl_PosixError(interp)); clean_up_after_child(interp,fdp->fd); action = outp->action_eof; change = (action && action->tty_reset); if (change && tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); te = inter_eval(interp,action,m); if (change && real_tty) tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } } u->printed = print; } /* u->printed is now accurate with respect to the buffer */ /* However, we're about to shift the old data out of the */ /* buffer. Thus, u->size, printed, and echoed must be */ /* updated */ /* first update size based on skip information */ /* then set skip to the total amount skipped */ if (rc == EXP_MATCH) { action = &km->action; skip += match_length; u->size -= skip; if (u->size) memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } else { if (skip) { u->size -= skip; memcpy(u->buffer, u->buffer + skip, u->size); exp_lowmemcpy(u->lower,u->buffer+ skip, u->size); } } /* as long as buffer is still around, null terminate it */ if (rc != EXP_EOF) { u->buffer[u->size] = '\0'; u->lower [u->size] = '\0'; } /* now update printed based on total amount skipped */ u->printed -= skip; /* if more skipped than printed (i.e., keymap encountered) */ /* for printed positive */ if (u->printed < 0) u->printed = 0; /* if we are in the middle of a match, force the next event */ /* to wait for more data to arrive */ u->force_read = (rc == EXP_CANMATCH); /* finally reset echoed if necessary */ if (rc != EXP_CANMATCH) { if (skip >= oldprinted + u->echoed) u->echoed = 0; } if (action) { change = (action && action->tty_reset); if (change && tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); te = inter_eval(interp,action,m); if (change && real_tty) tty_changed = exp_tty_raw_noecho(interp,&tty_old,&was_raw,&was_echo); switch (te) { case TCL_BREAK: case TCL_CONTINUE: finish(te); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); case TCL_OK: /* god knows what the user might */ /* have done to us in the way of */ /* closed fds, so .... */ action = 0; /* reset action */ continue; default: finish(te); } } } } } #endif /* SIMPLE_EVENT */ done: #ifdef SIMPLE_EVENT /* force child to exit upon eof from master */ if (pid == 0) { exit(SPAWNED_PROCESS_DIED); } #endif /* SIMPLE_EVENT */ if (need_to_close_master) exp_close(interp,master); if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); if (oldargv) ckfree((char *)argv); if (fd_list) ckfree((char *)fd_list); if (fd_to_input) ckfree((char *)fd_to_input); free_input(interp,input_base); free_action(action_base); return(status); } /* version of Tcl_Eval for interact */ static int inter_eval(interp,action,spawn_id) Tcl_Interp *interp; struct action *action; int spawn_id; { int status; char value[20]; /* deprecated */ if (action->timestamp) { time_t current_time; time(¤t_time); exp_timestamp(interp,¤t_time,INTER_OUT); } /* deprecated */ if (action->iwrite) { sprintf(value,"%d",spawn_id); out("spawn_id",value); } if (action->statement) { status = Tcl_Eval(interp,action->statement); } else { exp_nflog("\r\n",1); status = exp_interpreter(interp); } return status; } static void free_keymap(km) struct keymap *km; { if (km == 0) return; free_keymap(km->next); ckfree((char *)km); } static void free_action(a) struct action *a; { struct action *next; while (a) { next = a->next; ckfree((char *)a); a = next; } } static void free_input(interp,i) Tcl_Interp *interp; struct input *i; { if (i == 0) return; free_input(interp,i->next); exp_free_i(interp,i->i_list,inter_updateproc); free_output(interp,i->output); free_keymap(i->keymap); ckfree((char *)i); } static struct action * new_action(base) struct action **base; { struct action *o = new(struct action); /* stick new action into beginning of list of all actions */ o->next = *base; *base = o; return o; } static void free_output(interp,o) Tcl_Interp *interp; struct output *o; { if (o == 0) return; free_output(interp,o->next); exp_free_i(interp,o->i_list,inter_updateproc); ckfree((char *)o); } #endif /* __WIN32__ */ static struct exp_cmd_data cmd_data[] = { #ifndef __WIN32__ {"interact", 0, Exp_InteractCmd, 0, 0}, #endif {0}}; void exp_init_interact_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } |
Added generic/exp_log.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 | /* ---------------------------------------------------------------------------- * exp_log.c -- * * logging routines and other things common to both Expect * program and library. Note that this file must NOT have any * references to Tcl except for including tclInt.h * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #ifdef _MSC_VER # define vsnprintf _vsnprintf #endif int exp_loguser = TRUE; /* if TRUE, expect/spawn may write to stdout */ int exp_logfile_all = FALSE; /* if TRUE, write log of all interactions */ /* despite value of loguser. */ Tcl_Channel exp_logfile = NULL; Tcl_Channel exp_debugfile = NULL; int exp_is_debugging = FALSE; /* Following this are several functions that log the conversation. */ /* Most of them have multiple calls to printf-style functions. */ /* At first glance, it seems stupid to reformat the same arguments again */ /* but we have no way of telling how long the formatted output will be */ /* and hence cannot allocate a buffer to do so. */ /* Fortunately, in production code, most of the duplicate reformatting */ /* will be skipped, since it is due to handling errors and debugging. */ /* *---------------------------------------------------------------------- * * exp_log -- * * Send to the logfile if it is open. * Send to stderr if debugging is enabled. * use this for logging everything but the parent/child conversation * (this turns out to be almost nothing) * * Results: * None * * Side Effects: * Messages may be written to a logfile * * Notes: * Static buffer is used, so overflow can be in issue * *---------------------------------------------------------------------- */ #define LOGUSER (exp_loguser || force_stdout) /*VARARGS*/ void exp_log TCL_VARARGS_DEF(int,arg1) { int force_stdout; char buf[4096]; char *p = buf; int len = sizeof(buf); int n; char *fmt; Tcl_Channel chan; va_list args; force_stdout = TCL_VARARGS_START(int,arg1,args); fmt = va_arg(args,char *); n = -1; while (n == -1) { n = vsnprintf(p, len, fmt, args); if (n == -1) { if (p != buf) { free(p); } len *= 2; p = malloc(len); } } if (exp_debugfile) Tcl_Write(exp_debugfile, buf, n); if (exp_logfile_all || (LOGUSER && exp_logfile)) Tcl_Write(exp_logfile, buf, n); if (LOGUSER) { chan = Tcl_GetStdChannel(TCL_STDOUT); if (chan) { Tcl_Write(chan, buf, n); } } if (p != buf) { free(p); } va_end(args); } /* *---------------------------------------------------------------------- * * exp_nflog -- * * Send to the logfile if it is open. Just like exp_log, but * it does no formatting. Use this function for logging the * parent/child conversation * * Results: * None * * Side Effects: * Messages may be written to a logfile * *---------------------------------------------------------------------- */ void exp_nflog(buf,force_stdout) char *buf; int force_stdout; /* override value of loguser */ { int len = strlen(buf); Tcl_Channel chan; if (exp_debugfile) Tcl_Write(exp_debugfile, buf, len); if (exp_logfile_all || (LOGUSER && exp_logfile)) Tcl_Write(exp_logfile, buf, len); if (LOGUSER) { chan = Tcl_GetStdChannel(TCL_STDOUT); if (chan) { Tcl_Write(chan, buf, len); } } } #undef LOGUSER /* *---------------------------------------------------------------------- * * exp_debuglog -- * * Send to log if open and debugging enabled. * send to stderr if debugging enabled. * Use this function for recording unusual things in the log. * * Results: * None * * Side Effects: * Messages may be written to a logfile * * Notes: * Static buffer is used, so overflow can be in issue * *---------------------------------------------------------------------- */ /*VARARGS*/ void exp_debuglog TCL_VARARGS_DEF(char *,arg1) { char *fmt; char buf[4096]; char *p = buf; int len = sizeof(buf); int n; Tcl_Channel chan; va_list args; fmt = TCL_VARARGS_START(char *,arg1,args); n = -1; while (n == -1) { n = vsnprintf(p, len, fmt, args); if (n == -1) { if (p != buf) { ckfree(p); } len *= 2; p = ckalloc(len); } } if (exp_debugfile) Tcl_Write(exp_debugfile, buf, n); if (exp_is_debugging) { chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_Write(chan, buf, n); } if (exp_logfile) Tcl_Write(exp_logfile, buf, n); } if (p != buf) ckfree(p); va_end(args); } /* *---------------------------------------------------------------------- * * exp_errorlog -- * * Log to stderr and to a logfile if it is open. Also send to * debuglog if debugging is enabled. This function is used for * logging error conditions. * * Results: * None * * Notes: * Static buffer is used, so overflow can be in issue * *---------------------------------------------------------------------- */ /*VARARGS*/ void exp_errorlog TCL_VARARGS_DEF(char *,arg1) { char *fmt; char buf[4096]; char *p = buf; int len = sizeof(buf); int n; Tcl_Channel chan; va_list args; fmt = TCL_VARARGS_START(char *,arg1,args); n = -1; while (n == -1) { n = vsnprintf(p, len, fmt, args); if (n == -1) { if (p != buf) { free(p); } len *= 2; p = malloc(len); } } chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_Write(chan, buf, n); } if (exp_debugfile) Tcl_Write(exp_debugfile, buf, n); if (exp_logfile) Tcl_Write(exp_logfile, buf, n); if (p != buf) free(p); va_end(args); } /* *---------------------------------------------------------------------- * * exp_nferrorlog -- * * Log to stderr and to a logfile if it is open. Also send to * debuglog if debugging is enabled. This function is used for * logging the parent/child conversation. It is just like * exp_errorlog, but it does no formattting. * * Results: * None * *---------------------------------------------------------------------- */ /*ARGSUSED*/ void exp_nferrorlog(buf,force_stdout) char *buf; int force_stdout; /* not used, only declared here for compat with */ { int len = strlen(buf); Tcl_Channel chan; chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { Tcl_Write(chan, buf, len); } if (exp_debugfile) Tcl_Write(exp_debugfile, buf, len); if (exp_logfile) Tcl_Write(exp_logfile, buf, len); } #if 0 static int out_buffer_size; static char *outp_last; static char *out_buffer; static char *outp; /* pointer into out_buffer - static in order */ /* to update whenever out_buffer is enlarged */ void exp_init_log() { out_buffer = ckalloc(BUFSIZ); out_buffer_size = BUFSIZ; outp_last = out_buffer + BUFSIZ - 1; } char * enlarge_out_buffer() { int offset = outp - out_buffer; int new_out_buffer_size = out_buffer_size = BUFSIZ; realloc(out_buffer,new_out_buffer_size); out_buffer_size = new_out_buffer_size; outp = out_buffer + offset; outp_last = out_buffer + out_buffer_size - 1; return(out_buffer); } /* like sprintf, but uses a static buffer enlarged as necessary */ /* currently supported are %s, %d, and %#d where # is a single-digit */ void exp_sprintf TCL_VARARGS_DEF(char *,arg1) /* exp_sprintf(va_alist)*/ /*va_dcl*/ { char *fmt; va_list args; char int_literal[20]; /* big enough for an int literal? */ char *int_litp; /* pointer into int_literal */ char *width; char *string_arg; int int_arg; char *int_fmt; fmt = TCL_VARARGS_START(char *,arg1,args); /*va_start(args);*/ /*fmt = va_arg(args,char *);*/ while (*fmt != '\0') { if (*fmt != '%') { *outp++ = *fmt++; continue; } /* currently, only single-digit widths are used */ if (isdigit(*fmt)) { width = fmt++; } else width = 0; switch (*fmt) { case 's': /* interpolate string */ string_arg = va_arg(args,char *); while (*string_arg) { if (outp == outp_last) { if (enlarge_out_buffer() == 0) { /* FAIL */ return; } } *outp++ = *string_arg++; } fmt++; break; case 'd': /* interpolate int */ int_arg = va_arg(args,int); if (width) int_fmt = width; else int_fmt = fmt; sprintf(int_literal,int_fmt,int_arg); int_litp = int_literal; for (int_litp;*int_litp;) { if (enlarge_out_buffer() == 0) return; *outp++ = *int_litp++; } fmt++; break; default: /* anything else is literal */ if (enlarge_out_buffer() == 0) return; /* FAIL */ *outp++ = *fmt++; break; } } } /* copy input string to exp_output, replacing \r\n sequences by \n */ /* return length of new string */ int exp_copy_out(char *s) { outp = out_buffer; int count = 0; while (*s) { if ((*s == '\r') && (*(s+1) =='\n')) s++; if (enlarge_out_buffer() == 0) { /* FAIL */ break; } *outp = *s; count++; } return count; } #endif |
Added generic/exp_main_exp.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* main.c - main() and some logging routines for expect Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #define BUILD_clib #include "exp_port.h" #include <stdio.h> #include <stdlib.h> #include "tcl.h" #include "expect_tcl.h" int main(argc, argv) int argc; char *argv[]; { int rc = 0; Tcl_Interp *interp = Tcl_CreateInterp(); if (Tcl_Init(interp) == TCL_ERROR) { fprintf(stderr,"Tcl_Init failed: %s\n",interp->result); exit(1); } if (Expect_Init(interp) == TCL_ERROR) { fprintf(stderr,"Expect_Init failed: %s\n",interp->result); exit(1); } exp_parse_argv(interp,argc,argv); /* become interactive if requested or "nothing to do" */ if (exp_interactive) (void) exp_interpreter(interp); else if (exp_cmdfile) rc = exp_interpret_cmdfile(interp,exp_cmdfile); else if (exp_cmdfilename) rc = exp_interpret_cmdfilename(interp,exp_cmdfilename); /* assert(exp_cmdlinecmds != 0) */ exp_exit(interp,rc); /*NOTREACHED*/ return 0; /* Needed only to prevent compiler warning. */ } |
Added generic/exp_main_sub.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | /* ---------------------------------------------------------------------------- * exp_main_sub.c -- * * miscellaneous subroutines for Expect or Tk main() * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp_main_sub.c,v 1.1.2.1.2.7 2002/02/11 02:19:53 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #endif #ifdef __CENTERLINE__ #undef EXP_VERSION #define EXP_VERSION "5.0.3" /* I give up! */ /* It is not necessary that number */ /* be accurate. It is just here to */ /* pacify Centerline which doesn't */ /* seem to be able to get it from */ /* the Makefile. */ #undef SCRIPTDIR #define SCRIPTDIR "example/" #undef EXECSCRIPTDIR #define EXECSCRIPTDIR "example/" #endif char exp_version[] = EXP_VERSION; #define NEED_TCL_MAJOR 7 #define NEED_TCL_MINOR 5 #define TCL_DOES_STUBS \ (TCL_MAJOR_VERSION > 8 || TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION > 1 || \ (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE))) char *exp_argv0 = "this program"; /* default program name */ void (*exp_app_exit)() = 0; FILE *exp_cmdfile = 0; char *exp_cmdfilename = 0; int exp_cmdlinecmds = FALSE; int exp_interactive = FALSE; int exp_buffer_command_input = FALSE;/* read in entire cmdfile at once */ //int exp_fgets(); Tcl_Interp *exp_interp; /* for use by signal handlers who can't figure out */ /* the interpreter directly */ int exp_tcl_debugger_available = FALSE; int exp_getpid; TCL_DECLARE_MUTEX(initLock) /* * Declarations for local procedures defined in this file: */ static void exp_pty_exit_for_tcl _ANSI_ARGS_(( ClientData clientData)); static void usage(interp) Tcl_Interp *interp; { exp_errorlog("usage: expect [-div] [-c cmds] [[-f] cmdfile] [args]\r\n"); exp_exit(interp,1); } /*ARGSUSED*/ void exp_exit(interp,status) Tcl_Interp *interp; /* historic */ int status; { Tcl_Exit(status); } /* this clumsiness because pty routines don't know Tcl definitions */ static void exp_pty_exit_for_tcl(clientData) ClientData clientData; { exp_pty_exit(); } static void exp_init_pty_exit() { Tcl_CreateExitHandler(exp_pty_exit_for_tcl,(ClientData)0); } /* This can be called twice or even recursively - it's safe. */ void exp_exit_handlers(clientData) ClientData clientData; { extern int exp_forked; Tcl_Interp *interp = (Tcl_Interp *)clientData; /* use following checks to prevent recursion in exit handlers */ /* if this code ever supports multiple interps, these should */ /* become interp-specific */ static int did_app_exit = FALSE; static int did_expect_exit = FALSE; /* don't think this code is relevant any longer, but not positive! */ if (!interp) { /* if no interp handy (i.e., called from interrupt handler) */ /* use last one created - it's a hack but we're exiting */ /* ungracefully to begin with */ interp = exp_interp; } if (!did_expect_exit) { did_expect_exit = TRUE; /* called user-defined exit routine if one exists */ if (exp_onexit_action) { int result = Tcl_GlobalEval(interp,exp_onexit_action); if (result != TCL_OK) Tcl_BackgroundError(interp); } } else { exp_debuglog("onexit handler called recursively - forcing exit\r\n"); } if (exp_app_exit) { if (!did_app_exit) { did_app_exit = TRUE; (*exp_app_exit)(interp); } else { exp_debuglog("application exit handler called recursively - forcing exit\r\n"); } } #ifndef __WIN32__ if (!exp_disconnected && !exp_forked && (exp_dev_tty != -1) && isatty(exp_dev_tty) && exp_ioctled_devtty) { exp_tty_set(interp,&exp_tty_original,exp_dev_tty,0); } #endif #if 0 /* GCC: I don't think this is necessary anymore */ /* all other files either don't need to be flushed or will be implicitly closed at exit. Spawned processes are free to continue running, however most will shutdown after seeing EOF on stdin. Some systems also deliver SIGHUP and other sigs to idle processes which will blow them away if not prepared. */ exp_close_all(interp); #endif } /* this stupidity because Tcl needs commands in writable space */ static char prompt1[] = "prompt1"; static char prompt2[] = "prompt2"; static char *prompt2_default = "+> "; static char prompt1_default[] = "expect%d> "; /*ARGSUSED*/ int Exp_Prompt1Cmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { Interp *iPtr = (Interp *)interp; sprintf(interp->result,prompt1_default, iPtr->numLevels); return(TCL_OK); } /*ARGSUSED*/ int Exp_Prompt2Cmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { strcpy(interp->result,prompt2_default); return(TCL_OK); } /*ARGSUSED*/ static int ignore_procs(interp,s) Tcl_Interp *interp; char *s; /* function name */ { return ((s[0] == 'p') && (s[1] == 'r') && (s[2] == 'o') && (s[3] == 'm') && (s[4] == 'p') && (s[5] == 't') && ((s[6] == '1') || (s[6] == '2')) && (s[7] == '\0') ); } /* handle an error from Tcl_Eval or Tcl_EvalFile */ static void handle_eval_error(interp,check_for_nostack) Tcl_Interp *interp; int check_for_nostack; { CONST char *msg; /* if errorInfo has something, print it */ /* else use what's in interp->result */ msg = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY); if (!msg) msg = interp->result; else if (check_for_nostack) { /* suppress errorInfo if generated via */ /* error ... -nostack */ if (0 == strncmp("-nostack",msg,8)) return; /* * This shouldn't be necessary, but previous test fails * because of recent change John made - see eval_trap_action() * in exp_trap.c for more info */ if (exp_nostack_dump) { exp_nostack_dump = FALSE; return; } } /* no \n at end, since ccmd will already have one. */ /* Actually, this is not true if command is last in */ /* file and has no newline after it, oh well */ exp_errorlog("%s\r\n", exp_cook(msg,(int *)0)); } /* user has pressed escape char from interact or somehow requested expect. If a user-supplied command returns: TCL_ERROR, assume user is experimenting and reprompt TCL_OK, ditto TCL_RETURN, return TCL_OK (assume user just wants to escape() to return) EXP_TCL_RETURN, return TCL_RETURN anything else return it */ int exp_interpreter(interp) Tcl_Interp *interp; { #ifdef __WIN32__ fprintf(stderr, "expect.exe does not run in interactive mode. Use tclsh80.exe instead\n"); exit(1); return 0; #else int rc; char *ccmd; /* pointer to complete command */ char line[BUFSIZ+1]; /* space for partial command */ int newcmd = TRUE; Tcl_DString dstring; Interp *iPtr = (Interp *)interp; int tty_changed = FALSE; #ifndef __WIN32__ exp_tty tty_old; #endif int was_raw, was_echo; int dummy; int fd = fileno(stdin); expect_key++; Tcl_DStringInit(&dstring); newcmd = TRUE; while (TRUE) { /* force terminal state */ #ifndef __WIN32__ tty_changed = exp_tty_cooked_echo(interp,&tty_old,&was_raw,&was_echo); #endif if (newcmd) { rc = Tcl_Eval(interp,prompt1); if (rc == TCL_OK) exp_log(1,"%s",interp->result); else exp_log(1,prompt1_default,iPtr->numLevels); } else { rc = Tcl_Eval(interp,prompt2); if (rc == TCL_OK) exp_log(1,"%s",interp->result); else exp_log(1,prompt2_default,1); } #ifdef SHARE_CMD_BUFFER if (exp_fgets(interp,line,BUFSIZ) == EXP_EOF) { if (!newcmd) line[0] = 0; else exp_exit(interp,0); } #else exp_fs[fd].force_read = 1; rc = exp_get_next_event(interp,&fd,1,&dummy,EXP_TIME_INFINITY, exp_fs[fd].key); /* check for rc == EXP_TCLERROR? */ if (rc != EXP_EOF) { rc = read(0,line,BUFSIZ); #ifdef SIMPLE_EVENT if (rc == -1 && errno == EINTR) { if (Tcl_AsyncReady()) { (void) Tcl_AsyncInvoke(interp,TCL_OK); } continue; } #endif if (rc <= 0) { if (!newcmd) line[0] = 0; else rc = EXP_EOF; } else line[rc] = '\0'; } #ifdef BEFORE_ASYNC if (rc != EXP_EOF) { if (0 >= (rc = read(0,line,BUFSIZ))) { if (!newcmd) line[0] = 0; else rc = EXP_EOF; } else line[rc] = '\0'; } #endif if (rc == EXP_EOF) exp_exit(interp,0); if (debugfile) fwrite(line,1,strlen(line),debugfile); /* intentionally always write to logfile */ if (logfile) fwrite(line,1,strlen(line),logfile); /* no need to write to stdout, since they will see */ /* it just from it having been echoed as they are */ /* typing it */ #endif /*SHARE_CMD_BUFFER*/ ccmd = Tcl_DStringAppend(&dstring,line,rc); if (!Tcl_CommandComplete(ccmd)) { newcmd = FALSE; continue; /* continue collecting command */ } newcmd = TRUE; if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); /* Ousterhout says he fixed this, so that we no longer need the ifdefs */ rc = Tcl_RecordAndEval(interp,ccmd,0); #if 0 #if TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION < 4 rc = Tcl_RecordAndEval(interp,ccmd,0); #else rc = Tcl_RecordAndEval(interp,ccmd,TCL_NO_EVAL); rc = Tcl_Eval(interp,ccmd); #endif #endif Tcl_DStringFree(&dstring); switch (rc) { case TCL_OK: if (*interp->result != 0) exp_log(1,"%s\r\n",exp_cook(interp->result,(int *)0)); continue; case TCL_ERROR: handle_eval_error(interp,1); /* since user is typing by hand, we expect lots */ /* of errors, and want to give another chance */ continue; #define finish(x) {rc = x; goto done;} case TCL_BREAK: case TCL_CONTINUE: finish(rc); case EXP_TCL_RETURN: finish(TCL_RETURN); case TCL_RETURN: finish(TCL_OK); default: /* note that ccmd has trailing newline */ exp_errorlog("error %d: %s\r\n",rc,ccmd); continue; } } /* cannot fall thru here, must jump to label */ done: if (tty_changed) exp_tty_set(interp,&tty_old,was_raw,was_echo); Tcl_DStringFree(&dstring); return(rc); #endif /* ifdef __WIN32__ */ } /*ARGSUSED*/ int Exp_ExpVersionCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int emajor, umajor; char *user_version; /* user-supplied version string */ if (argc == 1) { Tcl_SetResult(interp,exp_version,TCL_STATIC); return(TCL_OK); } if (argc > 3) { exp_error(interp,"usage: exp_version [[-exit] version]"); return(TCL_ERROR); } user_version = argv[argc==2?1:2]; emajor = atoi(exp_version); umajor = atoi(user_version); /* first check major numbers */ if (emajor == umajor) { int u, e; /* now check minor numbers */ char *dot = strchr(user_version,'.'); if (!dot) { exp_error(interp,"version number must include a minor version number"); return TCL_ERROR; } u = atoi(dot+1); dot = strchr(exp_version,'.'); e = atoi(dot+1); if (e >= u) return(TCL_OK); } if (argc == 2) { exp_error(interp,"%s requires Expect version %s (but using %s)", exp_argv0,user_version,exp_version); return(TCL_ERROR); } exp_errorlog("%s: requires Expect version %s (but using %s)\r\n", exp_argv0,user_version,exp_version); exp_exit(interp,1); /*NOTREACHED*/ return TCL_OK; } /* * The following string is the startup script executed in new * interpreters. It looks on disk in several different directories * for a script "dpinit.tcl" that is compatible with this version of Dp. * The dpinit.tcl script does all of the real work of initialization. */ static char initScript[] = "proc expectInit {} {\n\ global exp_library auto_path env\n\ rename expectInit {}\n\ set version [exp_version]\n\ set dirs [list [file join .. examples] [file join . examples]]\n\ if [info exists env(EXP_LIBRARY)] {\n\ lappend dirs $env(EXP_LIBRARY)\n\ }\n\ set parentDir [file dirname [file dirname [info nameofexecutable]]]\n\ lappend dirs [file join [file join $parentDir lib] exp$version]\n\ set lib exp$version\n\ lappend dirs [file join [file join [file dirname $parentDir] $lib] library]\n\ lappend dirs [file join $parentDir library]\n\ set parentDir [file dirname [pwd]]\n\ lappend dirs [file join $parentDir library]\n\ foreach i $dirs {\n\ set exp_library $i\n\ if [file isfile [file join $i expect.rc]] {\n\ lappend auto_path $exp_library\n\ return\n\ }\n\ }\n\ foreach i $dirs {\n\ set exp_library $i\n\ if [file isfile [file join $i beer.exp]] {\n\ lappend auto_path $exp_library\n\ return\n\ }\n\ }\n\ }\n\ expectInit"; static char init_auto_path[] = "lappend auto_path $exp_library $exp_exec_library"; int Expect_Init(interp) Tcl_Interp *interp; { static int first_time = TRUE; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #else if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) { return TCL_ERROR; } #endif Tcl_MutexLock(&initLock); if (first_time) { int tcl_major = atoi(TCL_VERSION); char *dot = strchr(TCL_VERSION,'.'); int tcl_minor = atoi(dot+1); if (tcl_major < NEED_TCL_MAJOR || (tcl_major == NEED_TCL_MAJOR && tcl_minor < NEED_TCL_MINOR)) { sprintf(interp->result, "%s compiled with Tcl %d.%d but needs at least Tcl %d.%d\n", exp_argv0,tcl_major,tcl_minor, NEED_TCL_MAJOR,NEED_TCL_MINOR); return TCL_ERROR; } #ifdef __WIN32__ { extern void ExpWinInit (); ExpWinInit(); } #endif exp_getpid = getpid(); exp_init_spawn_ids(interp); exp_init_pty(interp); exp_init_pty_exit(); exp_init_tty(interp); /* do this only now that we have * looked at original tty state */ exp_init_stdio(); exp_init_sig(); exp_init_event(); exp_init_trap(); exp_init_unit_random(); Tcl_CreateExitHandler(exp_exit_handlers,(ClientData)interp); first_time = FALSE; } /* save last known interp for emergencies */ exp_interp = interp; Tcl_MutexUnlock(&initLock); /* initialize commands */ exp_init_most_cmds(interp); /* add misc cmds to interpreter */ exp_init_expect_cmds(interp); /* add expect cmds to interpreter */ exp_init_main_cmds(interp); /* add main cmds to interpreter */ exp_init_trap_cmds(interp); /* add trap cmds to interpreter */ exp_init_tty_cmds(interp); /* add tty cmds to interpreter */ exp_init_interact_cmds(interp); /* add interact cmds to interpreter */ exp_init_spawn_id_vars(interp); if (Tcl_Eval(interp, initScript) != TCL_OK) { return TCL_ERROR; } #ifdef TCL_DEBUGGER Dbg_IgnoreFuncs(interp,ignore_procs); #endif #if TCL_DOES_STUBS { extern ExpStubs expStubs; if (Tcl_PkgProvideEx(interp, "Expect", EXP_VERSION, (ClientData)&expStubs) != TCL_OK) { return TCL_ERROR; } } #else if (Tcl_PkgProvide(interp, "Expect", EXP_VERSION) != TCL_OK) { return TCL_ERROR; } #endif return TCL_OK; } static char sigexit_init_default[] = "trap exit {SIGINT SIGTERM}"; static char debug_init_default[] = "trap {exp_debug 1} SIGINT"; void exp_parse_argv(interp,argc,argv) Tcl_Interp *interp; int argc; char **argv; { char argc_rep[10]; /* enough space for storing literal rep of argc */ int sys_rc = TRUE; /* read system rc file */ int my_rc = TRUE; /* read personal rc file */ int c; int rc; extern int optind; extern char *optarg; char *args; /* ptr to string-rep of all args */ #ifdef __WIN32__ extern int getopt _ANSI_ARGS_((int argc,char **nargv, char *ostr)); #endif exp_argv0 = argv[0]; #ifdef TCL_DEBUGGER Dbg_ArgcArgv(argc,argv,1); #endif /* initially, we must assume we are not interactive */ /* this prevents interactive weirdness courtesy of unknown via -c */ /* after handling args, we can change our mind */ Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); Tcl_Eval(interp,sigexit_init_default); while ((c = getopt(argc, argv, "b:c:dD:f:inN-v")) != EOF) { switch(c) { case '-': /* getopt already handles -- internally, however */ /* this allows us to abort getopt when dash is at */ /* the end of another option which is required */ /* in order to allow things like -n- on #! line */ goto abort_getopt; case 'c': /* command */ exp_cmdlinecmds = TRUE; rc = Tcl_Eval(interp,optarg); if (rc != TCL_OK) { exp_errorlog("%s\r\n",exp_cook(Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY),(int *)0)); } break; case 'd': exp_is_debugging = TRUE; exp_debuglog("expect version %s\r\n",exp_version); break; #ifdef TCL_DEBUGGER case 'D': { char *debug_init; exp_tcl_debugger_available = TRUE; if (Tcl_GetInt(interp,optarg,&rc) != TCL_OK) { exp_errorlog("%s: -D argument must be 0 or 1\r\n", exp_argv0); exp_exit(interp,1); } /* set up trap handler before Dbg_On so user does */ /* not have to see it at first debugger prompt */ if (0 == (debug_init = getenv("EXPECT_DEBUG_INIT"))) { debug_init = debug_init_default; } Tcl_Eval(interp,debug_init); if (rc == 1) Dbg_On(interp,0); break; } #endif case 'f': /* name of cmd file */ exp_cmdfilename = optarg; break; case 'b': /* read cmdfile one part at a time */ exp_cmdfilename = optarg; exp_buffer_command_input = TRUE; break; case 'i': /* interactive */ exp_interactive = TRUE; break; case 'n': /* don't read personal rc file */ my_rc = FALSE; break; case 'N': /* don't read system-wide rc file */ sys_rc = FALSE; break; case 'v': printf("expect version %s\n", exp_version); exp_exit (interp, 0); break; default: usage(interp); } } abort_getopt: for (c = 0;c<argc;c++) { exp_debuglog("argv[%d] = %s ",c,argv[c]); } exp_debuglog("\r\n"); /* if user hasn't explicitly requested we be interactive */ /* look for a file or some other source of commands */ if (!exp_interactive) { /* get cmd file name, if we haven't got it already */ if (!exp_cmdfilename && (optind < argc)) { exp_cmdfilename = argv[optind]; optind++; } if (exp_cmdfilename) { if (streq(exp_cmdfilename,"-")) { exp_cmdfile = stdin; exp_cmdfilename = 0; } else if (exp_buffer_command_input) { errno = 0; exp_cmdfile = fopen(exp_cmdfilename,"r"); if (exp_cmdfile) { exp_cmdfilename = 0; exp_close_on_exec(fileno(exp_cmdfile)); } else { CONST char *msg; if (errno == 0) { msg = "could not read - odd file name?"; } else { msg = Tcl_ErrnoMsg(errno); } exp_errorlog("%s: %s\r\n",exp_cmdfilename,msg); exp_exit(interp,1); } } } else if (!exp_cmdlinecmds) { if (isatty(0)) { /* no other source of commands, force interactive */ exp_interactive = TRUE; } else { /* read cmds from redirected stdin */ exp_cmdfile = stdin; } } } if (exp_interactive) { Tcl_SetVar(interp, "tcl_interactive","1",TCL_GLOBAL_ONLY); } /* collect remaining args and make into argc, argv0, and argv */ sprintf(argc_rep,"%d",argc-optind); Tcl_SetVar(interp,"argc",argc_rep,0); exp_debuglog("set argc %s\r\n",argc_rep); if (exp_cmdfilename) { Tcl_SetVar(interp,"argv0",exp_cmdfilename,0); exp_debuglog("set argv0 \"%s\"\r\n",exp_cmdfilename); } else { Tcl_SetVar(interp,"argv0",exp_argv0,0); exp_debuglog("set argv0 \"%s\"\r\n",exp_argv0); } args = Tcl_Merge(argc-optind,argv+optind); exp_debuglog("set argv \"%s\"\r\n",args); Tcl_SetVar(interp,"argv",args,0); ckfree(args); exp_interpret_rcfiles(interp,my_rc,sys_rc); } /* read rc files */ void exp_interpret_rcfiles(interp,my_rc,sys_rc) Tcl_Interp *interp; int my_rc; int sys_rc; { int rc; if (sys_rc) { char file[200]; int fd; sprintf(file,"%s/expect.rc",Tcl_GetVar(interp, "exp_library", TCL_GLOBAL_ONLY)); if (-1 != (fd = open(file,0))) { if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) { exp_errorlog("error executing system initialization file: %s\r\n",file); if (rc != TCL_ERROR) exp_errorlog("Tcl_Eval = %d\r\n",rc); if (*interp->result != 0) exp_errorlog("%s\r\n",interp->result); exp_exit(interp,1); } close(fd); } } if (my_rc) { char file[200]; char *home; int fd; char *getenv(); if ((NULL != (home = getenv("DOTDIR"))) || (NULL != (home = getenv("HOME")))) { sprintf(file,"%s/.expect.rc",home); if (-1 != (fd = open(file,0))) { if (TCL_ERROR == (rc = Tcl_EvalFile(interp,file))) { exp_errorlog("error executing file: %s\r\n",file); if (rc != TCL_ERROR) exp_errorlog("Tcl_Eval = %d\r\n",rc); if (*interp->result != 0) exp_errorlog("%s\r\n",interp->result); exp_exit(interp,1); } close(fd); } } } } int exp_interpret_cmdfilename(interp,filename) Tcl_Interp *interp; char *filename; { int rc; exp_debuglog("executing commands from command file %s\r\n",filename); Tcl_ResetResult(interp); if (TCL_OK != (rc = Tcl_EvalFile(interp,filename))) { /* EvalFile doesn't bother to copy error to errorInfo */ /* so force it */ Tcl_AddErrorInfo(interp, ""); handle_eval_error(interp,0); } return rc; } int exp_interpret_cmdfile(interp,cmdfile) Tcl_Interp *interp; Tcl_Channel cmdfile; { int rc = 0; int newcmd; int eof; Tcl_DString dstring; Tcl_DStringInit(&dstring); exp_debuglog("executing commands from command file\r\n"); newcmd = TRUE; eof = FALSE; while (1) { Tcl_Obj *line = Tcl_NewObj(); /* buffer for partial Tcl command */ Tcl_GetsObj(cmdfile, line); if (Tcl_GetsObj(cmdfile, line) == -1) { if (newcmd) break; eof = TRUE; } if (!Tcl_CommandComplete(Tcl_GetString(line)) && !eof) { newcmd = FALSE; continue; /* continue collecting command */ } newcmd = TRUE; rc = Tcl_EvalObj(interp,line); Tcl_DecrRefCount(line); if (rc != TCL_OK) { handle_eval_error(interp,0); break; } if (eof) break; } return rc; } #ifdef SHARE_CMD_BUFFER /* fgets that shared input buffer with expect_user */ int exp_fgets(interp,buf,max) Tcl_Interp *interp; char *buf; int max; { char *nl; /* position of newline which signifies end of line */ int write_count;/* length of first line of incoming data */ int m = fileno(stdin); struct exp_f *f; int cc; int dummy; /* avoid returning no data, just because someone else read it in by */ /* passing most recent key */ cc = exp_get_next_event(interp,&m,1,&dummy,EXP_TIME_INFINITY,exp_fs[m].key); if (cc == EXP_DATA_NEW) { /* try to read it */ cc = exp_i_read(m,EXP_TIME_INFINITY); /* the meaning of 0 from i_read means eof. Muck with it a */ /* little, so that from now on it means "no new data arrived */ /* but it should be looked at again anyway". */ if (cc == 0) { cc = EXP_EOF; } else if (cc > 0) { f = exp_fs + m; f->buffer[f->size += cc] = '\0'; } } else if (cc == EXP_DATA_OLD) { f = exp_fs + m; cc = 0; } /* EOF and TIMEOUT return here */ /* In such cases, there is no need to update screen since, if there */ /* was prior data read, it would have been sent to the screen when */ /* it was read. */ if (cc < 0) return (cc); /* copy up to end of first line */ /* calculate end of first line */ nl = strchr(f->buffer,'\n'); if (nl) write_count = 1+nl-f->buffer; else write_count = f->size; /* make sure line fits in buffer area */ if (write_count > max) write_count = max; /* copy it */ memcpy(buf,f->buffer,write_count); buf[write_count] = '\0'; /* update display and f */ f->printed = 0; /* for simplicity force f->printed = 0. This way, the user gets */ /* to see the commands that are about to be executed. Not seeing */ /* commands you are supposedly typing sounds very uncomfortable! */ if (exp_logfile_all || (exp_loguser && exp_logfile)) { fwrite(f->buffer,1,write_count,exp_logfile); } if (exp_debugfile) fwrite(f->buffer,1,write_count,exp_debugfile); f->size -= write_count; memcpy(f->buffer,f->buffer+write_count,1+f->size); /* copy to lowercase buffer */ exp_lowmemcpy(f->lower,f->buffer,1+f->size); return(write_count); } #endif /*SHARE_CMD_BUFFER*/ static struct exp_cmd_data cmd_data[] = { {"exp_version", 0, Exp_ExpVersionCmd, 0, 0}, {"prompt1", 0, Exp_Prompt1Cmd, 0, 0}, {"prompt2", 0, Exp_Prompt2Cmd, 0, 0}, {0} }; void exp_init_main_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } |
Added generic/exp_main_tk.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | /* exp_main_tk.c - main for expectk This file consists of three pieces: 1) AppInit for Expectk. This has been suitably modified to invoke a modified version of Tk_Init. 2) Tk_Init for Expectk. What's wrong with the normal Tk_Init is that removes the -- in the cmd-line arg list, so Expect cannot know whether args are flags to Expectk or data for the script. Sigh. 3) Additions and supporting utilities to Tk's Argv parse table to support Expectk's flags. Author: Don Libes, NIST, 2/20/96 */ /* Expectk's AppInit */ /* * tkAppInit.c -- * * Provides a default version of the Tcl_AppInit procedure for * use in wish and similar Tk-based applications. * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef lint static char sccsid[] = "@(#) tkAppInit.c 1.19 95/12/23 17:09:24"; #endif /* not lint */ #include <ctype.h> #include "tk.h" #include "expect_tcl.h" #include "Dbg.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #ifdef TK_TEST EXTERN int Tktest_Init _ANSI_ARGS_((Tcl_Interp *interp)); #endif /* TK_TEST */ /* *---------------------------------------------------------------------- * * main -- * * This is the main program for the application. * * Results: * None: Tk_Main never returns here, so this procedure never * returns either. * * Side effects: * Whatever the application does. * *---------------------------------------------------------------------- */ int main(argc, argv) int argc; /* Number of command-line arguments. */ char **argv; /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. * Most applications, especially those that incorporate additional * packages, will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error * message in interp->result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tcl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* do Expect first so we can get access to Expect commands when */ /* Tk_Init does the argument parsing of -c */ if (Expect_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Expect", Expect_Init, (Tcl_PackageInitProc *)NULL); if (Tk_Init2(interp) == TCL_ERROR) { /* DEL */ return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); return TCL_OK; } /* * Count of number of main windows currently open in this process. */ static int numMainWindows; /* * The variables and table below are used to parse arguments from * the "argv" variable in Tk_Init. */ static int synchronize; static char *name; static char *display; static char *geometry; static char *colormap; static char *visual; static int rest = 0; /* for Expect */ int my_rc = 1; int sys_rc = 1; int optcmd_eval(); #ifdef TCL_DEBUGGER int optcmd_debug(); #endif int print_version = 0; static Tk_ArgvInfo argTable[] = { {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap, "Colormap for main window"}, {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, "Display to use"}, {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, "Initial geometry for window"}, {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, "Name to use for application"}, {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, "Use synchronous mode for display server"}, {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual, "Visual for main window"}, {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, "Pass all remaining arguments through to script"}, /* for Expect */ {"-command", TK_ARGV_GENFUNC, (char *) optcmd_eval, (char *)0, "Command(s) to execute immediately"}, {"-diag", TK_ARGV_CONSTANT, (char *) 1, (char *) &exp_is_debugging, "Enable diagnostics"}, {"-norc", TK_ARGV_CONSTANT, (char *) 0, (char *) &my_rc, "Don't read ~/.expect.rc"}, {"-NORC", TK_ARGV_CONSTANT, (char *) 0, (char *) &sys_rc, "Don't read system-wide expect.rc"}, {"-version", TK_ARGV_CONSTANT, (char *) 1, (char *) &print_version, "Print version and exit"}, #if TCL_DEBUGGER {"-Debug", TK_ARGV_GENFUNC, (char *) optcmd_debug, (char *)0, "Enable debugger"}, #endif {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, (char *) NULL} }; /* *---------------------------------------------------------------------- * * Tk_Init -- * * This procedure is invoked to add Tk to an interpreter. It * incorporates all of Tk's commands into the interpreter and * creates the main window for a new Tk application. If the * interpreter contains a variable "argv", this procedure * extracts several arguments from that variable, uses them * to configure the main window, and modifies argv to exclude * the arguments (see the "wish" documentation for a list of * the arguments that are extracted). * * Results: * Returns a standard Tcl completion code and sets interp->result * if there is an error. * * Side effects: * Depends on various initialization scripts that get invoked. * *---------------------------------------------------------------------- */ int Tk_Init2(interp) Tcl_Interp *interp; /* Interpreter to initialize. */ { char *p; int argc, code; char **argv, *args[20]; Tcl_DString class; char buffer[30]; /* * If there is an "argv" variable, get its value, extract out * relevant arguments from it, and rewrite the variable without * the arguments that we used. */ synchronize = 0; name = display = geometry = colormap = visual = NULL; p = Tcl_GetVar2(interp, "argv", (char *) NULL, TCL_GLOBAL_ONLY); argv = NULL; if (p != NULL) { if (Tcl_SplitList(interp, p, &argc, &argv) != TCL_OK) { argError: Tcl_AddErrorInfo(interp, "\n (processing arguments in argv variable)"); return TCL_ERROR; } if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS) != TCL_OK) { ckfree((char *) argv); goto argError; } if (print_version) { extern char exp_version[]; printf ("expectk version %s\n", exp_version); exp_exit (interp, 0); } p = Tcl_Merge(argc, argv); Tcl_SetVar2(interp, "argv", (char *) NULL, p, TCL_GLOBAL_ONLY); sprintf(buffer, "%d", argc); Tcl_SetVar2(interp, "argc", (char *) NULL, buffer, TCL_GLOBAL_ONLY); ckfree(p); } /* * Figure out the application's name and class. */ if (name == NULL) { name = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY); if ((name == NULL) || (*name == 0)) { name = "tk"; } else { p = (char *)strrchr(name, '/'); /* added cast - DEL */ if (p != NULL) { name = p+1; } } } Tcl_DStringInit(&class); Tcl_DStringAppend(&class, name, -1); p = Tcl_DStringValue(&class); if (islower(*p)) { *p = toupper((unsigned char) *p); } /* * Create an argument list for creating the top-level window, * using the information parsed from argv, if any. */ args[0] = "toplevel"; args[1] = "."; args[2] = "-class"; args[3] = Tcl_DStringValue(&class); argc = 4; if (display != NULL) { args[argc] = "-screen"; args[argc+1] = display; argc += 2; /* * If this is the first application for this process, save * the display name in the DISPLAY environment variable so * that it will be available to subprocesses created by us. */ if (numMainWindows == 0) { Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY); } } if (colormap != NULL) { args[argc] = "-colormap"; args[argc+1] = colormap; argc += 2; } if (visual != NULL) { args[argc] = "-visual"; args[argc+1] = visual; argc += 2; } args[argc] = NULL; code = TkCreateFrame((ClientData) NULL, interp, argc, args, 1, name); Tcl_DStringFree(&class); if (code != TCL_OK) { goto done; } Tcl_ResetResult(interp); if (synchronize) { XSynchronize(Tk_Display(Tk_MainWindow(interp)), True); } /* * Set the geometry of the main window, if requested. Put the * requested geometry into the "geometry" variable. */ if (geometry != NULL) { Tcl_SetVar(interp, "geometry", geometry, TCL_GLOBAL_ONLY); code = Tcl_VarEval(interp, "wm geometry . ", geometry, (char *) NULL); if (code != TCL_OK) { goto done; } } if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) { code = TCL_ERROR; goto done; } code = Tcl_PkgProvide(interp, "Tk", TK_VERSION); if (code != TCL_OK) { goto done; } /* * Invoke platform-specific initialization. */ code = TkPlatformInit(interp); done: if (argv != NULL) { ckfree((char *) argv); } return code; } /*ARGSUSED*/ int optcmd_eval(dst,interp,key,argc,argv) char *dst; Tcl_Interp *interp; char *key; int argc; char **argv; { int i; int rc; exp_cmdlinecmds = 1; rc = Tcl_Eval(interp,argv[0]); if (rc == TCL_ERROR) return -1; argc--; for (i=0;i<argc;i++) { argv[i] = argv[i+1]; } return argc; } #ifdef TCL_DEBUGGER /*ARGSUSED*/ int optcmd_debug(dst,interp,key,argc,argv) char *dst; Tcl_Interp *interp; char *key; int argc; char **argv; { int i; if (argc == 0) { strcpy(interp->result,"-Debug flag needs 1 or 0 argument"); return -1; } if (Tcl_GetInt(interp,argv[0],&i) != TCL_OK) { return -1; } if (i) { Dbg_On(interp,0); } argc--; for (i=0;i<argc;i++) { argv[i] = argv[i+1]; } return argc; } #endif /*TCL_DEBUGGER*/ |
Added generic/exp_noevent.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /* interact (with only one process) - give user keyboard control Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* This file exists for deficient versions of UNIX that lack select, poll, or some other multiplexing hook. Instead, this code uses two processes per spawned process. One sends characters from the spawnee to the spawner; a second send chars the other way. This will work on any UNIX system. The only sacrifice is that it doesn't support multiple processes. Eventually, it should catch SIGCHLD on dead processes and do the right thing. But it is pretty gruesome to imagine so many processes to do all this. If you change it successfully, please mail back the changes to me. - Don */ #include "tcl.h" #include "tclPort.h" #include "exp_port.h" #include "exp_prog.h" #include "exp_command.h" /* for struct exp_f defs */ #include "exp_event.h" /*ARGSUSED*/ void exp_arm_background_filehandler(f) struct exp_f *f; { } /*ARGSUSED*/ void exp_disarm_background_filehandler(f) struct exp_f *f; { } /*ARGSUSED*/ void exp_disarm_background_filehandler_force(f) struct exp_f *f; { } /*ARGSUSED*/ void exp_unblock_background_filehandler(f) struct exp_f *f; { } /*ARGSUSED*/ void exp_block_background_filehandler(f) struct exp_f *f; { } /*ARGSUSED*/ void exp_event_disarm(f) struct exp_f *f; { } /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ /*ARGSUSED*/ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; struct exp_f **masters; /* Array of expect process structures */ int n; /* # of masters */ struct exp_f **master_out; /* 1st ready master, not set if none */ int timeout; /* seconds */ int key; { struct exp_f *f; if (n > 1) { exp_error(interp,"expect not compiled with multiprocess support"); /* select a different INTERACT_TYPE in Makefile */ return(TCL_ERROR); } *master_out = masters[0]; f = masters[0]; if (f->key != key) { f->key = key; f->force_read = FALSE; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { return(EXP_DATA_OLD); } return(EXP_DATA_NEW); } /*ARGSUSED*/ int exp_get_next_event_info(interp,f,ready_mask) Tcl_Interp *interp; struct exp_f *f; int ready_mask; { if (ready_mask & TCL_READABLE) return EXP_DATA_NEW; return(EXP_EOF); } /* There is no portable way to do sub-second sleeps on such a system, so */ /* do the next best thing (without a busy loop) and fake it: sleep the right */ /* amount of time over the long run. Note that while "subtotal" isn't */ /* reinitialized, it really doesn't matter for such a gross hack as random */ /* scheduling pauses will easily introduce occasional one second delays. */ int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { static double subtotal = 0; int seconds; subtotal += sec; if (subtotal < 1) return TCL_OK; seconds = (int) subtotal; subtotal -= seconds; if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(rc); } #ifdef __WIN32__ Sleep(seconds*1000); #else sleep(seconds); #endif return TCL_OK; } #if 0 /* There is no portable way to do sub-second sleeps on such a system, so */ /* do the next best thing (without a busy loop) and fake it: sleep the right */ /* amount of time over the long run. Note that while "subtotal" isn't */ /* reinitialized, it really doesn't matter for such a gross hack as random */ /* scheduling pauses will easily introduce occasional one second delays. */ int /* returns TCL_XXX */ exp_usleep(interp,usec) Tcl_Interp *interp; long usec; /* microseconds */ { static subtotal = 0; int seconds; subtotal += usec; if (subtotal < 1000000) return TCL_OK; seconds = subtotal/1000000; subtotal = subtotal%1000000; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); } sleep(seconds); return TCL_OK; } #endif /*0*/ /* set things up for later calls to event handler */ void exp_init_event() { exp_event_exit = 0; } |
Added generic/exp_printify.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* ---------------------------------------------------------------------------- * exp_printify.c -- * * make non-printable characters printable. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #ifdef NO_STRING_H #include "../compat/string.h" #else #include <string.h> #endif #ifdef NO_STDLIB_H #include "../compat/stdlib.h" #else #include <stdlib.h> /* for malloc */ #endif #include <ctype.h> /* generate printable versions of random ASCII strings. Primarily used */ /* by cmdExpect when -d forces it to print strings it is examining. */ char * exp_printify(s) char *s; { static unsigned int destlen = 0; static char *dest = 0; char *d; /* ptr into dest */ unsigned int need; if (s == 0) return("<null>"); /* worst case is every character takes 4 to printify */ need = strlen(s)*4 + 1; if (need > destlen) { if (dest) ckfree(dest); dest = ckalloc(need); destlen = need; } for (d = dest;*s;s++) { if (*s == '\r') { strcpy(d,"\\r"); d += 2; } else if (*s == '\n') { strcpy(d,"\\n"); d += 2; } else if (*s == '\t') { strcpy(d,"\\t"); d += 2; } else if (isascii(*s) && isprint(*s)) { *d = *s; d += 1; } else { sprintf(d,"\\x%02x",*s & 0xff); d += 4; } } *d = '\0'; return(dest); } |
Added generic/exp_regexp.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | /* * regcomp and regexec -- regsub and regerror are elsewhere * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * Beware that some of this code is subtly aware of the way operator * precedence is structured in regular expressions. Serious changes in * regular-expression syntax might require a total rethink. * * *** NOTE: this code has been altered slightly for use in Tcl. *** * *** The only change is to use ckalloc and ckfree instead of *** * *** malloc and free. *** * *** and again for Expect!!! - DEL * *** More minor corrections stolen from tcl7.5p1/regexp.c - DEL */ #include "exp_port.h" #include "tcl.h" #include "exp_prog.h" #include "tclRegexp.h" #include "exp_regexp.h" #include "string.h" #define NOTSTATIC /* was at one time, but Expect needs access */ /* * The "internal use only" fields in regexp.h are present to pass info from * compile to execute that permits the execute phase to run lots faster on * simple cases. They are: * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? * regmust string (pointer into program) that match must include, or NULL * regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection * of lines that cannot possibly match. The regmust tests are costly enough * that regcomp() supplies a regmust only if the r.e. contains something * potentially expensive (at present, the only such thing detected is * or + * at the start of the r.e., which can involve a lot of backup). Regmlen is * supplied because the test in regexec() needs it and regcomp() is computing * it anyway. */ /* * Structure for regexp "program". This is essentially a linear encoding * of a nondeterministic finite-state machine (aka syntax charts or * "railroad normal form" in parsing technology). Each node is an opcode * plus a "next" pointer, possibly plus an operand. "Next" pointers of * all nodes except BRANCH implement concatenation; a "next" pointer with * a BRANCH on both ends of it is connecting two alternatives. (Here we * have one of the subtle syntax dependencies: an individual BRANCH (as * opposed to a collection of them) is never concatenated with anything * because of operator precedence.) The operand of some types of node is * a literal string; for others, it is a node leading into a sub-FSM. In * particular, the operand of a BRANCH node is the first node of the branch. * (NB this is *not* a tree structure: the tail of the branch connects * to the thing following the set of BRANCHes.) The opcodes are: */ /* definition number opnd? meaning */ #define END 0 /* no End of program. */ #define BOL 1 /* no Match "" at beginning of line. */ #define EOL 2 /* no Match "" at end of line. */ #define ANY 3 /* no Match any one character. */ #define ANYOF 4 /* str Match any character in this string. */ #define ANYBUT 5 /* str Match any character not in this string. */ #define BRANCH 6 /* node Match this alternative, or the next... */ #define BACK 7 /* no Match "", "next" ptr points backward. */ #define EXACTLY 8 /* str Match this string. */ #define NOTHING 9 /* no Match empty string. */ #define STAR 10 /* node Match this (simple) thing 0 or more times. */ #define PLUS 11 /* node Match this (simple) thing 1 or more times. */ #define OPEN 20 /* no Mark this point in input as start of #n. */ /* OPEN+1 is number 1, etc. */ #define CLOSE (OPEN+NSUBEXP) /* no Analogous to OPEN. */ /* * Opcode notes: * * BRANCH The set of branches constituting a single choice are hooked * together with their "next" pointers, since precedence prevents * anything being concatenated to any individual branch. The * "next" pointer of the last BRANCH in a choice points to the * thing following the whole choice. This is also where the * final "next" pointer of each individual branch points; each * branch starts with the operand node of a BRANCH node. * * BACK Normal "next" pointers all implicitly point forward; BACK * exists to make loop structures possible. * * STAR,PLUS '?', and complex '*' and '+', are implemented as circular * BRANCH structures using BACK. Simple cases (one character * per match) are implemented with STAR and PLUS for speed * and to minimize recursive plunges. * * OPEN,CLOSE ...are numbered at compile time. */ /* * A node is one char of opcode followed by two chars of "next" pointer. * "Next" pointers are stored as two 8-bit pieces, high order first. The * value is a positive offset from the opcode of the node containing it. * An operand, if any, simply follows the node. (Note that much of the * code generation knows about this implicit relationship.) * * Using two bytes for the "next" pointer is vast overkill for most things, * but allows patterns to get big without disasters. */ #define OP(p) (*(p)) #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) #define OPERAND(p) ((p) + 3) /* * See regmagic.h for one further detail of program structure. */ /* * Utility definitions. */ #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif #define FAIL(m) { regerror(m); return(NULL); } #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') #define META "^$.[()|?+*\\" /* * Flags to be passed up and down. */ #define HASWIDTH 01 /* Known never to match null string. */ #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ #define SPSTART 04 /* Starts with * or +. */ #define WORST 0 /* Worst case. */ /* * Global work variables for regcomp(). */ static char *regparse; /* Input-scan pointer. */ static int regnpar; /* () count. */ static char regdummy; static char *regcode; /* Code-emit pointer; ®dummy = don't. */ static long regsize; /* Code size. */ /* * The first byte of the regexp internal "program" is actually this magic * number; the start node begins in the second byte. */ #define MAGIC 0234 /* * Forward declarations for regcomp()'s friends. */ #ifndef STATIC #define STATIC static #endif STATIC char *reg(); STATIC char *regbranch(); STATIC char *regpiece(); STATIC char *regatom(); STATIC char *regnode(); STATIC char *regnext(); STATIC void regc(); STATIC void reginsert(); STATIC void regtail(); STATIC void regoptail(); #ifdef STRCSPN STATIC int strcspn(); #endif /* regcomp originally appeared here - DEL */ /* - reg - regular expression, i.e. main body or parenthesized thing * * Caller must absorb opening parenthesis. * * Combining parenthesis handling with the base level of regular expression * is a trifle forced, but the need to tie the tails of the branches to what * follows makes it hard to avoid. */ static char * reg(paren, flagp) int paren; /* Parenthesized? */ int *flagp; { register char *ret; register char *br; register char *ender; register int parno = 0; int flags; *flagp = HASWIDTH; /* Tentatively. */ /* Make an OPEN node, if parenthesized. */ if (paren) { if (regnpar >= NSUBEXP) FAIL("too many ()"); parno = regnpar; regnpar++; ret = regnode(OPEN+parno); } else ret = NULL; /* Pick up the branches, linking them together. */ br = regbranch(&flags); if (br == NULL) return(NULL); if (ret != NULL) regtail(ret, br); /* OPEN -> first. */ else ret = br; if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; while (*regparse == '|') { regparse++; br = regbranch(&flags); if (br == NULL) return(NULL); regtail(ret, br); /* BRANCH -> BRANCH. */ if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } /* Make a closing node, and hook it on the end. */ ender = regnode((paren) ? CLOSE+parno : END); regtail(ret, ender); /* Hook the tails of the branches to the closing node. */ for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); /* Check for proper termination. */ if (paren && *regparse++ != ')') { FAIL("unmatched ()"); } else if (!paren && *regparse != '\0') { if (*regparse == ')') { FAIL("unmatched ()"); } else FAIL("junk on end"); /* "Can't happen". */ /* NOTREACHED */ } return(ret); } /* - regbranch - one alternative of an | operator * * Implements the concatenation operator. */ static char * regbranch(flagp) int *flagp; { register char *ret; register char *chain; register char *latest; int flags; *flagp = WORST; /* Tentatively. */ ret = regnode(BRANCH); chain = NULL; while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { latest = regpiece(&flags); if (latest == NULL) return(NULL); *flagp |= flags&HASWIDTH; if (chain == NULL) /* First piece. */ *flagp |= flags&SPSTART; else regtail(chain, latest); chain = latest; } if (chain == NULL) /* Loop ran zero times. */ (void) regnode(NOTHING); return(ret); } /* - regpiece - something followed by possible [*+?] * * Note that the branching code sequences used for ? and the general cases * of * and + are somewhat optimized: they use the same NOTHING node as * both the endmarker for their branch list and the body of the last branch. * It might seem that this node could be dispensed with entirely, but the * endmarker role is not redundant. */ static char * regpiece(flagp) int *flagp; { register char *ret; register char op; register char *next; int flags; ret = regatom(&flags); if (ret == NULL) return(NULL); op = *regparse; if (!ISMULT(op)) { *flagp = flags; return(ret); } if (!(flags&HASWIDTH) && op != '?') FAIL("*+ operand could be empty"); *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); if (op == '*' && (flags&SIMPLE)) reginsert(STAR, ret); else if (op == '*') { /* Emit x* as (x&|), where & means "self". */ reginsert(BRANCH, ret); /* Either x */ regoptail(ret, regnode(BACK)); /* and loop */ regoptail(ret, ret); /* back */ regtail(ret, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '+' && (flags&SIMPLE)) reginsert(PLUS, ret); else if (op == '+') { /* Emit x+ as x(&|), where & means "self". */ next = regnode(BRANCH); /* Either */ regtail(ret, next); regtail(regnode(BACK), ret); /* loop back */ regtail(next, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '?') { /* Emit x? as (x|) */ reginsert(BRANCH, ret); /* Either x */ regtail(ret, regnode(BRANCH)); /* or */ next = regnode(NOTHING); /* null. */ regtail(ret, next); regoptail(ret, next); } regparse++; if (ISMULT(*regparse)) FAIL("nested *?+"); return(ret); } /* - regatom - the lowest level * * Optimization: gobbles an entire sequence of ordinary characters so that * it can turn them into a single node, which is smaller to store and * faster to run. Backslashed characters are exceptions, each becoming a * separate node; the code is simpler that way and it's not worth fixing. */ static char * regatom(flagp) int *flagp; { register char *ret; int flags; *flagp = WORST; /* Tentatively. */ switch (*regparse++) { case '^': ret = regnode(BOL); break; case '$': ret = regnode(EOL); break; case '.': ret = regnode(ANY); *flagp |= HASWIDTH|SIMPLE; break; case '[': { register int clss; register int classend; if (*regparse == '^') { /* Complement of range. */ ret = regnode(ANYBUT); regparse++; } else ret = regnode(ANYOF); if (*regparse == ']' || *regparse == '-') regc(*regparse++); while (*regparse != '\0' && *regparse != ']') { if (*regparse == '-') { regparse++; if (*regparse == ']' || *regparse == '\0') regc('-'); else { clss = UCHARAT(regparse-2)+1; classend = UCHARAT(regparse); if (clss > classend+1) FAIL("invalid [] range"); for (; clss <= classend; clss++) regc((char)clss); regparse++; } } else regc(*regparse++); } regc('\0'); if (*regparse != ']') FAIL("unmatched []"); regparse++; *flagp |= HASWIDTH|SIMPLE; } break; case '(': ret = reg(1, &flags); if (ret == NULL) return(NULL); *flagp |= flags&(HASWIDTH|SPSTART); break; case '\0': case '|': case ')': FAIL("internal urp"); /* Supposed to be caught earlier. */ /* NOTREACHED */ break; case '?': case '+': case '*': FAIL("?+* follows nothing"); /* NOTREACHED */ break; case '\\': if (*regparse == '\0') FAIL("trailing \\"); ret = regnode(EXACTLY); regc(*regparse++); regc('\0'); *flagp |= HASWIDTH|SIMPLE; break; default: { register int len; register char ender; regparse--; len = strcspn(regparse, META); if (len <= 0) FAIL("internal disaster"); ender = *(regparse+len); if (len > 1 && ISMULT(ender)) len--; /* Back off clear of ?+* operand. */ *flagp |= HASWIDTH; if (len == 1) *flagp |= SIMPLE; ret = regnode(EXACTLY); while (len > 0) { regc(*regparse++); len--; } regc('\0'); } break; } return(ret); } /* - regnode - emit a node */ static char * /* Location. */ regnode(op) int op; { register char *ret; register char *ptr; ret = regcode; if (ret == ®dummy) { regsize += 3; return(ret); } ptr = ret; *ptr++ = (char)op; *ptr++ = '\0'; /* Null "next" pointer. */ *ptr++ = '\0'; regcode = ptr; return(ret); } /* - regc - emit (if appropriate) a byte of code */ static void regc(b) int b; { if (regcode != ®dummy) *regcode++ = (char)b; else regsize++; } /* - reginsert - insert an operator in front of already-emitted operand * * Means relocating the operand. */ static void reginsert(op, opnd) int op; char *opnd; { register char *src; register char *dst; register char *place; if (regcode == ®dummy) { regsize += 3; return; } src = regcode; regcode += 3; dst = regcode; while (src > opnd) *--dst = *--src; place = opnd; /* Op node, where operand used to be. */ *place++ = (char)op; *place++ = '\0'; *place = '\0'; } /* - regtail - set the next-pointer at the end of a node chain */ static void regtail(p, val) char *p; char *val; { register char *scan; register char *temp; register int offset; if (p == ®dummy) return; /* Find last node. */ scan = p; for (;;) { temp = regnext(scan); if (temp == NULL) break; scan = temp; } if (OP(scan) == BACK) offset = scan - val; else offset = val - scan; *(scan+1) = (char)(offset>>8)&0377; *(scan+2) = (char)offset&0377; } /* - regoptail - regtail on operand of first argument; nop if operandless */ static void regoptail(p, val) char *p; char *val; { /* "Operandless" and "op != BRANCH" are synonymous in practice. */ if (p == NULL || p == ®dummy || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } /* * regexec and friends */ /* * Global work variables for regexec(). */ static char *reginput; /* String-input pointer. */ NOTSTATIC char *regbol; /* Beginning of input, for ^ check. */ static char **regstartp; /* Pointer to startp array. */ static char **regendp; /* Ditto for endp. */ /* * Forwards. */ NOTSTATIC int regtry(); STATIC int regmatch(); STATIC int regrepeat(); #ifdef DEBUG int regnarrate = 0; void regdump(); STATIC char *regprop(); #endif #if 0 /* - regexec - match a regexp against a string */ int regexec(prog, string, stringlength, matchlength) register regexp *prog; register char *string; /* note: CURRENTLY ASSUMED TO BE NULL-TERMINATED!!! */ int stringlength; /* length of string */ int *matchlength; /* number of chars matched (or to be skipped) */ /* set when MATCH or CANT_MATCH */ { register char *s; extern char *strchr(); /* Be paranoid... */ if (prog == NULL || string == NULL) { regerror("NULL parameter"); return(EXP_TCLERROR); } /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { regerror("corrupted program"); return(EXP_KM_ERROR); } #if THIS_RUINS_EXP /* no need for this shortcut anyway */ /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { s = string; while ((s = strchr(s, prog->regmust[0])) != NULL) { if (strncmp(s, prog->regmust, prog->regmlen) == 0) break; /* Found it. */ s++; } if (s == NULL) /* Not present. */ return(0); } #endif /* Mark beginning of line for ^ . */ regbol = string; /* Simplest case: anchored match need be tried only once. */ if (prog->reganch) { int r = regtry(prog,string,matchlength); if (r == CANT_MATCH) *matchlength = stringlength; return(r); } /* Messy cases: unanchored match. */ s = string; if (prog->regstart != '\0') { register char *s2 = s; /* We know what char it must start with. */ while (1) { int r; s2 = strchr(s2,prog->regstart); if (s2 == 0) { *matchlength = stringlength; return(CANT_MATCH); } r = regtry(prog,s2,matchlength); if (r == CANT_MATCH) { s2++; continue; } if (s2 == s) return(r); *matchlength = s2-s; return CANT_MATCH; } } else { /* We don't -- general case. */ register char *s2 = s; int r = regtry(prog,s,matchlength); if (r == EXP_MATCH) return(r); else if (r == EXP_CANMATCH) return(r); /* at this point, we know some characters at front */ /* of string don't match */ for (s2++;*s2;s2++) { r = regtry(prog,s2,matchlength); if (r == CANT_MATCH) continue; /* if we match or can_match, say cant_match and */ /* record the number of chars at front that don't match */ *matchlength = s2-s; return(CANT_MATCH); } /* made it thru string with CANT_MATCH all the way */ *matchlength = stringlength; return(CANT_MATCH); } } #endif /* - regtry - try match at specific point */ /* return CAN_MATCH, CANT_MATCH or MATCH */ int /* 0 failure, 1 success */ regtry(prog, string, matchlength) regexp *prog; char *string; int *matchlength; /* only set for MATCH */ { register int i; register char **sp; register char **ep; int r; /* result of regmatch */ reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } r = regmatch(prog->program + 1); if (EXP_MATCH == r) { prog->startp[0] = string; prog->endp[0] = reginput; *matchlength = reginput-string; return(EXP_MATCH); } return(r); /* CAN_MATCH or CANT_MATCH */ } /* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ /* returns CAN, CANT or MATCH */ static int /* 0 failure, 1 success */ regmatch(prog) char *prog; { register char *scan; /* Current node. */ char *next; /* Next node. */ #ifndef strchr /* May be #defined to something else */ extern char *strchr(); #endif scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) /* return(0);*/ return(EXP_CANTMATCH); break; case EOL: if (*reginput != '\0') /* return(0);*/ /* note this implies that "$" must match everything received to this point! */ return(EXP_CANTMATCH); break; case ANY: if (*reginput == '\0') /* return(0);*/ return(EXP_CANMATCH); reginput++; break; case EXACTLY: { /* register int len;*/ register char *opnd; opnd = OPERAND(scan); /* this section of code is totally rewritten - DEL */ /* group of literal chars in pattern */ /* compare each one */ do { if (*opnd != *reginput) { if (*reginput == '\0') { return EXP_CANMATCH; } else return EXP_CANTMATCH; } reginput++; opnd++; } while (*opnd != '\0'); } break; case ANYOF: /* if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return(0); */ if (*reginput == '\0') return(EXP_CANMATCH); if (strchr(OPERAND(scan),*reginput) == NULL) return(EXP_CANTMATCH); reginput++; break; case ANYBUT: /* if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) return(0); */ if (*reginput == '\0') return(EXP_CANMATCH); if (strchr(OPERAND(scan),*reginput) != NULL) return(EXP_CANTMATCH); reginput++; break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: { register int no; register char *save; int r; /* result of regmatch */ doOpen: no = OP(scan) - OPEN; save = reginput; r = regmatch(next); if (r == EXP_MATCH) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; } return(r); } /* NOTREACHED */ break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: { register int no; register char *save; int r; /* result of regmatch */ doClose: no = OP(scan) - CLOSE; save = reginput; r = regmatch(next); if (r == EXP_MATCH) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; } return(r); } /* NOTREACHED */ break; case BRANCH: { register char *save; int match_status; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { match_status = EXP_CANTMATCH; do { int r; save = reginput; r = regmatch(OPERAND(scan)); if (r == EXP_MATCH) return(r); if (r == EXP_CANMATCH) { match_status = r; } reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(match_status); /* NOTREACHED */ } } /* NOTREACHED */ break; case STAR: case PLUS: { register char nextch; register int no; register char *save; register int min; int match_status; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ match_status = EXP_CANTMATCH; nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); min = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ /* 3rd condition allows for CAN_MATCH */ if (nextch == '\0' || *reginput == nextch || *reginput == '\0') { int r = regmatch(next); if (r == EXP_MATCH) return(EXP_MATCH); if (r == EXP_CANMATCH) match_status = r; } /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(match_status); } /* NOTREACHED */ break; case END: return(EXP_MATCH); /* Success! */ /* NOTREACHED */ break; default: if (OP(scan) > OPEN && OP(scan) < OPEN+NSUBEXP) { goto doOpen; } else if (OP(scan) > CLOSE && OP(scan) < CLOSE+NSUBEXP) { goto doClose; } regerror("memory corruption"); return(EXP_TCLERROR); /* NOTREACHED */ break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(EXP_TCLERROR); } /* - regrepeat - repeatedly match something simple, report how many */ static int regrepeat(p) char *p; { register int count = 0; register char *scan; register char *opnd; #ifndef strchr /* May be #defined to something else */ /*DEL*/ extern char *strchr(); #endif scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = strlen(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { count++; scan++; } break; case ANYOF: while (*scan != '\0' && strchr(opnd, *scan) != NULL) { count++; scan++; } break; case ANYBUT: while (*scan != '\0' && strchr(opnd, *scan) == NULL) { count++; scan++; } break; default: /* Oh dear. Called inappropriately. */ regerror("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return(count); } /* - regnext - dig the "next" pointer out of a node */ static char * regnext(p) register char *p; { register int offset; if (p == ®dummy) return(NULL); offset = NEXT(p); if (offset == 0) return(NULL); if (OP(p) == BACK) return(p-offset); else return(p+offset); } #ifdef DEBUG STATIC char *regprop(); /* - regdump - dump a regexp onto stdout in vaguely comprehensible form */ void regdump(r) regexp *r; { register char *s; register char op = EXACTLY; /* Arbitrary non-END op. */ register char *next; extern char *strchr(); s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ op = OP(s); printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); if (next == NULL) /* Next ptr. */ printf("(0)"); else printf("(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF || op == ANYBUT || op == EXACTLY) { /* Literal string, where present. */ while (*s != '\0') { putchar(*s); s++; } s++; } putchar('\n'); } /* Header fields of interest. */ if (r->regstart != '\0') printf("start `%c' ", r->regstart); if (r->reganch) printf("anchored "); if (r->regmust != NULL) printf("must have \"%s\"", r->regmust); printf("\n"); } /* - regprop - printable representation of opcode */ static char * regprop(op) char *op; { register char *p; static char buf[50]; (void) strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; break; case STAR: p = "STAR"; break; case PLUS: p = "PLUS"; break; default: if (OP(op) > OPEN && OP(op) < OPEN+NSUBEXP) { sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; } else if (OP(op) > CLOSE && OP(op) < CLOSE+NSUBEXP) { sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; } else { TclRegError("corrupted opcode"); } break; } if (p != NULL) (void) strcat(buf, p); return(buf); } #endif /* * The following is provided for those people who do not have strcspn() in * their C libraries. They should get off their butts and do something * about it; at least one public-domain implementation of those (highly * useful) string routines has been published on Usenet. */ #ifdef STRCSPN /* * strcspn - find length of initial segment of s1 consisting entirely * of characters not from s2 */ static int strcspn(s1, s2) char *s1; char *s2; { register char *scan1; register char *scan2; register int count; count = 0; for (scan1 = s1; *scan1 != '\0'; scan1++) { for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ if (*scan1 == *scan2++) return(count); count++; } return(count); } #endif |
Added generic/exp_strf.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 | /* ---------------------------------------------------------------------------- * exp_strp.c -- * * functions for exp_timestamp. * * ---------------------------------------------------------------------------- * Notes: * * Public-domain implementation of ANSI C library routine. * * It's written in old-style C for maximal portability. * However, since I'm used to prototypes, I've included them too. * * If you want stuff in the System V ascftime routine, add the SYSV_EXT define. * For extensions from SunOS, add SUNOS_EXT. * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE. * For VMS dates, add VMS_EXT. * For complete POSIX semantics, add POSIX_SEMANTICS. * * The code for %c, %x, and %X now follows the 1003.2 specification for * the POSIX locale. * This version ignores LOCALE information. * It also doesn't worry about multi-byte characters. * So there. * * This file is also shipped with GAWK (GNU Awk), gawk specific bits of * code are included if GAWK is defined. * * Arnold Robbins <[email protected]> * January, February, March, 1991 * Updated March, April 1992 * Updated April, 1993 * Updated February, 1994 * Updated May, 1994 * Updated January 1995 * Updated September 1995 * * Fixes from [email protected] * February 1991, May 1992 * Fixes from Tor Lillqvist [email protected] * May, 1993 * Further fixes from [email protected] * February 1994 * %z code from [email protected] * Applied September 1995 * * * Modified by Don Libes for Expect, 10/93 and 12/95. * Forced POSIX semantics. * Replaced inline/min/max stuff with a single range function. * Removed tzset stuff. * Commented out tzname stuff. * * According to Arnold, the current version of this code can ftp'd from * ftp.mathcs.emory.edu:/pub/arnold/strftime.shar.gz * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #include "expPort.h" #include <stdio.h> #include <ctype.h> #include <string.h> #include <sys/types.h> #define SYSV_EXT 1 /* stuff in System V ascftime routine */ #define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */ #if defined(POSIX2_DATE) && ! defined(SYSV_EXT) #define SYSV_EXT 1 #endif #if defined(POSIX2_DATE) #define adddecl(stuff) stuff #else #define adddecl(stuff) #endif #ifndef __STDC__ static int weeknumber(); adddecl(static int iso8601wknum();) #else extern char *strchr(const char *str, int ch); static int weeknumber(const struct tm *timeptr, int firstweekday); adddecl(static int iso8601wknum(const struct tm *timeptr);) #endif /* attempt to use strftime to compute timezone, else fallback to */ /* less portable ways */ #if !defined(HAVE_STRFTIME) # if defined(HAVE_SV_TIMEZONE) # ifndef __WIN32__ extern char *tzname[2]; extern int daylight; # endif # else # if defined(HAVE_TIMEZONE) char * zone_name (tp) struct tm *tp; { char *timezone (); struct timeval tv; struct timezone tz; gettimeofday (&tv, &tz); return timezone (tz.tz_minuteswest, tp->tm_isdst); } # endif /* HAVE_TIMEZONE */ # endif /* HAVE_SV_TIMEZONE */ #endif /* HAVE_STRFTIME */ static int range(low,item,hi) int low, item, hi; { if (item < low) return low; if (item > hi) return hi; return item; } /* strftime --- produce formatted time */ void /*size_t*/ #ifndef __STDC__ exp_strftime(/*s,*/ format, timeptr, dstring) /*char *s;*/ char *format; CONST struct tm *timeptr; Tcl_DString *dstring; #else /*exp_strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)*/ exp_strftime(char *format, const struct tm *timeptr,Tcl_DString *dstring) #endif { int copied; /* used to suppress copying when called recursively */ #if 0 char *endp = s + maxsize; char *start = s; #endif char *percentptr; char tbuf[100]; int i; /* various tables, useful in North America */ static char *days_a[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", }; static char *days_l[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", }; static char *months_a[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", }; static char *months_l[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", }; static char *ampm[] = { "AM", "PM", }; /* for (; *format && s < endp - 1; format++) {*/ for (; *format ; format++) { tbuf[0] = '\0'; copied = 0; /* has not been copied yet */ percentptr = strchr(format,'%'); if (percentptr == 0) { Tcl_DStringAppend(dstring,format,-1); goto out; } else if (percentptr != format) { Tcl_DStringAppend(dstring,format,percentptr - format); format = percentptr; } #if 0 if (*format != '%') { *s++ = *format; continue; } #endif again: switch (*++format) { case '\0': Tcl_DStringAppend(dstring,"%",1); #if 0 *s++ = '%'; #endif goto out; case '%': Tcl_DStringAppend(dstring,"%",1); copied = 1; break; #if 0 *s++ = '%'; continue; #endif case 'a': /* abbreviated weekday name */ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) strcpy(tbuf, "?"); else strcpy(tbuf, days_a[timeptr->tm_wday]); break; case 'A': /* full weekday name */ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) strcpy(tbuf, "?"); else strcpy(tbuf, days_l[timeptr->tm_wday]); break; #ifdef SYSV_EXT case 'h': /* abbreviated month name */ #endif case 'b': /* abbreviated month name */ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) strcpy(tbuf, "?"); else strcpy(tbuf, months_a[timeptr->tm_mon]); break; case 'B': /* full month name */ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) strcpy(tbuf, "?"); else strcpy(tbuf, months_l[timeptr->tm_mon]); break; case 'c': /* appropriate date and time representation */ sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d", days_a[range(0, timeptr->tm_wday, 6)], months_a[range(0, timeptr->tm_mon, 11)], range(1, timeptr->tm_mday, 31), range(0, timeptr->tm_hour, 23), range(0, timeptr->tm_min, 59), range(0, timeptr->tm_sec, 61), timeptr->tm_year + 1900); break; case 'd': /* day of the month, 01 - 31 */ i = range(1, timeptr->tm_mday, 31); sprintf(tbuf, "%02d", i); break; case 'H': /* hour, 24-hour clock, 00 - 23 */ i = range(0, timeptr->tm_hour, 23); sprintf(tbuf, "%02d", i); break; case 'I': /* hour, 12-hour clock, 01 - 12 */ i = range(0, timeptr->tm_hour, 23); if (i == 0) i = 12; else if (i > 12) i -= 12; sprintf(tbuf, "%02d", i); break; case 'j': /* day of the year, 001 - 366 */ sprintf(tbuf, "%03d", timeptr->tm_yday + 1); break; case 'm': /* month, 01 - 12 */ i = range(0, timeptr->tm_mon, 11); sprintf(tbuf, "%02d", i + 1); break; case 'M': /* minute, 00 - 59 */ i = range(0, timeptr->tm_min, 59); sprintf(tbuf, "%02d", i); break; case 'p': /* am or pm based on 12-hour clock */ i = range(0, timeptr->tm_hour, 23); if (i < 12) strcpy(tbuf, ampm[0]); else strcpy(tbuf, ampm[1]); break; case 'S': /* second, 00 - 61 */ i = range(0, timeptr->tm_sec, 61); sprintf(tbuf, "%02d", i); break; case 'U': /* week of year, Sunday is first day of week */ sprintf(tbuf, "%02d", weeknumber(timeptr, 0)); break; case 'w': /* weekday, Sunday == 0, 0 - 6 */ i = range(0, timeptr->tm_wday, 6); sprintf(tbuf, "%d", i); break; case 'W': /* week of year, Monday is first day of week */ sprintf(tbuf, "%02d", weeknumber(timeptr, 1)); break; case 'x': /* appropriate date representation */ sprintf(tbuf, "%s %s %2d %d", days_a[range(0, timeptr->tm_wday, 6)], months_a[range(0, timeptr->tm_mon, 11)], range(1, timeptr->tm_mday, 31), timeptr->tm_year + 1900); break; case 'X': /* appropriate time representation */ sprintf(tbuf, "%02d:%02d:%02d", range(0, timeptr->tm_hour, 23), range(0, timeptr->tm_min, 59), range(0, timeptr->tm_sec, 61)); break; case 'y': /* year without a century, 00 - 99 */ i = timeptr->tm_year % 100; sprintf(tbuf, "%02d", i); break; case 'Y': /* year with century */ sprintf(tbuf, "%d", 1900 + timeptr->tm_year); break; case 'Z': /* time zone name or abbrevation */ #if defined(HAVE_STRFTIME) strftime(tbuf,sizeof tbuf,"%Z",timeptr); #else # if defined(HAVE_SV_TIMEZONE) i = 0; if (daylight && timeptr->tm_isdst) i = 1; strcpy(tbuf, tzname[i]); # else strcpy(tbuf, zone_name (timeptr)); # if defined(HAVE_TIMEZONE) # endif /* HAVE_TIMEZONE */ /* no timezone available */ /* feel free to add others here */ # endif /* HAVE_SV_TIMEZONE */ #endif /* HAVE STRFTIME */ break; #ifdef SYSV_EXT case 'n': /* same as \n */ tbuf[0] = '\n'; tbuf[1] = '\0'; break; case 't': /* same as \t */ tbuf[0] = '\t'; tbuf[1] = '\0'; break; case 'D': /* date as %m/%d/%y */ exp_strftime("%m/%d/%y", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);*/ break; case 'e': /* day of month, blank padded */ sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31)); break; case 'r': /* time as %I:%M:%S %p */ exp_strftime("%I:%M:%S %p", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);*/ break; case 'R': /* time as %H:%M */ exp_strftime("%H:%M", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);*/ break; case 'T': /* time as %H:%M:%S */ exp_strftime("%H:%M:%S", timeptr, dstring); copied = 1; /* exp_strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);*/ break; #endif #ifdef POSIX2_DATE case 'C': sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100); break; case 'E': case 'O': /* POSIX locale extensions, ignored for now */ goto again; case 'V': /* week of year according ISO 8601 */ sprintf(tbuf, "%02d", iso8601wknum(timeptr)); break; case 'u': /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 : timeptr->tm_wday); break; #endif /* POSIX2_DATE */ default: tbuf[0] = '%'; tbuf[1] = *format; tbuf[2] = '\0'; break; } if (!copied) Tcl_DStringAppend(dstring,tbuf,-1); #if 0 i = strlen(tbuf); if (i) { if (s + i < endp - 1) { strcpy(s, tbuf); s += i; } else return 0; #endif } out:; #if 0 if (s < endp && *format == '\0') { *s = '\0'; return (s - start); } else return 0; #endif } /* isleap --- is a year a leap year? */ #ifndef __STDC__ static int isleap(year) int year; #else static int isleap(int year) #endif { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); } #ifdef POSIX2_DATE /* iso8601wknum --- compute week number according to ISO 8601 */ #ifndef __STDC__ static int iso8601wknum(timeptr) const struct tm *timeptr; #else static int iso8601wknum(const struct tm *timeptr) #endif { /* * From 1003.2: * If the week (Monday to Sunday) containing January 1 * has four or more days in the new year, then it is week 1; * otherwise it is the highest numbered week of the previous * (52 or 53) year, and the next week is week 1. * * ADR: This means if Jan 1 was Monday through Thursday, * it was week 1, otherwise week 53. * * XPG4 erroneously included POSIX.2 rationale text in the * main body of the standard. Thus it requires week 53. */ int weeknum, jan1day; /* get week number, Monday as first day of the week */ weeknum = weeknumber(timeptr, 1); /* * With thanks and tip of the hatlo to [email protected] * * What day of the week does January 1 fall on? * We know that * (timeptr->tm_yday - jan1.tm_yday) MOD 7 == * (timeptr->tm_wday - jan1.tm_wday) MOD 7 * and that * jan1.tm_yday == 0 * and that * timeptr->tm_wday MOD 7 == timeptr->tm_wday * from which it follows that. . . */ jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7); if (jan1day < 0) jan1day += 7; /* * If Jan 1 was a Monday through Thursday, it was in * week 1. Otherwise it was last year's highest week, which is * this year's week 0. * * What does that mean? * If Jan 1 was Monday, the week number is exactly right, it can * never be 0. * If it was Tuesday through Thursday, the weeknumber is one * less than it should be, so we add one. * Otherwise, Friday, Saturday or Sunday, the week number is * OK, but if it is 0, it needs to be 52 or 53. */ switch (jan1day) { case 1: /* Monday */ break; case 2: /* Tuesday */ case 3: /* Wednesday */ case 4: /* Thursday */ weeknum++; break; case 5: /* Friday */ case 6: /* Saturday */ case 0: /* Sunday */ if (weeknum == 0) { #ifdef USE_BROKEN_XPG4 /* XPG4 (as of March 1994) says 53 unconditionally */ weeknum = 53; #else /* get week number of last week of last year */ struct tm dec31ly; /* 12/31 last year */ dec31ly = *timeptr; dec31ly.tm_year--; dec31ly.tm_mon = 11; dec31ly.tm_mday = 31; dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1; dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900); weeknum = iso8601wknum(& dec31ly); #endif } break; } if (timeptr->tm_mon == 11) { /* * The last week of the year * can be in week 1 of next year. * Sigh. * * This can only happen if * M T W * 29 30 31 * 30 31 * 31 */ int wday, mday; wday = timeptr->tm_wday; mday = timeptr->tm_mday; if ( (wday == 1 && (mday >= 29 && mday <= 31)) || (wday == 2 && (mday == 30 || mday == 31)) || (wday == 3 && mday == 31)) weeknum = 1; } return weeknum; } #endif /* weeknumber --- figure how many weeks into the year */ /* With thanks and tip of the hatlo to [email protected] */ #ifndef __STDC__ static int weeknumber(timeptr, firstweekday) const struct tm *timeptr; int firstweekday; #else static int weeknumber(const struct tm *timeptr, int firstweekday) #endif { int wday = timeptr->tm_wday; int ret; if (firstweekday == 1) { if (wday == 0) /* sunday */ wday = 6; else wday--; } ret = ((timeptr->tm_yday + 7 - wday) / 7); if (ret < 0) ret = 0; return ret; } |
Added generic/exp_win.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | /* exp_win.c - window support Written by: Don Libes, NIST, 10/25/93 This file is in the public domain. However, the author and NIST would appreciate credit if you use this file or parts of it. */ #include "expect_cf.h" #include "tcl.h" #ifdef NO_STDLIB_H #include "../compat/stdlib.h" #else #include <stdlib.h> #endif /* _IBCS2 required on some Intel platforms to allow the include files */ /* to produce a definition for winsize. */ #define _IBCS2 1 /* * get everyone's window size definitions * note that this is tricky because (of course) everyone puts them in different places. Worse, on some systems, some .h files conflict and cannot both be included even though both exist. This is the case, for example, on SunOS 4.1.3 using gcc where termios.h conflicts with sys/ioctl.h */ #ifdef HAVE_TERMIOS # include <termios.h> #else # include <sys/ioctl.h> #endif /* Sigh. On AIX 2.3, termios.h exists but does not define TIOCGWINSZ */ /* Instead, it has to come from ioctl.h. However, As I said above, this */ /* can't be cavalierly included on all machines, even when it exists. */ #if defined(HAVE_TERMIOS) && !defined(HAVE_TIOCGWINSZ_IN_TERMIOS_H) # include <sys/ioctl.h> #endif /* SCO defines window size structure in PTEM and TIOCGWINSZ in termio.h */ /* Sigh... */ #if defined(HAVE_SYS_PTEM_H) # include <sys/types.h> /* for stream.h's caddr_t */ # include <sys/stream.h> /* for ptem.h's mblk_t */ # include <sys/ptem.h> #endif /* HAVE_SYS_PTEM_H */ #include "exp_tty.h" #include "exp_win.h" #ifdef TIOCGWINSZ typedef struct winsize exp_winsize; #define columns ws_col #define rows ws_row #define EXP_WIN #endif #if !defined(EXP_WIN) && defined(TIOCGSIZE) typedef struct ttysize exp_winsize; #define columns ts_cols #define rows ts_lines #define EXP_WIN #endif #if !defined(EXP_WIN) typedef struct { int columns; int rows; } exp_winsize; #endif static exp_winsize winsize = {0, 0}; static exp_winsize win2size = {0, 0}; int exp_window_size_set(fd) int fd; { #ifdef TIOCSWINSZ ioctl(fd,TIOCSWINSZ,&winsize); #endif #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ) ioctl(fd,TIOCSSIZE,&winsize); #endif } int exp_window_size_get(fd) int fd; { #ifdef TIOCGWINSZ ioctl(fd,TIOCGWINSZ,&winsize); #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) ioctl(fd,TIOCGSIZE,&winsize); #endif #if !defined(EXP_WIN) winsize.rows = 0; winsize.columns = 0; #endif } void exp_win_rows_set(rows) char *rows; { winsize.rows = atoi(rows); exp_window_size_set(exp_dev_tty); } void exp_win_rows_get(rows) char *rows; { exp_window_size_get(exp_dev_tty); sprintf(rows,"%d",winsize.rows); } void exp_win_columns_set(columns) char *columns; { winsize.columns = atoi(columns); exp_window_size_set(exp_dev_tty); } void exp_win_columns_get(columns) char *columns; { exp_window_size_get(exp_dev_tty); sprintf(columns,"%d",winsize.columns); } /* * separate copy of everything above - used for handling user stty requests */ int exp_win2_size_set(fd) int fd; { #ifdef TIOCSWINSZ ioctl(fd,TIOCSWINSZ,&win2size); #endif #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ) ioctl(fd,TIOCSSIZE,&win2size); #endif } int exp_win2_size_get(fd) int fd; { #ifdef TIOCGWINSZ ioctl(fd,TIOCGWINSZ,&win2size); #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) ioctl(fd,TIOCGSIZE,&win2size); #endif } void exp_win2_rows_set(fd,rows) int fd; char *rows; { exp_win2_size_get(fd); win2size.rows = atoi(rows); exp_win2_size_set(fd); } void exp_win2_rows_get(fd,rows) int fd; char *rows; { exp_win2_size_get(fd); sprintf(rows,"%d",win2size.rows); #if !defined(EXP_WIN) win2size.rows = 0; win2size.columns = 0; #endif } void exp_win2_columns_set(fd,columns) int fd; char *columns; { exp_win2_size_get(fd); win2size.columns = atoi(columns); exp_win2_size_set(fd); } void exp_win2_columns_get(fd,columns) int fd; char *columns; { exp_win2_size_get(fd); sprintf(columns,"%d",win2size.columns); } |
Added generic/expect.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 | /* ---------------------------------------------------------------------------- * expect.c -- * * expect commands. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #endif /* initial length of strings that we can guarantee patterns can match */ int exp_default_match_max = 2000; #define INIT_EXPECT_TIMEOUT_LIT "10" /* seconds */ #define INIT_EXPECT_TIMEOUT 10 /* seconds */ int exp_default_parity = TRUE; int exp_default_rm_nulls = TRUE; /* user variable names */ #define EXPECT_TIMEOUT "timeout" #define EXPECT_OUT "expect_out" /* 1 ecase struct is reserved for each case in the expect command. Note that eof/timeout don't use any of theirs, but the algorithm is simpler this way. */ struct ecase { /* case for expect command */ struct exp_i *i_list; char *pat; /* original pattern spec */ char *body; /* ptr to body to be executed upon match */ #define PAT_EOF 1 #define PAT_TIMEOUT 2 #define PAT_DEFAULT 3 #define PAT_FULLBUFFER 4 #define PAT_GLOB 5 /* glob-style pattern list */ #define PAT_RE 6 /* regular expression */ #define PAT_EXACT 7 /* exact string */ #define PAT_NULL 8 /* ASCII 0 */ #define PAT_TYPES 9 /* used to size array of pattern type descriptions */ int use; /* PAT_XXX */ int simple_start;/* offset from start of buffer denoting where a */ /* glob or exact match begins */ int transfer; /* if false, leave matched chars in input stream */ int indices; /* if true, write indices */ /* int iwrite;*/ /* if true write spawn_id */ int iread; /* if true, reread indirects */ int timestamp; /* if true, write timestamps */ #define CASE_UNKNOWN 0 #define CASE_NORM 1 #define CASE_LOWER 2 int Case; /* convert case before doing match? */ Tcl_RegExp *re; /* if this is 0, then pattern match via glob */ }; /* descriptions of the pattern types, used for debugging */ char *pattern_style[PAT_TYPES]; struct exp_cases_descriptor { int count; struct ecase **cases; }; /* This describes an Expect command */ static struct exp_cmd_descriptor { int cmdtype; /* bg, before, after */ int duration; /* permanent or temporary */ int timeout_specified_by_flag; /* if -timeout flag used */ int timeout; /* timeout period if flag used */ struct exp_cases_descriptor ecd; struct exp_i *i_list; } exp_cmds[4]; /* note that exp_cmds[FG] is just a fake, the real contents is stored in some dynamically-allocated variable. We use exp_cmds[FG] mostly as a well-known address and also as a convenience and so we allocate just a few of its fields that we need. */ static void exp_cmd_init(cmd,cmdtype,duration) struct exp_cmd_descriptor *cmd; int duration; int cmdtype; { cmd->duration = duration; cmd->cmdtype = cmdtype; cmd->ecd.cases = 0; cmd->ecd.count = 0; cmd->i_list = 0; } static int i_read_errno;/* place to save errno, if i_read() == -1, so it doesn't get overwritten before we get to read it */ void exp_background_filehandlers_run_all(); /* * Declarations for local procedures defined in this file: */ /*exp_indirect_updateX is called by Tcl when an indirect variable is set */ static char * exp_indirect_update1 _ANSI_ARGS_((Tcl_Interp *interp, struct exp_cmd_descriptor *ecmd, struct exp_i *exp_i)); static char * exp_indirect_update2 _ANSI_ARGS_(( ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); /* 2-part Tcl variable names */ static int exp_i_read _ANSI_ARGS_((Tcl_Interp *,struct exp_f *, int,int)); /* *---------------------------------------------------------------------- * * rm_nulls -- * * Remove nulls from s. Initially, the number of chars in s is c, * not strlen(s). This count does not include the trailing null. * * Results: * Returns number of nulls removed. * *---------------------------------------------------------------------- */ static int rm_nulls(s,c) char *s; int c; { char *s2 = s; /* points to place in original string to put */ /* next non-null character */ int count = 0; int i; for (i=0;i<c;i++,s++) { if (0 == *s) { count++; continue; } if (count) *s2 = *s; s2++; } return(count); } /* *---------------------------------------------------------------------- * * free_ecase -- * * Free up everything in ecase * * Results: * None * *---------------------------------------------------------------------- */ static void free_ecase(interp,ec,free_ilist) Tcl_Interp *interp; struct ecase *ec; int free_ilist; /* if we should free ilist */ { if (ec->re) ckfree((char *)ec->re); if (ec->i_list->duration == EXP_PERMANENT) { if (ec->pat) ckfree(ec->pat); if (ec->body) ckfree(ec->body); } if (free_ilist) { ec->i_list->ecount--; if (ec->i_list->ecount == 0) exp_free_i(interp,ec->i_list,exp_indirect_update2); } ckfree((char *)ec); /* NEW */ } /* *---------------------------------------------------------------------- * * free_ecases -- * * Free up any argv structures in the ecases * * Results: * None * *---------------------------------------------------------------------- */ static void free_ecases(interp,eg,free_ilist) Tcl_Interp *interp; struct exp_cmd_descriptor *eg; int free_ilist; /* if true, free ilists */ { int i; if (!eg->ecd.cases) return; for (i=0;i<eg->ecd.count;i++) { free_ecase(interp,eg->ecd.cases[i],free_ilist); } ckfree((char *)eg->ecd.cases); eg->ecd.cases = 0; eg->ecd.count = 0; } /* *---------------------------------------------------------------------- * * save_str -- * * Make a copy of a string if necessary. In many places, there * is no need to malloc a copy of a string, since it will be * freed before we return to Tcl * * Results: * String is set through lhs * * Side Effects: * Memory may be allocated for a copy of the string * *---------------------------------------------------------------------- */ static void save_str(lhs,rhs,nosave) char **lhs; /* left hand side */ char *rhs; /* right hand side */ int nosave; { if (nosave || (rhs == 0)) { *lhs = rhs; } else { *lhs = ckalloc(strlen(rhs) + 1); strcpy(*lhs,rhs); } } /* *---------------------------------------------------------------------- * * exp_one_arg_braced -- * * The intent of this test is to support the ability of * commands to have all their args braced as one. This * conflicts with the possibility of actually intending * to have a single argument. The bad case is in expect * which can have a single argument with embedded \n's * although it's rare. Examples that this code should handle: * * \n FALSE (pattern) * \n\n FALSE * \n \n \n FALSE * foo FALSE * foo\n FALSE * \nfoo\n TRUE (set of args) * \nfoo\nbar TRUE * * Current test is very cheap and almost always right :-) * * Results: * TRUE if string appears to be a set of arguments * *---------------------------------------------------------------------- */ int exp_one_arg_braced(objPtr) /* INTL */ Tcl_Obj *objPtr; { int seen_nl = FALSE; char *p = Tcl_GetString(objPtr); for (;*p;p++) { if (*p == '\n') { seen_nl = TRUE; continue; } if (!isspace(*p)) { /* INTL: ISO space */ return(seen_nl); } } return FALSE; } /* *---------------------------------------------------------------------- * * exp_eval_with_one_arg -- * * Called to execute a command of only one argument - a hack * to commands to be called with all args surrounded by an * outer set of braces * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ /*ARGSUSED*/ /* called to execute a command of only one argument - a hack to commands */ /* to be called with all args surrounded by an outer set of braces */ /* returns TCL_whatever */ /*ARGSUSED*/ int exp_eval_with_one_arg(clientData,interp,objv) /* INTL */ ClientData clientData; Tcl_Interp *interp; Tcl_Obj *CONST objv[]; /* Argument objects. */ { #define NUM_STATIC_OBJS 20 Tcl_Obj *staticObjArray[NUM_STATIC_OBJS]; int maxobjs = NUM_STATIC_OBJS; Tcl_Token *tokenPtr; char *p, *next; int rc; Tcl_Obj **objs = staticObjArray; int objc, bytesLeft, numWords, i; Tcl_Parse parse; /* * Prepend the command name and the -nobrace switch so we can * reinvoke without recursing. */ objc = 2; objs[0] = objv[0]; objs[1] = Tcl_NewStringObj("-nobrace", -1); Tcl_IncrRefCount(objs[0]); Tcl_IncrRefCount(objs[1]); p = Tcl_GetStringFromObj(objv[1], &bytesLeft); /* * Treat the pattern/action block like a series of Tcl commands. * For each command, parse the command words, perform substititions * on each word, and add the words to an array of values. We don't * actually evaluate the individual commands, just the substitutions. */ do { if (Tcl_ParseCommand(interp, p, bytesLeft, 0, &parse) != TCL_OK) { rc = TCL_ERROR; goto done; } numWords = parse.numWords; if (numWords > 0) { /* * Generate an array of objects for the words of the command. */ if (objc + numWords > maxobjs) { Tcl_Obj ** newobjs; maxobjs = (objc + numWords) * 2; newobjs = (Tcl_Obj **)ckalloc(maxobjs * sizeof (Tcl_Obj *)); memcpy(newobjs, objs, objc*sizeof(Tcl_Obj *)); if (objs != staticObjArray) { ckfree((char*)objs); } objs = newobjs; } /* * For each word, perform substitutions then store the * result in the objs array. */ for (tokenPtr = parse.tokenPtr; numWords > 0; numWords--, tokenPtr += (tokenPtr->numComponents + 1)) { objs[objc] = Tcl_EvalTokens(interp, tokenPtr+1, tokenPtr->numComponents); if (objs[objc] == NULL) { rc = TCL_ERROR; goto done; } objc++; } } /* * Advance to the next command in the script. */ next = parse.commandStart + parse.commandSize; bytesLeft -= next - p; p = next; Tcl_FreeParse(&parse); } while (bytesLeft > 0); /* * Now evaluate the entire command with no further substitutions. */ rc = Tcl_EvalObjv(interp, objc, objs, 0); done: for (i = 0; i < objc; i++) { Tcl_DecrRefCount(objs[i]); } if (objs != staticObjArray) { ckfree((char *) objs); } return(rc); #undef NUM_STATIC_OBJS } static void ecase_clear(ec) struct ecase *ec; { ec->i_list = 0; ec->pat = 0; ec->body = 0; ec->transfer = TRUE; ec->indices = FALSE; /* ec->iwrite = FALSE;*/ ec->iread = FALSE; ec->timestamp = FALSE; ec->re = 0; ec->Case = CASE_NORM; ec->use = PAT_GLOB; } static struct ecase * ecase_new() { struct ecase *ec = (struct ecase *)ckalloc(sizeof(struct ecase)); ecase_clear(ec); return ec; } /* *---------------------------------------------------------------------- * * parse_expect_args -- * * Parses the arguments to expect or its variants. It normally * returns TCL_OK, and returns TCL_ERROR for failure. (It can't * return i_list directly because there is no way to differentiate * between clearing, say, expect_before and signalling an error.) * * eg (expect_global) is initialized to reflect the arguments parsed * eg->ecd.cases is an array of ecases * eg->ecd.count is the # of ecases * eg->i_list is a linked list of exp_i's which represent the -i info * * Each exp_i is chained to the next so that they can be easily free'd * if necessary. Each exp_i has a reference count. If the -i is not * used (e.g., has no following patterns), the ref count will be 0. * * Each ecase points to an exp_i. Several ecases may point to the * same exp_i. Variables named by indirect exp_i's are read for the * direct values. * * If called from a foreground expect and no patterns or -i are given, * a default exp_i is forced so that the command "expect" works right. * * The exp_i chain can be broken by the caller if desired. * * Results: * A standard TCL result. * *---------------------------------------------------------------------- */ static int parse_expect_args(interp,eg,default_spawn_id,objc,objv) Tcl_Interp *interp; struct exp_cmd_descriptor *eg; struct exp_f *default_spawn_id; /* suggested master if called as * expect_user or _tty */ int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { int i; char *string; struct ecase ec; /* temporary to collect args */ eg->timeout_specified_by_flag = FALSE; ecase_clear(&ec); /* Allocate an array to store the ecases. Force array even if 0 */ /* cases. This will often be too large (i.e., if there are flags) */ /* but won't affect anything. */ eg->ecd.cases = (struct ecase **)ckalloc(sizeof(struct ecase *) * (1+(objc/2))); eg->ecd.count = 0; for (i = 1;i<objc;i++) { int index; string = Tcl_GetString(objv[i]); if (string[0] == '-') { static char *flags[] = { "-glob", "-regexp", "-exact", "-notransfer", "-nocase", "-i", "-indices", "-iread", "-timestamp", "-timeout", "-nobrace", "--", (char *)0 }; enum flags { EXP_ARG_GLOB, EXP_ARG_REGEXP, EXP_ARG_EXACT, EXP_ARG_NOTRANSFER, EXP_ARG_NOCASE, EXP_ARG_SPAWN_ID, EXP_ARG_INDICES, EXP_ARG_IREAD, EXP_ARG_TIMESTAMP, EXP_ARG_DASH_TIMEOUT, EXP_ARG_NOBRACE, EXP_ARG_DASH }; /* * Allow abbreviations of switches and report an error if we * get an invalid switch. */ if (Tcl_GetIndexFromObj(interp, objv[i], flags, "flag", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum flags) index) { case EXP_ARG_GLOB: case EXP_ARG_DASH: i++; /* assignment here is not actually necessary */ /* since cases are initialized this way above */ /* ec.use = PAT_GLOB; */ if (i >= objc) { Tcl_WrongNumArgs(interp, 1, objv,"-glob pattern"); return TCL_ERROR; } goto pattern; case EXP_ARG_REGEXP: i++; if (i >= objc) { Tcl_WrongNumArgs(interp, 1, objv,"-regexp regexp"); return TCL_ERROR; } ec.use = PAT_RE; /* * Try compiling the expression so we can report * any errors now rather then when we first try to * use it. */ if (!(Tcl_GetRegExpFromObj(interp, objv[i], TCL_REG_ADVANCED))) { goto error; } goto pattern; case EXP_ARG_EXACT: i++; if (i >= objc) { Tcl_WrongNumArgs(interp, 1, objv, "-exact string"); return TCL_ERROR; } ec.use = PAT_EXACT; goto pattern; case EXP_ARG_NOTRANSFER: ec.transfer = 0; break; case EXP_ARG_NOCASE: ec.Case = CASE_LOWER; break; case EXP_ARG_SPAWN_ID: i++; if (i>=objc) { Tcl_WrongNumArgs(interp, 1, objv, "-i spawn_id"); goto error; } ec.i_list = exp_new_i_complex(interp, Tcl_GetString(objv[i]), eg->duration, exp_indirect_update2,Tcl_GetString(objv[0])); ec.i_list->cmdtype = eg->cmdtype; /* link new i_list to head of list */ ec.i_list->next = eg->i_list; eg->i_list = ec.i_list; break; case EXP_ARG_INDICES: ec.indices = TRUE; break; case EXP_ARG_IREAD: ec.iread = TRUE; break; case EXP_ARG_TIMESTAMP: ec.timestamp = TRUE; break; case EXP_ARG_DASH_TIMEOUT: i++; if (i>=objc) { Tcl_WrongNumArgs(interp, 1, objv, "-timeout seconds"); goto error; } if (Tcl_GetIntFromObj(interp, objv[i], &eg->timeout) != TCL_OK) { goto error; } eg->timeout_specified_by_flag = TRUE; break; case EXP_ARG_NOBRACE: /* nobrace does nothing but take up space */ /* on the command line which prevents */ /* us from re-expanding any command lines */ /* of one argument that looks like it should */ /* be expanded to multiple arguments. */ break; } /* * Keep processing arguments, we aren't ready for the * pattern yet. */ continue; } else { /* * We have a pattern or keyword. */ static char *keywords[] = { "timeout", "eof", "full_buffer", "default", "null", (char *)NULL }; enum keywords { EXP_ARG_TIMEOUT, EXP_ARG_EOF, EXP_ARG_FULL_BUFFER, EXP_ARG_DEFAULT, EXP_ARG_NULL }; /* * Match keywords exactly, otherwise they are patterns. */ if (Tcl_GetIndexFromObj(interp, objv[i], keywords, "keyword", 1 /* exact */, &index) != TCL_OK) { Tcl_ResetResult(interp); goto pattern; } switch ((enum keywords) index) { case EXP_ARG_TIMEOUT: ec.use = PAT_TIMEOUT; break; case EXP_ARG_EOF: ec.use = PAT_EOF; break; case EXP_ARG_FULL_BUFFER: ec.use = PAT_FULLBUFFER; break; case EXP_ARG_DEFAULT: ec.use = PAT_DEFAULT; break; case EXP_ARG_NULL: ec.use = PAT_NULL; break; } pattern: /* if no -i, use previous one */ if (!ec.i_list) { /* if no -i flag has occurred yet, use default */ if (!eg->i_list) { if (default_spawn_id != NULL) { eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration); } else { /* it'll be checked later, if used */ default_spawn_id = exp_update_master(interp,0,0); eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration); } } ec.i_list = eg->i_list; } ec.i_list->ecount++; /* save original pattern spec */ /* keywords such as "-timeout" are saved as patterns here */ /* useful for debugging but not otherwise used */ save_str(&ec.pat,Tcl_GetString(objv[i]),eg->duration == EXP_TEMPORARY); save_str(&ec.body,Tcl_GetString(objv[i+1]),eg->duration == EXP_TEMPORARY); i++; *(eg->ecd.cases[eg->ecd.count] = ecase_new()) = ec; /* clear out for next set */ ecase_clear(&ec); eg->ecd.count++; } } /* if no patterns at all have appeared force the current */ /* spawn id to be added to list anyway */ if (eg->i_list == 0) { if (default_spawn_id != NULL) { eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration); } else { /* it'll be checked later, if used */ default_spawn_id = exp_update_master(interp,0,0); eg->i_list = exp_new_i_simple(default_spawn_id,eg->duration); } } return(TCL_OK); error: /* very hard to free case_master_list here if it hasn't already */ /* been attached to a case, ugh */ /* note that i_list must be avail to free ecases! */ free_ecases(interp,eg,0); /* undo temporary ecase */ /* free_ecase doesn't quite handle this right, so do it by hand */ if (ec.re) ckfree((char *)ec.re); if (eg->duration == EXP_PERMANENT) { if (ec.pat) ckfree(ec.pat); if (ec.body) ckfree(ec.body); } if (eg->i_list) exp_free_i(interp,eg->i_list,exp_indirect_update2); return(TCL_ERROR); } #define EXP_IS_DEFAULT(x) ((x) == EXP_TIMEOUT || (x) == EXP_EOF) static char yes[] = "yes\r\n"; static char no[] = "no\r\n"; /* this describes status of a successful match */ struct eval_out { struct ecase *e; /* ecase that matched */ struct exp_f *f; /* struct exp_f that matched */ char *buffer; /* buffer that matched */ int match; /* # of chars in buffer that matched */ /* or # of chars in buffer at EOF */ }; /* *---------------------------------------------------------------------- * * eval_case_string -- * * Like eval_cases, but handles only a single cases that needs a real * string match * * Results: * Returns EXP_X where X is MATCH, NOMATCH, FULLBUFFER, TCL_ERRROR * *---------------------------------------------------------------------- */ static int eval_case_string(interp,e,f,o,last_f,last_case,suffix) Tcl_Interp *interp; struct ecase *e; struct exp_f *f; struct eval_out *o; /* 'output' - i.e., final case of interest */ /* next two args are for debugging, when they change, reprint buffer */ struct exp_f **last_f; int *last_case; char *suffix; { char *buffer; Tcl_RegExpInfo info; /* if -nocase, use the lowerized buffer */ buffer = ((e->Case == CASE_NORM)?f->buffer:f->lower); /* if master or case changed, redisplay debug-buffer */ if ((f != *last_f) || e->Case != *last_case) { exp_debuglog("\r\nexpect%s: does \"%s\" (spawn_id %s) match %s ", suffix, dprintify(buffer),f->spawnId, pattern_style[e->use]); *last_f = f; *last_case = e->Case; } if (e->use == PAT_RE) { exp_debuglog("\"%s\"? ",dprintify(e->pat)); //TclRegError((char *)0); if (buffer && Tcl_RegExpExec(interp,*e->re,buffer,buffer)) { o->e = e; Tcl_RegExpGetInfo(*e->re, &info); o->match = Tcl_UtfAtIndex(buffer, info.matches[0].end)-buffer; o->buffer = buffer; o->f = f; exp_debuglog(yes); return(EXP_MATCH); } else { exp_debuglog(no); //if (TclGetRegError()) { // exp_error(interp,"-re failed: %s",TclGetRegError()); return(EXP_TCLERROR); // } } } else if (e->use == PAT_GLOB) { int match; /* # of chars that matched */ exp_debuglog("\"%s\"? ",dprintify(e->pat)); if (buffer && (-1 != (match = Exp_StringMatch( buffer,e->pat,&e->simple_start)))) { o->e = e; o->match = match; o->buffer = buffer; o->f = f; exp_debuglog(yes); return(EXP_MATCH); } else exp_debuglog(no); } else if (e->use == PAT_EXACT) { char *p = strstr(buffer,e->pat); exp_debuglog("\"%s\"? ",dprintify(e->pat)); if (p) { e->simple_start = p - buffer; o->e = e; o->match = strlen(e->pat); o->buffer = buffer; o->f = f; exp_debuglog(yes); return(EXP_MATCH); } else exp_debuglog(no); } else if (e->use == PAT_NULL) { int i = 0; exp_debuglog("null? "); for (;i<f->size;i++) { if (buffer[i] == 0) { o->e = e; o->match = i+1; /* in this case, match is */ /* just the # of chars + 1 */ /* before the null */ o->buffer = buffer; o->f = f; exp_debuglog(yes); return EXP_MATCH; } } exp_debuglog(no); } else if ((f->size == f->msize) && (f->size > 0)) { exp_debuglog("%s? ",e->pat); o->e = e; o->match = f->umsize; o->buffer = f->buffer; o->f = f; exp_debuglog(yes); return(EXP_FULLBUFFER); } return(EXP_NOMATCH); } /* *---------------------------------------------------------------------- * * eval_cases -- * * Sets o.e if successfully finds a matching pattern, eof, * timeout or deflt. * * Results: * Original status arg or EXP_TCLERROR * * Side Effects: * *---------------------------------------------------------------------- */ static int eval_cases(interp,eg,f,o,last_f,last_case,status,masters,mcount,suffix) Tcl_Interp *interp; struct exp_cmd_descriptor *eg; struct exp_f *f; struct eval_out *o; /* 'output' - i.e., final case of interest */ /* next two args are for debugging, when they change, reprint buffer */ struct exp_f **last_f; int *last_case; int status; struct exp_fs **masters; int mcount; char *suffix; { int i; struct exp_f *em; /* master of ecase */ struct ecase *e; if (o->e || status == EXP_TCLERROR || eg->ecd.count == 0) return(status); if (status == EXP_TIMEOUT) { for (i=0;i<eg->ecd.count;i++) { e = eg->ecd.cases[i]; if (e->use == PAT_TIMEOUT || e->use == PAT_DEFAULT) { o->e = e; break; } } return(status); } else if (status == EXP_EOF) { for (i=0;i<eg->ecd.count;i++) { e = eg->ecd.cases[i]; if (e->use == PAT_EOF || e->use == PAT_DEFAULT) { struct exp_fs_list *fsl; for (fsl=e->i_list->fs_list; fsl ;fsl=fsl->next) { em = fsl->f; if (em == NULL || em == exp_f_any || em == f) { o->e = e; return(status); } } } } return(status); } /* the top loops are split from the bottom loop only because I can't */ /* split'em further. */ /* The bufferful condition does not prevent a pattern match from */ /* occurring and vice versa, so it is scanned with patterns */ for (i=0;i<eg->ecd.count;i++) { struct exp_fs_list *fsl; int j; e = eg->ecd.cases[i]; if (e->use == PAT_TIMEOUT || e->use == PAT_DEFAULT || e->use == PAT_EOF) continue; for (fsl = e->i_list->fs_list; fsl; fsl = fsl->next) { em = fsl->f; /* if em == exp_f_any, then user is explicitly asking */ /* every case to be checked against every master */ if (em == NULL || em == exp_f_any) { /* test against each spawn_id */ for (j=0;j<mcount;j++) { status = eval_case_string(interp,e,masters[j],o,last_f,last_case,suffix); if (status != EXP_NOMATCH) return(status); } } else { /* reject things immediately from wrong spawn_id */ if (em != f) continue; status = eval_case_string(interp,e,f,o,last_f,last_case,suffix); if (status != EXP_NOMATCH) return(status); } } } return(EXP_NOMATCH); } static void ecases_remove_by_expi(interp,ecmd,exp_i) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_i *exp_i; { int i; /* delete every ecase dependent on it */ for (i=0;i<ecmd->ecd.count;) { struct ecase *e = ecmd->ecd.cases[i]; if (e->i_list == exp_i) { free_ecase(interp,e,0); /* shift remaining elements down */ /* but only if there are any left */ if (i+1 != ecmd->ecd.count) { memcpy(&ecmd->ecd.cases[i], &ecmd->ecd.cases[i+1], ((ecmd->ecd.count - i) - 1) * sizeof(struct exp_cmd_descriptor *)); } ecmd->ecd.count--; if (0 == ecmd->ecd.count) { ckfree((char *)ecmd->ecd.cases); ecmd->ecd.cases = 0; } } else { i++; } } } /* remove exp_i from list */ static void exp_i_remove(interp,ei,exp_i) Tcl_Interp *interp; struct exp_i **ei; /* list to remove from */ struct exp_i *exp_i; /* element to remove */ { /* since it's in middle of list, free exp_i by hand */ for (;*ei; ei = &(*ei)->next) { if (*ei == exp_i) { *ei = exp_i->next; exp_i->next = 0; exp_free_i(interp,exp_i,exp_indirect_update2); break; } } } /* remove exp_i from list and remove any dependent ecases */ static void exp_i_remove_with_ecases(interp,ecmd,exp_i) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_i *exp_i; { ecases_remove_by_expi(interp,ecmd,exp_i); exp_i_remove(interp,&ecmd->i_list,exp_i); } /* remove ecases tied to a single direct spawn id */ static void ecmd_remove_f(interp,ecmd,f,direct) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_f *f; int direct; { struct exp_i *exp_i, *next; struct exp_fs_list **fsl; for (exp_i=ecmd->i_list;exp_i;exp_i=next) { next = exp_i->next; if (!(direct & exp_i->direct)) continue; for (fsl = &exp_i->fs_list;*fsl;) { if (f == ((*fsl)->f)) { struct exp_fs_list *tmp = *fsl; *fsl = (*fsl)->next; exp_free_fs_single(tmp); /* if last bg ecase, disarm spawn id */ if (ecmd->cmdtype == EXP_CMD_BG) { f->bg_ecount--; if (f->bg_ecount == 0) { exp_disarm_background_filehandler(f); f->bg_interp = 0; } } continue; } fsl = &(*fsl)->next; } /* if left with no fds (and is direct), get rid of it */ /* and any dependent ecases */ if (exp_i->direct == EXP_DIRECT && !exp_i->fs_list) { exp_i_remove_with_ecases(interp,ecmd,exp_i); } } } /* this is called from exp_close to clean up f */ void exp_ecmd_remove_f_direct_and_indirect(interp,f) Tcl_Interp *interp; struct exp_f *f; { ecmd_remove_f(interp,&exp_cmds[EXP_CMD_BEFORE],f,EXP_DIRECT|EXP_INDIRECT); ecmd_remove_f(interp,&exp_cmds[EXP_CMD_AFTER],f,EXP_DIRECT|EXP_INDIRECT); ecmd_remove_f(interp,&exp_cmds[EXP_CMD_BG],f,EXP_DIRECT|EXP_INDIRECT); /* force it - explanation in exp_tk.c where this func is defined */ exp_disarm_background_filehandler_force(f); } /* arm a list of background f's */ static void fs_list_arm(interp,fsl) Tcl_Interp *interp; struct exp_fs_list *fsl; { struct exp_f *f; /* for each spawn id in list, arm if necessary */ for (;fsl;fsl=fsl->next) { f = fsl->f; if (f == NULL || f == exp_f_any) continue; if (f->bg_ecount == 0) { exp_arm_background_filehandler(f); f->bg_interp = interp; } f->bg_ecount++; } } /* return TRUE if this ecase is used by this f */ static int exp_i_uses_f(exp_i,f) struct exp_i *exp_i; struct exp_f *f; { struct exp_fs_list *fsp; for (fsp = exp_i->fs_list;fsp;fsp=fsp->next) { if (fsp->f == f) return 1; } return 0; } static void ecase_append(interp,ec) Tcl_Interp *interp; struct ecase *ec; { if (!ec->transfer) Tcl_AppendElement(interp,"-notransfer"); if (ec->indices) Tcl_AppendElement(interp,"-indices"); /* if (ec->iwrite) Tcl_AppendElement(interp,"-iwrite");*/ if (!ec->Case) Tcl_AppendElement(interp,"-nocase"); if (ec->re) Tcl_AppendElement(interp,"-re"); else if (ec->use == PAT_GLOB) Tcl_AppendElement(interp,"-gl"); else if (ec->use == PAT_EXACT) Tcl_AppendElement(interp,"-ex"); Tcl_AppendElement(interp,ec->pat); Tcl_AppendElement(interp,ec->body?ec->body:""); } /* append all ecases that match this exp_i */ static void ecase_by_exp_i_append(interp,ecmd,exp_i) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_i *exp_i; { int i; for (i=0;i<ecmd->ecd.count;i++) { if (ecmd->ecd.cases[i]->i_list == exp_i) { ecase_append(interp,ecmd->ecd.cases[i]); } } } static void exp_i_append(interp,exp_i) Tcl_Interp *interp; struct exp_i *exp_i; { Tcl_AppendElement(interp,"-i"); if (exp_i->direct == EXP_INDIRECT) { Tcl_AppendElement(interp,exp_i->variable); } else { struct exp_fs_list *fsp; /* if more than one element, add braces */ if (exp_i->fs_list->next) Tcl_AppendResult(interp," {",(char *)0); for (fsp = exp_i->fs_list;fsp;fsp=fsp->next) { char buf[10]; /* big enough for a small int */ sprintf(buf,"%s",fsp->f->spawnId); Tcl_AppendElement(interp,buf); } if (exp_i->fs_list->next) Tcl_AppendResult(interp,"} ",(char *)0); } } /* *---------------------------------------------------------------------- * * expect_info -- * * Return current setting of the permanent expect_before/after/bg * * Results: * A standard Tcl result * *---------------------------------------------------------------------- */ int expect_info(interp,ecmd,argc,argv) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; int argc; char **argv; { struct exp_i *exp_i; int i; int direct = EXP_DIRECT|EXP_INDIRECT; int all = FALSE; /* report on all fds */ char *chanId = NULL; struct exp_f *f; char *argv0 = argv[0]; while (*argv) { if (streq(argv[0],"-i") && argv[1]) { chanId = argv[1]; argc-=2; argv+=2; } else if (streq(argv[0],"-all")) { all = TRUE; argc--; argv++; } else if (streq(argv[0],"-noindirect")) { direct &= ~EXP_INDIRECT; argc--; argv++; } else { exp_error(interp,"usage: -info [-all | -i spawn_id]\n"); return TCL_ERROR; } } if (all) { /* avoid printing out -i when redundant */ struct exp_i *previous = 0; for (i=0;i<ecmd->ecd.count;i++) { if (previous != ecmd->ecd.cases[i]->i_list) { exp_i_append(interp,ecmd->ecd.cases[i]->i_list); previous = ecmd->ecd.cases[i]->i_list; } ecase_append(interp,ecmd->ecd.cases[i]); } return TCL_OK; } if (chanId == NULL) { f = exp_update_master(interp,0,0); if (f == NULL) { return(TCL_ERROR); } } else { f = exp_chan2f(interp, chanId, 1, 0, argv0); if (f == NULL) { /* handle as in indirect */ Tcl_ResetResult(interp); for (i=0;i<ecmd->ecd.count;i++) { if (ecmd->ecd.cases[i]->i_list->direct == EXP_INDIRECT && streq(ecmd->ecd.cases[i]->i_list->variable,chanId)) { ecase_append(interp,ecmd->ecd.cases[i]); } } return TCL_OK; } } /* print ecases of this direct_fd */ for (exp_i=ecmd->i_list;exp_i;exp_i=exp_i->next) { if (!(direct & exp_i->direct)) continue; if (!exp_i_uses_f(exp_i,f)) continue; ecase_by_exp_i_append(interp,ecmd,exp_i); } return TCL_OK; } /* Exp_ExpectGlobalCmd is invoked to process expect_before/after */ /*ARGSUSED*/ int Exp_ExpectGlobalCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; { int result = TCL_OK; struct exp_i *exp_i, **eip; struct exp_fs_list *fsl; /* temp for interating over fs_list */ struct exp_cmd_descriptor eg; int count; //char *argv0; struct exp_cmd_descriptor *ecmd = (struct exp_cmd_descriptor *) clientData; if ((objc == 2) && exp_one_arg_braced(objv[1])) { return(exp_eval_with_one_arg(clientData,interp,objv)); } else if ((objc == 3) && streq(Tcl_GetString(objv[1]),"-brace")) { Tcl_Obj *new_objv[2]; new_objv[0] = objv[0]; new_objv[1] = objv[2]; return(exp_eval_with_one_arg(clientData,interp,new_objv)); } if (objc > 1 && (Tcl_GetString(objv[1])[0] == '-')) { if (exp_flageq("info",Tcl_GetString(objv[1])+1,4)) { return(expect_info(interp,ecmd,objc,objv)); } } exp_cmd_init(&eg,ecmd->cmdtype,EXP_PERMANENT); if (TCL_ERROR == parse_expect_args(interp,&eg,EXP_SPAWN_ID_BAD, objc,objv)) { return TCL_ERROR; } /* * visit each NEW direct exp_i looking for spawn ids. * When found, remove them from any OLD exp_i's. */ /* visit each exp_i */ for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) { if (exp_i->direct == EXP_INDIRECT) continue; /* for each spawn id, remove it from ecases */ for (fsl=exp_i->fs_list;fsl;fsl=fsl->next) { struct exp_f *f = fsl->f; /* validate all input descriptors */ if (f != exp_f_any) { if (!exp_fcheck(interp,f,1,1,Tcl_GetString(objv[0]))) { result = TCL_ERROR; goto cleanup; } } /* remove spawn id from exp_i */ ecmd_remove_f(interp,ecmd,f,EXP_DIRECT); } } /* * For each indirect variable, release its old ecases and * clean up the matching spawn ids. * Same logic as in "expect_X delete" command. */ for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) { struct exp_i **old_i; if (exp_i->direct == EXP_DIRECT) continue; for (old_i = &ecmd->i_list;*old_i;) { struct exp_i *tmp; if (((*old_i)->direct == EXP_DIRECT) || (!streq((*old_i)->variable,exp_i->variable))) { old_i = &(*old_i)->next; continue; } ecases_remove_by_expi(interp,ecmd,*old_i); /* unlink from middle of list */ tmp = *old_i; *old_i = tmp->next; tmp->next = 0; exp_free_i(interp,tmp,exp_indirect_update2); } /* if new one has ecases, update it */ if (exp_i->ecount) { char *msg = exp_indirect_update1(interp,ecmd,exp_i); if (msg) { /* unusual way of handling error return */ /* because of Tcl's variable tracing */ strcpy(interp->result,msg); result = TCL_ERROR; goto indirect_update_abort; } } } /* empty i_lists have to be removed from global eg.i_list */ /* before returning, even if during error */ indirect_update_abort: /* * New exp_i's that have 0 ecases indicate fd/vars to be deleted. * Now that the deletions have been done, discard the new exp_i's. */ for (exp_i=eg.i_list;exp_i;) { struct exp_i *next = exp_i->next; if (exp_i->ecount == 0) { exp_i_remove(interp,&eg.i_list,exp_i); } exp_i = next; } if (result == TCL_ERROR) goto cleanup; /* * arm all new bg direct fds */ if (ecmd->cmdtype == EXP_CMD_BG) { for (exp_i=eg.i_list;exp_i;exp_i=exp_i->next) { if (exp_i->direct == EXP_DIRECT) { fs_list_arm(interp,exp_i->fs_list); } } } /* * now that old ecases are gone, add new ecases and exp_i's (both * direct and indirect). */ /* append ecases */ count = ecmd->ecd.count + eg.ecd.count; if (eg.ecd.count) { int start_index; /* where to add new ecases in old list */ if (ecmd->ecd.count) { /* append to end */ ecmd->ecd.cases = (struct ecase **)ckrealloc((char *)ecmd->ecd.cases, count * sizeof(struct ecase *)); start_index = ecmd->ecd.count; } else { /* append to beginning */ ecmd->ecd.cases = (struct ecase **)ckalloc(eg.ecd.count * sizeof(struct ecase *)); start_index = 0; } memcpy(&ecmd->ecd.cases[start_index],eg.ecd.cases, eg.ecd.count*sizeof(struct ecase *)); ecmd->ecd.count = count; } /* append exp_i's */ for (eip = &ecmd->i_list;*eip;eip = &(*eip)->next) { /* empty loop to get to end of list */ } /* *exp_i now points to end of list */ *eip = eg.i_list; /* connect new list to end of current list */ cleanup: if (result == TCL_ERROR) { /* in event of error, free any unreferenced ecases */ /* but first, split up i_list so that exp_i's aren't */ /* freed twice */ for (exp_i=eg.i_list;exp_i;) { struct exp_i *next = exp_i->next; exp_i->next = 0; exp_i = next; } free_ecases(interp,&eg,1); } else { if (eg.ecd.cases) ckfree((char *)eg.ecd.cases); } if (ecmd->cmdtype == EXP_CMD_BG) { exp_background_filehandlers_run_all(); } return(result); } /* *---------------------------------------------------------------------- * * exp_adjust -- * * Adjusts file according to user's size request * * Results: * None * * Side Effects: * Memory may be allocated or reallocated * *---------------------------------------------------------------------- */ void exp_adjust(f) struct exp_f *f; { int new_msize; /* * get the latest buffer size. Double the user input for * two reasons. 1) Need twice the space in case the match * straddles two bufferfuls, 2) easier to hack the division * by two when shifting the buffers later on. The extra * byte in the malloc's is just space for a null we can slam on the * end. It makes the logic easier later. The -1 here is so that * requests actually come out to even/word boundaries (if user * gives "reasonable" requests) */ new_msize = f->umsize*2 - 1; if (new_msize != f->msize) { if (!f->buffer) { /* allocate buffer space for 1st time */ f->buffer = ckalloc((unsigned)new_msize+1); f->lower = ckalloc((unsigned)new_msize+1); f->size = 0; } else { /* buffer already exists - resize */ /* if truncated, forget about some data */ if (f->size > new_msize) { /* copy end of buffer down */ memmove(f->buffer,f->buffer+(f->size - new_msize),new_msize); memmove(f->lower, f->lower +(f->size - new_msize),new_msize); f->size = new_msize; f->key = expect_key++; } f->buffer = ckrealloc(f->buffer,new_msize+1); f->lower = ckrealloc(f->lower,new_msize+1); } f->msize = new_msize; f->buffer[f->size] = '\0'; f->lower[f->size] = '\0'; } } /* *---------------------------------------------------------------------- * * expect_read -- * * Does the logical equivalent of a read() for the expect * command. This includes figuring out which descriptor should * be read from. The result of the read() is left in a spawn_id's * buffer rather than explicitly passing it back. Note that if * someone else has modified a buffer either before or while this * expect is running (i.e., if we or some event has called Tcl_Eval * which did another expect/interact), expect_read will also call * this a successful read (for the purposes if needing to pattern * match against it). * * * Results: * If it returns a negative number, it corresponds to a EXP_XXX result * If it returns a non-negative number, it means there is data * 0 means nothing new was actually read, but it should be looked at again * * Side Effects * *---------------------------------------------------------------------- */ int expect_read(interp,masters,masters_max,m,timeout,key) Tcl_Interp *interp; struct exp_f **masters; /* If NULL, then m is already known and set. */ int masters_max; /* If *masters is not-zero, then masters_max * is the number of masters. * If *masters is zero, then masters_max * is used as the mask (ready vs except). * Crude but simplifies the interface. */ struct exp_f **m; /* Out variable to leave new master. */ int timeout; int key; { struct exp_f *f; int cc; int write_count; int tcl_set_flags; /* if we have to discard chars, this tells */ /* whether to show user locally or globally */ if (masters == 0) { /* we already know the master, just find out what happened */ cc = exp_get_next_event_info(interp,*m,masters_max); tcl_set_flags = TCL_GLOBAL_ONLY; } else { cc = exp_get_next_event(interp,masters,masters_max,m,timeout,key); tcl_set_flags = 0; } if (cc == EXP_DATA_NEW) { /* try to read it */ cc = exp_i_read(interp,*m,timeout,tcl_set_flags); /* the meaning of 0 from i_read means eof. Muck with it a */ /* little, so that from now on it means "no new data arrived */ /* but it should be looked at again anyway". */ if (cc == 0) { cc = EXP_EOF; } else if (cc > 0) { f = *m; f->buffer[f->size += cc] = '\0'; /* strip parity if requested */ if (f->parity == 0) { /* do it from end backwards */ char *p = f->buffer + f->size - 1; int count = cc; while (count--) { *p-- &= 0x7f; } } } /* else { assert(cc < 0) in which case some sort of error was encountered such as an interrupt with that forced an error return } */ } else if (cc == EXP_DATA_OLD) { f = *m; cc = 0; } else if (cc == EXP_RECONFIGURE) { return EXP_RECONFIGURE; } if (cc == EXP_ABEOF) { /* abnormal EOF */ /* On many systems, ptys produce EIO upon EOF - sigh */ if (i_read_errno == EIO) { /* Sun, Cray, BSD, and others */ cc = EXP_EOF; } else if (i_read_errno == EINVAL) { /* Solaris 2.4 occasionally returns this */ cc = EXP_EOF; } else { if (i_read_errno == EBADF) { exp_error(interp,"bad spawn_id (process died earlier?)"); } else { exp_error(interp,"i_read(spawn_id=%d): %s",*m, Tcl_PosixError(interp)); exp_close(interp,*m); } return(EXP_TCLERROR); /* was goto error; */ } } /* EOF, TIMEOUT, and ERROR return here */ /* In such cases, there is no need to update screen since, if there */ /* was prior data read, it would have been sent to the screen when */ /* it was read. */ if (cc < 0) return (cc); /* update display */ if (f->size) write_count = f->size - f->printed; else write_count = 0; if (write_count) { if (exp_logfile_all || (exp_loguser && exp_logfile)) { Tcl_Write(exp_logfile, f->buffer + f->printed, write_count); } /* * don't write to user if they're seeing it already, * that is, typing it! */ if (exp_loguser) { if (strcmp("stdin", (*m)->spawnId) != 0) { Tcl_Write(Tcl_GetStdChannel(TCL_STDOUT), f->buffer + f->printed, write_count); } } if (exp_debugfile) { Tcl_Write(exp_debugfile, f->buffer + f->printed, write_count); } /* remove nulls from input, since there is no way */ /* for Tcl to deal with such strings. Doing it here */ /* lets them be sent to the screen, just in case */ /* they are involved in formatting operations */ if (f->rm_nulls) { f->size -= rm_nulls(f->buffer + f->printed,write_count); } f->buffer[f->size] = '\0'; /* copy to lowercase buffer */ exp_lowmemcpy(f->lower+f->printed, f->buffer+f->printed, 1 + f->size - f->printed); f->printed = f->size; /* count'm even if not logging */ } return(cc); } /* when buffer fills, copy second half over first and */ /* continue, so we can do matches over multiple buffers */ void exp_buffer_shuffle(interp,f,save_flags,array_name,caller_name) Tcl_Interp *interp; struct exp_f *f; int save_flags; char *array_name; char *caller_name; { char spawn_id[10]; /* enough for a %d */ char match_char; /* place to hold char temporarily */ /* uprooted by a NULL */ int first_half = f->size/2; int second_half = f->size - first_half; /* * allow user to see data we are discarding */ sprintf(spawn_id,"%s",f->spawnId); exp_debuglog("%s: set %s(spawn_id) \"%s\"\r\n", caller_name,array_name,dprintify(spawn_id)); Tcl_SetVar2(interp,array_name,"spawn_id",spawn_id,save_flags); /* temporarily null-terminate buffer in middle */ match_char = f->buffer[first_half]; f->buffer[first_half] = 0; exp_debuglog("%s: set %s(buffer) \"%s\"\r\n", caller_name,array_name,dprintify(f->buffer)); Tcl_SetVar2(interp,array_name,"buffer",f->buffer,save_flags); /* remove middle-null-terminator */ f->buffer[first_half] = match_char; memcpy(f->buffer,f->buffer+first_half,second_half); memcpy(f->lower, f->lower +first_half,second_half); f->size = second_half; f->printed -= first_half; if (f->printed < 0) f->printed = 0; } /* map EXP_ style return value to TCL_ style return value */ /* not defined to work on TCL_OK */ int exp_tcl2_returnvalue(x) int x; { switch (x) { case TCL_ERROR: return EXP_TCLERROR; case TCL_RETURN: return EXP_TCLRET; case TCL_BREAK: return EXP_TCLBRK; case TCL_CONTINUE: return EXP_TCLCNT; case EXP_CONTINUE: return EXP_TCLCNTEXP; case EXP_CONTINUE_TIMER: return EXP_TCLCNTTIMER; case EXP_TCL_RETURN: return EXP_TCLRETTCL; } return -1; } /* map from EXP_ style return value to TCL_ style return values */ int exp_2tcl_returnvalue(x) int x; { switch (x) { case EXP_TCLERROR: return TCL_ERROR; case EXP_TCLRET: return TCL_RETURN; case EXP_TCLBRK: return TCL_BREAK; case EXP_TCLCNT: return TCL_CONTINUE; case EXP_TCLCNTEXP: return EXP_CONTINUE; case EXP_TCLCNTTIMER: return EXP_CONTINUE_TIMER; case EXP_TCLRETTCL: return EXP_TCL_RETURN; } return -1; } /* *---------------------------------------------------------------------- * * exp_i_read -- * * Reads from the input channel. Returns # of chars read or * (non-positive) error of form EXP_XXX. * Results: * returns 0 for end of file * If timeout is non-zero, assume the read will complete immediately * because data is known to be available. * * Side Effects: * Data is read from a channel * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int exp_i_read(interp,f,timeout,save_flags) Tcl_Interp *interp; struct exp_f *f; int timeout; int save_flags; { int nread; if (f->size == f->msize) exp_buffer_shuffle(interp,f,save_flags,EXPECT_OUT,"expect"); nread = Tcl_Read(f->channel, f->buffer+f->size, f->msize-f->size); if (nread == -1) { i_read_errno = errno; } else { /* {DWORD x; f->buffer[f->size] = 0; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), f->buffer+f->size, nread, &x, NULL); printf("exp_i_read: Got %d bytes\n", nread);} */ nread = nread; } return(nread); } /* *---------------------------------------------------------------------- * * exp_get_var -- * * Variables predefined by expect are retrieved using this routine * which looks in the global space if they are not in the local space. * This allows the user to localize them if desired, and also to * avoid having to put "global" in procedure definitions. * * Results: * The value of the variable if it exists * *---------------------------------------------------------------------- */ CONST char * exp_get_var(interp,var) Tcl_Interp *interp; char *var; { CONST char *val; if (NULL != (val = Tcl_GetVar(interp,var,0 /* local */))) return(val); return(Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY)); } /* *---------------------------------------------------------------------- * * get_timeout -- * * Gets the value of the 'timeout' variable * * Results: * The value of the variable if it exists * *---------------------------------------------------------------------- */ static int get_timeout(interp) Tcl_Interp *interp; { static int timeout = INIT_EXPECT_TIMEOUT; CONST char *t; if (NULL != (t = exp_get_var(interp,EXPECT_TIMEOUT))) { timeout = atoi(t); } return(timeout); } /* make a copy of a linked list (1st arg) and attach to end of another (2nd arg) */ static int update_expect_fds(i_list,fd_union) struct exp_i *i_list; struct exp_fs_list **fd_union; { struct exp_i *p; /* for each i_list in an expect statement ... */ for (p=i_list;p;p=p->next) { struct exp_fs_list *fsl; /* for each fd in the i_list */ for (fsl=p->fs_list;fsl;fsl=fsl->next) { struct exp_fs_list *tmpfsl; struct exp_fs_list *u; if (fsl->f == exp_f_any || fsl->f == NULL) continue; /* check this one against all so far */ for (u = *fd_union;u;u=u->next) { if (fsl->f == u->f) goto found; } /* if not found, link in as head of list */ tmpfsl = exp_new_fs(fsl->f); tmpfsl->next = *fd_union; *fd_union = tmpfsl; found:; } } return TCL_OK; } char * exp_cmdtype_printable(cmdtype) int cmdtype; { switch (cmdtype) { case EXP_CMD_FG: return("expect"); case EXP_CMD_BG: return("expect_background"); case EXP_CMD_BEFORE: return("expect_before"); case EXP_CMD_AFTER: return("expect_after"); } //#ifdef LINT return("unknown expect command"); //#endif } /* *---------------------------------------------------------------------- * * exp_indirect_update2 -- * * This is called back via Tcl's trace handler whenever * an indirect spawn id list is changed * * Results: * A string * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static char * exp_indirect_update2(clientData, interp, name1, name2, flags) ClientData clientData; Tcl_Interp *interp; /* Interpreter containing variable. */ char *name1; /* Name of variable. */ char *name2; /* Second part of variable name. */ int flags; /* Information about what happened. */ { char *msg; struct exp_i *exp_i = (struct exp_i *)clientData; exp_configure_count++; msg = exp_indirect_update1(interp,&exp_cmds[exp_i->cmdtype],exp_i); exp_background_filehandlers_run_all(); return msg; } /* *---------------------------------------------------------------------- * * exp_indirect_update1 -- * * Get the updated value of a variable * * Results: * A string * *---------------------------------------------------------------------- */ static char * exp_indirect_update1(interp,ecmd,exp_i) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_i *exp_i; { struct exp_fs_list *fsl; /* temp for interating over fs_list */ /* * disarm any fd's that lose all their ecases */ if (ecmd->cmdtype == EXP_CMD_BG) { /* clean up each spawn id used by this exp_i */ for (fsl=exp_i->fs_list;fsl;fsl=fsl->next) { struct exp_f *f = fsl->f; if (f == NULL || f == exp_f_any) continue; /* silently skip closed or preposterous fds */ /* since we're just disabling them anyway */ /* preposterous fds will have been reported */ /* by code in next section already */ if (! exp_fcheck(interp, f, 1, 0, "")) continue; f->bg_ecount--; if (f->bg_ecount == 0) { exp_disarm_background_filehandler(f); f->bg_interp = 0; } } } /* * reread indirect variable */ exp_i_update(interp,exp_i); /* * check validity of all fd's in variable */ for (fsl=exp_i->fs_list;fsl;fsl=fsl->next) { /* validate all input descriptors */ if (fsl->f == NULL || fsl->f == exp_f_any) continue; if (!exp_fcheck(interp,fsl->f,1,1, exp_cmdtype_printable(ecmd->cmdtype))) { static char msg[200]; sprintf(msg,"%s from indirect variable (%s)", interp->result,exp_i->variable); return msg; } } /* for each spawn id in list, arm if necessary */ if (ecmd->cmdtype == EXP_CMD_BG) { fs_list_arm(interp,exp_i->fs_list); } return (char *)0; } /* *---------------------------------------------------------------------- * * exp_background_filehandlers_run_all -- * * See which channels need to be checked for events and * start up an event handler * * Results: * None * * Side Effects: * Event handlers are put in place * *---------------------------------------------------------------------- */ void exp_background_filehandlers_run_all() { struct exp_f *f; Tcl_HashEntry *hPtr; Tcl_HashSearch search; hPtr = Tcl_FirstHashEntry(exp_f_table, &search); while (hPtr) { f = (struct exp_f *) Tcl_GetHashValue(hPtr); /* kick off any that already have input waiting */ if (!f->valid) continue; /* is bg_interp the best way to check if armed? */ if (f->bg_interp && (f->size > 0)) { exp_background_filehandler((ClientData)f, 0 /*ignored*/); } hPtr = Tcl_NextHashEntry(&search); } } /* *---------------------------------------------------------------------- * * exp_background_filehandler -- * * This function is called from the background when input arrives * * Results: * None * * Side Effects: * *---------------------------------------------------------------------- */ /*ARGSUSED*/ void exp_background_filehandler(clientData,mask) ClientData clientData; int mask; { Tcl_Interp *interp; int cc; /* number of chars returned in a single read * or negative EXP_whatever */ struct exp_f *f; /* file associated with master */ int i; /* trusty temporary */ struct eval_out eo; /* final case of interest */ struct exp_f *last_f; /* for differentiating when multiple f's * to print out better debugging messages */ int last_case; /* as above but for case */ /* restore our environment */ f = (struct exp_f *) clientData; interp = f->bg_interp; /* temporarily prevent this handler from being invoked again */ exp_block_background_filehandler(f); /* * if mask == 0, then we've been called because the patterns changed * not because the waiting data has changed, so don't actually do * any I/O */ if (mask == 0) { cc = 0; } else { cc = expect_read(interp,NULL,mask,&f,EXP_TIME_INFINITY,0); } do_more_data: eo.e = 0; /* no final case yet */ eo.f = 0; /* no final file selected yet */ eo.match = 0; /* nothing matched yet */ /* force redisplay of buffer when debugging */ last_f = NULL; if (cc == EXP_EOF) { /* do nothing */ } else if (cc < 0) { /* EXP_TCLERROR or any other weird value*/ goto finish; /* if we were going to do this right, we should */ /* differentiate between things like HP ioctl-open-traps */ /* that fall out here and should rightfully be ignored */ /* and real errors that should be reported. Come to */ /* think of it, the only errors will come from HP */ /* ioctl handshake botches anyway. */ } else { /* normal case, got data */ /* new data if cc > 0, same old data if cc == 0 */ /* below here, cc as general status */ cc = EXP_NOMATCH; } cc = eval_cases(interp,&exp_cmds[EXP_CMD_BEFORE], f,&eo,&last_f,&last_case,cc,&f,1,"_background"); cc = eval_cases(interp,&exp_cmds[EXP_CMD_BG], f,&eo,&last_f,&last_case,cc,&f,1,"_background"); cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER], f,&eo,&last_f,&last_case,cc,&f,1,"_background"); if (cc == EXP_TCLERROR) { /* only likely problem here is some internal regexp botch */ Tcl_BackgroundError(interp); goto finish; } /* special eof code that cannot be done in eval_cases */ /* or above, because it would then be executed several times */ if (cc == EXP_EOF) { eo.f = f; eo.match = eo.f->size; eo.buffer = eo.f->buffer; exp_debuglog("expect_background: read eof\r\n"); goto matched; } if (!eo.e) { /* if we get here, there must not have been a match */ goto finish; } matched: #define out(i,val) exp_debuglog("expect_background: set %s(%s) \"%s\"\r\n",EXPECT_OUT,i, \ dprintify(val)); \ Tcl_SetVar2(interp,EXPECT_OUT,i,val,TCL_GLOBAL_ONLY); { /* int iwrite = FALSE;*/ /* write spawn_id? */ char *body = 0; char *buffer; /* pointer to normal or lowercased data */ struct ecase *e = 0; /* points to current ecase */ int match = -1; /* characters matched */ char match_char; /* place to hold char temporarily */ /* uprooted by a NULL */ char *eof_body = 0; if (eo.e) { e = eo.e; body = e->body; /* iwrite = e->iwrite;*/ if (cc != EXP_TIMEOUT) { f = eo.f; match = eo.match; buffer = eo.buffer; } } else if (cc == EXP_EOF) { /* read an eof but no user-supplied case */ f = eo.f; match = eo.match; buffer = eo.buffer; } if (match >= 0) { char name[20], value[20]; if (e && e->use == PAT_RE) { Tcl_RegExpInfo info; Tcl_RegExpGetInfo(*e->re, &info); for (i=0;i<info.nsubs;i++) { int start, end; Tcl_Obj *val; start = info.matches[i].start; end = info.matches[i].end-1; if (start == -1) continue; if (e->indices) { /* start index */ sprintf(name,"%d,start",i); sprintf(value,"%d",start); out(name,value); /* end index */ sprintf(name,"%d,end",i); sprintf(value,"%d",end); out(name,value); } /* string itself */ sprintf(name,"%d,string",i); val = Tcl_GetRange(Tcl_NewStringObj(buffer,-1), start, end); out(name,Tcl_GetString(val)); } } else if (e && (e->use == PAT_GLOB || e->use == PAT_EXACT)) { char *str; if (e->indices) { /* start index */ sprintf(value,"%d",e->simple_start); out("0,start",value); /* end index */ sprintf(value,"%d",e->simple_start + match - 1); out("0,end",value); } /* string itself */ str = f->buffer + e->simple_start; /* temporarily null-terminate in middle */ match_char = str[match]; str[match] = 0; out("0,string",str); str[match] = match_char; /* redefine length of string that */ /* matched for later extraction */ match += e->simple_start; } else if (e && e->use == PAT_NULL && e->indices) { /* start index */ sprintf(value,"%d",match-1); out("0,start",value); /* end index */ sprintf(value,"%d",match-1); out("0,end",value); } else if (e && e->use == PAT_FULLBUFFER) { exp_debuglog("expect_background: full buffer\r\n"); } } /* this is broken out of (match > 0) (above) since it can */ /* that an EOF occurred with match == 0 */ if (eo.f) { char spawn_id[10]; /* enough for a %d */ sprintf(spawn_id,"%s",f->spawnId); out("spawn_id",spawn_id); /* save buf[0..match] */ /* temporarily null-terminate string in middle */ match_char = f->buffer[match]; f->buffer[match] = 0; out("buffer",f->buffer); /* remove middle-null-terminator */ f->buffer[match] = match_char; /* "!e" means no case matched - transfer by default */ if (!e || e->transfer) { /* delete matched chars from input buffer */ f->size -= match; f->printed -= match; if (f->size != 0) { memmove(f->buffer,f->buffer+match,f->size); memmove(f->lower,f->lower+match,f->size); } f->buffer[f->size] = '\0'; f->lower[f->size] = '\0'; } if (cc == EXP_EOF) { /* exp_close() deletes all background bodies */ /* so save eof body temporarily */ if (body) { eof_body = ckalloc(strlen(body)+1); strcpy(eof_body,body); body = eof_body; } exp_close(interp,f); } } if (body) { int result = Tcl_GlobalEval(interp,body); if (result != TCL_OK) Tcl_BackgroundError(interp); if (eof_body) ckfree(eof_body); } /* * Event handler will not call us back if there is more input * pending but it has already arrived. bg_status will be * "blocked" only if armed. */ if (f->valid && (f->bg_status == blocked) && (f->size > 0)) { cc = f->size; goto do_more_data; } } finish: /* fd could have gone away, so check before using */ if (f->valid) exp_unblock_background_filehandler(f); } #undef out /* *---------------------------------------------------------------------- * * Exp_ExpectCmd -- * * Implements the 'expect', 'expect_user', and 'expect_tty' * commands. * * Results: * A standard Tcl result * * Side Effects: * Input is likely to be read * * Notes: * If non-null, clientData holds the name of the channel to * use. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int Exp_ExpectCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { int cc; /* number of chars returned in a single read * or negative EXP_whatever */ struct exp_f *f; /* file associated with master */ int i; /* trusty temporary */ struct exp_cmd_descriptor eg; struct exp_fs_list *fs_list; /* list of masters to watch */ struct exp_fs_list *fsl; /* temp for interating over fs_list */ struct exp_f **masters; /* array of masters to watch */ int mcount; /* number of masters to watch */ struct eval_out eo; /* final case of interest */ int result; /* Tcl result */ time_t start_time_total; /* time at beginning of this procedure */ time_t start_time = 0; /* time when restart label hit */ time_t current_time = 0; /* current time (when we last looked)*/ time_t end_time; /* future time at which to give up */ time_t elapsed_time_total; /* time from now to match/fail/timeout */ time_t elapsed_time; /* time from restart to (ditto) */ struct exp_f *last_f; /* for differentiating when multiple f's * to print out better debugging messages */ int last_case; /* as above but for case */ int first_time = 1; /* if not "restarted" */ int key; /* identify this expect command instance */ int configure_count; /* monitor exp_configure_count */ int timeout; /* seconds */ int remtime; /* remaining time in timeout */ int reset_timer; /* should timer be reset after continue? */ if ((objc == 2) && exp_one_arg_braced(objv[1])) { return(exp_eval_with_one_arg(clientData,interp,objv)); } else if ((objc == 3) && streq(Tcl_GetString(objv[1]),"-brace")) { Tcl_Obj *new_objv[2]; new_objv[0] = objv[0]; new_objv[1] = objv[2]; return(exp_eval_with_one_arg(clientData,interp,new_objv)); } time(&start_time_total); start_time = start_time_total; reset_timer = TRUE; /* make arg list for processing cases */ /* do it dynamically, since expect can be called recursively */ exp_cmd_init(&eg,EXP_CMD_FG,EXP_TEMPORARY); fs_list = NULL; masters = NULL; if (clientData) { f = exp_chan2f(interp,(char *) clientData,1,0,Tcl_GetString(objv[0])); if (f == NULL) { return TCL_ERROR; } } else { f = NULL; } if (TCL_ERROR == parse_expect_args(interp,&eg,f,objc,objv,Tcl_GetString(objv[0]))) return TCL_ERROR; restart_with_update: /* validate all descriptors */ /* and flatten fds into array */ if ((TCL_ERROR == update_expect_fds(exp_cmds[EXP_CMD_BEFORE].i_list,&fs_list)) || (TCL_ERROR == update_expect_fds(exp_cmds[EXP_CMD_AFTER].i_list, &fs_list)) || (TCL_ERROR == update_expect_fds(eg.i_list,&fs_list))) { result = TCL_ERROR; goto cleanup; } /* declare ourselves "in sync" with external view of close/indirect */ configure_count = exp_configure_count; /* count and validate fs_list */ mcount = 0; for (fsl=fs_list;fsl;fsl=fsl->next) { mcount++; /* validate all input descriptors */ if (!exp_fcheck(interp,fsl->f,1,1,Tcl_GetString(objv[0]))) { result = TCL_ERROR; goto cleanup; } } /* make into an array */ masters = (struct exp_f **)ckalloc(mcount * sizeof(struct exp_f *)); for (fsl=fs_list,i=0;fsl;fsl=fsl->next,i++) { masters[i] = fsl->f; } restart: if (first_time) first_time = 0; else time(&start_time); if (eg.timeout_specified_by_flag) { timeout = eg.timeout; } else { /* get the latest timeout */ timeout = get_timeout(interp); } key = expect_key++; result = TCL_OK; last_f = 0; /* end of restart code */ eo.e = 0; /* no final case yet */ eo.f = 0; /* no final file selected yet */ eo.match = 0; /* nothing matched yet */ /* timeout code is a little tricky, be very careful changing it */ if (timeout != EXP_TIME_INFINITY) { /* if exp_continue -continue_timer, do not update end_time */ if (reset_timer) { time(¤t_time); end_time = current_time + timeout; } else { reset_timer = TRUE; } } /* remtime and current_time updated at bottom of loop */ remtime = timeout; for (;;) { if ((timeout != EXP_TIME_INFINITY) && (remtime < 0)) { cc = EXP_TIMEOUT; } else { cc = expect_read(interp,masters,mcount,&f,remtime,key); } /*SUPPRESS 530*/ if (cc == EXP_EOF) { /* do nothing */ } else if (cc == EXP_TIMEOUT) { exp_debuglog("expect: timed out\r\n"); } else if (cc == EXP_RECONFIGURE) { reset_timer = FALSE; goto restart_with_update; } else if (cc < 0) { /* EXP_TCLERROR or any other weird value*/ goto error; } else { /* new data if cc > 0, same old data if cc == 0 */ /* below here, cc as general status */ cc = EXP_NOMATCH; /* force redisplay of buffer when debugging */ last_f = 0; } cc = eval_cases(interp,&exp_cmds[EXP_CMD_BEFORE], f,&eo,&last_f,&last_case,cc,masters,mcount,""); cc = eval_cases(interp,&eg, f,&eo,&last_f,&last_case,cc,masters,mcount,""); cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER], f,&eo,&last_f,&last_case,cc,masters,mcount,""); if (cc == EXP_TCLERROR) goto error; /* special eof code that cannot be done in eval_cases */ /* or above, because it would then be executed several times */ if (cc == EXP_EOF) { eo.f = f; eo.match = eo.f->size; eo.buffer = eo.f->buffer; exp_debuglog("expect: read eof\r\n"); break; } else if (cc == EXP_TIMEOUT) break; /* break if timeout or eof and failed to find a case for it */ if (eo.e) break; /* no match was made with current data, force a read */ f->force_read = TRUE; if (timeout != EXP_TIME_INFINITY) { time(¤t_time); remtime = end_time - current_time; } } goto done; error: result = exp_2tcl_returnvalue(cc); done: #define out(i,val) exp_debuglog("expect: set %s(%s) \"%s\"\r\n",EXPECT_OUT,i, \ dprintify(val)); \ Tcl_SetVar2(interp,EXPECT_OUT,i,val,0); if (result != TCL_ERROR) { /* int iwrite = FALSE;*/ /* write spawn_id? */ char *body = 0; char *buffer; /* pointer to normal or lowercased data */ struct ecase *e = 0; /* points to current ecase */ int match = -1; /* characters matched */ char match_char; /* place to hold char temporarily */ /* uprooted by a NULL */ char *eof_body = 0; if (eo.e) { e = eo.e; body = e->body; /* iwrite = e->iwrite;*/ if (cc != EXP_TIMEOUT) { f = eo.f; match = eo.match; buffer = eo.buffer; } if (e->timestamp) { char value[20]; time(¤t_time); elapsed_time = current_time - start_time; elapsed_time_total = current_time - start_time_total; sprintf(value,"%d",elapsed_time); out("seconds",value); sprintf(value,"%d",elapsed_time_total); out("seconds_total",value); /* deprecated */ exp_timestamp(interp,¤t_time,EXPECT_OUT); } } else if (cc == EXP_EOF) { /* read an eof but no user-supplied case */ f = eo.f; match = eo.match; buffer = eo.buffer; } if (match >= 0) { char name[20], value[20]; if (e && e->use == PAT_RE) { Tcl_RegExpInfo info; Tcl_RegExpGetInfo(*e->re, &info); for (i=0;i<info.nsubs;i++) { int start, end; Tcl_Obj *val; start = info.matches[i].start; end = info.matches[i].end-1; if (start == -1) continue; if (e->indices) { /* start index */ sprintf(name,"%d,start",i); sprintf(value,"%d",start); out(name,value); /* end index */ sprintf(name,"%d,end",i); sprintf(value,"%d",end); out(name,value); } /* string itself */ sprintf(name,"%d,string",i); val = Tcl_GetRange(Tcl_NewStringObj(buffer,-1), start, end); out(name,Tcl_GetString(val)); } } else if (e && (e->use == PAT_GLOB || e->use == PAT_EXACT)) { char *str; if (e->indices) { /* start index */ sprintf(value,"%d",e->simple_start); out("0,start",value); /* end index */ sprintf(value,"%d",e->simple_start + match - 1); out("0,end",value); } /* string itself */ str = f->buffer + e->simple_start; /* temporarily null-terminate in middle */ match_char = str[match]; str[match] = 0; out("0,string",str); str[match] = match_char; /* redefine length of string that */ /* matched for later extraction */ match += e->simple_start; } else if (e && e->use == PAT_NULL && e->indices) { /* start index */ sprintf(value,"%d",match-1); out("0,start",value); /* end index */ sprintf(value,"%d",match-1); out("0,end",value); } else if (e && e->use == PAT_FULLBUFFER) { exp_debuglog("expect: full buffer\r\n"); } } /* this is broken out of (match > 0) (above) since it can */ /* that an EOF occurred with match == 0 */ if (eo.f) { char spawn_id[10]; /* enough for a %d */ /* if (iwrite) {*/ sprintf(spawn_id,"%s",f->spawnId); out("spawn_id",spawn_id); /* }*/ /* save buf[0..match] */ /* temporarily null-terminate string in middle */ match_char = f->buffer[match]; f->buffer[match] = 0; out("buffer",f->buffer); /* remove middle-null-terminator */ f->buffer[match] = match_char; /* "!e" means no case matched - transfer by default */ if (!e || e->transfer) { /* delete matched chars from input buffer */ f->size -= match; f->printed -= match; if (f->size != 0) { memmove(f->buffer,f->buffer+match,f->size); memmove(f->lower,f->lower+match,f->size); } f->buffer[f->size] = '\0'; f->lower[f->size] = '\0'; } if (cc == EXP_EOF) { /* exp_close() deletes all background bodies */ /* so save eof body temporarily */ if (body) { eof_body = ckalloc(strlen(body)+1); strcpy(eof_body,body); body = eof_body; } exp_close(interp,f); } } if (body) { result = Tcl_Eval(interp,body); if (eof_body) ckfree(eof_body); } } cleanup: if (result == EXP_CONTINUE_TIMER) { reset_timer = FALSE; result = EXP_CONTINUE; } if ((result == EXP_CONTINUE) && (configure_count == exp_configure_count)) { exp_debuglog("expect: continuing expect\r\n"); goto restart; } if (fs_list) { exp_free_fs(fs_list); fs_list = 0; } if (masters) { ckfree((char *)masters); masters = 0; } if (result == EXP_CONTINUE) { exp_debuglog("expect: continuing expect after update\r\n"); goto restart_with_update; } free_ecases(interp,&eg,0); /* requires i_lists to be avail */ exp_free_i(interp,eg.i_list,exp_indirect_update2); return(result); } #undef out /* beginning of deprecated code */ #define out(elt) Tcl_SetVar2(interp,array,elt,ascii,0); void exp_timestamp(interp,timeval,array) Tcl_Interp *interp; time_t *timeval; char *array; { struct tm *tm; char *ascii; tm = localtime(timeval); /* split */ ascii = asctime(tm); /* print */ ascii[24] = '\0'; /* zap trailing \n */ out("timestamp"); sprintf(ascii,"%ld",*timeval); out("epoch"); sprintf(ascii,"%d",tm->tm_sec); out("sec"); sprintf(ascii,"%d",tm->tm_min); out("min"); sprintf(ascii,"%d",tm->tm_hour); out("hour"); sprintf(ascii,"%d",tm->tm_mday); out("mday"); sprintf(ascii,"%d",tm->tm_mon); out("mon"); sprintf(ascii,"%d",tm->tm_year); out("year"); sprintf(ascii,"%d",tm->tm_wday); out("wday"); sprintf(ascii,"%d",tm->tm_yday); out("yday"); sprintf(ascii,"%d",tm->tm_isdst); out("isdst"); } /* end of deprecated code */ /*ARGSUSED*/ static int Exp_TimestampCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *format = 0; time_t seconds = -1; int gmt = FALSE; /* local time by default */ struct tm *tm; Tcl_DString dstring; argc--; argv++; while (*argv) { if (streq(*argv,"-format")) { argc--; argv++; if (!*argv) goto usage_error; format = *argv; argc--; argv++; } else if (streq(*argv,"-seconds")) { argc--; argv++; if (!*argv) goto usage_error; seconds = atoi(*argv); argc--; argv++; } else if (streq(*argv,"-gmt")) { gmt = TRUE; argc--; argv++; } else break; } if (argc) goto usage_error; if (seconds == -1) { time(&seconds); } Tcl_DStringInit(&dstring); if (format) { if (gmt) { tm = gmtime(&seconds); } else { tm = localtime(&seconds); } /* exp_strftime(interp->result,TCL_RESULT_SIZE,format,tm);*/ exp_strftime(format,tm,&dstring); Tcl_DStringResult(interp,&dstring); } else { sprintf(interp->result,"%ld",seconds); } return TCL_OK; usage_error: exp_error(interp,"args: [-seconds #] [-format format]"); return TCL_ERROR; } /* lowmemcpy - like memcpy but it lowercases result */ void exp_lowmemcpy(dest,src,n) char *dest; CONST char *src; int n; { for (;n>0;n--) { *dest = ((isascii(*src) && isupper(*src))?tolower(*src):*src); src++; dest++; } } /*ARGSUSED*/ int Exp_MatchMaxCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int size = -1; struct exp_f *f; int Default = FALSE; char *chan = NULL; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-d")) { Default = TRUE; } else if (streq(*argv,"-i")) { argc--;argv++; if (argc < 1) { exp_error(interp,"-i needs argument"); return(TCL_ERROR); } chan = *argv; } else break; } if (!Default) { if (chan == NULL) { if (!(f = exp_update_master(interp,0,0))) return(TCL_ERROR); } else { if (!(f = exp_chan2f(interp,chan,0,0,"match_max"))) return(TCL_ERROR); } } else if (chan != NULL) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (argc == 0) { if (Default) { size = exp_default_match_max; } else { size = f->umsize; } sprintf(interp->result,"%d",size); return(TCL_OK); } if (argc > 1) { exp_error(interp,"too many arguments"); return(TCL_OK); } /* all that's left is to set the size */ size = atoi(argv[0]); if (size <= 0) { exp_error(interp,"must be positive"); return(TCL_ERROR); } if (Default) exp_default_match_max = size; else f->umsize = size; return(TCL_OK); } /*ARGSUSED*/ int Exp_RemoveNullsCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int value = -1; struct exp_f *f; int Default = FALSE; char *chan = NULL; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-d")) { Default = TRUE; } else if (streq(*argv,"-i")) { argc--;argv++; if (argc < 1) { exp_error(interp,"-i needs argument"); return(TCL_ERROR); } chan = *argv; } else break; } if (!Default) { if (chan == NULL) { if (!(f = exp_update_master(interp,0,0))) return(TCL_ERROR); } else { if (!(f = exp_chan2f(interp,chan,0,0,"remove_nulls"))) return(TCL_ERROR); } } else if (chan != NULL) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (argc == 0) { if (Default) { value = exp_default_match_max; } else { value = f->rm_nulls; } sprintf(interp->result,"%d",value); return(TCL_OK); } if (argc > 1) { exp_error(interp,"too many arguments"); return(TCL_OK); } /* all that's left is to set the value */ value = atoi(argv[0]); if (value != 0 && value != 1) { exp_error(interp,"must be 0 or 1"); return(TCL_ERROR); } if (Default) exp_default_rm_nulls = value; else f->rm_nulls = value; return(TCL_OK); } /*ARGSUSED*/ int Exp_ParityCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int parity; int m = -1; struct exp_f *f; int Default = FALSE; char *chan = NULL; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-d")) { Default = TRUE; } else if (streq(*argv,"-i")) { argc--;argv++; if (argc < 1) { exp_error(interp,"-i needs argument"); return(TCL_ERROR); } chan = *argv; } else break; } if (!Default) { if (chan == NULL) { if (!(f = exp_update_master(interp,0,0))) return(TCL_ERROR); } else { if (!(f = exp_chan2f(interp,chan,0,0,"parity"))) return(TCL_ERROR); } } else if (chan != NULL) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (argc == 0) { if (Default) { parity = exp_default_parity; } else { parity = f->parity; } sprintf(interp->result,"%d",parity); return(TCL_OK); } if (argc > 1) { exp_error(interp,"too many arguments"); return(TCL_OK); } /* all that's left is to set the parity */ parity = atoi(argv[0]); if (Default) exp_default_parity = parity; else f->parity = parity; return(TCL_OK); } #if DEBUG_PERM_ECASES /* This big chunk of code is just for debugging the permanent */ /* expect cases */ void exp_fd_print(fsl) struct exp_fs_list *fsl; { if (!fsl) return; printf("%s ",fsl->spawnId); exp_fd_print(fsl->next); } void exp_i_print(exp_i) struct exp_i *exp_i; { if (!exp_i) return; printf("exp_i %x",exp_i); printf((exp_i->direct == EXP_DIRECT)?" direct":" indirect"); printf((exp_i->duration == EXP_PERMANENT)?" perm":" tmp"); printf(" ecount = %d\n",exp_i->ecount); printf("variable %s, value %s\n", ((exp_i->variable)?exp_i->variable:"--"), ((exp_i->value)?exp_i->value:"--")); printf("fds: "); exp_fd_print(exp_i->fs_list); printf("\n"); exp_i_print(exp_i->next); } void exp_ecase_print(ecase) struct ecase *ecase; { printf("pat <%s>\n",ecase->pat); printf("exp_i = %x\n",ecase->i_list); } void exp_ecases_print(ecd) struct exp_cases_descriptor *ecd; { int i; printf("%d cases\n",ecd->count); for (i=0;i<ecd->count;i++) exp_ecase_print(ecd->cases[i]); } void exp_cmd_print(ecmd) struct exp_cmd_descriptor *ecmd; { printf("expect cmd type: %17s",exp_cmdtype_printable(ecmd->cmdtype)); printf((ecmd->duration==EXP_PERMANENT)?" perm ": "tmp "); /* printdict */ exp_ecases_print(&ecmd->ecd); exp_i_print(ecmd->i_list); } void exp_cmds_print() { exp_cmd_print(&exp_cmds[EXP_CMD_BEFORE]); exp_cmd_print(&exp_cmds[EXP_CMD_AFTER]); exp_cmd_print(&exp_cmds[EXP_CMD_BG]); } /*ARGSUSED*/ int cmdX(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { exp_cmds_print(); return TCL_OK; } #endif /*DEBUG_PERM_ECASES*/ static struct exp_cmd_data cmd_data[] = { {"expect", Exp_ExpectCmd, 0, (ClientData) NULL, 0}, {"expect_after",Exp_ExpectGlobalCmd, 0, (ClientData)&exp_cmds[EXP_CMD_AFTER],0}, {"expect_before",Exp_ExpectGlobalCmd, 0, (ClientData)&exp_cmds[EXP_CMD_BEFORE],0}, {"expect_user", Exp_ExpectCmd, 0, (ClientData)"exp_user", 0}, {"expect_tty", Exp_ExpectCmd, 0, (ClientData)"exp_tty", 0}, {"expect_background",Exp_ExpectGlobalCmd, 0, (ClientData)&exp_cmds[EXP_CMD_BG],0}, {"match_max", 0, Exp_MatchMaxCmd, 0, 0}, {"remove_nulls",0, Exp_RemoveNullsCmd, 0, 0}, {"parity", 0, Exp_ParityCmd, 0, 0}, {"timestamp", 0, Exp_TimestampCmd, 0, 0}, {0} }; /* *---------------------------------------------------------------------- * * exp_init_expect_cmds -- * * Initialize all the 'expect' type commands. * * Results: * None * * Side Effects: * Commands are added to and variables are set in the interpreter. * *---------------------------------------------------------------------- */ void exp_init_expect_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); Tcl_SetVar(interp,EXPECT_TIMEOUT,INIT_EXPECT_TIMEOUT_LIT,0); Tcl_SetVar(interp,EXP_SPAWN_ID_ANY_VARNAME,EXP_SPAWN_ID_ANY,0); exp_cmd_init(&exp_cmds[EXP_CMD_BEFORE],EXP_CMD_BEFORE,EXP_PERMANENT); exp_cmd_init(&exp_cmds[EXP_CMD_AFTER ],EXP_CMD_AFTER, EXP_PERMANENT); exp_cmd_init(&exp_cmds[EXP_CMD_BG ],EXP_CMD_BG, EXP_PERMANENT); exp_cmd_init(&exp_cmds[EXP_CMD_FG ],EXP_CMD_FG, EXP_TEMPORARY); /* preallocate to one element, so future realloc's work */ exp_cmds[EXP_CMD_BEFORE].ecd.cases = 0; exp_cmds[EXP_CMD_AFTER ].ecd.cases = 0; exp_cmds[EXP_CMD_BG ].ecd.cases = 0; pattern_style[PAT_EOF] = "eof"; pattern_style[PAT_TIMEOUT] = "timeout"; pattern_style[PAT_DEFAULT] = "default"; pattern_style[PAT_FULLBUFFER] = "full buffer"; pattern_style[PAT_GLOB] = "glob pattern"; pattern_style[PAT_RE] = "regular expression"; pattern_style[PAT_EXACT] = "exact string"; pattern_style[PAT_NULL] = "null"; } void exp_init_sig() { } |
Added generic/getopt.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* got this off net.sources */ #include <stdio.h> #include <string.h> /* * get option letter from argument vector */ int opterr = 1, /* useless, never set or used */ optind = 1, /* index into parent argv vector */ optopt; /* character checked for validity */ char *optarg; /* argument associated with option */ #define BADCH (int)'?' #define EMSG "" #define errmsg(s) fputs(*argv,stderr);fputs(s,stderr); \ fputc(optopt,stderr);fputc('\n',stderr);return(BADCH); int getopt(argc,argv,ostr) int argc; char **argv, *ostr; { static char *place = EMSG; /* option letter processing */ register char *oli; /* option letter list index */ char *index(); if(!*place) { /* update scanning pointer */ if(optind >= argc || *(place = argv[optind]) != '-' || !*++place) return(EOF); if (*place == '-') { /* found "--" */ ++optind; return(EOF); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) { if(!*place) ++optind; errmsg(": illegal option -- "); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) optarg = place; /* no white space */ else if (argc <= ++optind) { /* no arg */ place = EMSG; errmsg(": option requires an argument -- "); } else optarg = argv[optind]; /* white space */ place = EMSG; ++optind; } return(optopt); /* dump back option letter */ } |
Deleted libexpect.man.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added mac/README.mac.txt.
> > > | 1 2 3 | /* RCS: @(#) $Id: $ */ Nothing here... |
Changes to pty_sgttyb.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | #include <signal.h> #include <setjmp.h> #include "expect_cf.h" #include "exp_rename.h" #include "exp_tty_in.h" #include "exp_pty.h" | | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <signal.h> #include <setjmp.h> #include "expect_cf.h" #include "exp_rename.h" #include "exp_tty_in.h" #include "exp_pty.h" void expDiagLog(); void expDiagLogU(); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static char master_name[] = "/dev/ptyXX"; /* master */ |
︙ | ︙ | |||
155 156 157 158 159 160 161 | #if experimental /* code to allocate force expect to get a controlling tty */ /* even if it doesn't start with one (i.e., under cron). */ /* This code is not necessary, but helpful for testing odd things. */ if (exp_dev_tty == -1) { /* give ourselves a controlling tty */ | | | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | #if experimental /* code to allocate force expect to get a controlling tty */ /* even if it doesn't start with one (i.e., under cron). */ /* This code is not necessary, but helpful for testing odd things. */ if (exp_dev_tty == -1) { /* give ourselves a controlling tty */ int master = exp_getptymaster(); fcntl(master,F_SETFD,1); /* close-on-exec */ setpgrp(0,0); close(0); close(1); exp_getptyslave(exp_get_var(exp_interp,"stty_init")); close(2); fcntl(0,F_DUPFD,2); /* dup 0 onto 2 */ } #endif knew_dev_tty = (exp_dev_tty != -1); if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0); } /* returns fd of master end of pseudotty */ int exp_getptymaster() { int master = -1; char *hex, *bank; struct stat statbuf; exp_pty_error = 0; |
︙ | ︙ | |||
214 215 216 217 218 219 220 | exp_slave_control(master,control) int master; int control; { } int | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | exp_slave_control(master,control) int master; int control; { } int exp_getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave; if (0 > (slave = open(slave_name, O_RDWR))) return(-1); |
︙ | ︙ |
Changes to pty_termios.c.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | The functions are relatively small but painful enough that I don't care to recode them. You may, if you absolutely want to get rid of any vestiges of Tcl. */ extern char *TclGetRegError(); #if defined(HAVE_PTYM) && defined(HAVE_PTMX) /* * HP-UX 10.0 with streams (optional) have both PTMX and PTYM. I don't * know which is preferred but seeing as how the HP trap stuff is so * unusual, it is probably safer to stick with the native HP pty support, * too. | > > > > > > > > > > > > > > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | The functions are relatively small but painful enough that I don't care to recode them. You may, if you absolutely want to get rid of any vestiges of Tcl. */ extern char *TclGetRegError(); #if defined(HAVE_PTMX_BSD) && defined(HAVE_PTMX) /* * Some systems have both PTMX and PTMX_BSD. * In fact, alphaev56-dec-osf4.0e has /dev/pts, /dev/pty, /dev/ptym, * /dev/ptm, /dev/ptmx, and /dev/ptmx_bsd * Suggestion from Martin Buchholz <[email protected]> is that BSD * is usually deprecated and so should be here. */ #undef HAVE_PTMX_BSD #endif /* Linux and Digital systems can be configured to have both. According to Ashley Pittman <[email protected]>, Digital works better with openpty which supports 4000 while ptmx supports 60. */ #if defined(HAVE_OPENPTY) && defined(HAVE_PTMX) #undef HAVE_PTMX #endif #if defined(HAVE_PTYM) && defined(HAVE_PTMX) /* * HP-UX 10.0 with streams (optional) have both PTMX and PTYM. I don't * know which is preferred but seeing as how the HP trap stuff is so * unusual, it is probably safer to stick with the native HP pty support, * too. |
︙ | ︙ | |||
70 71 72 73 74 75 76 | # include <fcntl.h> #endif #if defined(_SEQUENT_) # include <sys/strpty.h> #endif | | | > | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # include <fcntl.h> #endif #if defined(_SEQUENT_) # include <sys/strpty.h> #endif #if defined(HAVE_PTMX) && defined(HAVE_STROPTS_H) # include <sys/stropts.h> #endif #include "exp_win.h" #include "exp_tty_in.h" #include "exp_rename.h" #include "exp_pty.h" void expDiagLog(); void expDiagLogPtr(); #include <errno.h> /*extern char *sys_errlist[];*/ #ifndef TRUE #define TRUE 1 #define FALSE 0 |
︙ | ︙ | |||
301 302 303 304 305 306 307 | /* Apollo Domain doesn't need this */ #ifdef DFLT_STTY if (ttyinit) { /* overlay parms originally supplied by Makefile */ /* As long as BSD stty insists on stdout == stderr, we can no longer write */ /* diagnostics to parent stderr, since stderr has is now child's */ /* Maybe someday they will fix stty? */ | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | /* Apollo Domain doesn't need this */ #ifdef DFLT_STTY if (ttyinit) { /* overlay parms originally supplied by Makefile */ /* As long as BSD stty insists on stdout == stderr, we can no longer write */ /* diagnostics to parent stderr, since stderr has is now child's */ /* Maybe someday they will fix stty? */ /* expDiagLogPtrStr("exp_getptyslave: (default) stty %s\n",DFLT_STTY);*/ pty_stty(DFLT_STTY,slave_name); } #endif /* lastly, give user chance to override any terminal parms */ if (s) { /* give user a chance to override any terminal parms */ /* expDiagLogPtrStr("exp_getptyslave: (user-requested) stty %s\n",s);*/ pty_stty(s,slave_name); } } } void exp_init_pty() |
︙ | ︙ | |||
346 347 348 349 350 351 352 | #ifndef R_OK /* 3b2 doesn't define these according to [email protected]. */ #define R_OK 04 #define W_OK 02 #endif int | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | #ifndef R_OK /* 3b2 doesn't define these according to [email protected]. */ #define R_OK 04 #define W_OK 02 #endif int exp_getptymaster() { char *hex, *bank; struct stat stat_buf; int master = -1; int slave = -1; int num; |
︙ | ︙ | |||
371 372 373 374 375 376 377 | #endif if ((slave_name = (char *)ptsname(master)) == NULL || unlockpt(master)) { close(master); return(-1); } else if (grantpt(master)) { static char buf[500]; exp_pty_error = buf; | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | #endif if ((slave_name = (char *)ptsname(master)) == NULL || unlockpt(master)) { close(master); return(-1); } else if (grantpt(master)) { static char buf[500]; exp_pty_error = buf; sprintf(exp_pty_error,"grantpt(%s) failed - likely reason is that your system administrator (in a rage of blind passion to rid the system of security holes) removed setuid from the utility used internally by grantpt to change pty permissions. Tell your system admin to reestablish setuid on the utility. Get the utility name by running Expect under truss or trace.", expErrnoMsg(errno)); close(master); return(-1); } #ifdef TIOCFLUSH (void) ioctl(master,TIOCFLUSH,(char *)0); #endif /* TIOCFLUSH */ |
︙ | ︙ | |||
480 481 482 483 484 485 486 | sprintf (num_str, "%d", num); sprintf (master_name, "%s%s", "/dev/ptyp", num_str); if (stat (master_name, &stat_buf) < 0) break; sprintf (slave_name, "%s%s", "/dev/ttyp", num_str); | | | 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | sprintf (num_str, "%d", num); sprintf (master_name, "%s%s", "/dev/ptyp", num_str); if (stat (master_name, &stat_buf) < 0) break; sprintf (slave_name, "%s%s", "/dev/ttyp", num_str); master = exp_pty_test(master_name,slave_name,'0',num_str); if (master >= 0) goto done; } #endif #ifdef HAVE_PTYM /* systems with PTYM follow this idea: |
︙ | ︙ | |||
537 538 539 540 541 542 543 | *tty_bank = *bank; sprintf(tty_num,"00"); if (stat(master_name, &stat_buf) < 0) break; for (num = 0; num<100; num++) { *slave_bank = *tty_bank; sprintf(tty_num,"%02d",num); strcpy(slave_num,tty_num); | | | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | *tty_bank = *bank; sprintf(tty_num,"00"); if (stat(master_name, &stat_buf) < 0) break; for (num = 0; num<100; num++) { *slave_bank = *tty_bank; sprintf(tty_num,"%02d",num); strcpy(slave_num,tty_num); master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num); if (master >= 0) goto done; } } /* * tty[p-za-ce-o][0-9][0-9][0-9] */ for (bank = banks;*bank;bank++) { *tty_bank = *bank; sprintf(tty_num,"000"); if (stat(master_name, &stat_buf) < 0) break; for (num = 0; num<1000; num++) { *slave_bank = *tty_bank; sprintf(tty_num,"%03d",num); strcpy(slave_num,tty_num); master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num); if (master >= 0) goto done; } } #endif /* HAVE_PTYM */ #if defined(HAVE_CONVEX_GETPTY) |
︙ | ︙ | |||
598 599 600 601 602 603 604 | { #ifdef HAVE_PTYTRAP ioctl(master, TIOCTRAP, &control); #endif /* HAVE_PTYTRAP */ } int | | | > > > > > | | | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | { #ifdef HAVE_PTYTRAP ioctl(master, TIOCTRAP, &control); #endif /* HAVE_PTYTRAP */ } int exp_getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave, slave2; char buf[10240]; if (0 > (slave = open(slave_name, O_RDWR))) { static char buf[500]; exp_pty_error = buf; sprintf(exp_pty_error,"open(%s,rw) = %d (%s)",slave_name,slave,expErrnoMsg(errno)); return(-1); } #if defined(HAVE_PTMX_BSD) if (ioctl (slave, I_LOOK, buf) != 0) if (ioctl (slave, I_PUSH, "ldterm")) { expDiagLogPtrStrStr("ioctl(%d,I_PUSH,\"ldterm\") = %s\n",slave,expErrnoMsg(errno)); } #else #if defined(HAVE_PTMX) if (ioctl(slave, I_PUSH, "ptem")) { expDiagLogPtrStrStr("ioctl(%d,I_PUSH,\"ptem\") = %s\n",slave,expErrnoMsg(errno)); } if (ioctl(slave, I_PUSH, "ldterm")) { expDiagLogPtrStrStr("ioctl(%d,I_PUSH,\"ldterm\") = %s\n",slave,expErrnoMsg(errno)); } if (ioctl(slave, I_PUSH, "ttcompat")) { expDiagLogPtrStrStr("ioctl(%d,I_PUSH,\"ttcompat\") = %s\n",slave,expErrnoMsg(errno)); } #endif #endif if (0 == slave) { /* if opened in a new process, slave will be 0 (and */ /* ultimately, 1 and 2 as well) */ |
︙ | ︙ | |||
698 699 700 701 702 703 704 | rc = select(maxfds, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)&excep, &t); if (rc != 1) { | | | | | | | | | | | | 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 | rc = select(maxfds, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)&excep, &t); if (rc != 1) { expDiagLogPtrStr("spawned process never started: %s\r\n",expErrnoMsg(errno)); return(-1); } if (ioctl(fd,TIOCREQCHECK,&ioctl_info) < 0) { expDiagLogPtrStr("ioctl(TIOCREQCHECK) failed: %s\r\n",expErrnoMsg(errno)); return(-1); } found = ioctl_info.request; expDiagLogPtrX("trapped pty op = %x",found); if (found == TIOCOPEN) { expDiagLogPtr(" TIOCOPEN"); } else if (found == TIOCCLOSE) { expDiagLogPtr(" TIOCCLOSE"); } #ifdef TIOCSCTTY if (found == TIOCSCTTY) { expDiagLogPtr(" TIOCSCTTY"); } #endif if (found & IOC_IN) { expDiagLogPtr(" IOC_IN (set)"); } else if (found & IOC_OUT) { expDiagLogPtr(" IOC_OUT (get)"); } expDiagLogPtr("\n"); if (ioctl(fd, TIOCREQSET, &ioctl_info) < 0) { expDiagLogPtrStr("ioctl(TIOCREQSET) failed: %s\r\n",expErrnoMsg(errno)); return(-1); } return(found); } #endif void exp_pty_exit() { /* a stub so we can do weird things on the cray */ } |
Changes to pty_unicos.c.
︙ | ︙ | |||
52 53 54 55 56 57 58 | #include "exp_tty_in.h" #include "exp_rename.h" #ifdef HAVE_SYSCONF_H #include <sys/sysconfig.h> #endif | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #include "exp_tty_in.h" #include "exp_rename.h" #ifdef HAVE_SYSCONF_H #include <sys/sysconfig.h> #endif void expDiagLog(); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifndef MAXHOSTNAMELEN |
︙ | ︙ | |||
198 199 200 201 202 203 204 | */ setuid(0); setreuid(realuid,realuid); } /* returns fd of master end of pseudotty */ int | | | | | | | | | | | | | | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | */ setuid(0); setreuid(realuid,realuid); } /* returns fd of master end of pseudotty */ int exp_getptymaster() { struct stat sb; int master; int npty; exp_pty_error = 0; expDiagLog("exp_getptymaster: lowpty=%d highpty=%d\n",lowpty,highpty); for (npty = lowpty; npty <= highpty; npty++) { if (seteuid(0) == -1) { /* we need to be root! */ expDiagLog("exp_getptymaster: seteuid root errno=%d\n", errno); } (void) sprintf(linep, "/dev/pty/%03d", npty); master = open(linep, O_RDWR); if (master < 0) { expDiagLog("exp_getptymaster: open linep=%s errno=%d\n", linep,errno); continue; } (void) sprintf(linet, "/dev/ttyp%03d", npty); if(stat(linet, &sb) < 0) { expDiagLog("exp_getptymaster: stat linet=%s errno=%d\n", linet,errno); (void) close(master); continue; } if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) { if (chown(linet, realuid, realgid) == -1) { expDiagLog("exp_getptymaster: chown linet=%s errno=%d\n", linet,errno); } if (chmod(linet, 0600) == -1) { expDiagLog("exp_getptymaster: chmod linet=%s errno=%d\n", linet,errno); } (void)close(master); master = open(linep, 2); if (master < 0) { expDiagLog("exp_getptymaster: reopen linep=%s errno=%d\n", linep,errno); continue; } } if (seteuid(realuid) == -1) { /* back to who we are! */ expDiagLog("exp_getptymaster: seteuid user errno=%d\n", errno); } if (access(linet, R_OK|W_OK) != 0) { expDiagLog("exp_getptymaster: access linet=%s errno=%d\n", linet,errno); (void) close(master); continue; } expDiagLog("exp_getptymaster: allocated %s\n",linet); ptys[npty] = -1; exp_pty_slave_name = linet; return(master); } if (seteuid(realuid) == -1) { /* back to who we are! */ expDiagLog("exp_getptymaster: seteuid user errno=%d\n",errno); } return(-1); } /* see comment in pty_termios.c */ /*ARGSUSED*/ void exp_slave_control(master,control) int master; int control; { } int exp_getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave; if (0 > (slave = open(linet, O_RDWR))) { expDiagLog("exp_getptyslave: open linet=%s errno=%d\n",linet,errno); return(-1); } /* sanity check - if slave not 0, skip rest of this and return */ /* to what will later be detected as an error in caller */ if (0 != slave) { expDiagLog("exp_getptyslave: slave fd not 0\n"); return(slave); } if (0 == slave) { /* if opened in a new process, slave will be 0 (and */ /* ultimately, 1 and 2 as well) */ |
︙ | ︙ | |||
313 314 315 316 317 318 319 | } setptyutmp() { struct utmp utmp; if (seteuid(0) == -1) { /* Need to be root */ | | | | | | | | | | | | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | } setptyutmp() { struct utmp utmp; if (seteuid(0) == -1) { /* Need to be root */ expDiagLog("setptyutmp: setuid root errno=%d\n",errno); return(-1); } (void) time(&utmp.ut_time); utmp.ut_type = USER_PROCESS; utmp.ut_pid = getpid(); strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user)); strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host)); strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line)); strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id)); if (pututline(&utmp) == NULL) { expDiagLog("setptyutmp: pututline failed\n"); } endutent(); if (seteuid(realuid) == -1) expDiagLog("setptyutmp: seteuid user errno=%d\n",errno); return(0); } setptypid(pid) int pid; { int npty; for (npty = lowpty; npty <= highpty; npty++) { if (ptys[npty] < 0) { expDiagLog("setptypid: ttyp%03d pid=%d\n",npty,pid); ptys[npty] = pid; break; } } } ttyp_reset() { int npty; if (seteuid(0) == -1) { /* we need to be root! */ expDiagLog("ttyp_reset: seteuid root errno=%d\n",errno); } for (npty = lowpty; npty <= highpty; npty++) { if (ptys[npty] <= 0) continue; (void) sprintf(linet, "/dev/ttyp%03d", npty); expDiagLog("ttyp_reset: resetting %s, killing %d\n", linet,ptys[npty]); if (chown(linet,0,0) == -1) { expDiagLog("ttyp_reset: chown %s errno=%d\n",linet,errno); } if (chmod(linet, 0666) == -1) { expDiagLog("ttyp_reset: chmod %s errno=%d\n",linet,errno); } resetptyutmp(); if (kill(ptys[npty],SIGKILL) == -1) { expDiagLog("ttyp_reset: kill pid=%d errno=%d\n", ptys[npty],errno); } } if (seteuid(realuid) == -1) { /* Back to who we really are */ expDiagLog("ttyp_reset: seteuid user errno=%d\n",errno); } } void exp_pty_exit() { ttyp_reset(); |
︙ | ︙ | |||
395 396 397 398 399 400 401 | /* set up entry to search for */ (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4, sizeof (utmp.ut_id)); utmp.ut_type = USER_PROCESS; /* position to entry in utmp file */ if(getutid(&utmp) == NULL) { | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | /* set up entry to search for */ (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4, sizeof (utmp.ut_id)); utmp.ut_type = USER_PROCESS; /* position to entry in utmp file */ if(getutid(&utmp) == NULL) { expDiagLog("resetptyutmp: no utmp entry for %s\n",linet); return(-1); /* no utmp entry for this line ??? */ } /* set up the new entry */ strncpy(utmp.ut_name,"",sizeof(utmp.ut_name)); strncpy(utmp.ut_host,"",sizeof(utmp.ut_host)); time(&utmp.ut_time); |
︙ | ︙ |
Changes to tcldbg.h.
︙ | ︙ | |||
33 34 35 36 37 38 39 | ClientData data; } Dbg_OutputStruct; EXTERN char *Dbg_VarName; EXTERN char *Dbg_DefaultCmdName; /* trivial interface, creates a "debug" command in your interp */ | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | ClientData data; } Dbg_OutputStruct; EXTERN char *Dbg_VarName; EXTERN char *Dbg_DefaultCmdName; /* trivial interface, creates a "debug" command in your interp */ EXTERN int Tcldbg_Init _ANSI_ARGS_((Tcl_Interp *)); EXTERN void Dbg_On _ANSI_ARGS_((Tcl_Interp *interp, int immediate)); EXTERN void Dbg_Off _ANSI_ARGS_((Tcl_Interp *interp)); EXTERN char **Dbg_ArgcArgv _ANSI_ARGS_((int argc,char *argv[], int copy)); EXTERN int Dbg_Active _ANSI_ARGS_((Tcl_Interp *interp)); |
︙ | ︙ |
Changes to tests/.Sanitize.
︙ | ︙ | |||
21 22 23 24 25 26 27 | # called. Directories not listed will be removed in their entirety # with rm -rf. Things-to-keep: .Sanitize README | | > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # called. Directories not listed will be removed in their entirety # with rm -rf. Things-to-keep: .Sanitize README all.tcl defs logfile.test send.test spawn.test pid.test cat.test expect.test stty.test # The lines between the "Do-last:" line and the end of the file |
︙ | ︙ |
Changes to tests/README.
1 | Expect Test Suite | | | > | | | | < | > | | > < > | > | < | > > > > | | | > | | > | < > > < | < | > | < | | | | < | > > > > | > | > > > | > | < > > | > > | | | | < < > > > > > < > > < < > < > | > > > < | | | | | | < | > | | > | > | > | > > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | Expect Test Suite ----------------- This directory contains a set of validation tests for the Expect commands. Each of the files whose name ends in ".test" is intended to fully exercise one or a few Expect commands. The commands tested by a given file are listed in the first line of the file. You can run the tests in three ways: (a) type "make test" in the parent directory to this one; this will run all of the tests. (b) type "expect <testFile> ?<option> <value>? Command line options include: -help display usage information -verbose <level> set the level of verbosity to a substring of "bps". See the "Test output" section of the tcltest man page for an explanation of this option. -match <matchList> only run tests that match one or more of the glob patterns in <matchList> -skip <skipList> do not run tests that match one or more of the glob patterns in <skipList> -file <globPatternList> only source test files that match one or more of the glob patterns in <globPatternList> (relative to the "tests" directory). This option only applies when you run the test suite with the "all.tcl" file. -notfile <globPatternList> do not source test files that match one or more of the patterns in <globPatternList> (relative to the "tests" directory). This option only applies when you run the test suite with the "all.tcl" file. -constraints <list> tests with any constraints in <list> will not be skipped. Not that elements of <list> must exactly match the existing constraints. -limitconstraints <bool> If 1, limit test runs to those tests that match the constraints listed using the -constraints flag. Use of this flag requires use of the -constraints flag. The default value is 0. -tmpdir <dirname> put temporary files created by ::tcltest::makeFile and ::tcltest::makeDirectory in the named directory. The default location is ::tcltest::workingDirectory. -preservecore <level> check for core files. If level is 0, check for core files only when cleanupTests is called from an all.tcl file. If 1, also check at the end of every test command. If 2, also save core files in ::tcltest::temporaryDirectory. The default level is 0. (c) start up expect in this directory, then "source" the test file (for example, type "source parse.test"). To run all of the tests, type "source all.tcl". To use the options in interactive mode, you can set their corresponding tcltest namespace variables after loading the tcltest package. For example, some of the tcltest variables are: ::tcltest::match ::tcltest::skip ::tcltest::testConstraints(nonPortable) ::tcltest::testConstraints(knownBug) ::tcltest::testConstraints(userInteractive) Please see the man page for the 'tcltest' package for more detailed information on the features of the testing environment. This approach to testing was copied from the Tcl distribution. Incompatibilities with prior versions ------------------------------------- 1) Global variables such as VERBOSE, TESTS, and testConfig are now renamed to use the new "tcltest" namespace. old name new name -------- -------- VERBOSE ::tcltest::verbose TESTS ::tcltest::match testConfig ::tcltest::testConstraints 2) VERBOSE values are no longer numeric. 3) When you run "make test", the working dir for the test suite is now the one from which you called "make test", rather than the "tests" directory. This change allows for both unix and windows test suites to be run simultaneously without interference with each other or with existing files. All tests must now run independently of their working directory. 4) The "all" file is now called all.tcl. 5) The "defs" file no longer exists. 6) Instead of creating a doAllTests file in the tests directory, to run all nonPortable tests, just use the "-constraints nonPortable" command line flag. If you are running interactively, you can set the ::tcltest::testConstraints(nonPortable) variable to 1 (after loading the tcltest package). |
Deleted tests/all.
|
| < < < < < < < < < < |
Added tests/all.tcl.
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # all.tcl -- # # This file contains a top-level script to run all of the Tcl # tests. Execute it by invoking "source all" when running tclTest # in this directory. package require tcltest namespace import ::tcltest::* set ::tcltest::testSingleFile false set ::tcltest::testsDirectory [file dirname [info script]] foreach file [lsort [::tcltest::getMatchingFiles]] { set tail [file tail $file] puts stdout $tail if {[catch {source $file} msg]} { puts stdout $msg } } ::tcltest::cleanupTests 1 return |
Changes to tests/cat.test.
1 2 3 4 5 6 | # Commands covered: cat (UNIX) # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # Commands covered: cat (UNIX) # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } #exp_internal -f /dev/ttyp5 0 catch {unset x} log_user 0 test cat-1.1 {basic cat operation} { exp_spawn cat -u exp_send "\r" set timeout 10 expect \r {set x 1} timeout {set x 0} exp_close exp_wait set x } {1} #exp_internal 0 cleanupTests return |
Deleted tests/defs.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to tests/expect.test.
1 2 3 4 5 6 | # Commands covered: cat (UNIX), expect # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. | | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | # Commands covered: cat (UNIX), expect # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } catch {unset x} log_user 0 exp_spawn cat -u exp_stty -echo < $spawn_out(slave,name) test expect-1.1 {exact pattern} { expect "*" exp_send "a\r" set timeout 10 set x 0 expect -ex a {set x 1} set x } {1} test expect-1.2 {exact pattern buffering} { expect "*" exp_send "hiahi\r" set timeout 10 set x 0 expect -ex hi expect -ex hi {set x 1} set x } {1} # if only this test fails, then configure has guessed incorrectly and # stty accesses the control terminal from stdout. The quick fix is # to edit expect_cf.h and define STTY_READS_STDOUT to 1. (It should # be commented out.) If you figure out a way to fix the configure test, # let me know. Else, let me know a way to test for your particular # machine and os version so it can be hardwired. test expect-1.3 {exact pattern failure} { expect "*" exp_send "hiahi\r" set timeout 10 set x 0 expect -ex hi {set x 1} expect -ex hi {set x 2} expect -ex hi {set x 3} set x } {2} test expect-1.4 {glob pattern} { expect "*" exp_send "a\r" set timeout 10 set x 0 expect "a" {set x 1} set x } {1} test expect-1.5 {glob pattern buffering} { expect "*" exp_send "a\r" set timeout 10 set x 0 expect "*" {set x 1} set x } {1} test expect-1.6 {glob buffer} { expect "*" exp_send "philosophic\r" set timeout 10 set x 0 expect "hi" set x [string match *phi $expect_out(buffer)] } {1} test expect-1.7 {glob string} { expect "*" exp_send "philosophic\r" set timeout 10 set x 0 expect "hi" set expect_out(0,string) } {hi} close wait set filename /tmp/null.[pid] set fid [open $filename w] puts $fid "a\u0000b" close $fid test expect-1.8 {default remove null behavior} { spawn cat $filename expect a\u0000b set rc [regexp $expect_out(buffer) "ab"] wait set rc } {0} test expect-1.8b {default remove null behavior} { spawn cat $filename expect ab set rc [regexp $expect_out(buffer) "ab"] wait set rc } {1} test expect-1.9 {match null inline} { spawn cat $filename remove_nulls 0 expect a\u0000b set rc [regexp $expect_out(buffer) "a\u0000b"] close wait set rc } {1} file delete -force $filename cleanupTests return |
Added tests/logfile.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # Commands covered: log_file # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } test logfile-1.1 {basic logfile} { set filename /tmp/logfile.[pid] file delete -force $filename log_file $filename unset spawn_id ;# clean up results of previous test send "via send" send_user "via send_user" send_error "via send_stdout" send_tty "via send_tty" send_log "via send_log" log_file set fid [open $filename] gets $fid buffer close $fid file delete -force $filename # verify everything but "send" is logged regexp "via send_uservia send_stdoutvia send_ttyvia send_log" $buffer } {1} cleanupTests return |
Changes to tests/pid.test.
1 2 3 4 5 6 | # Commands covered: pid # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. | | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Commands covered: pid # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } catch {unset x} #exp_internal -f /dev/ttyp5 0 test pid-1.2 {basic pid operation} { set cat [exp_spawn -noecho cat] |
︙ | ︙ | |||
24 25 26 27 28 29 30 | set x [expr {0!=[string compare [exp_pid -i $cat2] [exp_pid -i $cat]]}] exp_close -i $cat;exp_wait -i $cat;exp_close -i $cat2;exp_wait -i $cat2 set x } {1} test pid-1.4 {basic pid operation} { list [catch {exp_pid -i 100} msg] $msg | | > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | set x [expr {0!=[string compare [exp_pid -i $cat2] [exp_pid -i $cat]]}] exp_close -i $cat;exp_wait -i $cat;exp_close -i $cat2;exp_wait -i $cat2 set x } {1} test pid-1.4 {basic pid operation} { list [catch {exp_pid -i 100} msg] $msg } {1 {can not find channel named "100"}} test pid-1.5 {basic pid operation} { list [catch {exp_pid -j} msg] $msg } {1 {usage: -i spawn_id}} cleanupTests return |
Added tests/send.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # Commands covered: send # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } log_user 0 #exp_internal -f /dev/ttyp5 0 test send-1.1 {basic send operation} { spawn cat after 1000 send "foo\r" expect foo after 1000 send "\u0004" expect eof regexp "\r\nfoo\r\n" $expect_out(buffer) } {1} test send-1.2 {send null} { spawn od -c send "a\u0000b\r" after 1000 send \u0004 expect eof regexp "a \\\\0 b" $expect_out(buffer) } {1} cleanupTests return |
Changes to tests/spawn.test.
1 2 3 4 5 6 | # Commands covered: spawn # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. | | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # Commands covered: spawn # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } log_user 0 #exp_internal -f /dev/ttyp5 0 test spawn-1.1 {basic spawn operation} { set x [catch {exp_spawn cat}] |
︙ | ︙ | |||
46 47 48 49 50 51 52 | exec rm /tmp/[pid] exp_wait list $x $y $pid } {1 1 0} test spawn-1.5 {spawn with no fd leak} { exp_spawn cat | | > > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | exec rm /tmp/[pid] exp_wait list $x $y $pid } {1 1 0} test spawn-1.5 {spawn with no fd leak} { exp_spawn cat set x [expr {"$first_spawn_id"=="$spawn_id"}] exp_close; exp_wait set x } {1} # looks to be some control-char problem #ftest spawn-1.6 {spawn with echo} { # exp_spawn cat #} {spawn cat} #ftest spawn-1.7 {spawn with -noecho} { # exp_spawn -noecho cat #} {} cleanupTests return |
Changes to tests/stty.test.
1 2 3 4 5 6 | # Commands covered: stty # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # Commands covered: stty # # This file contains a collection of tests for one or more of the Tcl # built-in commands. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } #exp_internal -f /dev/ttyp5 0 catch {unset x} log_user 0 test stty-1.1 {basic stty operation} { exp_spawn cat -u catch {exp_stty < $spawn_out(slave,name)} } {0} test stty-1.2 {basic stty operation} { exp_spawn cat -u catch {exp_stty -echo < $spawn_out(slave,name)} } {0} #exp_internal 0 cleanupTests return |
Changes to testsuite/Makefile.in.
︙ | ︙ | |||
35 36 37 38 39 40 41 42 43 44 45 46 47 48 | if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \ echo ${srcdir}/../../dejagnu/runtest ; \ else echo runtest ; fi` RUNTESTFLAGS = all: .PHONY: info install-info check installcheck info: install-info: check: installcheck: .NOEXPORT: | > > > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \ echo ${srcdir}/../../dejagnu/runtest ; \ else echo runtest ; fi` RUNTESTFLAGS = all: binaries: libraries: .PHONY: info install-info check installcheck info: install-info: check: installcheck: .NOEXPORT: |
︙ | ︙ |
Changes to testsuite/configure.
1 2 3 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. | | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE |
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then | > > > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then |
︙ | ︙ | |||
330 331 332 333 334 335 336 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } |
︙ | ︙ | |||
432 433 434 435 436 437 438 | *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. | < | | > > > | > | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that |
︙ | ︙ | |||
497 498 499 500 501 502 503 | > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' | | > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < > | > | > | > | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says [email protected]. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:533: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:563: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" |
︙ | ︙ | |||
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 | CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > | > | | | | > > | > | | | | < < < < | < < < < < | < < < < < < < < | < < < < | < < < < < < < < < < < < < < < < | < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 | CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:614: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 657 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:693: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:721: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi CY_AC_C_WORKS # This is for LynxOS, which needs a flag to force true POSIX when # building. It's weirder than that, cause the flag varies depending # how old the compiler is. So... # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly CY_AC_TCL_LYNX_POSIX CY_AC_PATH_TCLH trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure |
︙ | ︙ | |||
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | | > > > > > > > > > > > > > | > | | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 | # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else |
︙ | ︙ | |||
1149 1150 1151 1152 1153 1154 1155 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) | | > > < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@TCLHDIR@%$TCLHDIR%g s%@host@%$host%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" |
︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 | if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g | > > > | | > > > > | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <<EOF EOF cat >> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 |
Added unix/DbgMkfl.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | # # Makefile for tcl debugger # VERSION = \"@DBG_VERSION_FULL@\" SHORT_VERSION = @DBG_VERSION@ # Compatible with Tcl version 7.5 # Compatible with Tk version 4.1 srcdir = @srcdir@ VPATH = @srcdir@ ###################################################################### # The following lines are things you are likely to want to change ###################################################################### # Tcl include files. (If you haven't installed Tcl yet, read the README file). # This must point to the directory that contains ALL of Tcl's include # files, not just the public ones. TCLHDIR = @TCLHDIR@ # flags to pass to cc # You should be able to leave this just the way it is. However, here are some # note if you run into problems: # # Avoid -O (optimize) unless you are convinced your optimizer is flawless # (hint: not a chance). I have heard many reports of -O causing Expect to # misbehave. # I encourage you to use -g (debugging). While it is unlikely you will # encounter an internal error in Expect, should this happen, I may just need # the -g information and then you will need to recompile Expect. As an aside, # Expect is not a space or time pig, so this won't affect the performance of # your Expect scripts. # Note: On Linux systems which only have dynamic X libraries, the -g prevents # the linker from using them. So do not use -g on such systems. CFLAGS = @DBG_CFLAGS@ @TCL_SHLIB_CFLAGS@ # which C compiler to use CC = @CC@ # By default, `make install' will install the appropriate files in # /usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify # an installation prefix other than /usr/local here: prefix = @prefix@ # You can specify a separate installation prefix for architecture-specific # files such as binaries and libraries. exec_prefix = @exec_prefix@ # If you have ranlib but it should be avoided, change this from "ranlib" # # to something innocuous like "echo". Known systems with this problem: # older SCO boxes. RANLIB = @TCL_RANLIB@ ###################################################################### # End of things you are likely to want to change ###################################################################### libdir = $(exec_prefix)/lib datadir = $(prefix)/lib mandir = @mandir@ man1dir = $(mandir)/man1 includedir = $(prefix)/include # Where to store utility scripts. This corresponds to the variable # "dbg_library". DBG_SCRIPTDIR = $(datadir)/dbg INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ AR = ar ARFLAGS = cr # TCLHDIR includes "-I" CPPFLAGS = -I. -I$(srcdir) $(TCLHDIR) \ -DDBG_VERSION=$(VERSION) \ -DDBG_SCRIPTDIR=\"$(DBG_SCRIPTDIR)\" CFLAGS_INT = $(MH_CFLAGS) $(CPPFLAGS) $(CFLAGS) .c.o: $(CC) -c $(CFLAGS_INT) $(HDEFS) $< CFILES = Dbg.c Dbg_cmd.c OFILES = Dbg.o Dbg_cmd.o # libraries (both .a and shared) DBG_LIB_FILES = @DBG_LIB_FILES@ # default Dbg library (shared if possible, otherwise static) DBG_LIB_FILE = @DBG_LIB_FILE@ # Dbg object library (.a) DBG_NONSHARED_LIB_FILE = @DBG_NONSHARED_LIB_FILE@ # Dbg object library (shared, if possible) DBG_SHARED_LIB_FILE = @DBG_SHARED_LIB_FILE@ all: $(DBG_LIB_FILES) $(DBG_NONSHARED_LIB_FILE): $(OFILES) -rm -f $(DBG_NONSHARED_LIB_FILE) $(AR) $(ARFLAGS) $(DBG_NONSHARED_LIB_FILE) $(OFILES) -$(RANLIB) $(DBG_NONSHARED_LIB_FILE) $(DBG_SHARED_LIB_FILE): $(OFILES) -rm -f $(DBG_SHARED_LIB_FILE) @TCL_SHLIB_LD@ -o $(DBG_SHARED_LIB_FILE) $(OFILES) # Delete all the installed files that the `install' target creates # (but not the noninstalled files such as `make all' creates) uninstall: -rm -f $(man1dir)/tcldbg.1 \ $(libdir)/$(DBG_SHARED_LIB_FILE) \ $(libdir)/$(DBG_NONSHARED_LIB_FILE) \ $(includedir)/Dbg.h \ $(DBG_SCRIPTDIR)/pkgIndex.tcl install: $(DBG_LIB_FILES) ${srcdir}/mkinstalldirs $(man1dir) $(libdir) $(includedir) $(DBG_SCRIPTDIR) $(INSTALL_DATA) $(srcdir)/tcldbg.man $(man1dir)/tcldbg.1 if [ -s $(DBG_NONSHARED_LIB_FILE) ] ; then \ $(INSTALL_DATA) $(DBG_NONSHARED_LIB_FILE) $(libdir)/$(DBG_NONSHARED_LIB_FILE) ; \ $(RANLIB) $(libdir)/$(DBG_NONSHARED_LIB_FILE) ; \ fi if [ -s $(DBG_SHARED_LIB_FILE) ] ; then \ $(INSTALL_DATA) $(DBG_SHARED_LIB_FILE) $(libdir)/$(DBG_SHARED_LIB_FILE) ; \ fi $(INSTALL_DATA) $(srcdir)/Dbg.h $(includedir) # create utility-script directory $(INSTALL_DATA) $(srcdir)/Dbg_lib.tcl $(DBG_SCRIPTDIR) $(INSTALL_DATA) $(srcdir)/tclIndex $(DBG_SCRIPTDIR) ################################### # Targets for Makefile and configure ################################### Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) config.status @echo "Rebuilding the Makefile..." $(SHELL) config.status configure: $(srcdir)/configure.in $(srcdir)/Makefile.in autoconf configure.in > configure -@chmod a+x configure config.status: $(srcdir)/configure @echo "Rebuilding config.status..." $(SHELL) ./config.status --recheck ################################################ # Various "clean" targets follow GNU conventions ################################################ clean: -rm -f *~ *.o core \ $(DBG_NONSHARED_LIB_FILE) $(DBG_SHARED_LIB_FILE) # like "clean", but also delete files created by "configure" distclean: clean -rm -f Makefile config.status config.cache config.log Dbg_cf.h # like "clean", but doesn't delete test utilities or massaged scripts # because most people don't have to worry about them mostlyclean: -rm -f *~ *.o core \ $(DBG_NONSHARED_LIB_FILE) $(DBG_SHARED_LIB_FILE) # delete everything from current directory that can be reconstructed # except for configure realclean: distclean tclIndex: Dbg_lib.tcl expect -c "auto_mkindex . *.tcl;exit" LINTFLAGS = -h -q -x lint: lint $(LINTFLAGS) $(CPPFLAGS) $(CFILES) $(TCLLINTLIB) | tee debug.lint ################################## # Targets for development at NIST ################################## nist: configure --verbose --prefix=/depot/tcl --exec-prefix=/depot/tcl/arch # report globals that shouldn't be public but are bad_globals: nm $(DBG_NONSHARED_LIB_FILE) | egrep -v " [a-zU] | _Dbg" # after copying source directory, restablish all links symlink: rm -f aclocal.m4 ln -s ../expect/aclocal.m4 ###################################### # Targets for pushing out releases ###################################### FTPDIR = /proj/itl/www/div826/subject/expect/tcl-debug ftp: tcl-debug-$(SHORT_VERSION).tar.Z tcl-debug-$(SHORT_VERSION).tar.gz cp tcl-debug-$(SHORT_VERSION).tar.Z $(FTPDIR)/tcl-debug.tar.Z cp tcl-debug-$(SHORT_VERSION).tar.gz $(FTPDIR)/tcl-debug.tar.gz cp HISTORY $(FTPDIR) cp README $(FTPDIR)/README.distribution rm tcl-debug-$(SHORT_VERSION).tar* ls -l $(FTPDIR)/tcl-debug.tar* # make an alpha relase and install it on ftp server alpha: tcl-debug-$(SHORT_VERSION).tar.Z tcl-debug-$(SHORT_VERSION).tar.gz cp tcl-debug-$(SHORT_VERSION).tar.Z $(FTPDIR)/tcl-debug-alpha.tar.Z cp tcl-debug-$(SHORT_VERSION).tar.gz $(FTPDIR)/tcl-debug-alpha.tar.gz rm tcl-debug-$(SHORT_VERSION).tar* ls -l $(FTPDIR)/tcl-debug-alpha.tar* tcl-debug-$(SHORT_VERSION).tar: rm -f ../tcl-debug-$(SHORT_VERSION) ln -s `pwd` ../tcl-debug-$(SHORT_VERSION) rm -f ../pubfile ln pubfile .. cd ..;tar cvfh $@ `pubfile tcl-debug-$(SHORT_VERSION)` mv ../$@ . tcl-debug-$(SHORT_VERSION).tar.Z: tcl-debug-$(SHORT_VERSION).tar compress -fc tcl-debug-$(SHORT_VERSION).tar > $@ tcl-debug-$(SHORT_VERSION).tar.gz: tcl-debug-$(SHORT_VERSION).tar gzip -fc tcl-debug-$(SHORT_VERSION).tar > $@ Dbg.o: $(srcdir)/Dbg.c $(srcdir)/Dbg.h |
Added unix/Dbg_cf.h.in.
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* This file is only to be included by the Debugger itself. */ /* Applications should only include Dbg.h. */ /* * Check for headers */ #ifndef __NIST_DBG_CF_H__ #define __NIST_DBG_CF_H__ #undef NO_STDLIB_H /* Tcl requires this name */ /* * Check for functions */ #undef HAVE_STRCHR #ifndef HAVE_STRCHR #define strchr(s,c) index(s,c) #endif /* HAVE_STRCHR */ #endif /* __NIST_DBG_CF_H__ */ |
Added unix/Dbgconfig.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | dnl Process this file with autoconf to produce a configure script. AC_INIT(Dbg.h) DBG_MAJOR_VERSION=5 DBG_MINOR_VERSION=20 DBG_MICRO_VERSION=0 DBG_VERSION=$DBG_MAJOR_VERSION.$DBG_MINOR_VERSION DBG_VERSION_FULL=$DBG_VERSION.$DBG_MICRO_VERSION AC_CONFIG_HEADER(Dbg_cf.h) CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC AC_PROG_CC CY_AC_C_WORKS # this'll use a BSD compatible install or our included install-sh AC_PROG_INSTALL # This is for LynxOS, which needs a flag to force true POSIX when # building. It's weirder than that, cause the flag varies depending # how old the compiler is. So... # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly CY_AC_TCL_LYNX_POSIX # we really only need the header files CY_AC_PATH_TCLH if test x"$no_tcl" = x"true" ; then echo " ERROR: Can't find Tcl directory" echo " See README for information on how to obtain Tcl." echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # Use -g on all systems but Linux where it upsets the dynamic X libraries. AC_MSG_CHECKING([if we are running Linux]) if test "x`(uname) 2>/dev/null`" = xLinux; then AC_MSG_RESULT(yes) linux=1 DBG_CFLAGS= else AC_MSG_RESULT(no) linux=0 DBG_CFLAGS=-g fi # # Look for functions that may be missing # AC_FUNC_CHECK(strchr, AC_DEFINE(HAVE_STRCHR)) # # Look for various header files # AC_HEADER_CHECK(stdlib.h, ,AC_DEFINE(NO_STDLIB_H)) # consume these flags so that user can invoke tcl-debug's configure with # the same command as Tcl's configure AC_ARG_ENABLE(load, [ --disable-load disallow dynamic loading], [disable_dl=yes], [disable_dl=no]) AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available], [enable_gcc=yes], [enable_gcc=no]) DBG_NONSHARED_LIB_FILE=libtcldbg.a AC_MSG_CHECKING([if generating shared or nonshared library]) AC_ARG_ENABLE(shared, [ --enable-shared build libtcldbg as a shared library], [enable_shared=yes], [enable_shared=no]) if test "$enable_shared" = "yes" -a "x${TCL_SHLIB_SUFFIX}" != "x" ; then DBG_SHARED_LIB_FILE=libtcldbg$DBG_VERSION$TCL_SHLIB_SUFFIX DBG_LIB_FILE=$DBG_SHARED_LIB_FILE DBG_LIB_FILES="$DBG_SHARED_LIB_FILE $DBG_NONSHARED_LIB_FILE" AC_MSG_RESULT(both shared and nonshared) else DBG_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library" DBG_LIB_FILE=$DBG_NONSHARED_LIB_FILE DBG_LIB_FILES="$DBG_NONSHARED_LIB_FILE" AC_MSG_RESULT(nonshared) fi # # Set up makefile substitutions # AC_SUBST(DBG_MAJOR_VERSION) AC_SUBST(DBG_MINOR_VERSION) AC_SUBST(DBG_MICRO_VERSION) AC_SUBST(DBG_VERSION_FULL) AC_SUBST(DBG_VERSION) AC_SUBST(CC) AC_SUBST(DBG_SHARED_LIB_FILE) AC_SUBST(DBG_NONSHARED_LIB_FILE) AC_SUBST(DBG_LIB_FILE) AC_SUBST(DBG_LIB_FILES) AC_SUBST(DBG_CFLAGS) AC_OUTPUT(Makefile) |
Added unix/Makefile.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 | # # Makefile for Expect # VERSION = \"@EXP_VERSION_FULL@\" SHORT_VERSION = @EXP_VERSION@ # Requires at least Tcl 7.5 # Known to work with up to Tcl 7.5 # While Tk is optional, if you do use Tk, it must be at least Tk 4.1 # Known to work with up to Tk 4.1 srcdir = @srcdir@ VPATH = @srcdir@ SUBDIRS = @subdirs@ ###################################################################### # The following lines are things you may want to change ###################################################################### # Tcl include files. (If you haven't installed Tcl yet, read the README file). # This must point to the directory that contains ALL of Tcl's include # files, not just the public ones. TCLHDIR = @TCLHDIR@ # Tcl library uninstalled. Should be something like -ltcl or ../tcl/libtcl.a TCLLIB = @TCL_BUILD_LIB_SPEC@ # Tcl library installed. Should be something like -ltcl or ../tcl/libtcl.a TCLLIB_INSTALLED = @TCL_LIB_SPEC@ # The following definitions are only nec. if you want to use Tk with Expect. # Tk include files TKHDIR = @TKHDIR@ # Tk library TKLIB = @TK_BUILD_LIB_SPEC@ TKLIB_INSTALLED = @TK_LIB_SPEC@ # X11 include files and other flags to compiler X11_CFLAGS = @TK_XINCLUDES@ # X library X11_LD_FLAGS = X11_PROGS = @X_PROGS@ # X11_PROGS_INSTALLED should really be a separate symbol generated by configure but we're # hitting configure's limit on substitutions, so be crude and use one less symbol. X11_PROGS_INSTALLED = @X_PROGS@_installed # Flags to pass to both cc and ld # You should be able to leave this just the way it is. However, here are some # note if you run into problems: # # Avoid -O (optimize) unless you are convinced your optimizer is flawless # (hint: not a chance). I have heard many reports of -O causing Expect to # misbehave. # I encourage you to use -g (debugging). While it is unlikely you will # encounter an internal error in Expect, should this happen, I may just need # the -g information and then you will need to recompile Expect. As an aside, # Expect is not a space or time pig, so this won't affect the performance of # your Expect scripts. # Note: On Linux systems which only have dynamic X libraries, the -g prevents # the linker from using them. So do not use -g on such systems. CFLAGS = @CFLAGS@ #XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ @EXP_SHLIB_CFLAGS@ XCFLAGS = @CFLAGS@ @EXP_CFLAGS@ # From now on, CFLAGS is never used. Instead, use XCFLAGS. This is done so # that we can provide a public interface for CFLAGS thereby allowing users # to add to it on the Make command-line and still get the rest of the flags # computed by configure. Do this at your own risk - it obvious goes against # the idea of configure's interface, however this is established tradition # at some sites (e.g., Cygnus)! # Flags to pass only to linker (after .o files but before libraries) LDFLAGS = @EXP_LDFLAGS@ # Which C compiler to use. For simplicity, we inherit the same definition # used when Tcl was compiled. Changing this definition here can screw up # deductions that the configure script made on the assumption that you were # using a different compiler. CC = @CC@ # By default, "make install" will install the appropriate files in # /usr/local/bin, /usr/local/lib, /usr/local/man, etc. By changing this # variable, you can specify an installation prefix other than /usr/local. # You may find it preferable to call configure with the --prefix option # to control this information. This is especially handy if you are # installing Expect several times (perhaps on a number of machines or # in different places). Then you don't have to hand-edit this file. # See the INSTALL file for more information. (Analogous information # applies to the next variable as well.) prefix = @prefix@ # You can specify a separate installation prefix for architecture-specific # files such as binaries and libraries. exec_prefix = @exec_prefix@ # The following Expect scripts are not necessary to have installed as # commands, but are very useful. Edit out what you don't want installed. # The INSTALL file describes these and others in more detail. # Some Make's screw up if you delete all of them because SCRIPTS is a # target. If this is a problem, just comment out the SCRIPTS target itself. SCRIPTS = timed-run timed-read ftp-rfc autopasswd lpunlock weather \ passmass rftp kibitz rlogin-cwd xpstat tkpasswd dislocate xkibitz \ tknewsbiff unbuffer mkpasswd cryptdir decryptdir autoexpect # A couple of the scripts have man pages of their own. # You can delete these too if you don't want'em. SCRIPTS_MANPAGES = kibitz dislocate xkibitz tknewsbiff unbuffer mkpasswd \ passmass cryptdir decryptdir autoexpect # Short directory path where expect binary can be found to support #! hack. # This directory path can be the same as the directory in which the binary # actually sits except when the path is so long that the #! mechanism breaks # (usually at 32 characters). # The solution is to create a directory with a very short name, which consists # only of symbolic links back to the true binaries. Subtracting two for "#!" # and a couple more for arguments (typically " -f" or " --") gives you 27 # characters. Pathnames over this length won't be able to use the #! magic. # For more info on this, see the execve(2) man page. SHORT_BINDIR = $(exec_prefix)/bin # If you have ranlib but it should be avoided, change this from "ranlib" # to something innocuous like "echo". Known systems with this problem: # older SCO boxes. RANLIB = @TCL_RANLIB@ # Change EVENT_ABLE to "noevent" if your system is: # old SCO because poll doesn't exist and select is broken on ptys # 3b2 SVR3 because select doesn't exist and poll is broken on ptys # If you do use "noevent": # 1) you must also edit expect_cf.h and change # "#undef SIMPLE_EVENT" to "#define SIMPLE_EVENT", # 2) you cannot use any event facilities such as "after" or anything in Tk. # 3) you cannot expect or interact with two or more processes simultaneously # EVENT_ABLE = @EVENT_ABLE@ # Change EVENT_TYPE to poll if your system is: # NCR SVR4 (1.03.01) where select is broken on ttys # StarServer (SVR3 and SVR4.0) where select is broken on ttys # # You will need to change EVENT_TYPE to select if your system is: # Pyramid OSx in the att universe where poll is broken (see LIBS below) # EVENT_TYPE = @EVENT_TYPE@ # Define default parameters for ptys. This is used when 1) running in the # background, 2) user has not defined the variable STTY_INIT to initialize # ptys, and 3) the pty-driver's defaults suck. # # If your system doesn't understand "sane", try "cooked". Apollo systems # need nothing at all and should delete this line. Systems using 8-bit # character sets may need to disable parity. # Systems that define sane to use @ as line kill and # as erase should # use something like "sane kill erase ". STTY = -DDFLT_STTY="\"@DEFAULT_STTY_ARGS@\"" ###################################################################### # End of things you may want to change # # Do not change anything after this ###################################################################### bindir = @bindir@ bindir_arch_indep = $(prefix)/bin libdir = @libdir@ libdir_arch_indep = $(prefix)/lib mandir = @mandir@ man1dir = $(mandir)/man1 man3dir = $(mandir)/man3 infodir = @infodir@ includedir = @includedir@ # Expect's utility script directories - arch-independent and arch-non- # independent. These correspond to the variables "exp_library" and # "exp_exec_library". SCRIPTDIR = $(libdir_arch_indep)/expect$(SHORT_VERSION) EXECSCRIPTDIR = $(libdir)/expect$(SHORT_VERSION) SHELL = @EXP_CONFIG_SHELL@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ AR = ar ARFLAGS = cr LOCAL_EXPECT=LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./expect # These definitions are used by the "subdirs_do" target to pass # the compile flags down recursively. FLAGS_TO_PASS = \ "CC=$(CC)" \ "CFLAGS=$(XCFLAGS)" \ "CFLAGS_INT=$(CFLAGS_INT)" \ "HDEFS=$(HDEFS)" \ "INSTALL=$(INSTALL)" \ "INSTALL_DATA=$(INSTALL_DATA)" \ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ "LDFLAGS=$(LDFLAGS)" \ "RUNTEST=$(RUNTEST)" \ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ "SHLIB_CFLAGS=$(@EXP_SHLIB_CFLAGS@)" \ "prefix=$(prefix)" \ "exec_prefix=$(exec_prefix)" # # Following defines are for DejaGnu # # These let the DejaGnu test suite run when DejaGnu isn't # installed yet, so run it from the srcdir and objdir. EXPECT = ` \ if [ -f $${rootme}/expect ] ; then \ echo $${rootme}/expect ; \ else echo expect ; fi` RUNTESTFLAGS = RUNTEST = ` \ if [ -f ${srcdir}/../dejagnu/runtest ] ; then \ echo ${srcdir}/../dejagnu/runtest ; \ else echo runtest ; fi` PTY_TYPE = @PTY_TYPE@ PTY = pty_$(PTY_TYPE) CFILES = exp_command.c expect.c $(PTY).c \ exp_inter.c exp_regexp.c exp_tty.c \ exp_log.c exp_main_sub.c exp_pty.c \ exp_printify.c exp_trap.c exp_strf.c \ exp_console.c exp_glob.c exp_win.c Dbg.c exp_clib.c \ exp_closetcl.c exp_memmove.c exp_tty_comm.c \ exp_$(EVENT_TYPE).c exp_$(EVENT_ABLE).c OFILES = exp_command.o expect.o $(PTY).o exp_inter.o exp_regexp.o exp_tty.o \ exp_log.o exp_main_sub.o exp_pty.o exp_printify.o exp_trap.o \ exp_console.o exp_strf.o exp_glob.o exp_win.o Dbg.o exp_clib.o \ exp_closetcl.o exp_memmove.o exp_tty_comm.o \ exp_$(EVENT_TYPE).o exp_$(EVENT_ABLE).o SHARED_OFILES = shared/exp_command.o shared/expect.o shared/$(PTY).o \ shared/exp_inter.o shared/exp_regexp.o shared/exp_tty.o \ shared/exp_log.o shared/exp_main_sub.o shared/exp_pty.o \ shared/exp_printify.o shared/exp_trap.o \ shared/exp_console.o shared/exp_strf.o shared/exp_glob.o \ shared/exp_win.o shared/Dbg.o shared/exp_clib.o \ shared/exp_closetcl.o shared/exp_memmove.o shared/exp_tty_comm.o \ shared/exp_$(EVENT_TYPE).o shared/exp_$(EVENT_ABLE).o # Expect libraries (both .a and shared) EXP_LIB_FILES = @EXP_LIB_FILES@ # default Expect library (shared if possible, otherwise static) EXP_LIB_FILE = @EXP_LIB_FILE@ # Expect object library (.a) EXP_NONSHARED_LIB_FILE = @EXP_NONSHARED_LIB_FILE@ # Expect object library (shared, if possible) EXP_SHARED_LIB_FILE = @EXP_SHARED_LIB_FILE@ # expect must be setuid on crays in order to open ptys (and accordingly, # you must run this Makefile as root). # See the FAQ for more info on why this is necessary on Crays. SETUID = @SETUID@ # SETUID = chmod u+s # allow us to handle null list gracefully, "end_of_list" should not exist SCRIPT_LIST = $(SCRIPTS) end_of_list SCRIPT_MANPAGE_LIST = $(SCRIPTS_MANPAGES) end_of_list # Both TKHDIR and TCLHDIR include "-I" # flags to pass only to the C compiler (not to ld) # because STTY can include whitespace and quotes, pass STTY separately CPPFLAGS = -I. -I$(srcdir) $(TCLHDIR) $(TKHDIR) $(X11_CFLAGS) \ -DEXP_VERSION=$(VERSION) \ -DSCRIPTDIR=\"$(SCRIPTDIR)\" \ -DEXECSCRIPTDIR=\"$(EXECSCRIPTDIR)\" \ -DTCL_DEBUGGER # Flags to pass to cc (i.e. add to the end of the CLDFLAGS line below). # Note that setting one will not set others automatically. Set all that # are relevant. # # NOTE THAT THESE FLAGS ARE NO LONGER SUPPORTED. THE FUNCTIONALLY IS REPLACED # BY THE AUTOMATIC CONFIGURATION CODE. ONLY MESS WITH THE FOLLOWING DEFS IF # YOU ARE POSITIVE THE AUTO CONFIG CODE IS FAILING. # # -DSYSV3 if you are running SVR3 or later. # -DSYSV4 if you are running SVR4. This option does not preclude -DSYSV3. # -DAUX2 if you are running Mac A/UX 2. # -DMIPS_BSD if you are on a Mips machine using the BSD universe. # -D_BSD_SIGNALS if you are on a Silicon Graphics AND want BSD semantics when # using the expect library. Otherwise, you are better off just sticking # with rearming signals. # Flags to pass to ld # You may need to add additional ones to the end of the LIBS line below: # -lc -lBSD If you are using the BSD compatibility library on an HP/UX, # force libc.a to be loaded first. # -lsocket For SCO UNIX 3.2.2 (this should now be done automatically) # -lX11 For Pyramid OSx, poll is broken, so use select from X lib # /usr/ucblib/libucb.a is needed for solaris 2.0 after -lm EXP_AND_TCL_LIBS = $(LDFLAGS) @EXP_AND_TCL_LIBS@ EXP_AND_TK_LIBS = $(LDFLAGS) @EXP_AND_TK_LIBS@ CFLAGS_INT = $(MH_CFLAGS) $(CPPFLAGS) $(XCFLAGS) LIB_INSTALL_DIR = $(libdir) LIB_RUNTIME_DIR = $(libdir) # I don't understand why Tcl splits these up, but it does. LIB_RUNTIME_DIR # can appear as part of the LD_SEARCH_FLAGS inherited by configure. .c.o: $(CC) -c $(CFLAGS_INT) $(STTY) $(HDEFS) $< if [ "x$(EXP_NONSHARED_LIB_FILE)" != "x$(EXP_LIB_FILE)" ] ; then \ if [ ! -d shared ] ; then \ mkdir shared ; \ else true; fi ; \ $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ $(STTY) $(HDEFS) $< -o shared/$@ ; \ fi all: expect $(EXP_LIB_FILES) ${X11_PROGS} @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS) info: dvi: # build expect binary that does not depend on Expect's shared libs expect: exp_main_exp.o $(EXP_NONSHARED_LIB_FILE) $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expect exp_main_exp.o $(EXP_NONSHARED_LIB_FILE) $(TCLLIB) $(EXP_AND_TCL_LIBS) $(SETUID) expect # install Expect library # This is done before the install target because the libraries have to be # in place before the installed expect is built. Actually, only the shared # lib has to be handled this way, but do both here for consistency. install_shared_lib: $(EXP_LIB_FILES) if [ -s $(EXP_NONSHARED_LIB_FILE) ] ; then \ $(INSTALL_DATA) $(EXP_NONSHARED_LIB_FILE) $(libdir)/$(EXP_NONSHARED_LIB_FILE) ; \ $(RANLIB) $(libdir)/$(EXP_NONSHARED_LIB_FILE) ; \ else true; fi if [ -s $(EXP_SHARED_LIB_FILE) ] ; then \ $(INSTALL_PROGRAM) $(EXP_SHARED_LIB_FILE) $(libdir)/$(EXP_SHARED_LIB_FILE) ; \ else true; fi expect_installed: exp_main_exp.o $(EXP_LIB_FILE) install_shared_lib $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect_installed exp_main_exp.o @EXP_LIB_SPEC@ $(TCLLIB_INSTALLED) $(EXP_AND_TCL_LIBS) $(SETUID) expect_installed # Build Expect with TestCenter expect.tc: exp_main_exp.o $(OFILES) proof $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expect.tc $(OFILES) exp_main_exp.o $(TCLLIB) $(EXP_AND_TCL_LIBS) $(SETUID) expect.tc # Build an executable with both Expect and Tk. # Yes, I know that the link line can have libraries repeated. This is a # consequence of Tcl's configure combining the Tcl and X dependent libs # together. I could fix it by testing all the libraries (again, in Expect's # configure) separately for Expectk, but as far as I know, it doesn't hurt # anything here, so I'm not worrying about it. expectk: exp_main_tk.o $(EXP_NONSHARED_LIB_FILE) $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk exp_main_tk.o $(EXP_NONSHARED_LIB_FILE) $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk expectk_installed: exp_main_tk.o $(EXP_LIB_FILE) $(CC) $(XCFLAGS) @EXP_SHLIB_CFLAGS@ @TCL_LD_FLAGS@ -o expectk_installed exp_main_tk.o @EXP_LIB_SPEC@ $(TKLIB_INSTALLED) $(TCLLIB_INSTALLED) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk_installed # Build Expectk with TestCenter expectk.tc: exp_main_tk.o $(OFILES) proof $(CC) $(XCFLAGS) @TCL_LD_FLAGS@ -o expectk.tc $(OFILES) exp_main_tk.o $(TKLIB) $(TCLLIB) $(X11_LD_FLAGS) $(EXP_AND_TK_LIBS) $(SETUID) expectk.tc $(EXP_NONSHARED_LIB_FILE): $(OFILES) -rm -f $(EXP_NONSHARED_LIB_FILE) $(AR) $(ARFLAGS) $(EXP_NONSHARED_LIB_FILE) $(OFILES) -$(RANLIB) $(EXP_NONSHARED_LIB_FILE) # the dependency should really be SHARED_OFILES rather than OFILES # but there's no way to write a rule that says shared/XYZ.o should # depend on XYZ.c in a different directory (except by writing the # rule out for each file, sigh). $(EXP_SHARED_LIB_FILE): $(OFILES) -rm -f $(EXP_SHARED_LIB_FILE) @TCL_SHLIB_LD@ -o $(EXP_SHARED_LIB_FILE) $(SHARED_OFILES) @EXP_SHLIB_LD_LIBS@ # Delete all the installed files that the `install' target creates # (but not the noninstalled files such as `make all' creates) uninstall: -rm -f $(bindir)/expectk \ $(man1dir)/expect.1 \ $(man1dir)/expectk.1 \ $(libdir)/$(EXP_SHARED_LIB_FILE) \ $(libdir)/$(EXP_NONSHARED_LIB_FILE) \ $(man3dir)/libexpect.3 \ $(includedir)/expect_cf.h \ $(includedir)/expect.h \ $(includedir)/expect_tcl.h \ $(includedir)/expect_comm.h \ $(EXECSCRIPTDIR)/cat-buffers \ $(SCRIPTDIR)/pkgIndex.tcl # debugger is not removed, since other things could depend on it # remove standalone scripts and man pages -for i in $(SCRIPT_LIST) ; do \ rm -f $(bindir_arch_indep)/$$i ; \ done -for i in $(SCRIPT_MANPAGE_LIST) ; do \ rm -f $(man1dir)/$$i.1 ; \ done .PHONY: install-info install info install-info: install: expect expect_installed ${X11_PROGS_INSTALLED} $(SCRIPTS) pkgIndex.tcl ${srcdir}/mkinstalldirs $(man1dir) $(man3dir) $(bindir) $(libdir) $(includedir) # install Expect $(INSTALL_PROGRAM) expect_installed $(bindir)/expect # install Expectk (and man page) if present -if [ -s expectk_installed ] ; then \ $(INSTALL_PROGRAM) expectk_installed $(bindir)/expectk ; \ $(INSTALL_DATA) $(srcdir)/expectk.man $(man1dir)/expectk.1 ; \ else true; fi # install Expect man page $(INSTALL_DATA) $(srcdir)/expect.man $(man1dir)/expect.1 # install man page for Expect and Expectk libraries $(INSTALL_DATA) $(srcdir)/libexpect.man $(man3dir)/libexpect.3 # install Expect's public include files # $(INSTALL_DATA) expect_cf.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect_tcl.h $(includedir) $(INSTALL_DATA) $(srcdir)/expect_comm.h $(includedir) # install Debugger's public include file (just in case it's not there) $(INSTALL_DATA) $(srcdir)/Dbg.h $(includedir) # some people don't install Tcl, sigh TCL_LIBRARY=`echo @TCLHDIR@ | sed -e 's/-I//' -e 's/generic//'`/library ; \ export TCL_LIBRARY ; \ if $(LOCAL_EXPECT) $(srcdir)/fixcat ; then \ $(INSTALL_DATA) $(srcdir)/fixcat $(EXECSCRIPTDIR)/cat-buffers ; \ else true; fi # install standalone scripts and their man pages, if requested ${srcdir}/mkinstalldirs $(bindir_arch_indep) $(man1dir) $(SCRIPTDIR) $(EXECSCRIPTDIR) -for i in $(SCRIPT_LIST) ; do \ if [ -f $$i ] ; then \ $(INSTALL_PROGRAM) $$i $(bindir_arch_indep)/$$i ; \ rm -f $$i ; \ else true; fi ; \ done -for i in $(SCRIPT_MANPAGE_LIST) ; do \ if [ -f $(srcdir)/example/$$i.man ] ; then \ $(INSTALL_DATA) $(srcdir)/example/$$i.man $(man1dir)/$$i.1 ; \ else true; fi ; \ done $(INSTALL_DATA) pkgIndex.tcl $(SCRIPTDIR) $(SCRIPT_LIST): TCL_LIBRARY=`echo @TCLHDIR@ | sed -e 's/-I//' -e 's/generic//'`/library ; \ export TCL_LIBRARY ; \ $(LOCAL_EXPECT) $(srcdir)/fixline1 $(SHORT_BINDIR) < $(srcdir)/example/$@ > $@ ################################### # Targets for Makefile and configure ################################### Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) config.status @echo "Rebuilding the Makefile..." $(SHELL) ./config.status # Let "make -f Makefile.in" produce a configure file configure: $(srcdir)/configure.in $(srcdir)/Makefile.in \ $(srcdir)/expect_cf.h.in $(srcdir)/aclocal.m4 @echo "Rebuilding configure..." if [ x"${srcdir}" = x"@srcdir@" ] ; then \ srcdir=. ; export srcdir ; \ else true ; fi ; \ (cd $${srcdir}; autoconf) config.status: $(srcdir)/configure @echo "Rebuilding config.status..." $(SHELL) ./config.status --recheck check: @if [ -f testsuite/Makefile ]; then \ cd testsuite && $(MAKE) $(FLAGS_TO_PASS) check; \ else true; fi # Original Dbgconfig.in comes from the NIST Tcl debugger distribution. Dbgconfigure: $(srcdir)/Dbgconfig.in $(srcdir)/Makefile.in \ $(srcdir)/Dbg_cf.h.in $(srcdir)/aclocal.m4 @echo "Rebuilding Dbgconfigure..." @if [ x"${srcdir}" = x"@srcdir@" ] ; then \ srcdir=. ; export srcdir ; \ else true ; fi ; \ (cd $${srcdir}; rm -fr Dbgconfigure ; \ autoconf Dbgconfig.in > Dbgconfigure ; \ chmod a+x Dbgconfigure) # updating of pkgIndex.tcl.in has not yet been totally automated # Instructions: # shell> tclsh7.5 # % pkg_mkIndex . libexpect$(version...).so # % exit # shell> cp pkgIndex.tcl pkgIndex.in # Edit pkgIndex.in and: # - insert \r's because configure cannot handle too long lines. # replace filename and version number by macros. # - change "$dir" to "@exec_prefix/dir@". This kludges around a design # "feature". The problem is that Tcl insists libraries should be in the # same directory as the pkgIndex.tcl file while the natural thing to do # would be to split them up and put the .tcl file in the arch-indepent # app-specific scripts dir and the lib in the arch-dependent common dir. # Sigh. # Ideally, a single rule could have configure generate the file from its # .in template. Alas, the .in file name is then too long for some systems, # so we go through a intermediate filename, to avoid this problem. pkgIndex.tcl: pkgIndex mv pkgIndex pkgIndex.tcl pkgIndex: $(srcdir)/pkgIndex.in $(SHELL) ./config.status ################################################ # Various "clean" targets follow GNU conventions ################################################ # delete all files from current directory that are created by "make" clean: -rm -rf *~ *.o shared core \ expect expect_installed expectk expectk_installed \ dumb exho devtty \ $(EXP_NONSHARED_LIB_FILE) $(EXP_SHARED_LIB_FILE) \ $(SCRIPT_LIST) @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS) # like "clean", but also delete files created by "configure" distclean: clean @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS) -rm -f Makefile config.status config.cache config.log expect_cf.h -rm -f Dbg_cf.h # like "clean", but doesn't delete test utilities or massaged scripts # because most people don't have to worry about them mostlyclean: -rm -rf *~ *.o shared core \ expect expect_installed expectk expectk_installed \ $(EXP_NONSHARED_LIB_FILE) $(EXP_SHARED_LIB_FILE) @$(MAKE) subdir_do DO=$@ $(FLAGS_TO_PASS) # delete everything from current directory that can be reconstructed # except for configure realclean: distclean ################################## # Targets for development at NIST ################################## # the unsets allow calling this via Makefile.in nist: unset CC ; \ configure --verbose --prefix=/depot/tcl --exec-prefix=/depot/tcl/arch epg: unset CC ; \ echo configure --verbose --prefix=/users/libes --exec-prefix=/users/libes/arch mink: unset CC ; \ configure --verbose --prefix=/usr/tmp --exec-prefix=/usr/tmp/arch cam: unset CC ; \ configure --verbose --prefix=/tmp_mnt/home/fs1a/libes \ --exec-prefix=/tmp_mnt/home/fs1a/libes/arch granta: unset CC ; \ configure --verbose --prefix=/home/nist/libes/cray --exec-prefix=/home/nist/libes/cray/arch hudson: unset CC ; \ configure --verbose --prefix=/granta/home/nist/libes/ibm --exec-prefix=/granta /home/nist/libes/ibm/arch # report globals that shouldn't be public but are bad_globals: nm $(EXP_NONSHARED_LIB_FILE) | egrep -v " [a-zU] | _exp| _Exp| _Dbg" LINTFLAGS = -h -q -x lint: lint $(LINTFLAGS) $(CPPFLAGS) $(STTY) $(CFILES) exp_main_exp.c $(TCLLINTLIB) | tee expect.lint # after copying source directory, restablish all links symlink: rm -rf Dbg* e ek testsuite/aclocal.m4 ln -s ../tcl-debug/configure.in Dbgconfig.in ln -s ../tcl-debug/Makefile.in DbgMkfl.in ln -s ../tcl-debug/Dbg_cf.h.in ln -s ../tcl-debug/Dbg.h ln -s ../tcl-debug/Dbg.c ln -s ../aclocal.m4 testsuite ######################################### # Targets for building with CodeCenter ######################################### GCCROOT = /depot/gnu/arch/lib/gcc-lib/sparc-sun-sunos4.1/2.3.3 GCCLIB = $(GCCROOT)/libgcc.a GCCINC = -I$(GCCROOT)/include # following only on Sparcs SABERDEFINE = -D__sparc__ # Following target builds expect under CodeCenter. # If using ObjectCenter, before loading, type: setopt primary_language C exp: $(CFILES) exp_main_exp.c #load $(CPPFLAGS) $(STTY) $(CFILES) exp_main_exp.c $(TCLLIB) $(GCCLIB) $(EXP_AND_TCL_LIBS) # Following target builds expectk under CodeCenter. Notes: # Because of explicit #includes of <X11/...> in tk.h, you need to create # a symlink from your X11 include directory to this directory tk: $(CFILES) exp_main_tk.c #load $(CPPFLAGS) $(STTY) $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS) # Follow definitions are for building expect and expectk under ObjectCenter oexp: $(CFILES) exp_main_exp.c #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_exp.c $(TCLLIB) $(GCCLIB) $(EXP_AND_TCL_LIBS) otk: $(CFILES) exp_main_tk.c #load $(CPPFLAGS) $(STTY) -C $(CFILES) exp_main_tk.c $(TKLIB) $(TCLLIB) $(EXP_AND_TK_LIBS) ###################################### # Targets for pushing out releases ###################################### # until we are completely switched over, keep updating old ftp site too OLDFTPDIR = /proj/elib/online/pub/expect FTPDIR = /proj/itl/www/div826/subject/expect # make a private tar file for myself tar: expect-$(SHORT_VERSION).tar mv expect-$(SHORT_VERSION).tar expect.tar # make a release and install it on ftp server ftp: expect-$(SHORT_VERSION).tar.Z expect-$(SHORT_VERSION).tar.gz cp expect-$(SHORT_VERSION).tar.Z $(FTPDIR)/expect.tar.Z cp expect-$(SHORT_VERSION).tar.gz $(FTPDIR)/expect.tar.gz cp HISTORY $(FTPDIR) cp README $(FTPDIR)/README.distribution cp example/README $(FTPDIR)/example cp `pubfile example` $(FTPDIR)/example ls -l $(FTPDIR)/expect.tar* # update old ftp site too cp expect-$(SHORT_VERSION).tar.Z $(OLDFTPDIR)/expect.tar.Z cp expect-$(SHORT_VERSION).tar.gz $(OLDFTPDIR)/expect.tar.gz cp HISTORY $(OLDFTPDIR) cp README $(OLDFTPDIR)/README.distribution cp example/README $(OLDFTPDIR)/example cp `pubfile example` $(OLDFTPDIR)/example ls -l $(OLDFTPDIR)/expect.tar* # delete temp files rm expect-$(SHORT_VERSION).tar* # make an alpha relase and install it on ftp server alpha: expect-$(SHORT_VERSION).tar.Z expect-$(SHORT_VERSION).tar.gz cp expect-$(SHORT_VERSION).tar.Z $(FTPDIR)/alpha.tar.Z cp expect-$(SHORT_VERSION).tar.gz $(FTPDIR)/alpha.tar.gz cp HISTORY $(FTPDIR) rm expect-$(SHORT_VERSION).tar* ls -l $(FTPDIR)/alpha.tar* # make a beta relase and install it on ftp server beta: expect-$(SHORT_VERSION).tar.Z expect-$(SHORT_VERSION).tar.gz rm -rf $(FTPDIR)/alpha.tar* cp expect-$(SHORT_VERSION).tar.Z $(FTPDIR)/beta.tar.Z cp expect-$(SHORT_VERSION).tar.gz $(FTPDIR)/beta.tar.gz cp HISTORY $(FTPDIR) rm expect-$(SHORT_VERSION).tar* ls -l $(FTPDIR)/beta.tar* expect-$(SHORT_VERSION).tar: configure rm -f ../expect-$(SHORT_VERSION) ln -s `pwd` ../expect-$(SHORT_VERSION) rm -f ../pubfile ln pubfile .. cd ..;tar cvfh $@ `pubfile expect-$(SHORT_VERSION)` mv ../$@ . expect-$(SHORT_VERSION).tar.Z: expect-$(SHORT_VERSION).tar compress -fc expect-$(SHORT_VERSION).tar > $@ expect-$(SHORT_VERSION).tar.gz: expect-$(SHORT_VERSION).tar gzip -fc expect-$(SHORT_VERSION).tar > $@ test: expect rm -f .tmp echo "set objdir" `pwd` > .tmp if [ "$(srcdir)" = "." ] ; then \ echo "set srcdir" `pwd` >> .tmp ; \ else echo "set srcdir" $(srcdir) >> .tmp ; fi echo "cd \$${srcdir}/tests" >> .tmp echo "source all" >> .tmp rootme=`pwd`; export rootme; \ srcdir=${srcdir} ; export srcdir ; \ if [ -f ./expect ] ; then \ TCL_LIBRARY=`echo @TCLHDIR@ | sed -e 's/-I//' -e 's/generic//'`/library ; \ export TCL_LIBRARY ; fi ; \ $(LOCAL_EXPECT) -f .tmp rm -f .tmp ########################### # Targets for producing FAQ and homepage ########################### #WEBDIR = /proj/elib/online/pub/expect WEBDIR = /proj/itl/www/div826/subject/expect # create the FAQ in html form FAQ.html: FAQ.src FAQ.tcl FAQ.src html > FAQ.html # create the FAQ in text form FAQ: FAQ.src FAQ.tcl FAQ.src text > FAQ # generate Expect home page homepage.html: homepage.src homepage.tcl homepage.src > homepage.html # install various html docs on our web server install-html: FAQ.html homepage.html cp homepage.html $(WEBDIR)/index.html # cp FAQ.html $(WEBDIR) # cp FAQ.src $(WEBDIR) # cp FAQ.tcl $(WEBDIR) # add recursive support to the build process. subdir_do: force @for i in $(SUBDIRS); do \ echo "Making $(DO) in $${i}..." ; \ if [ -d ./$$i ] ; then \ if (rootme=`pwd`/ ; export rootme ; \ rootsrc=`cd $(srcdir); pwd`/ ; export rootsrc ; \ cd ./$$i; \ $(MAKE) $(FLAGS_TO_PASS) $(DO)) ; then true ; \ else exit 1 ; fi ; \ else true ; fi ; \ done force: ## dependencies will be put after this line... ## Dbg.o: $(srcdir)/Dbg.c Dbg.h exp_$(EVENT_ABLE).o: $(srcdir)/exp_$(EVENT_ABLE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_$(EVENT_TYPE).o: $(srcdir)/exp_$(EVENT_TYPE).c expect_cf.h expect.h \ exp_command.h exp_event.h exp_command.o: $(srcdir)/exp_command.c expect_cf.h exp_tty.h \ exp_rename.h expect.h exp_command.h \ exp_log.h exp_printify.h exp_event.h exp_pty.h exp_inter.o: $(srcdir)/exp_inter.c expect_cf.h \ exp_tty_in.h exp_tty.h exp_rename.h expect.h exp_command.h \ exp_log.h exp_printify.h exp_regexp.h exp_tstamp.h exp_log.o: $(srcdir)/exp_log.c expect_cf.h expect.h \ exp_rename.h exp_log.h exp_printify.h exp_main_exp.o: $(srcdir)/exp_main_exp.c expect_cf.h \ expect.h exp_rename.h exp_command.h exp_log.h exp_printify.h exp_main_sub.o: $(srcdir)/exp_main_sub.c expect_cf.h \ exp_rename.h \ expect.h exp_command.h exp_tty_in.h exp_tty.h exp_log.h \ exp_printify.h exp_event.h exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h Dbg.h $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $< shared/exp_main_tk.o: $(srcdir)/exp_main_tk.c expect_cf.h Dbg.h $(CC) -c @TK_DEFS@ $(CFLAGS_INT) $(HDEFS) $< exp_noevent.o: $(srcdir)/exp_noevent.c expect_cf.h exp_prog.h exp_command.h \ exp_event.h exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \ exp_command.h exp_event.h $(CC) -c $(CFLAGS_INT) @TCL_DEFS@ $(HDEFS) $< shared/exp_poll.o: $(srcdir)/exp_poll.c expect_cf.h expect.h \ exp_command.h exp_event.h $(CC) -c $(CFLAGS_INT) @EXP_SHLIB_CFLAGS@ @TCL_DEFS@ $(HDEFS) $< -o shared/$@ exp_printify.o: $(srcdir)/exp_printify.c expect_cf.h exp_pty.o: $(srcdir)/exp_pty.c expect_cf.h exp_rename.h exp_pty.h exp_regexp.o: $(srcdir)/exp_regexp.c expect_cf.h \ expect.h exp_regexp.h exp_select.o: $(srcdir)/exp_select.c expect_cf.h \ expect.h exp_command.h exp_event.h exp_simple.o: $(srcdir)/exp_simple.c expect_cf.h \ expect.h exp_command.h exp_event.h exp_strf.o: $(srcdir)/exp_strf.c exp_trap.o: $(srcdir)/exp_trap.c expect_cf.h expect.h \ exp_command.h exp_log.h exp_printify.h exp_tty.o: $(srcdir)/exp_tty.c expect_cf.h \ expect.h exp_rename.h exp_tty_in.h exp_tty.h exp_log.h \ exp_printify.h exp_command.h exp_win.o: $(srcdir)/exp_win.c exp_win.h expect.o: $(srcdir)/expect.c expect_cf.h \ exp_rename.h expect.h exp_command.h \ exp_log.h exp_printify.h exp_event.h exp_tty.h exp_tstamp.h lib_exp.o: $(srcdir)/lib_exp.c expect_cf.h exp_rename.h expect.h \ exp_printify.h pty_sgttyb.o: $(srcdir)/pty_sgttyb.c expect_cf.h exp_rename.h exp_tty_in.h \ exp_tty.h exp_pty.h pty_termios.o: $(srcdir)/pty_termios.c expect_cf.h exp_win.h \ exp_tty_in.h exp_tty.h exp_rename.h exp_pty.h pty_unicos.o: $(srcdir)/pty_unicos.c expect_cf.h exp_rename.h |
Added unix/aclocal.m4.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | dnl written by Rob Savoye <[email protected]> for Cygnus Support dnl major rewriting for Tcl 7.5 by Don Libes <[email protected]> dnl CY_AC_PATH_TCLCONFIG and CY_AC_LOAD_TCLCONFIG should be invoked dnl (in that order) before any other TCL macros. Similarly for TK. dnl CYGNUS LOCAL: This gets the right posix flag for gcc AC_DEFUN(CY_AC_TCL_LYNX_POSIX, [AC_REQUIRE([AC_PROG_CC])AC_REQUIRE([AC_PROG_CPP]) AC_MSG_CHECKING([if running LynxOS]) AC_CACHE_VAL(ac_cv_os_lynx, [AC_EGREP_CPP(yes, [/* * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__" */ #if defined(__Lynx__) || defined(Lynx) yes #endif ], ac_cv_os_lynx=yes, ac_cv_os_lynx=no)]) # if test "$ac_cv_os_lynx" = "yes" ; then AC_MSG_RESULT(yes) AC_DEFINE(LYNX) AC_MSG_CHECKING([whether -mposix or -X is available]) AC_CACHE_VAL(ac_cv_c_posix_flag, [AC_TRY_COMPILE(,[ /* * This flag varies depending on how old the compiler is. * -X is for the old "cc" and "gcc" (based on 1.42). * -mposix is for the new gcc (at least 2.5.8). */ #if defined(__GNUC__) && __GNUC__ >= 2 choke me #endif ], ac_cv_c_posix_flag=" -mposix", ac_cv_c_posix_flag=" -X")]) CC="$CC $ac_cv_c_posix_flag" AC_MSG_RESULT($ac_cv_c_posix_flag) else AC_MSG_RESULT(no) fi ]) # # Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This # makes configure think it's cross compiling. If --target wasn't used, then # we can't configure, so something is wrong. We don't use the cache # here cause if somebody fixes their compiler install, we want this to work. AC_DEFUN(CY_AC_C_WORKS, [# If we cannot compile and link a trivial program, we can't expect anything to work AC_MSG_CHECKING(whether the compiler ($CC) actually works) AC_TRY_COMPILE(, [/* don't need anything here */], c_compiles=yes, c_compiles=no) AC_TRY_LINK(, [/* don't need anything here */], c_links=yes, c_links=no) if test x"${c_compiles}" = x"no" ; then AC_MSG_ERROR(the native compiler is broken and won't compile.) fi if test x"${c_links}" = x"no" ; then AC_MSG_ERROR(the native compiler is broken and won't link.) fi AC_MSG_RESULT(yes) ]) AC_DEFUN(CY_AC_PATH_TCLH, [ # # Ok, lets find the tcl source trees so we can use the headers # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true AC_MSG_CHECKING(for Tcl private headers) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory where tcl private headers are], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh,[ # first check to see if --with-tclinclude was specified if test x"${with_tclinclude}" != x ; then if test -f ${with_tclinclude}/tclInt.h ; then ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)` elif test -f ${with_tclinclude}/generic/tclInt.h ; then ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)` else AC_MSG_ERROR([${with_tclinclude} directory doesn't contain private headers]) fi fi # next check if it came with Tcl configuration file if test x"${ac_cv_c_tclconfig}" != x ; then if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)` fi fi # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` \ ${srcdir}/../../tcl \ `ls -dr ${srcdir}/../../tcl[[7-9]]* 2>/dev/null` \ ${srcdir}/../../../tcl \ `ls -dr ${srcdir}/../../../tcl[[7-9]]* 2>/dev/null ` ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ `ls -dr /usr/local/src/tcl[[7-9]]* 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[[7-9]]* 2>/dev/null` \ /usr/local/src/tcl \ /usr/local/lib/tcl \ ${prefix}/include ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tclh}" = x ; then AC_HEADER_CHECK(tclInt.h, ac_cv_c_tclh=installed, ac_cv_c_tclh="") fi ]) if test x"${ac_cv_c_tclh}" = x ; then TCLHDIR="# no Tcl private headers found" AC_MSG_ERROR([Can't find Tcl private headers]) fi if test x"${ac_cv_c_tclh}" != x ; then no_tcl="" if test x"${ac_cv_c_tclh}" = x"installed" ; then AC_MSG_RESULT([is installed]) TCLHDIR="" else AC_MSG_RESULT([found in ${ac_cv_c_tclh}]) # this hack is cause the TCLHDIR won't print if there is a "-I" in it. TCLHDIR="-I${ac_cv_c_tclh}" fi fi AC_SUBST(TCLHDIR) ]) AC_DEFUN(CY_AC_PATH_TCLCONFIG, [ # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tclconfig # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tclconfig, [ --with-tclconfig directory containing tcl configuration (tclConfig.sh)], with_tclconfig=${withval}) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tclconfig was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[7-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[7-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[7-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[7-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCLCONFIG="# no Tcl configs found" AC_MSG_WARN(Can't find Tcl configuration definitions) else no_tcl= TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh AC_MSG_RESULT(found $TCLCONFIG) fi fi ]) # Defined as a separate macro so we don't have to cache the values # from PATH_TCLCONFIG (because this can also be cached). AC_DEFUN(CY_AC_LOAD_TCLCONFIG, [ . $TCLCONFIG dnl AC_SUBST(TCL_VERSION) dnl AC_SUBST(TCL_MAJOR_VERSION) dnl AC_SUBST(TCL_MINOR_VERSION) dnl AC_SUBST(TCL_CC) AC_SUBST(TCL_DEFS) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_LIB_FILE) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_EXEC_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_SHLIB_CFLAGS) AC_SUBST(TCL_SHLIB_LD) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_SHLIB_LD_LIBS) dnl AC_SUBST(TCL_SHLIB_SUFFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_DL_LIBS) AC_SUBST(TCL_LD_FLAGS) dnl don't export, not used outside of configure dnl AC_SUBST(TCL_LD_SEARCH_FLAGS) dnl AC_SUBST(TCL_COMPAT_OBJS) AC_SUBST(TCL_RANLIB) AC_SUBST(TCL_BUILD_LIB_SPEC) AC_SUBST(TCL_LIB_SPEC) dnl AC_SUBST(TCL_LIB_VERSIONS_OK) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_SHARED_LIB_SUFFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TCL_UNSHARED_LIB_SUFFIX) ]) # Warning: Tk definitions are very similar to Tcl definitions but # are not precisely the same. There are a couple of differences, # so don't do changes to Tcl thinking you can cut and paste it do # the Tk differences and later simply substitute "Tk" for "Tcl". # Known differences: # - Acceptable Tcl major version #s is 7-9 while Tk is 4-9 # - Searching for Tcl includes looking for tclInt.h, Tk looks for tk.h # - Computing major/minor versions is different because Tk depends on # headers to Tcl, Tk, and X. # - Symbols in tkConfig.sh are different than tclConfig.sh # - Acceptable for Tk to be missing but not Tcl. AC_DEFUN(CY_AC_PATH_TKH, [ # # Ok, lets find the tk source trees so we can use the headers # If the directory (presumably symlink) named "tk" exists, use that one # in preference to any others. Same logic is used when choosing library # and again with Tcl. The search order is the best place to look first, then in # decreasing significance. The loop breaks if the trigger file is found. # Note the gross little conversion here of srcdir by cd'ing to the found # directory. This converts the path from a relative to an absolute, so # recursive cache variables for the path will work right. We check all # the possible paths in one loop rather than many seperate loops to speed # things up. # the alternative search directory is involked by --with-tkinclude # #no_tk=true AC_MSG_CHECKING(for Tk private headers) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory where tk private headers are], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh,[ # first check to see if --with-tkinclude was specified if test x"${with_tkinclude}" != x ; then if test -f ${with_tkinclude}/tk.h ; then ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)` elif test -f ${with_tkinclude}/generic/tk.h ; then ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)` else AC_MSG_ERROR([${with_tkinclude} directory doesn't contain private headers]) fi fi # next check if it came with Tk configuration file if test x"${ac_cv_c_tkconfig}" != x ; then if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/../generic; pwd)` fi fi # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[[4-9]]* 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[[4-9]]* 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[[4-9]]* 2>/dev/null` \ `ls -dr /usr/local/lib/tk[[4-9]]* 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tkh}" = x ; then AC_HEADER_CHECK(tk.h, ac_cv_c_tkh=installed, ac_cv_c_tkh="") fi ]) if test x"${ac_cv_c_tkh}" != x ; then # no_tk="" if test x"${ac_cv_c_tkh}" = x"installed" ; then AC_MSG_RESULT([is installed]) TKHDIR="" else AC_MSG_RESULT([found in ${ac_cv_c_tkh}]) # this hack is cause the TKHDIR won't print if there is a "-I" in it. TKHDIR="-I${ac_cv_c_tkh}" fi else TKHDIR="# no Tk directory found" AC_MSG_WARN([Can't find Tk private headers]) no_tk=true fi AC_SUBST(TKHDIR) ]) AC_DEFUN(CY_AC_PATH_TKCONFIG, [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tkconfig # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tkconfig, [ --with-tkconfig directory containing tk configuration (tkConfig.sh)], with_tkconfig=${withval}) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[4-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[4-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[4-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[4-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TKCONFIG="# no Tk configs found" AC_MSG_WARN(Can't find Tk configuration definitions) else no_tk= TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh AC_MSG_RESULT(found $TKCONFIG) fi fi ]) # Defined as a separate macro so we don't have to cache the values # from PATH_TKCONFIG (because this can also be cached). AC_DEFUN(CY_AC_LOAD_TKCONFIG, [ if test -f "$TKCONFIG" ; then . $TKCONFIG fi AC_SUBST(TK_VERSION) dnl not actually used, don't export to save symbols dnl AC_SUBST(TK_MAJOR_VERSION) dnl AC_SUBST(TK_MINOR_VERSION) AC_SUBST(TK_DEFS) dnl not used, don't export to save symbols dnl AC_SUBST(TK_LIB_FILE) dnl not used outside of configure dnl AC_SUBST(TK_LIBS) dnl not used, don't export to save symbols dnl AC_SUBST(TK_PREFIX) dnl not used, don't export to save symbols dnl AC_SUBST(TK_EXEC_PREFIX) AC_SUBST(TK_XINCLUDES) AC_SUBST(TK_XLIBSW) AC_SUBST(TK_BUILD_LIB_SPEC) AC_SUBST(TK_LIB_SPEC) ]) |
Added unix/config.guess.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner <[email protected]>. # The master version of this file is at the FSF in /home/gd/gnu/lib. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # ([email protected] 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:V*:*) # After 1.2, OSF1 uses "V1.3" for uname -r. echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'` exit 0 ;; alpha:OSF1:*:*) # 1.2 uses "1.2" for uname -r. echo alpha-dec-osf${UNAME_RELEASE} exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; Pyramid*:OSx*:*:*) if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; sun4*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; atari*:NetBSD:*:*) echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; mips:*:4*:UMIPS) echo mips-mips-riscos4sysv exit 0 ;; mips:*:5*:RISCos) echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i[34]86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >dummy.c #include <sys/systemcfg.h> main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[3478]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/7?? | 9000/8?[79] ) HP_ARCH=hppa1.1 ;; 9000/8?? ) HP_ARCH=hppa1.0 ;; esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >dummy.c #include <unistd.h> int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*C90:*:*:*) echo c90-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; i[34]86:BSD/386:*:* | *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. ld_help_string=`ld --help 2>&1` if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then echo "${UNAME_MACHINE}-unknown-linux" ; exit 0 elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0 elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0 elif test "${UNAME_MACHINE}" = "alpha" ; then echo alpha-unknown-linux ; exit 0 else # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout. test ! -d /usr/lib/ldscripts/. \ && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0 # Determine whether the default compiler is a.out or elf cat >dummy.c <<EOF main(argc, argv) int argc; char *argv[]; { #ifdef __ELF__ printf ("%s-unknown-linux\n", argv[1]); #else printf ("%s-unknown-linuxaout\n", argv[1]); #endif return 0; } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i[34]86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; i[34]86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL else echo ${UNAME_MACHINE}-unknown-sysv32 fi exit 0 ;; Intel:Mach:3*:*) echo i386-unknown-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M680[234]0:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3 && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m680[234]0:LynxOS:2.[23]*:*) echo m68k-lynx-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i[34]86:LynxOS:2.[23]*:*) echo i386-lynx-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.[23]*:*) echo sparc-lynx-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.[23]*:*) echo rs6000-lynx-lynxos${UNAME_RELEASE} exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include <sys/param.h> printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-unknown-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 |
Added unix/config.sub.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 | #! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # It is wrong to echo any other type of specification. if [ x$1 = x ] then echo Configuration name missing. 1>&2 echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 echo "or $0 ALIAS" 1>&2 echo where ALIAS is a recognized configuration type. 1>&2 exit 1 fi # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; esac # Separate what the user gave into CPU-COMPANY and OS (if any). basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp ) os= basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | armeb \ | armel | pyramid \ | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \ | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \ | pdp11 | mips64el | mips64orion | mips64orionel \ | sparc) basic_machine=$basic_machine-unknown ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \ | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigados) basic_machine=m68k-cbm os=-amigados ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[345]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` os=-sysv32 ;; i[345]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` os=-sysv4 ;; i[345]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` os=-sysv ;; i[345]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'` os=-solaris2 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; np1) basic_machine=np1-gould ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | p6) # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium basic_machine=i586-intel ;; pentium-* | p5-* | p6-*) # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; k5) # We don't have specific support for AMD's K5 yet, so just call it a Pentium basic_machine=i586-amd ;; nexgen) # We don't have specific support for Nexgen yet, so just call it a Pentium basic_machine=i586-nexgen ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. mips) basic_machine=mips-mips ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware* | svr4*) os=-sysv4 ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative must end in a *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -lites* | -minix* | -genix* | -ultrix* | -irix* \ | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* \ | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* | -lites* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi | -eabi*) ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -ctix* | -uts*) os=-sysv ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -xenix) os=-xenix ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-ibm) os=-aix ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigados ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -lynxos*) vendor=lynx ;; -aix*) vendor=ibm ;; -hpux*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxworks*) vendor=wrs ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os |
Added unix/configure.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 | #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.11 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-tclconfig directory containing tcl configuration (tclConfig.sh)" ac_help="$ac_help --with-tkconfig directory containing tk configuration (tkConfig.sh)" ac_help="$ac_help --with-tclinclude directory where tcl private headers are" ac_help="$ac_help --enable-shared build libexpect as a shared library" ac_help="$ac_help --with-x whether or not to use X (default yes)" ac_help="$ac_help --with-tkinclude directory where tk private headers are" ac_help="$ac_help --disable-load disallow dynamic loading" ac_help="$ac_help --enable-gcc allow use of gcc if available" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.11" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LANG+set}" = set; then LANG=C; export LANG; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=expect.h # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says [email protected]. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi EXP_MAJOR_VERSION=5 EXP_MINOR_VERSION=21 EXP_MICRO_VERSION=7 EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION # Too many people send me configure output without identifying the version. # This forced identification should reduce my pain significantly. echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Do some error checking and defaulting for the host and target type. # The inputs are: # configure --host=HOST --target=TARGET --build=BUILD NONOPT # # The rules are: # 1. You are not allowed to specify --host, --target, and nonopt at the # same time. # 2. Host defaults to nonopt. # 3. If nonopt is not specified, then host defaults to the current host, # as determined by config.guess. # 4. Target and build default to nonopt. # 5. If nonopt is not specified, then target and build default to host. # The aliases save the names the user supplied, while $host etc. # will get canonicalized. case $host---$target---$nonopt in NONE---*---* | *---NONE---* | *---*---NONE) ;; *) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; esac # Make sure we can run config.sub. if $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:586: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`$ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`$ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 echo "configure:607: checking target system type" >&5 target_alias=$target case "$target_alias" in NONE) case $nonopt in NONE) target_alias=$host_alias ;; *) target_alias=$nonopt ;; esac ;; esac target=`$ac_config_sub $target_alias` target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 echo "configure:625: checking build system type" >&5 build_alias=$build case "$build_alias" in NONE) case $nonopt in NONE) build_alias=$host_alias ;; *) build_alias=$nonopt ;; esac ;; esac build=`$ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$build" 1>&6 test "$host_alias" != "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- # /bin/sh on some systems is too deficient (in particular, Ultrix 4.3 # sh lacks unset and we *need* that), but all these systems come with # alternatives, so take user's choice or whatever we're using here and # allow it to be seen by Make. echo $ac_n "checking shell to use within Make""... $ac_c" 1>&6 echo "configure:655: checking shell to use within Make" >&5 EXP_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} echo "$ac_t""$CONFIG_SHELL" 1>&6 # If `configure' is invoked (in)directly via `make', ensure that it # encounters no `make' conflicts. # MFLAGS= MAKEFLAGS= # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tclconfig # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tclconfig or --without-tclconfig was given. if test "${with_tclconfig+set}" = set; then withval="$with_tclconfig" with_tclconfig=${withval} fi echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6 echo "configure:682: checking for Tcl configuration" >&5 if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # First check to see if --with-tclconfig was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; } fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[7-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[7-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[7-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCLCONFIG="# no Tcl configs found" echo "configure: warning: Can't find Tcl configuration definitions" 1>&2 else no_tcl= TCLCONFIG=${ac_cv_c_tclconfig}/tclConfig.sh echo "$ac_t""found $TCLCONFIG" 1>&6 fi fi . $TCLCONFIG CC=$TCL_CC EXP_AND_TCL_LIBS=$TCL_LIBS # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tkconfig # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tkconfig or --without-tkconfig was given. if test "${with_tkconfig+set}" = set; then withval="$with_tkconfig" with_tkconfig=${withval} fi echo $ac_n "checking for Tk configuration""... $ac_c" 1>&6 echo "configure:781: checking for Tk configuration" >&5 if eval "test \"`echo '$''{'ac_cv_c_tkconfig'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` else { echo "configure: error: ${with_tkconfig} directory doesn't contain tkConfig.sh" 1>&2; exit 1; } fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[4-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[4-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[4-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${prefix}/lib /usr/local/lib 2>/dev/null` ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i; pwd)` break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[4-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig=`(cd $i/unix; pwd)` break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TKCONFIG="# no Tk configs found" echo "configure: warning: Can't find Tk configuration definitions" 1>&2 else no_tk= TKCONFIG=${ac_cv_c_tkconfig}/tkConfig.sh echo "$ac_t""found $TKCONFIG" 1>&6 fi fi if test -f "$TKCONFIG" ; then . $TKCONFIG fi EXP_AND_TK_LIBS=$TK_LIBS # An explanation is in order for the strange things going on with the # various LIBS. There are three separate definitions for LIBS. The # reason is that some systems require shared libraries include # references to their dependent libraries, i.e., any additional # libraries that must be linked to. And some systems get upset if the # references are repeated on the link line. So therefore, we create # one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl # (EXP_AND_TCL_LIBS), and finally, one for building Expect's own # shared library. Tcl's tclConfig.sh insists that any shared libs # that it "helps" build must pass the libraries as LIBS (see comment # near end of this configure file). I would do but since we're close # to hitting config's max symbols, we take one short cut and pack the # LIBS into EXP_SHLIB_LD_LIBS (which is basically what Tcl wants to do # for us). The point, however, is that there's no separate LIBS or # EXP_LIBS symbol passed out of configure. One additional point for # confusion is that LIBS is what configure uses to do all library # tests, so we have to swap definitions of LIBS peridically. When we # are swapping out the one for Expect's shared library, we save it in # EXP_LIBS. Sigh. OLD_CFLAGS=$CFLAGS # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:887: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:916: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:964: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cat > conftest.$ac_ext <<EOF #line 973 "configure" #include "confdefs.h" int main() { ; return 0; } EOF if { (eval echo configure:980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_prog_cc_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_prog_cc_works=no fi rm -f conftest* echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: Installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:998: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <<EOF #ifdef __GNUC__ yes; #endif EOF if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1007: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:1022: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_gcc_g=yes else ac_cv_prog_gcc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_gcc_g = yes; then CFLAGS="-g -O2" else CFLAGS="-O2" fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi CFLAGS=$OLD_CFLAGS # If we cannot compile and link a trivial program, we can't expect anything to work echo $ac_n "checking whether the compiler ($CC) actually works""... $ac_c" 1>&6 echo "configure:1053: checking whether the compiler ($CC) actually works" >&5 cat > conftest.$ac_ext <<EOF #line 1055 "configure" #include "confdefs.h" int main() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:1062: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* c_compiles=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* c_compiles=no fi rm -f conftest* cat > conftest.$ac_ext <<EOF #line 1075 "configure" #include "confdefs.h" int main() { /* don't need anything here */ ; return 0; } EOF if { (eval echo configure:1082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* c_links=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* c_links=no fi rm -f conftest* if test x"${c_compiles}" = x"no" ; then { echo "configure: error: the native compiler is broken and won't compile." 1>&2; exit 1; } fi if test x"${c_links}" = x"no" ; then { echo "configure: error: the native compiler is broken and won't link." 1>&2; exit 1; } fi echo "$ac_t""yes" 1>&6 # this'll use a BSD compatible install or our included install-sh # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1116: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_ifs" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # these are the other subdirectories we need to configure subdirs="testsuite" # This is for LynxOS, which needs a flag to force true POSIX when # building. The flag varies depending how old the compiler is. # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:1177: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext <<EOF #line 1192 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext <<EOF #line 1209 "configure" #include "confdefs.h" #include <assert.h> Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1215: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking if running LynxOS""... $ac_c" 1>&6 echo "configure:1239: checking if running LynxOS" >&5 if eval "test \"`echo '$''{'ac_cv_os_lynx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1244 "configure" #include "confdefs.h" /* * The old Lynx "cc" only defines "Lynx", but the newer one uses "__Lynx__" */ #if defined(__Lynx__) || defined(Lynx) yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_lynx=yes else rm -rf conftest* ac_cv_os_lynx=no fi rm -f conftest* fi # if test "$ac_cv_os_lynx" = "yes" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define LYNX 1 EOF echo $ac_n "checking whether -mposix or -X is available""... $ac_c" 1>&6 echo "configure:1274: checking whether -mposix or -X is available" >&5 if eval "test \"`echo '$''{'ac_cv_c_posix_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1279 "configure" #include "confdefs.h" int main() { /* * This flag varies depending on how old the compiler is. * -X is for the old "cc" and "gcc" (based on 1.42). * -mposix is for the new gcc (at least 2.5.8). */ #if defined(__GNUC__) && __GNUC__ >= 2 choke me #endif ; return 0; } EOF if { (eval echo configure:1295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_posix_flag=" -mposix" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_posix_flag=" -X" fi rm -f conftest* fi CC="$CC $ac_cv_c_posix_flag" echo "$ac_t""$ac_cv_c_posix_flag" 1>&6 else echo "$ac_t""no" 1>&6 fi # If we cannot run a trivial program, we are probably using a cross compiler. echo $ac_n "checking whether using a cross-compiler""... $ac_c" 1>&6 echo "configure:1317: checking whether using a cross-compiler" >&5 if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_cross=yes else cat > conftest.$ac_ext <<EOF #line 1325 "configure" #include "confdefs.h" main(){return(0);} EOF { (eval echo configure:1329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_cross=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_cross=yes fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_cross" 1>&6 cross_compiling=$ac_cv_c_cross echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1347: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1352 "configure" #include "confdefs.h" #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1360: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext <<EOF #line 1377 "configure" #include "confdefs.h" #include <string.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext <<EOF #line 1395 "configure" #include "confdefs.h" #include <stdlib.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF #line 1416 "configure" #include "confdefs.h" #include <ctype.h> #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 echo "configure:1451: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1456 "configure" #include "confdefs.h" #include <sys/types.h> #if STDC_HEADERS #include <stdlib.h> #include <stddef.h> #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else rm -rf conftest* ac_cv_type_pid_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_pid_t" 1>&6 if test $ac_cv_type_pid_t = no; then cat >> confdefs.h <<\EOF #define pid_t int EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:1484: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1489 "configure" #include "confdefs.h" #include <sys/types.h> #include <signal.h> #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:1506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <<EOF #define RETSIGTYPE $ac_cv_type_signal EOF echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1526: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1531 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/time.h> #include <time.h> int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1540: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 echo "configure:1562: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1567 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/wait.h> #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main() { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF if { (eval echo configure:1583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_sys_wait_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 if test $ac_cv_header_sys_wait_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_SYS_WAIT_H 1 EOF fi EXP_CFLAGS=-g case "${host}" in # Use -g on all systems but Linux where it upsets the dynamic X libraries. i[3456]86-*-linux*) EXP_CFLAGS="" ;; esac echo $ac_n "checking if running Mach""... $ac_c" 1>&6 echo "configure:1612: checking if running Mach" >&5 mach=0 case "${host}" in # Both Next and pure Mach behave identically with respect # to a few things, so just lump them together as "mach" *-*-mach*) mach=1 ;; *-*-next*) mach=1 ; next=1 ;; esac if test $mach -eq 1 ; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if running MachTen""... $ac_c" 1>&6 echo "configure:1628: checking if running MachTen" >&5 # yet another Mach clone if test -r /MachTen ; then echo "$ac_t""yes" 1>&6 mach=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if on Pyramid""... $ac_c" 1>&6 echo "configure:1638: checking if on Pyramid" >&5 if test -r /bin/pyr ; then echo "$ac_t""yes" 1>&6 pyr=1 else echo "$ac_t""no" 1>&6 pyr=0 fi echo $ac_n "checking if on Apollo""... $ac_c" 1>&6 echo "configure:1648: checking if on Apollo" >&5 if test -r /usr/apollo/bin ; then echo "$ac_t""yes" 1>&6 apollo=1 else echo "$ac_t""no" 1>&6 apollo=0 fi echo $ac_n "checking if on Interactive""... $ac_c" 1>&6 echo "configure:1658: checking if on Interactive" >&5 if test "x`(uname -s) 2>/dev/null`" = xIUNIX; then echo "$ac_t""yes" 1>&6 iunix=1 else echo "$ac_t""no" 1>&6 iunix=0 fi echo $ac_n "checking if stty reads stdout""... $ac_c" 1>&6 echo "configure:1668: checking if stty reads stdout" >&5 # On some systems stty can't be run in the background (svr4) or get it # wrong because they fail to complain (next, mach), so don't attempt # the test on some systems. stty_reads_stdout="" case "${host}" in *-*-solaris*) stty_reads_stdout=0 ;; *-*-irix*) stty_reads_stdout=0 ;; *-sco3.2v[45]*) stty_reads_stdout=1 ;; i[3456]86-*-linux*) stty_reads_stdout=0 ;; # Not sure about old convex but 5.2 definitely reads from stdout c[12]-*-*) stty_reads_stdout=1 ;; *-*-aix[34]*) stty_reads_stdout=0 ;; *-*-hpux9*) stty_reads_stdout=0 ;; *-*-hpux10*) stty_reads_stdout=0 ;; *-*-osf[234]*) stty_reads_stdout=0 ;; *-*-ultrix4.4) stty_reads_stdout=0 ;; *-*-dgux*) stty_reads_stdout=0 ;; esac if test $mach -eq 1 ; then stty_reads_stdout=1 fi if test $apollo -eq 1 ; then stty_reads_stdout=1 fi if test $pyr -eq 1 ; then stty_reads_stdout=1 fi # if we still don't know, test if test x"${stty_reads_stdout}" = x"" ; then /bin/stty > /dev/null 2> /dev/null if test $? -ne 0 ; then stty_reads_stdout=1 else stty_reads_stdout=0 fi fi if test ${stty_reads_stdout} -eq 1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define STTY_READS_STDOUT 1 EOF else echo "$ac_t""no" 1>&6 fi # Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts # of traditional but nonstandard stuff in header files. echo $ac_n "checking if running Solaris""... $ac_c" 1>&6 echo "configure:1723: checking if running Solaris" >&5 solaris=0 case "${host}" in *-*-solaris*) solaris=1;; esac if test $solaris -eq 1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define SOLARIS 1 EOF else echo "$ac_t""no" 1>&6 fi # On a few systems, libm.a is the same as libc.a # Don't bother to test against Tcl and Tk libs, they always include -lm echo $ac_n "checking for sin""... $ac_c" 1>&6 echo "configure:1743: checking for sin" >&5 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1748 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sin(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else sin(); #endif ; return 0; } EOF if { (eval echo configure:1771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_sin=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 LIBS="${LIBS} -lm" fi # On Interactive UNIX, -Xp must be added to LIBS in order to find strftime. # This test should really be done by Tcl. So just check Tcl's definition. # If defective, add to all three LIBS. (It's not actually necessary for # EXP_LIBS since -Xp will just be ignored the way that EXP_LIBS is used in # the Makefile, but we include it for consistency.) if test $iunix -eq 1 ; then EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS echo $ac_n "checking for strftime""... $ac_c" 1>&6 echo "configure:1801: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1806 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strftime(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strftime(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strftime) || defined (__stub___strftime) choke me #else strftime(); #endif ; return 0; } EOF if { (eval echo configure:1829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strftime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_LIBS="${LIBS} -Xp" EXP_AND_TCL_LIBS="${LIBS} -Xp" EXP_AND_TK_LIBS="${LIBS} -Xp" fi LIBS=EXP_LIBS fi # # Ok, lets find the tcl source trees so we can use the headers # # # Ok, lets find the tcl source trees so we can use the headers # Warning: transition of version 9 to 10 will break this algorithm # because 10 sorts before 9. We also look for just tcl. We have to # be careful that we don't match stuff like tclX by accident. # the alternative search directory is involked by --with-tclinclude # no_tcl=true echo $ac_n "checking for Tcl private headers""... $ac_c" 1>&6 echo "configure:1869: checking for Tcl private headers" >&5 # Check whether --with-tclinclude or --without-tclinclude was given. if test "${with_tclinclude+set}" = set; then withval="$with_tclinclude" with_tclinclude=${withval} fi if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # first check to see if --with-tclinclude was specified if test x"${with_tclinclude}" != x ; then if test -f ${with_tclinclude}/tclInt.h ; then ac_cv_c_tclh=`(cd ${with_tclinclude}; pwd)` elif test -f ${with_tclinclude}/generic/tclInt.h ; then ac_cv_c_tclh=`(cd ${with_tclinclude}/generic; pwd)` else { echo "configure: error: ${with_tclinclude} directory doesn't contain private headers" 1>&2; exit 1; } fi fi # next check if it came with Tcl configuration file if test x"${ac_cv_c_tclconfig}" != x ; then if test -f $ac_cv_c_tclconfig/../generic/tclInt.h ; then ac_cv_c_tclh=`(cd $ac_cv_c_tclconfig/../generic; pwd)` fi fi # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[7-9]* 2>/dev/null` \ ${srcdir}/../../tcl \ `ls -dr ${srcdir}/../../tcl[7-9]* 2>/dev/null` \ ${srcdir}/../../../tcl \ `ls -dr ${srcdir}/../../../tcl[7-9]* 2>/dev/null ` ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tclh}" = x ; then for i in \ `ls -dr /usr/local/src/tcl[7-9]* 2>/dev/null` \ `ls -dr /usr/local/lib/tcl[7-9]* 2>/dev/null` \ /usr/local/src/tcl \ /usr/local/lib/tcl \ ${prefix}/include ; do if test -f $i/generic/tclInt.h ; then ac_cv_c_tclh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tclh}" = x ; then ac_safe=`echo "tclInt.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tclInt.h""... $ac_c" 1>&6 echo "configure:1935: checking for tclInt.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 1940 "configure" #include "confdefs.h" #include <tclInt.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_cv_c_tclh=installed else echo "$ac_t""no" 1>&6 ac_cv_c_tclh="" fi fi fi if test x"${ac_cv_c_tclh}" = x ; then TCLHDIR="# no Tcl private headers found" { echo "configure: error: Can't find Tcl private headers" 1>&2; exit 1; } fi if test x"${ac_cv_c_tclh}" != x ; then no_tcl="" if test x"${ac_cv_c_tclh}" = x"installed" ; then echo "$ac_t""is installed" 1>&6 TCLHDIR="" else echo "$ac_t""found in ${ac_cv_c_tclh}" 1>&6 # this hack is cause the TCLHDIR won't print if there is a "-I" in it. TCLHDIR="-I${ac_cv_c_tclh}" fi fi if test x"$no_tcl" = x"true" ; then echo " ERROR: Can't find Tcl headers or library." echo " See README for information on how to obtain Tcl." echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # have to know whether we're generating shared libs before configuring debugger echo $ac_n "checking for type of library to build""... $ac_c" 1>&6 echo "configure:1999: checking for type of library to build" >&5 # Check whether --enable-shared or --disable-shared was given. if test "${enable_shared+set}" = set; then enableval="$enable_shared" enable_shared=$enableval else enable_shared=no fi if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then echo "$ac_t""both shared and nonshared" 1>&6 else echo "$ac_t""nonshared" 1>&6 fi # # Now that we've found the Tcl sources, configure the debugger # this is a little tricky because it has its own configure script # which produces a Makefile and cf file. We only want the cf file, # so switch to a temporary directory and run the debugger's configure. # Then save the cf file and delete the rest. # # Incidentally, the debugger can't depend on Expect's cf file, because # the debugger is designed to be independent of Expect. # test -n "$verbose" && echo "configuring Tcl debugger" tmpdir=./Dbg$$ mkdir ${tmpdir} #if test "${enable_shared+set}" = set; then if test "${enable_shared}" = "yes"; then dbg_config_flags='--enable-shared' else dbg_config_flags='--disable-shared' fi # (cd;pwd) in next several commands converts relative dirs to absolute. # This is required because the debugger src is at a different level in # the filesystem than Expect src (where we are presently), thereby # making the relative pathnames incorrect. if test "x$with_tclconfig" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tclconfig=`(cd ${with_tclconfig}; pwd)`" fi if test "x$with_tcllibdir" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tcllibdir=`(cd ${with_tcllibdir}; pwd)`" fi if test "x$with_tcllib" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tcllib=`(cd ${with_tcllib}; pwd)`" fi if test "x$with_tclinclude" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tclinclude=`(cd ${with_tclinclude}; pwd)`" fi case "$cache_file" in /*) dbg_config_flags="$dbg_config_flags --cache-file=$cache_file" ;; *) dbg_config_flags="$dbg_config_flags --cache-file=../$cache_file" ;; esac cp ${srcdir}/Dbgconfigure ${srcdir}/Dbg.h ${srcdir}/Dbg_cf.h.in ${srcdir}/install-sh ${tmpdir} cp $srcdir/DbgMkfl.in ${tmpdir}/Makefile.in (cd $tmpdir; ${CONFIG_SHELL-/bin/sh} Dbgconfigure --with-tclinclude=`echo ${TCLHDIR} | sed -e 's/-I//'` $dbg_config_flags) cp ${tmpdir}/Dbg_cf.h . rm -rf $tmpdir test -n "$verbose" && echo "configured Tcl debugger" # some people would complain if this explanation wasn't provided... echo "Begin tests for function/library dependencies. Tests may be repeated" echo "up to three times. First test is for building Expect's shared library." echo "Second set is for building with Tcl. Third is for building with Tk." # required by Sequent ptx2 unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2076: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2081 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostname) || defined (__stub___gethostname) choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2127: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2135 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2146: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2172: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2177 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostname) || defined (__stub___gethostname) choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2223: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2231 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_gethostname echo $ac_n "checking for gethostname""... $ac_c" 1>&6 echo "configure:2268: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2273 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostname) || defined (__stub___gethostname) choke me #else gethostname(); #endif ; return 0; } EOF if { (eval echo configure:2296: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then echo "$ac_t""yes" 1>&6 gethostname=1 else echo "$ac_t""no" 1>&6 gethostname=0 fi if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname echo $ac_n "checking for gethostname in -linet""... $ac_c" 1>&6 echo "configure:2319: checking for gethostname in -linet" >&5 ac_lib_var=`echo inet'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2327 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostname(); int main() { gethostname() ; return 0; } EOF if { (eval echo configure:2338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # required by Fischman's ISC 4.0 unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2366: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2371 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2394: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2417: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2425 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:2436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2462: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2467 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2513: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2521 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:2532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_socket echo $ac_n "checking for socket""... $ac_c" 1>&6 echo "configure:2558: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2563 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char socket(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_socket) || defined (__stub___socket) choke me #else socket(); #endif ; return 0; } EOF if { (eval echo configure:2586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_socket=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_socket=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then echo "$ac_t""yes" 1>&6 socket=1 else echo "$ac_t""no" 1>&6 socket=0 fi if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket echo $ac_n "checking for socket in -linet""... $ac_c" 1>&6 echo "configure:2609: checking for socket in -linet" >&5 ac_lib_var=`echo inet'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2617 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char socket(); int main() { socket() ; return 0; } EOF if { (eval echo configure:2628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:2655: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2660 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_select) || defined (__stub___select) choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:2683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:2706: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2714 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:2725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:2751: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2756 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_select) || defined (__stub___select) choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:2779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:2802: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2810 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:2821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:2847: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2852 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_select) || defined (__stub___select) choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:2875: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 select=0 fi if test $select -eq 0 ; then unset ac_cv_lib_inet_select echo $ac_n "checking for select in -linet""... $ac_c" 1>&6 echo "configure:2898: checking for select in -linet" >&5 ac_lib_var=`echo inet'_'select | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-linet $LIBS" cat > conftest.$ac_ext <<EOF #line 2906 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { select() ; return 0; } EOF if { (eval echo configure:2917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -linet" else echo "$ac_t""no" 1>&6 fi fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:2944: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 2949 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpseudotty) || defined (__stub___getpseudotty) choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:2972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:2995: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3003 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-lseq $LIBS" else echo "$ac_t""no" 1>&6 fi fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:3047: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3052 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpseudotty) || defined (__stub___getpseudotty) choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:3075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:3098: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3106 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-lseq $LIBS" else echo "$ac_t""no" 1>&6 fi fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_getpseudotty echo $ac_n "checking for getpseudotty""... $ac_c" 1>&6 echo "configure:3150: checking for getpseudotty" >&5 if eval "test \"`echo '$''{'ac_cv_func_getpseudotty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3155 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char getpseudotty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_getpseudotty) || defined (__stub___getpseudotty) choke me #else getpseudotty(); #endif ; return 0; } EOF if { (eval echo configure:3178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_getpseudotty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_getpseudotty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'getpseudotty`\" = yes"; then echo "$ac_t""yes" 1>&6 getpseudotty=1 else echo "$ac_t""no" 1>&6 getpseudotty=0 fi if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty echo $ac_n "checking for getpseudotty in -lseq""... $ac_c" 1>&6 echo "configure:3201: checking for getpseudotty in -lseq" >&5 ac_lib_var=`echo seq'_'getpseudotty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lseq $LIBS" cat > conftest.$ac_ext <<EOF #line 3209 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char getpseudotty(); int main() { getpseudotty() ; return 0; } EOF if { (eval echo configure:3220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo seq | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-lseq $LIBS" else echo "$ac_t""no" 1>&6 fi fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # Check for FreeBSD/NetBSD openpty() unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3255: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3260 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_openpty) || defined (__stub___openpty) choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3306: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3314 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 # we only need to define OPENPTY once, but since we are overriding # the default behavior, we must also handle augment LIBS too. # This needn't be done in the 2nd and 3rd tests. cat >> confdefs.h <<\EOF #define HAVE_OPENPTY 1 EOF LIBS="$LIBS -lutil" else echo "$ac_t""no" 1>&6 fi fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3360: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3365 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_openpty) || defined (__stub___openpty) choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3411: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3419 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3430: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo util | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-lutil $LIBS" else echo "$ac_t""no" 1>&6 fi fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_openpty echo $ac_n "checking for openpty""... $ac_c" 1>&6 echo "configure:3463: checking for openpty" >&5 if eval "test \"`echo '$''{'ac_cv_func_openpty'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3468 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char openpty(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_openpty) || defined (__stub___openpty) choke me #else openpty(); #endif ; return 0; } EOF if { (eval echo configure:3491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_openpty=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'openpty`\" = yes"; then echo "$ac_t""yes" 1>&6 openpty=1 else echo "$ac_t""no" 1>&6 openpty=0 fi if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 echo "configure:3514: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext <<EOF #line 3522 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char openpty(); int main() { openpty() ; return 0; } EOF if { (eval echo configure:3533: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo util | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <<EOF #define $ac_tr_lib 1 EOF LIBS="-lutil $LIBS" else echo "$ac_t""no" 1>&6 fi fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # # Look for various header files # ac_safe=`echo "sys/sysmacros.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/sysmacros.h""... $ac_c" 1>&6 echo "configure:3570: checking for sys/sysmacros.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3575 "configure" #include "confdefs.h" #include <sys/sysmacros.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3580: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSMACROS_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6 echo "configure:3606: checking for stdlib.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3611 "configure" #include "confdefs.h" #include <stdlib.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3616: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define NO_STDLIB_H 1 EOF fi # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! ac_safe=`echo "varargs.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for varargs.h""... $ac_c" 1>&6 echo "configure:3647: checking for varargs.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3652 "configure" #include "confdefs.h" #include <varargs.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3657: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VARARGS_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "unistd.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for unistd.h""... $ac_c" 1>&6 echo "configure:3683: checking for unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3688 "configure" #include "confdefs.h" #include <unistd.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3693: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_UNISTD_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/stropts.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/stropts.h""... $ac_c" 1>&6 echo "configure:3719: checking for sys/stropts.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3724 "configure" #include "confdefs.h" #include <sys/stropts.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STROPTS_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/sysconfig.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/sysconfig.h""... $ac_c" 1>&6 echo "configure:3755: checking for sys/sysconfig.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3760 "configure" #include "confdefs.h" #include <sys/sysconfig.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3765: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSCONF_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/fcntl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/fcntl.h""... $ac_c" 1>&6 echo "configure:3791: checking for sys/fcntl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3796 "configure" #include "confdefs.h" #include <sys/fcntl.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYS_FCNTL_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/select.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/select.h""... $ac_c" 1>&6 echo "configure:3827: checking for sys/select.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3832 "configure" #include "confdefs.h" #include <sys/select.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3837: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYS_SELECT_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/time.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/time.h""... $ac_c" 1>&6 echo "configure:3863: checking for sys/time.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3868 "configure" #include "confdefs.h" #include <sys/time.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3873: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYS_TIME_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/ptem.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/ptem.h""... $ac_c" 1>&6 echo "configure:3899: checking for sys/ptem.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3904 "configure" #include "confdefs.h" #include <sys/ptem.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3909: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYS_PTEM_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strredir.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strredir.h""... $ac_c" 1>&6 echo "configure:3935: checking for sys/strredir.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3940 "configure" #include "confdefs.h" #include <sys/strredir.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3945: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRREDIR_H 1 EOF else echo "$ac_t""no" 1>&6 fi ac_safe=`echo "sys/strpty.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/strpty.h""... $ac_c" 1>&6 echo "configure:3971: checking for sys/strpty.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 3976 "configure" #include "confdefs.h" #include <sys/strpty.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3981: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRPTY_H 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sys/bsdtypes.h""... $ac_c" 1>&6 echo "configure:4008: checking for sys/bsdtypes.h" >&5 if test "ISC_${ISC}" = "ISC_1" ; then echo "$ac_t""yes" 1>&6 # if on ISC 1, we need <sys/bsdtypes.h> to get FD_SET macros for ac_hdr in sys/bsdtypes.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:4016: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4021 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:4026: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <<EOF #define $ac_tr_hdr 1 EOF else echo "$ac_t""no" 1>&6 fi done else echo "$ac_t""no" 1>&6 fi # # Look for functions that may be missing # echo $ac_n "checking for memmove""... $ac_c" 1>&6 echo "configure:4060: checking for memmove" >&5 if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4065 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char memmove(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char memmove(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_memmove) || defined (__stub___memmove) choke me #else memmove(); #endif ; return 0; } EOF if { (eval echo configure:4088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_memmove=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_memmove=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_MEMMOVE 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for sysconf""... $ac_c" 1>&6 echo "configure:4111: checking for sysconf" >&5 if eval "test \"`echo '$''{'ac_cv_func_sysconf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4116 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char sysconf(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sysconf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sysconf) || defined (__stub___sysconf) choke me #else sysconf(); #endif ; return 0; } EOF if { (eval echo configure:4139: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_sysconf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sysconf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sysconf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SYSCONF 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strftime""... $ac_c" 1>&6 echo "configure:4162: checking for strftime" >&5 if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4167 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strftime(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strftime(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strftime) || defined (__stub___strftime) choke me #else strftime(); #endif ; return 0; } EOF if { (eval echo configure:4190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_strftime=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strftime=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRFTIME 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for strchr""... $ac_c" 1>&6 echo "configure:4213: checking for strchr" >&5 if eval "test \"`echo '$''{'ac_cv_func_strchr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4218 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char strchr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char strchr(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_strchr) || defined (__stub___strchr) choke me #else strchr(); #endif ; return 0; } EOF if { (eval echo configure:4241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_strchr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strchr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'strchr`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_STRCHR 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for timezone""... $ac_c" 1>&6 echo "configure:4264: checking for timezone" >&5 if eval "test \"`echo '$''{'ac_cv_func_timezone'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4269 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char timezone(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char timezone(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_timezone) || defined (__stub___timezone) choke me #else timezone(); #endif ; return 0; } EOF if { (eval echo configure:4292: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_timezone=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_timezone=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'timezone`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_TIMEZONE 1 EOF else echo "$ac_t""no" 1>&6 fi # dnl check for memcpy by hand # because Unixware 2.0 handles it specially and refuses to compile # autoconf's automatic test that is a call with no arguments echo $ac_n "checking for memcpy""... $ac_c" 1>&6 echo "configure:4319: checking for memcpy" >&5 cat > conftest.$ac_ext <<EOF #line 4321 "configure" #include "confdefs.h" int main() { char *s1, *s2; memcpy(s1,s2,0); ; return 0; } EOF if { (eval echo configure:4331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_MEMCPY 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* # Some systems only define WNOHANG if _POSIX_SOURCE is defined # The following merely tests that sys/wait.h can be included # and if so that WNOHANG is not defined. The only place I've # seen this is ISC. echo $ac_n "checking if WNOHANG requires _POSIX_SOURCE""... $ac_c" 1>&6 echo "configure:4354: checking if WNOHANG requires _POSIX_SOURCE" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 4360 "configure" #include "confdefs.h" #include <sys/wait.h> main() { #ifndef WNOHANG return 0; #else return 1; #endif } EOF { (eval echo configure:4372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define WNOHANG_REQUIRES_POSIX_SOURCE 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking if any value exists for WNOHANG""... $ac_c" 1>&6 echo "configure:4392: checking if any value exists for WNOHANG" >&5 rm -rf wnohang if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 4399 "configure" #include "confdefs.h" #include <stdio.h> #include <sys/wait.h> main() { #ifdef WNOHANG FILE *fp = fopen("wnohang","w"); fprintf(fp,"%d",WNOHANG); fclose(fp); return 0; #else return 1; #endif } EOF { (eval echo configure:4415: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<EOF #define WNOHANG_BACKUP_VALUE `cat wnohang` EOF rm -f wnohang else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define WNOHANG_BACKUP_VALUE 1 EOF fi rm -fr conftest* fi # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then # proceeds to ignore it and use int. # Pattern matching on int could be loosened. # Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp. echo $ac_n "checking mask type of select""... $ac_c" 1>&6 echo "configure:4449: checking mask type of select" >&5 if egrep "select\(size_t, int" /usr/include/sys/time.h >/dev/null 2>&1; then echo "$ac_t""int" 1>&6 cat >> confdefs.h <<\EOF #define SELECT_MASK_TYPE int EOF else echo "$ac_t""none" 1>&6 fi # FIXME: check if alarm exists echo $ac_n "checking if signals need to be re-armed""... $ac_c" 1>&6 echo "configure:4463: checking if signals need to be re-armed" >&5 if test "$cross_compiling" = yes; then echo "configure: warning: Expect can't be cross compiled" 1>&2 else cat > conftest.$ac_ext <<EOF #line 4469 "configure" #include "confdefs.h" #include <signal.h> #define RETSIGTYPE $retsigtype int signal_rearms = 0; RETSIGTYPE child_sigint_handler(n) int n; { } RETSIGTYPE parent_sigint_handler(n) int n; { signal_rearms++; } main() { signal(SIGINT,parent_sigint_handler); if (0 == fork()) { signal(SIGINT,child_sigint_handler); kill(getpid(),SIGINT); kill(getpid(),SIGINT); kill(getppid(),SIGINT); } else { int status; wait(&status); unlink("core"); exit(signal_rearms); } } EOF { (eval echo configure:4508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define REARM_SIG 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # HPUX7 has trouble with the big cat so split it # Owen Rees <[email protected]> 29Mar93 SEDDEFS="${SEDDEFS}CONFEOF cat >> conftest.sed <<CONFEOF " # # There are multiple versions of getpty, alas. # I don't remember who has the first one, but Convex just added one # so check for it. Unfortunately, there is no header so the only # reasonable way to make sure is to look it we are on a Convex. echo $ac_n "checking if on Convex""... $ac_c" 1>&6 echo "configure:4539: checking if on Convex" >&5 convex=0 case "${host}" in c[12]-*-*) convex=1;; esac if test $convex -eq 1 ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define CONVEX 1 EOF else echo "$ac_t""no" 1>&6 fi EXP_LDFLAGS= echo $ac_n "checking if on NeXT""... $ac_c" 1>&6 echo "configure:4558: checking if on NeXT" >&5 if test -r /NextApps ; then echo "$ac_t""yes" 1>&6 # "-m" flag suppresses complaints about multiple strtod EXP_LDFLAGS="$EXP_LDFLAGS -m" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking if on HP""... $ac_c" 1>&6 echo "configure:4569: checking if on HP" >&5 if test "x`(uname) 2>/dev/null`" = xHP-UX; then echo "$ac_t""yes" 1>&6 hp=1 else echo "$ac_t""no" 1>&6 hp=0 fi echo $ac_n "checking sane default stty arguments""... $ac_c" 1>&6 echo "configure:4579: checking sane default stty arguments" >&5 DEFAULT_STTY_ARGS="sane" if test $mach -eq 1 ; then DEFAULT_STTY_ARGS="cooked" fi if test $hp -eq 1 ; then DEFAULT_STTY_ARGS="sane kill " fi echo "$ac_t""$DEFAULT_STTY_ARG" 1>&6 # Look for various features to determine what kind of pty # we have. For some weird reason, ac_compile_check would not # work, but ac_test_program does. # echo $ac_n "checking for HP style pty allocation""... $ac_c" 1>&6 echo "configure:4597: checking for HP style pty allocation" >&5 # following test fails on DECstations and other things that don't grok -c # but that's ok, since they don't have PTYMs anyway if test -r /dev/ptym/ptyp0 2>/dev/null ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTYM 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for HP style pty trapping""... $ac_c" 1>&6 echo "configure:4611: checking for HP style pty trapping" >&5 cat > conftest.$ac_ext <<EOF #line 4613 "configure" #include "confdefs.h" #include <sys/ptyio.h> EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "struct.*request_info" >/dev/null 2>&1; then rm -rf conftest* echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTYTRAP 1 EOF else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* echo $ac_n "checking for AIX new-style pty allocation""... $ac_c" 1>&6 echo "configure:4635: checking for AIX new-style pty allocation" >&5 if test -r /dev/ptc -a -r /dev/pts ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTC_PTS 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for SGI old-style pty allocation""... $ac_c" 1>&6 echo "configure:4647: checking for SGI old-style pty allocation" >&5 if test -r /dev/ptc -a ! -r /dev/pts ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTC 1 EOF else echo "$ac_t""no" 1>&6 fi # On SCO OpenServer, two types of ptys are available: SVR4 streams and c-list. # The library routines to open the SVR4 ptys are broken on certain systems and # the SCO command to increase the number of ptys only configure c-list ones # anyway. So we chose these, which have a special numbering scheme. # echo $ac_n "checking for SCO style pty allocation""... $ac_c" 1>&6 echo "configure:4664: checking for SCO style pty allocation" >&5 sco_ptys="" case "${host}" in *-sco3.2v[45]*) sco_clist_ptys=1 svr4_ptys_broken=1;; esac if test x"${sco_clist_ptys}" != x"" ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SCO_CLIST_PTYS 1 EOF else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for SVR4 style pty allocation""... $ac_c" 1>&6 echo "configure:4681: checking for SVR4 style pty allocation" >&5 if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x ; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_PTMX 1 EOF # aargg. Some systems need libpt.a to use /dev/ptmx echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:4690: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4695 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char ptsname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_ptsname) || defined (__stub___ptsname) choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:4718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 LIBS="${LIBS} -lpt" fi # I've never seen Tcl or Tk include -lpt so don't bother with explicit test echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:4740: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4745 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char ptsname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_ptsname) || defined (__stub___ptsname) choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:4768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} -lpt" fi echo $ac_n "checking for ptsname""... $ac_c" 1>&6 echo "configure:4789: checking for ptsname" >&5 if eval "test \"`echo '$''{'ac_cv_func_ptsname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4794 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ptsname(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char ptsname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_ptsname) || defined (__stub___ptsname) choke me #else ptsname(); #endif ; return 0; } EOF if { (eval echo configure:4817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_ptsname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_ptsname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'ptsname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} -lpt" fi else echo "$ac_t""no" 1>&6 fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp <[email protected]> 17Aug93 echo $ac_n "checking for OSF/1 style pty allocation""... $ac_c" 1>&6 echo "configure:4844: checking for OSF/1 style pty allocation" >&5 if test -r /dev/ptmx_bsd ; then cat >> confdefs.h <<\EOF #define HAVE_PTMX_BSD 1 EOF echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi tcgetattr=0 tcsetattr=0 echo $ac_n "checking for tcgetattr""... $ac_c" 1>&6 echo "configure:4858: checking for tcgetattr" >&5 if eval "test \"`echo '$''{'ac_cv_func_tcgetattr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4863 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char tcgetattr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char tcgetattr(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_tcgetattr) || defined (__stub___tcgetattr) choke me #else tcgetattr(); #endif ; return 0; } EOF if { (eval echo configure:4886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_tcgetattr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tcgetattr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tcgetattr`\" = yes"; then echo "$ac_t""yes" 1>&6 tcgetattr=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for tcsetattr""... $ac_c" 1>&6 echo "configure:4906: checking for tcsetattr" >&5 if eval "test \"`echo '$''{'ac_cv_func_tcsetattr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 4911 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char tcsetattr(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char tcsetattr(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_tcsetattr) || defined (__stub___tcsetattr) choke me #else tcsetattr(); #endif ; return 0; } EOF if { (eval echo configure:4934: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_tcsetattr=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tcsetattr=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tcsetattr`\" = yes"; then echo "$ac_t""yes" 1>&6 tcsetattr=1 else echo "$ac_t""no" 1>&6 fi if test $tcgetattr -eq 1 -a $tcsetattr -eq 1 ; then cat >> confdefs.h <<\EOF #define HAVE_TCSETATTR 1 EOF cat >> confdefs.h <<\EOF #define POSIX 1 EOF fi # first check for the pure bsd echo $ac_n "checking for struct sgttyb""... $ac_c" 1>&6 echo "configure:4966: checking for struct sgttyb" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 4972 "configure" #include "confdefs.h" #include <sgtty.h> main() { struct sgttyb tmp; exit(0); } EOF { (eval echo configure:4982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_SGTTYB 1 EOF PTY_TYPE=sgttyb else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # mach systems have include files for unimplemented features # so avoid doing following test on those systems if test $mach -eq 0 ; then # next check for the older style ttys # note that if we detect termio.h (only), we still set PTY_TYPE=termios # since that just controls which of pty_XXXX.c file is use and # pty_termios.c is set up to handle pty_termio. echo $ac_n "checking for struct termio""... $ac_c" 1>&6 echo "configure:5011: checking for struct termio" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5017 "configure" #include "confdefs.h" #include <termio.h> main() { struct termio tmp; exit(0); } EOF { (eval echo configure:5026: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then cat >> confdefs.h <<\EOF #define HAVE_TERMIO 1 EOF PTY_TYPE=termios echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # now check for the new style ttys (not yet posix) echo $ac_n "checking for struct termios""... $ac_c" 1>&6 echo "configure:5048: checking for struct termios" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5054 "configure" #include "confdefs.h" #include <termios.h> main() { struct termios tmp; exit(0); } EOF { (eval echo configure:5063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then cat >> confdefs.h <<\EOF #define HAVE_TERMIOS 1 EOF PTY_TYPE=termios echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi fi echo $ac_n "checking if TCGETS or TCGETA in termios.h""... $ac_c" 1>&6 echo "configure:5085: checking if TCGETS or TCGETA in termios.h" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5091 "configure" #include "confdefs.h" #include <termios.h> main() { #if defined(TCGETS) || defined(TCGETA) return 0; #else return 1; #endif } EOF { (eval echo configure:5103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then cat >> confdefs.h <<\EOF #define HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi echo $ac_n "checking if TIOCGWINSZ in termios.h""... $ac_c" 1>&6 echo "configure:5123: checking if TIOCGWINSZ in termios.h" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5129 "configure" #include "confdefs.h" #include <termios.h> main() { #ifdef TIOCGWINSZ return 0; #else return 1; #endif } EOF { (eval echo configure:5141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then cat >> confdefs.h <<\EOF #define HAVE_TIOCGWINSZ_IN_TERMIOS_H 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # finally check for Cray style ttys echo $ac_n "checking for Cray-style ptys""... $ac_c" 1>&6 echo "configure:5162: checking for Cray-style ptys" >&5 SETUID=":" if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5169 "configure" #include "confdefs.h" main(){ #ifdef CRAY return 0; #else return 1; #endif } EOF { (eval echo configure:5181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then PTY_TYPE=unicos SETUID="chmod u+s" echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # # Check for select and/or poll. If both exist, we prefer select. # if neither exists, define SIMPLE_EVENT. # select=0 poll=0 unset ac_cv_func_select echo $ac_n "checking for select""... $ac_c" 1>&6 echo "configure:5206: checking for select" >&5 if eval "test \"`echo '$''{'ac_cv_func_select'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5211 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char select(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char select(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_select) || defined (__stub___select) choke me #else select(); #endif ; return 0; } EOF if { (eval echo configure:5234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_select=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_select=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'select`\" = yes"; then echo "$ac_t""yes" 1>&6 select=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for poll""... $ac_c" 1>&6 echo "configure:5254: checking for poll" >&5 if eval "test \"`echo '$''{'ac_cv_func_poll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5259 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char poll(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char poll(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_poll) || defined (__stub___poll) choke me #else poll(); #endif ; return 0; } EOF if { (eval echo configure:5282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_poll=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_poll=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'poll`\" = yes"; then echo "$ac_t""yes" 1>&6 poll=1 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking event handling""... $ac_c" 1>&6 echo "configure:5302: checking event handling" >&5 if test $select -eq 1 ; then EVENT_TYPE=select EVENT_ABLE=event echo "$ac_t""via select" 1>&6 elif test $poll -eq 1 ; then EVENT_TYPE=poll EVENT_ABLE=event echo "$ac_t""via poll" 1>&6 else EVENT_TYPE=simple EVENT_ABLE=noevent echo "$ac_t""none" 1>&6 cat >> confdefs.h <<\EOF #define SIMPLE_EVENT 1 EOF fi for ac_func in _getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:5324: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5329 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:5352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF else echo "$ac_t""no" 1>&6 fi done for ac_func in getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:5379: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5384 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ #include <assert.h> /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:5407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <<EOF #define $ac_tr_func 1 EOF else echo "$ac_t""no" 1>&6 fi done # # check for timezones # echo $ac_n "checking for SV-style timezone""... $ac_c" 1>&6 echo "configure:5436: checking for SV-style timezone" >&5 if test "$cross_compiling" = yes; then { echo "configure: error: Expect can't be cross compiled" 1>&2; exit 1; } else cat > conftest.$ac_ext <<EOF #line 5442 "configure" #include "confdefs.h" extern char *tzname[2]; extern int daylight; main() { int *x = &daylight; char **y = tzname; exit(0); } EOF { (eval echo configure:5455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then cat >> confdefs.h <<\EOF #define HAVE_SV_TIMEZONE 1 EOF echo "$ac_t""yes" 1>&6 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* echo "$ac_t""no" 1>&6 fi rm -fr conftest* fi # only look for Tk stuff if we have X11 and user doesn't say not to # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then withval="$with_x" : else with_x=yes fi if test "$with_x" = "no"; then no_tk=true else # # Ok, lets find the tk source trees so we can use the headers # If the directory (presumably symlink) named "tk" exists, use that one # in preference to any others. Same logic is used when choosing library # and again with Tcl. The search order is the best place to look first, then in # decreasing significance. The loop breaks if the trigger file is found. # Note the gross little conversion here of srcdir by cd'ing to the found # directory. This converts the path from a relative to an absolute, so # recursive cache variables for the path will work right. We check all # the possible paths in one loop rather than many seperate loops to speed # things up. # the alternative search directory is involked by --with-tkinclude # #no_tk=true echo $ac_n "checking for Tk private headers""... $ac_c" 1>&6 echo "configure:5501: checking for Tk private headers" >&5 # Check whether --with-tkinclude or --without-tkinclude was given. if test "${with_tkinclude+set}" = set; then withval="$with_tkinclude" with_tkinclude=${withval} fi if eval "test \"`echo '$''{'ac_cv_c_tkh'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # first check to see if --with-tkinclude was specified if test x"${with_tkinclude}" != x ; then if test -f ${with_tkinclude}/tk.h ; then ac_cv_c_tkh=`(cd ${with_tkinclude}; pwd)` elif test -f ${with_tkinclude}/generic/tk.h ; then ac_cv_c_tkh=`(cd ${with_tkinclude}/generic; pwd)` else { echo "configure: error: ${with_tkinclude} directory doesn't contain private headers" 1>&2; exit 1; } fi fi # next check if it came with Tk configuration file if test x"${ac_cv_c_tkconfig}" != x ; then if test -f $ac_cv_c_tkconfig/../generic/tk.h ; then ac_cv_c_tkh=`(cd $ac_cv_c_tkconfig/../generic; pwd)` fi fi # next check in private source directory # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[4-9]* 2>/dev/null` \ ${srcdir}/../../tk \ `ls -dr ${srcdir}/../../tk[4-9]* 2>/dev/null` \ ${srcdir}/../../../tk \ `ls -dr ${srcdir}/../../../tk[4-9]* 2>/dev/null ` ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # finally check in a few common install locations # # since ls returns lowest version numbers first, reverse its output if test x"${ac_cv_c_tkh}" = x ; then for i in \ `ls -dr /usr/local/src/tk[4-9]* 2>/dev/null` \ `ls -dr /usr/local/lib/tk[4-9]* 2>/dev/null` \ /usr/local/src/tk \ /usr/local/lib/tk \ ${prefix}/include ; do if test -f $i/generic/tk.h ; then ac_cv_c_tkh=`(cd $i/generic; pwd)` break fi done fi # see if one is installed if test x"${ac_cv_c_tkh}" = x ; then ac_safe=`echo "tk.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tk.h""... $ac_c" 1>&6 echo "configure:5567: checking for tk.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF #line 5572 "configure" #include "confdefs.h" #include <tk.h> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:5577: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_cv_c_tkh=installed else echo "$ac_t""no" 1>&6 ac_cv_c_tkh="" fi fi fi if test x"${ac_cv_c_tkh}" != x ; then # no_tk="" if test x"${ac_cv_c_tkh}" = x"installed" ; then echo "$ac_t""is installed" 1>&6 TKHDIR="" else echo "$ac_t""found in ${ac_cv_c_tkh}" 1>&6 # this hack is cause the TKHDIR won't print if there is a "-I" in it. TKHDIR="-I${ac_cv_c_tkh}" fi else TKHDIR="# no Tk directory found" echo "configure: warning: Can't find Tk private headers" 1>&2 no_tk=true fi fi if test x"$no_tk" != x"true" ; then # libexpectk no longer exists # X_PROGS="expectk \$(LIBEXPECTK)" X_PROGS=expectk # should really generate following symbol, but I'm hitting configure's limit on substs. X_PROGS_INSTALLED=expectk_installed else X_PROGS="# no X support on this system" echo "configure: warning: No X based programs will be built" 1>&2 echo " WARNING: Can't find Tk headers or library. You can still" echo " build expect, but not expectk. See Expect's README for" echo " information on how to obtain Tk. If Tk is installed, see" echo " Expect's INSTALL on how to tell configure where Tk is" echo " installed." fi # consume these flags so that user can invoke Expect's configure with # the same command as Tcl's configure # Check whether --enable-load or --disable-load was given. if test "${enable_load+set}" = set; then enableval="$enable_load" disable_dl=$enableval else disable_dl=no fi # Check whether --enable-gcc or --disable-gcc was given. if test "${enable_gcc+set}" = set; then enableval="$enable_gcc" enable_gcc=$enableval else enable_gcc=no fi # Following comment stolen from Tcl's configure.in: # Note: in the following variable, it's important to use the absolute # path name of the Tcl directory rather than "..": this is because # AIX remembers this path and will attempt to use it at run-time to look # up the Tcl library. if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then EXP_LIB_VERSION=$EXP_VERSION else EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi if test $iunix -eq 1 ; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) echo $ac_n "checking for long file names""... $ac_c" 1>&6 echo "configure:5676: checking for long file names" >&5 if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_sys_long_file_names=yes # Test for long file names in all the places we know might matter: # . the current directory, where building will happen # $prefix/lib where we will be installing things # $exec_prefix/lib likewise # eval it to expand exec_prefix. # $TMPDIR if set, where it might want to write temporary files # if $TMPDIR is not set: # /tmp where it might want to write temporary files # /var/tmp likewise # /usr/tmp likewise if test -n "$TMPDIR" && test -d "$TMPDIR" && test -w "$TMPDIR"; then ac_tmpdirs="$TMPDIR" else ac_tmpdirs='/tmp /var/tmp /usr/tmp' fi for ac_dir in . $ac_tmpdirs `eval echo $prefix/lib $exec_prefix/lib` ; do test -d $ac_dir || continue test -w $ac_dir || continue # It is less confusing to not echo anything here. (echo 1 > $ac_dir/conftest9012345) 2>/dev/null (echo 2 > $ac_dir/conftest9012346) 2>/dev/null val=`cat $ac_dir/conftest9012345 2>/dev/null` if test ! -f $ac_dir/conftest9012345 || test "$val" != 1; then ac_cv_sys_long_file_names=no rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null break fi rm -f $ac_dir/conftest9012345 $ac_dir/conftest9012346 2>/dev/null done fi echo "$ac_t""$ac_cv_sys_long_file_names" 1>&6 if test $ac_cv_sys_long_file_names = yes; then cat >> confdefs.h <<\EOF #define HAVE_LONG_FILE_NAMES 1 EOF fi if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}" EXP_LIB_SPEC="-L\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}" EXP_NONSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}.a echo $ac_n "checking for type of library to build""... $ac_c" 1>&6 echo "configure:5728: checking for type of library to build" >&5 if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS EXP_SHARED_LIB_FILE=libexpect$EXP_LIB_VERSION$TCL_SHLIB_SUFFIX EXP_LIB_FILE=$EXP_SHARED_LIB_FILE EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_NONSHARED_LIB_FILE" echo "$ac_t""both shared and nonshared" 1>&6 else EXP_SHLIB_CFLAGS= EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library" EXP_LIB_FILE=$EXP_NONSHARED_LIB_FILE EXP_LIB_FILES="$EXP_NONSHARED_LIB_FILE" echo "$ac_t""nonshared" 1>&6 fi # now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this # in order to avoid repeating lib specs to which some systems object. EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $TCL_LD_SEARCH_FLAGS" EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $TCL_LD_SEARCH_FLAGS" # Sigh - Tcl's defines SHLIB_LD_LIBS to be either empty or ${LIBS} and # LIBS is intended to be expanded by Make. But since we're too close # to hitting config's max symbols, pack everything together here and # do test ourselves. Ugh. # if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then EXP_SHLIB_LD_LIBS="" else # seems a little strange to build in Tcl's build-lib, but # that's what Tk does. EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc" fi # # Set up makefile substitutions # trap '' 1 2 15 trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS <<EOF #! /bin/sh # Generated automatically by configure. # Run this file to recreate the current configuration. # This directory was configured as follows, # on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.11" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile pkgIndex expect_cf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS <<EOF # Protect against being on the right side of a sed subst in config.status. sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@target@%$target%g s%@target_alias@%$target_alias%g s%@target_cpu@%$target_cpu%g s%@target_vendor@%$target_vendor%g s%@target_os@%$target_os%g s%@build@%$build%g s%@build_alias@%$build_alias%g s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@TCL_DEFS@%$TCL_DEFS%g s%@TCL_SHLIB_LD@%$TCL_SHLIB_LD%g s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g s%@TCL_RANLIB@%$TCL_RANLIB%g s%@TCL_BUILD_LIB_SPEC@%$TCL_BUILD_LIB_SPEC%g s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g s%@TK_VERSION@%$TK_VERSION%g s%@TK_DEFS@%$TK_DEFS%g s%@TK_XINCLUDES@%$TK_XINCLUDES%g s%@TK_XLIBSW@%$TK_XLIBSW%g s%@TK_BUILD_LIB_SPEC@%$TK_BUILD_LIB_SPEC%g s%@TK_LIB_SPEC@%$TK_LIB_SPEC%g s%@CC@%$CC%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@subdirs@%$subdirs%g s%@CPP@%$CPP%g s%@TCLHDIR@%$TCLHDIR%g s%@TKHDIR@%$TKHDIR%g s%@EXP_MAJOR_VERSION@%$EXP_MAJOR_VERSION%g s%@EXP_MINOR_VERSION@%$EXP_MINOR_VERSION%g s%@EXP_MICRO_VERSION@%$EXP_MICRO_VERSION%g s%@EXP_VERSION_FULL@%$EXP_VERSION_FULL%g s%@EXP_VERSION@%$EXP_VERSION%g s%@EXP_CONFIG_SHELL@%$EXP_CONFIG_SHELL%g s%@EXP_SHARED_LIB_FILE@%$EXP_SHARED_LIB_FILE%g s%@EXP_NONSHARED_LIB_FILE@%$EXP_NONSHARED_LIB_FILE%g s%@EXP_SHLIB_CFLAGS@%$EXP_SHLIB_CFLAGS%g s%@EXP_LIB_FILE@%$EXP_LIB_FILE%g s%@EXP_LIB_FILES@%$EXP_LIB_FILES%g s%@EXP_BUILD_LIB_SPEC@%$EXP_BUILD_LIB_SPEC%g s%@EXP_LIB_SPEC@%$EXP_LIB_SPEC%g s%@EXP_CFLAGS@%$EXP_CFLAGS%g s%@EXP_LDFLAGS@%$EXP_LDFLAGS%g s%@EXP_AND_TCL_LIBS@%$EXP_AND_TCL_LIBS%g s%@EXP_AND_TK_LIBS@%$EXP_AND_TK_LIBS%g s%@EXP_SHLIB_LD_LIBS@%$EXP_SHLIB_LD_LIBS%g s%@X_PROGS@%$X_PROGS%g s%@PTY_TYPE@%$PTY_TYPE%g s%@EVENT_TYPE@%$EVENT_TYPE%g s%@EVENT_ABLE@%$EVENT_ABLE%g s%@SETUID@%$SETUID%g s%@DEFAULT_STTY_ARGS@%$DEFAULT_STTY_ARGS%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <<EOF CONFIG_FILES=\${CONFIG_FILES-"Makefile pkgIndex"} EOF cat >> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_given_srcdir/$ac_file_in | eval "$ac_sed_cmds" > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test -z "$CONFIG_HEADERS"; then EOF cat >> $CONFIG_STATUS <<EOF CONFIG_HEADERS="expect_cf.h" EOF cat >> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out cp $ac_given_srcdir/$ac_file_in conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 if test "$no_recursion" != yes; then # Remove --cache-file and --srcdir arguments so they do not pile up. ac_sub_configure_args= ac_prev= for ac_arg in $ac_configure_args; do if test -n "$ac_prev"; then ac_prev= continue fi case "$ac_arg" in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; esac done for ac_config_dir in testsuite; do # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. if test ! -d $srcdir/$ac_config_dir; then continue fi echo configuring in $ac_config_dir case "$srcdir" in .) ;; *) if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; else { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } fi ;; esac ac_popdir=`pwd` cd $ac_config_dir # A "../" for each directory in /$ac_config_dir. ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` case "$srcdir" in .) # No --srcdir option. We are building in place. ac_sub_srcdir=$srcdir ;; /*) # Absolute path. ac_sub_srcdir=$srcdir/$ac_config_dir ;; *) # Relative path. ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; esac # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_sub_srcdir/configure; then ac_sub_configure=$ac_sub_srcdir/configure elif test -f $ac_sub_srcdir/configure.in; then ac_sub_configure=$ac_configure else echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case "$cache_file" in /*) ac_sub_cache_file=$cache_file ;; *) # Relative path. ac_sub_cache_file="$ac_dots$cache_file" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" # The eval makes quoting arguments work. if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir then : else { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } fi fi cd $ac_popdir done fi |
Added unix/configure.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 | # Process this file with autoconf to produce a configure script. # while Expect is in alpha/beta, disable caching so as not to confuse # people trying to fix configure bugs define([AC_CACHE_LOAD], ) define([AC_CACHE_SAVE], ) AC_INIT(expect.h) EXP_MAJOR_VERSION=5 EXP_MINOR_VERSION=21 EXP_MICRO_VERSION=7 EXP_VERSION=$EXP_MAJOR_VERSION.$EXP_MINOR_VERSION EXP_VERSION_NODOTS=$EXP_MAJOR_VERSION$EXP_MINOR_VERSION EXP_VERSION_FULL=$EXP_VERSION.$EXP_MICRO_VERSION # Too many people send me configure output without identifying the version. # This forced identification should reduce my pain significantly. echo "configuring Expect $EXP_MAJOR_VERSION.$EXP_MINOR_VERSION.$EXP_MICRO_VERSION" dnl AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..) AC_CANONICAL_SYSTEM AC_CONFIG_HEADER(expect_cf.h) # /bin/sh on some systems is too deficient (in particular, Ultrix 4.3 # sh lacks unset and we *need* that), but all these systems come with # alternatives, so take user's choice or whatever we're using here and # allow it to be seen by Make. AC_MSG_CHECKING([shell to use within Make]) EXP_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} AC_MSG_RESULT($CONFIG_SHELL) # If `configure' is invoked (in)directly via `make', ensure that it # encounters no `make' conflicts. # dnl unset MFLAGS MAKEFLAGS MFLAGS= MAKEFLAGS= CY_AC_PATH_TCLCONFIG CY_AC_LOAD_TCLCONFIG CC=$TCL_CC EXP_AND_TCL_LIBS=$TCL_LIBS CY_AC_PATH_TKCONFIG CY_AC_LOAD_TKCONFIG EXP_AND_TK_LIBS=$TK_LIBS # An explanation is in order for the strange things going on with the # various LIBS. There are three separate definitions for LIBS. The # reason is that some systems require shared libraries include # references to their dependent libraries, i.e., any additional # libraries that must be linked to. And some systems get upset if the # references are repeated on the link line. So therefore, we create # one for Expect and Tk (EXP_AND_TK_LIBS), one for Expect and Tcl # (EXP_AND_TCL_LIBS), and finally, one for building Expect's own # shared library. Tcl's tclConfig.sh insists that any shared libs # that it "helps" build must pass the libraries as LIBS (see comment # near end of this configure file). I would do but since we're close # to hitting config's max symbols, we take one short cut and pack the # LIBS into EXP_SHLIB_LD_LIBS (which is basically what Tcl wants to do # for us). The point, however, is that there's no separate LIBS or # EXP_LIBS symbol passed out of configure. One additional point for # confusion is that LIBS is what configure uses to do all library # tests, so we have to swap definitions of LIBS peridically. When we # are swapping out the one for Expect's shared library, we save it in # EXP_LIBS. Sigh. dnl AC_PROG_CC insists on sticking crap -g and -O in CFLAGS dnl but I want to control it. Can't just throw it out at the dnl end alas, because the user might have defined CFLAGS. OLD_CFLAGS=$CFLAGS AC_PROG_CC CFLAGS=$OLD_CFLAGS CY_AC_C_WORKS # this'll use a BSD compatible install or our included install-sh AC_PROG_INSTALL # these are the other subdirectories we need to configure AC_CONFIG_SUBDIRS(testsuite) # This is for LynxOS, which needs a flag to force true POSIX when # building. The flag varies depending how old the compiler is. # -X is for the old "cc" and "gcc" (based on 1.42) # -mposix is for the new gcc (at least 2.5.8) # This modifies the value of $CC to have the POSIX flag added # so it'll configure correctly CY_AC_TCL_LYNX_POSIX AC_TYPE_PID_T AC_RETSIGTYPE dnl AC_TIME_WITH_SYS_TIME AC_HEADER_TIME AC_HEADER_SYS_WAIT EXP_CFLAGS=-g case "${host}" in # Use -g on all systems but Linux where it upsets the dynamic X libraries. i[[3456]]86-*-linux*) EXP_CFLAGS="" ;; esac AC_MSG_CHECKING([if running Mach]) mach=0 case "${host}" in # Both Next and pure Mach behave identically with respect # to a few things, so just lump them together as "mach" *-*-mach*) mach=1 ;; *-*-next*) mach=1 ; next=1 ;; esac if test $mach -eq 1 ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([if running MachTen]) # yet another Mach clone if test -r /MachTen ; then AC_MSG_RESULT(yes) mach=1 else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([if on Pyramid]) if test -r /bin/pyr ; then AC_MSG_RESULT(yes) pyr=1 else AC_MSG_RESULT(no) pyr=0 fi AC_MSG_CHECKING([if on Apollo]) if test -r /usr/apollo/bin ; then AC_MSG_RESULT(yes) apollo=1 else AC_MSG_RESULT(no) apollo=0 fi AC_MSG_CHECKING([if on Interactive]) if test "x`(uname -s) 2>/dev/null`" = xIUNIX; then AC_MSG_RESULT(yes) iunix=1 else AC_MSG_RESULT(no) iunix=0 fi AC_MSG_CHECKING([if stty reads stdout]) # On some systems stty can't be run in the background (svr4) or get it # wrong because they fail to complain (next, mach), so don't attempt # the test on some systems. stty_reads_stdout="" case "${host}" in *-*-solaris*) stty_reads_stdout=0 ;; *-*-irix*) stty_reads_stdout=0 ;; *-sco3.2v[[45]]*) stty_reads_stdout=1 ;; i[[3456]]86-*-linux*) stty_reads_stdout=0 ;; # Not sure about old convex but 5.2 definitely reads from stdout c[[12]]-*-*) stty_reads_stdout=1 ;; *-*-aix[[34]]*) stty_reads_stdout=0 ;; *-*-hpux9*) stty_reads_stdout=0 ;; *-*-hpux10*) stty_reads_stdout=0 ;; *-*-osf[[234]]*) stty_reads_stdout=0 ;; *-*-ultrix4.4) stty_reads_stdout=0 ;; *-*-dgux*) stty_reads_stdout=0 ;; esac if test $mach -eq 1 ; then stty_reads_stdout=1 fi if test $apollo -eq 1 ; then stty_reads_stdout=1 fi if test $pyr -eq 1 ; then stty_reads_stdout=1 fi # if we still don't know, test if test x"${stty_reads_stdout}" = x"" ; then /bin/stty > /dev/null 2> /dev/null if test $? -ne 0 ; then stty_reads_stdout=1 else stty_reads_stdout=0 fi fi if test ${stty_reads_stdout} -eq 1 ; then AC_MSG_RESULT(yes) AC_DEFINE(STTY_READS_STDOUT) else AC_MSG_RESULT(no) fi # Solaris 2.4 and later requires __EXTENSIONS__ in order to see all sorts # of traditional but nonstandard stuff in header files. AC_MSG_CHECKING([if running Solaris]) solaris=0 case "${host}" in *-*-solaris*) solaris=1;; esac if test $solaris -eq 1 ; then AC_MSG_RESULT(yes) AC_DEFINE(SOLARIS) else AC_MSG_RESULT(no) fi # On a few systems, libm.a is the same as libc.a # Don't bother to test against Tcl and Tk libs, they always include -lm AC_CHECK_FUNC(sin, , LIBS="${LIBS} -lm" ) # On Interactive UNIX, -Xp must be added to LIBS in order to find strftime. # This test should really be done by Tcl. So just check Tcl's definition. # If defective, add to all three LIBS. (It's not actually necessary for # EXP_LIBS since -Xp will just be ignored the way that EXP_LIBS is used in # the Makefile, but we include it for consistency.) if test $iunix -eq 1 ; then EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS AC_CHECK_FUNC(strftime, , [ EXP_LIBS="${LIBS} -Xp" EXP_AND_TCL_LIBS="${LIBS} -Xp" EXP_AND_TK_LIBS="${LIBS} -Xp" ]) LIBS=EXP_LIBS fi # # Ok, lets find the tcl source trees so we can use the headers # CY_AC_PATH_TCLH if test x"$no_tcl" = x"true" ; then echo " ERROR: Can't find Tcl headers or library." echo " See README for information on how to obtain Tcl." echo " If Tcl is installed, see INSTALL on how to tell" echo " configure where Tcl is installed." exit 1 fi # have to know whether we're generating shared libs before configuring debugger AC_MSG_CHECKING([for type of library to build]) AC_ARG_ENABLE(shared, [ --enable-shared build libexpect as a shared library], [enable_shared=$enableval], [enable_shared=no]) if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then AC_MSG_RESULT(both shared and nonshared) else AC_MSG_RESULT(nonshared) fi # # Now that we've found the Tcl sources, configure the debugger # this is a little tricky because it has its own configure script # which produces a Makefile and cf file. We only want the cf file, # so switch to a temporary directory and run the debugger's configure. # Then save the cf file and delete the rest. # # Incidentally, the debugger can't depend on Expect's cf file, because # the debugger is designed to be independent of Expect. # test -n "$verbose" && echo "configuring Tcl debugger" tmpdir=./Dbg$$ mkdir ${tmpdir} #if test "${enable_shared+set}" = set; then if test "${enable_shared}" = "yes"; then dbg_config_flags='--enable-shared' else dbg_config_flags='--disable-shared' fi # (cd;pwd) in next several commands converts relative dirs to absolute. # This is required because the debugger src is at a different level in # the filesystem than Expect src (where we are presently), thereby # making the relative pathnames incorrect. if test "x$with_tclconfig" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tclconfig=`(cd ${with_tclconfig}; pwd)`" fi if test "x$with_tcllibdir" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tcllibdir=`(cd ${with_tcllibdir}; pwd)`" fi if test "x$with_tcllib" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tcllib=`(cd ${with_tcllib}; pwd)`" fi if test "x$with_tclinclude" != "x" ; then dbg_config_flags="$dbg_config_flags --with-tclinclude=`(cd ${with_tclinclude}; pwd)`" fi case "$cache_file" in /*) dbg_config_flags="$dbg_config_flags --cache-file=$cache_file" ;; *) dbg_config_flags="$dbg_config_flags --cache-file=../$cache_file" ;; esac cp ${srcdir}/Dbgconfigure ${srcdir}/Dbg.h ${srcdir}/Dbg_cf.h.in ${srcdir}/install-sh ${tmpdir} cp $srcdir/DbgMkfl.in ${tmpdir}/Makefile.in (cd $tmpdir; ${CONFIG_SHELL-/bin/sh} Dbgconfigure --with-tclinclude=`echo ${TCLHDIR} | sed -e 's/-I//'` $dbg_config_flags) cp ${tmpdir}/Dbg_cf.h . rm -rf $tmpdir test -n "$verbose" && echo "configured Tcl debugger" # some people would complain if this explanation wasn't provided... echo "Begin tests for function/library dependencies. Tests may be repeated" echo "up to three times. First test is for building Expect's shared library." echo "Second set is for building with Tcl. Third is for building with Tk." # required by Sequent ptx2 unset ac_cv_func_gethostname AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0) if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet") fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_gethostname AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0) if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet") fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_gethostname AC_CHECK_FUNC(gethostname, gethostname=1 , gethostname=0) if test $gethostname -eq 0 ; then unset ac_cv_lib_inet_gethostname AC_CHECK_LIB(inet, gethostname, LIBS="$LIBS -linet") fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # required by Fischman's ISC 4.0 unset ac_cv_func_socket AC_CHECK_FUNC(socket, socket=1 , socket=0) if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet") fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_socket AC_CHECK_FUNC(socket, socket=1 , socket=0) if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet") fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_socket AC_CHECK_FUNC(socket, socket=1 , socket=0) if test $socket -eq 0 ; then unset ac_cv_lib_inet_socket AC_CHECK_LIB(inet, socket, LIBS="$LIBS -linet") fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS unset ac_cv_func_select AC_CHECK_FUNC(select, select=1 , select=0) if test $select -eq 0 ; then unset ac_cv_lib_inet_select AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet") fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_select AC_CHECK_FUNC(select, select=1 , select=0) if test $select -eq 0 ; then unset ac_cv_lib_inet_select AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet") fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_select AC_CHECK_FUNC(select, select=1 , select=0) if test $select -eq 0 ; then unset ac_cv_lib_inet_select AC_CHECK_LIB(inet, select, LIBS="$LIBS -linet") fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS unset ac_cv_func_getpseudotty AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0) if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty AC_CHECK_LIB(seq, getpseudotty) fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_getpseudotty AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0) if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty AC_CHECK_LIB(seq, getpseudotty) fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_getpseudotty AC_CHECK_FUNC(getpseudotty, getpseudotty=1 , getpseudotty=0) if test $getpseudotty -eq 0 ; then unset ac_cv_lib_seq_getpseudotty AC_CHECK_LIB(seq, getpseudotty) fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # Check for FreeBSD/NetBSD openpty() unset ac_cv_func_openpty AC_CHECK_FUNC(openpty, openpty=1 , openpty=0) if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty AC_CHECK_LIB(util, openpty, [ # we only need to define OPENPTY once, but since we are overriding # the default behavior, we must also handle augment LIBS too. # This needn't be done in the 2nd and 3rd tests. AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lutil" ]) fi # save results and retry for Tcl EXP_LIBS=$LIBS LIBS=$EXP_AND_TCL_LIBS unset ac_cv_func_openpty AC_CHECK_FUNC(openpty, openpty=1 , openpty=0) if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty AC_CHECK_LIB(util, openpty) fi # save Tcl results and retry for Tk EXP_AND_TCL_LIBS=$LIBS LIBS=$EXP_AND_TK_LIBS unset ac_cv_func_openpty AC_CHECK_FUNC(openpty, openpty=1 , openpty=0) if test $openpty -eq 0 ; then unset ac_cv_lib_util_openpty AC_CHECK_LIB(util, openpty) fi # save Tk results and reset for Expect EXP_AND_TK_LIBS=$LIBS LIBS=$EXP_LIBS # # Look for various header files # AC_CHECK_HEADER(sys/sysmacros.h, AC_DEFINE(HAVE_SYSMACROS_H)) AC_CHECK_HEADER(stdlib.h, ,AC_DEFINE(NO_STDLIB_H)) # Oddly, some systems have stdarg but don't support prototypes # Tcl avoids the whole issue by not using stdarg on UNIX at all! dnl AC_CHECK_HEADER(stdarg.h, AC_DEFINE(HAVE_STDARG_H)) AC_CHECK_HEADER(varargs.h, AC_DEFINE(HAVE_VARARGS_H)) AC_CHECK_HEADER(unistd.h, AC_DEFINE(HAVE_UNISTD_H)) AC_CHECK_HEADER(sys/stropts.h, AC_DEFINE(HAVE_STROPTS_H)) AC_CHECK_HEADER(sys/sysconfig.h, AC_DEFINE(HAVE_SYSCONF_H)) AC_CHECK_HEADER(sys/fcntl.h, AC_DEFINE(HAVE_SYS_FCNTL_H)) AC_CHECK_HEADER(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H)) AC_CHECK_HEADER(sys/time.h, AC_DEFINE(HAVE_SYS_TIME_H)) AC_CHECK_HEADER(sys/ptem.h, AC_DEFINE(HAVE_SYS_PTEM_H)) AC_CHECK_HEADER(sys/strredir.h, AC_DEFINE(HAVE_STRREDIR_H)) AC_CHECK_HEADER(sys/strpty.h, AC_DEFINE(HAVE_STRPTY_H)) dnl #echo checking for ucbinclude/sys/ioctl.h (ucb-style ioctl.h under SV) dnl #if test -f /usr/ucbinclude/sys/ioctl.h ; then dnl # AC_DEFINE(HAVE_UCB_IOCTL_H) dnl #fi AC_MSG_CHECKING([for sys/bsdtypes.h]) if test "ISC_${ISC}" = "ISC_1" ; then AC_MSG_RESULT(yes) # if on ISC 1, we need <sys/bsdtypes.h> to get FD_SET macros AC_HAVE_HEADERS(sys/bsdtypes.h) else AC_MSG_RESULT(no) fi # # Look for functions that may be missing # dnl AC_CHECK_FUNC(memcpy, AC_DEFINE(HAVE_MEMCPY)) AC_CHECK_FUNC(memmove, AC_DEFINE(HAVE_MEMMOVE)) AC_CHECK_FUNC(sysconf, AC_DEFINE(HAVE_SYSCONF)) AC_CHECK_FUNC(strftime, AC_DEFINE(HAVE_STRFTIME)) AC_CHECK_FUNC(strchr, AC_DEFINE(HAVE_STRCHR)) AC_CHECK_FUNC(timezone, AC_DEFINE(HAVE_TIMEZONE)) # dnl check for memcpy by hand # because Unixware 2.0 handles it specially and refuses to compile # autoconf's automatic test that is a call with no arguments AC_MSG_CHECKING([for memcpy]) AC_TRY_LINK(,[ char *s1, *s2; memcpy(s1,s2,0); ], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_MEMCPY) , AC_MSG_RESULT(no) ) # Some systems only define WNOHANG if _POSIX_SOURCE is defined # The following merely tests that sys/wait.h can be included # and if so that WNOHANG is not defined. The only place I've # seen this is ISC. AC_MSG_CHECKING([if WNOHANG requires _POSIX_SOURCE]) AC_TRY_RUN([ #include <sys/wait.h> main() { #ifndef WNOHANG return 0; #else return 1; #endif }], AC_MSG_RESULT(yes) AC_DEFINE(WNOHANG_REQUIRES_POSIX_SOURCE) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) AC_MSG_CHECKING([if any value exists for WNOHANG]) rm -rf wnohang AC_TRY_RUN([ #include <stdio.h> #include <sys/wait.h> main() { #ifdef WNOHANG FILE *fp = fopen("wnohang","w"); fprintf(fp,"%d",WNOHANG); fclose(fp); return 0; #else return 1; #endif }], AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(WNOHANG_BACKUP_VALUE, `cat wnohang`) rm -f wnohang , AC_MSG_RESULT(no) AC_DEFINE(WNOHANG_BACKUP_VALUE, 1) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # # check how signals work # # Check for the data type of the mask used in select(). # This picks up HP braindamage which defines fd_set and then # proceeds to ignore it and use int. # Pattern matching on int could be loosened. # Can't use ac_header_egrep since that doesn't see prototypes with K&R cpp. AC_MSG_CHECKING([mask type of select]) if egrep "select\(size_t, int" /usr/include/sys/time.h >/dev/null 2>&1; then AC_MSG_RESULT(int) AC_DEFINE(SELECT_MASK_TYPE, int) else AC_MSG_RESULT(none) fi dnl # Check for the data type of the function used in signal(). This dnl # must be before the test for rearming. dnl # echo checking return type of signal handlers dnl AC_HEADER_EGREP([(void|sighandler_t).*signal], signal.h, retsigtype=void,AC_DEFINE(RETSIGTYPE, int) retsigtype=int) # FIXME: check if alarm exists AC_MSG_CHECKING([if signals need to be re-armed]) AC_TRY_RUN([ #include <signal.h> #define RETSIGTYPE $retsigtype int signal_rearms = 0; RETSIGTYPE child_sigint_handler(n) int n; { } RETSIGTYPE parent_sigint_handler(n) int n; { signal_rearms++; } main() { signal(SIGINT,parent_sigint_handler); if (0 == fork()) { signal(SIGINT,child_sigint_handler); kill(getpid(),SIGINT); kill(getpid(),SIGINT); kill(getppid(),SIGINT); } else { int status; wait(&status); unlink("core"); exit(signal_rearms); } }], AC_MSG_RESULT(yes) AC_DEFINE(REARM_SIG) , AC_MSG_RESULT(no) , AC_MSG_WARN([Expect can't be cross compiled]) ) # HPUX7 has trouble with the big cat so split it # Owen Rees <[email protected]> 29Mar93 SEDDEFS="${SEDDEFS}CONFEOF cat >> conftest.sed <<CONFEOF " # # There are multiple versions of getpty, alas. # I don't remember who has the first one, but Convex just added one # so check for it. Unfortunately, there is no header so the only # reasonable way to make sure is to look it we are on a Convex. AC_MSG_CHECKING([if on Convex]) convex=0 case "${host}" in c[[12]]-*-*) convex=1;; esac if test $convex -eq 1 ; then AC_MSG_RESULT(yes) AC_DEFINE(CONVEX) else AC_MSG_RESULT(no) fi EXP_LDFLAGS= AC_MSG_CHECKING([if on NeXT]) if test -r /NextApps ; then AC_MSG_RESULT(yes) # "-m" flag suppresses complaints about multiple strtod EXP_LDFLAGS="$EXP_LDFLAGS -m" else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([if on HP]) if test "x`(uname) 2>/dev/null`" = xHP-UX; then AC_MSG_RESULT(yes) hp=1 else AC_MSG_RESULT(no) hp=0 fi AC_MSG_CHECKING([sane default stty arguments]) DEFAULT_STTY_ARGS="sane" if test $mach -eq 1 ; then DEFAULT_STTY_ARGS="cooked" fi if test $hp -eq 1 ; then DEFAULT_STTY_ARGS="sane kill " fi AC_MSG_RESULT($DEFAULT_STTY_ARG) # Look for various features to determine what kind of pty # we have. For some weird reason, ac_compile_check would not # work, but ac_test_program does. # AC_MSG_CHECKING([for HP style pty allocation]) # following test fails on DECstations and other things that don't grok -c # but that's ok, since they don't have PTYMs anyway if test -r /dev/ptym/ptyp0 2>/dev/null ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTYM) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([for HP style pty trapping]) AC_HEADER_EGREP([struct.*request_info], sys/ptyio.h, AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTYTRAP) , AC_MSG_RESULT(no) ) AC_MSG_CHECKING([for AIX new-style pty allocation]) if test -r /dev/ptc -a -r /dev/pts ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTC_PTS) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([for SGI old-style pty allocation]) if test -r /dev/ptc -a ! -r /dev/pts ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTC) else AC_MSG_RESULT(no) fi # On SCO OpenServer, two types of ptys are available: SVR4 streams and c-list. # The library routines to open the SVR4 ptys are broken on certain systems and # the SCO command to increase the number of ptys only configure c-list ones # anyway. So we chose these, which have a special numbering scheme. # AC_MSG_CHECKING([for SCO style pty allocation]) sco_ptys="" case "${host}" in *-sco3.2v[[45]]*) sco_clist_ptys=1 svr4_ptys_broken=1;; esac if test x"${sco_clist_ptys}" != x"" ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SCO_CLIST_PTYS) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING([for SVR4 style pty allocation]) if test -r /dev/ptmx -a "x$svr4_ptys_broken" = x ; then AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PTMX) # aargg. Some systems need libpt.a to use /dev/ptmx AC_CHECK_FUNC(ptsname, , LIBS="${LIBS} -lpt") # I've never seen Tcl or Tk include -lpt so don't bother with explicit test AC_CHECK_FUNC(ptsname, , EXP_AND_TCL_LIBS="${EXP_AND_TCL_LIBS} -lpt") AC_CHECK_FUNC(ptsname, , EXP_AND_TK_LIBS="${EXP_AND_TK_LIBS} -lpt") else AC_MSG_RESULT(no) fi # In OSF/1 case, SVR4 are somewhat different. # Gregory Depp <[email protected]> 17Aug93 AC_MSG_CHECKING([for OSF/1 style pty allocation]) if test -r /dev/ptmx_bsd ; then AC_DEFINE(HAVE_PTMX_BSD) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi tcgetattr=0 tcsetattr=0 AC_CHECK_FUNC(tcgetattr, tcgetattr=1) AC_CHECK_FUNC(tcsetattr, tcsetattr=1) if test $tcgetattr -eq 1 -a $tcsetattr -eq 1 ; then AC_DEFINE(HAVE_TCSETATTR) AC_DEFINE(POSIX) fi # first check for the pure bsd AC_MSG_CHECKING([for struct sgttyb]) AC_TRY_RUN([ #include <sgtty.h> main() { struct sgttyb tmp; exit(0); }], AC_MSG_RESULT(yes) AC_DEFINE(HAVE_SGTTYB) PTY_TYPE=sgttyb , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # mach systems have include files for unimplemented features # so avoid doing following test on those systems if test $mach -eq 0 ; then # next check for the older style ttys # note that if we detect termio.h (only), we still set PTY_TYPE=termios # since that just controls which of pty_XXXX.c file is use and # pty_termios.c is set up to handle pty_termio. AC_MSG_CHECKING([for struct termio]) AC_TRY_RUN([#include <termio.h> main() { struct termio tmp; exit(0); }], AC_DEFINE(HAVE_TERMIO) PTY_TYPE=termios AC_MSG_RESULT(yes) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # now check for the new style ttys (not yet posix) AC_MSG_CHECKING([for struct termios]) AC_TRY_RUN([#include <termios.h> main() { struct termios tmp; exit(0); }], AC_DEFINE(HAVE_TERMIOS) PTY_TYPE=termios AC_MSG_RESULT(yes) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) fi AC_MSG_CHECKING([if TCGETS or TCGETA in termios.h]) AC_TRY_RUN([ #include <termios.h> main() { #if defined(TCGETS) || defined(TCGETA) return 0; #else return 1; #endif }], AC_DEFINE(HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) AC_MSG_CHECKING([if TIOCGWINSZ in termios.h]) AC_TRY_RUN([ #include <termios.h> main() { #ifdef TIOCGWINSZ return 0; #else return 1; #endif }], AC_DEFINE(HAVE_TIOCGWINSZ_IN_TERMIOS_H) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # finally check for Cray style ttys AC_MSG_CHECKING([for Cray-style ptys]) SETUID=":" AC_TRY_RUN([ main(){ #ifdef CRAY return 0; #else return 1; #endif } ], PTY_TYPE=unicos SETUID="chmod u+s" AC_MSG_RESULT(yes) , AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # # Check for select and/or poll. If both exist, we prefer select. # if neither exists, define SIMPLE_EVENT. # select=0 poll=0 unset ac_cv_func_select AC_CHECK_FUNC(select, select=1) AC_CHECK_FUNC(poll, poll=1) AC_MSG_CHECKING([event handling]) if test $select -eq 1 ; then EVENT_TYPE=select EVENT_ABLE=event AC_MSG_RESULT(via select) elif test $poll -eq 1 ; then EVENT_TYPE=poll EVENT_ABLE=event AC_MSG_RESULT(via poll) else EVENT_TYPE=simple EVENT_ABLE=noevent AC_MSG_RESULT(none) AC_DEFINE(SIMPLE_EVENT) fi AC_HAVE_FUNCS(_getpty) AC_HAVE_FUNCS(getpty) # # check for timezones # AC_MSG_CHECKING([for SV-style timezone]) AC_TRY_RUN([ extern char *tzname[2]; extern int daylight; main() { int *x = &daylight; char **y = tzname; exit(0); }], AC_DEFINE(HAVE_SV_TIMEZONE) AC_MSG_RESULT(yes), AC_MSG_RESULT(no) , AC_MSG_ERROR([Expect can't be cross compiled]) ) # only look for Tk stuff if we have X11 and user doesn't say not to AC_ARG_WITH(x, [ --with-x whether or not to use X (default yes)], , with_x=yes) if test "$with_x" = "no"; then no_tk=true else CY_AC_PATH_TKH fi if test x"$no_tk" != x"true" ; then # libexpectk no longer exists # X_PROGS="expectk \$(LIBEXPECTK)" X_PROGS=expectk # should really generate following symbol, but I'm hitting configure's limit on substs. X_PROGS_INSTALLED=expectk_installed else X_PROGS="# no X support on this system" AC_MSG_WARN([No X based programs will be built]) echo " WARNING: Can't find Tk headers or library. You can still" echo " build expect, but not expectk. See Expect's README for" echo " information on how to obtain Tk. If Tk is installed, see" echo " Expect's INSTALL on how to tell configure where Tk is" echo " installed." fi # consume these flags so that user can invoke Expect's configure with # the same command as Tcl's configure AC_ARG_ENABLE(load, [ --disable-load disallow dynamic loading], [disable_dl=$enableval], [disable_dl=no]) AC_ARG_ENABLE(gcc, [ --enable-gcc allow use of gcc if available], [enable_gcc=$enableval], [enable_gcc=no]) # Following comment stolen from Tcl's configure.in: # Note: in the following variable, it's important to use the absolute # path name of the Tcl directory rather than "..": this is because # AIX remembers this path and will attempt to use it at run-time to look # up the Tcl library. if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then EXP_LIB_VERSION=$EXP_VERSION else EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi if test $iunix -eq 1 ; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi # also remove dots on systems that don't support filenames > 14 # (are there systems which support shared libs and restrict filename lengths!?) AC_SYS_LONG_FILE_NAMES if test $ac_cv_sys_long_file_names = no; then EXP_LIB_VERSION=$EXP_VERSION_NODOTS fi EXP_BUILD_LIB_SPEC="-L`pwd` -lexpect${EXP_LIB_VERSION}" EXP_LIB_SPEC="-L\${exec_prefix}/lib -lexpect${EXP_LIB_VERSION}" EXP_NONSHARED_LIB_FILE=libexpect${EXP_LIB_VERSION}.a AC_MSG_CHECKING([for type of library to build]) if test "$enable_shared" = "yes" && test "x${TCL_SHLIB_SUFFIX}" != "x" ; then EXP_SHLIB_CFLAGS=$TCL_SHLIB_CFLAGS EXP_SHARED_LIB_FILE=libexpect$EXP_LIB_VERSION$TCL_SHLIB_SUFFIX EXP_LIB_FILE=$EXP_SHARED_LIB_FILE EXP_LIB_FILES="$EXP_SHARED_LIB_FILE $EXP_NONSHARED_LIB_FILE" AC_MSG_RESULT(both shared and nonshared) else EXP_SHLIB_CFLAGS= EXP_SHARED_LIB_FILE="reconfigure_Tcl_for_shared_library" EXP_LIB_FILE=$EXP_NONSHARED_LIB_FILE EXP_LIB_FILES="$EXP_NONSHARED_LIB_FILE" AC_MSG_RESULT(nonshared) fi # now broken out into EXP_AND_TCL_LIBS and EXP_AND_TK_LIBS. Had to do this # in order to avoid repeating lib specs to which some systems object. EXP_AND_TCL_LIBS="$EXP_AND_TCL_LIBS $TCL_LD_SEARCH_FLAGS" EXP_AND_TK_LIBS="$EXP_AND_TK_LIBS $TCL_LD_SEARCH_FLAGS" # Sigh - Tcl's defines SHLIB_LD_LIBS to be either empty or ${LIBS} and # LIBS is intended to be expanded by Make. But since we're too close # to hitting config's max symbols, pack everything together here and # do test ourselves. Ugh. # if test "x$TCL_SHLIB_LD_LIBS" = "x" ; then EXP_SHLIB_LD_LIBS="" else # seems a little strange to build in Tcl's build-lib, but # that's what Tk does. EXP_SHLIB_LD_LIBS="$TCL_BUILD_LIB_SPEC $TCL_DL_LIBS $LIBS -lc" fi # # Set up makefile substitutions # AC_SUBST(EXP_MAJOR_VERSION) AC_SUBST(EXP_MINOR_VERSION) AC_SUBST(EXP_MICRO_VERSION) AC_SUBST(EXP_VERSION_FULL) AC_SUBST(EXP_VERSION) AC_SUBST(CC) AC_SUBST(EXP_CONFIG_SHELL) AC_SUBST(EXP_SHARED_LIB_FILE) AC_SUBST(EXP_NONSHARED_LIB_FILE) AC_SUBST(EXP_SHLIB_CFLAGS) AC_SUBST(EXP_LIB_FILE) AC_SUBST(EXP_LIB_FILES) AC_SUBST(EXP_BUILD_LIB_SPEC) AC_SUBST(EXP_LIB_SPEC) AC_SUBST(EXP_CFLAGS) AC_SUBST(EXP_LDFLAGS) AC_SUBST(EXP_AND_TCL_LIBS) AC_SUBST(EXP_AND_TK_LIBS) AC_SUBST(EXP_SHLIB_LD_LIBS) AC_SUBST(X_PROGS) AC_SUBST(PTY_TYPE) AC_SUBST(EVENT_TYPE) AC_SUBST(EVENT_ABLE) AC_SUBST(SETUID) AC_SUBST(DEFAULT_STTY_ARGS) AC_OUTPUT(Makefile pkgIndex) |
Added unix/expUnixCommand.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 | #define STTY_INIT "stty_init" /* zero out the wait status field */ static void exp_wait_zero(status) WAIT_STATUS_TYPE *status; { int i; for (i=0;i<sizeof(WAIT_STATUS_TYPE);i++) { ((char *)status)[i] = 0; } } /* prevent an fd from being allocated */ void exp_busy(fd) int fd; { int x = open("/dev/null",0); if (x != fd) { fcntl(x,F_DUPFD,fd); close(x); } } /* *---------------------------------------------------------------------- * * exp_f_new_platform -- * * Platform specific initialization of exp_f structure * * Results: * TRUE if successful, FALSE if unsuccessful. * * Side Effects: * None * *---------------------------------------------------------------------- */ int exp_f_new_platform(f) exp_f *f; { f->tclPid = f->pid; return TRUE; } void exp_close_on_exec(fd) int fd; { (void) fcntl(fd,F_SETFD,1); } /* *---------------------------------------------------------------------- * * exp_getpidproc -- * * Return the process id for this process * * Results: * A process id * *---------------------------------------------------------------------- */ int exp_getpidproc() { return getpid(); } /* *---------------------------------------------------------------------- * * Exp_SpawnCmd -- * * Creates a new expect process id. It normally does this * by creating a new process, but it may choose to open a * Tcl file id. * * Results: * A standard Tcl result * * Side Effects: * * Notes: * arguments are passed verbatim to execvp() *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_SpawnCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int slave; int pid; char **a; /* tell Saber to ignore non-use of ttyfd */ /*SUPPRESS 591*/ int errorfd; /* place to stash fileno(stderr) in child */ /* while we're setting up new stderr */ int ttyfd; int master; int write_master; /* write fd of Tcl-opened files */ int ttyinit = TRUE; int ttycopy = TRUE; int echo = TRUE; int console = FALSE; int pty_only = FALSE; #ifdef FULLTRAPS /* Allow user to reset signals in child */ /* The following array contains indicates */ /* whether sig should be DFL or IGN */ /* ERR is used to indicate no initialization */ RETSIGTYPE (*traps[NSIG])(); #endif int ignore[NSIG]; /* if true, signal in child is ignored */ /* if false, signal gets default behavior */ int i; /* trusty overused temporary */ char *argv0 = argv[0]; char *openarg = 0; int leaveopen = FALSE; FILE *readfilePtr; FILE *writefilePtr; int rc, wc; char *stty_init; int slave_write_ioctls = 1; /* by default, slave will be write-ioctled this many times */ int slave_opens = 3; /* by default, slave will be opened this many times */ /* first comes from initial allocation */ /* second comes from stty */ /* third is our own signal that stty is done */ int sync_fds[2]; int sync2_fds[2]; int status_pipe[2]; int child_errno; char sync_byte; char buf[4]; /* enough space for a string literal */ /* representing a file descriptor */ Tcl_DString dstring; Tcl_DStringInit(&dstring); #ifdef FULLTRAPS init_traps(&traps); #endif /* don't ignore any signals in child by default */ for (i=1;i<NSIG;i++) { ignore[i] = FALSE; } argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-nottyinit")) { ttyinit = FALSE; slave_write_ioctls--; slave_opens--; } else if (streq(*argv,"-nottycopy")) { ttycopy = FALSE; } else if (streq(*argv,"-noecho")) { echo = FALSE; } else if (streq(*argv,"-console")) { console = TRUE; } else if (streq(*argv,"-pty")) { pty_only = TRUE; } else if (streq(*argv,"-open")) { if (argc < 2) { exp_error(interp,"usage: -open file-identifier"); return TCL_ERROR; } openarg = argv[1]; argc--; argv++; } else if (streq(*argv,"-leaveopen")) { if (argc < 2) { exp_error(interp,"usage: -open file-identifier"); return TCL_ERROR; } openarg = argv[1]; leaveopen = TRUE; argc--; argv++; } else if (streq(*argv,"-ignore")) { int sig; if (argc < 2) { exp_error(interp,"usage: -ignore signal"); return TCL_ERROR; } sig = exp_string_to_signal(interp,argv[1]); if (sig == -1) { exp_error(interp,"usage: -ignore %s: unknown signal name",argv[1]); return TCL_ERROR; } ignore[sig] = TRUE; argc--; argv++; #ifdef FULLTRAPS } else if (streq(*argv,"-trap")) { /* argv[1] is action */ /* argv[2] is list of signals */ RETSIGTYPE (*sig_handler)(); int n; /* number of signals in list */ char **list; /* list of signals */ if (argc < 3) { exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN"); return TCL_ERROR; } if (0 == strcmp(argv[2],"SIG_DFL")) { sig_handler = SIG_DFL; } else if (0 == strcmp(argv[2],"SIG_IGN")) { sig_handler = SIG_IGN; } else { exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN"); return TCL_ERROR; } if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) { exp_errorlog("%s\r\n",interp->result); exp_error(interp,"usage: -trap {siglist} ..."); return TCL_ERROR; } for (i=0;i<n;i++) { int sig = exp_string_to_signal(interp,list[i]); if (sig == -1) { ckfree((char *)&list); return TCL_ERROR; } traps[sig] = sig_handler; } ckfree((char *)&list); argc--; argv++; argc--; argv++; #endif /*FULLTRAPS*/ } else break; } if (openarg && (argc != 0)) { exp_error(interp,"usage: -[leave]open [fileXX]"); return TCL_ERROR; } if (!pty_only && !openarg && (argc == 0)) { exp_error(interp,"usage: spawn [spawn-args] program [program-args]"); return(TCL_ERROR); } stty_init = exp_get_var(interp,STTY_INIT); if (stty_init) { slave_write_ioctls++; slave_opens++; } /* any extraneous ioctl's that occur in slave must be accounted for when trapping, see below in child half of fork */ #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) slave_write_ioctls++; slave_opens++; #endif exp_pty_slave_name = 0; Tcl_ReapDetachedProcs(); if (!openarg) { if (echo) { exp_log(0,"%s ",argv0); for (a = argv;*a;a++) { exp_log(0,"%s ",*a); } exp_nflog("\r\n",0); } if (0 > (master = getptymaster())) { /* * failed to allocate pty, try and figure out why * so we can suggest to user what to do about it. */ int count; int testfd; if (exp_pty_error) { exp_error(interp,"%s",exp_pty_error); return TCL_ERROR; } count = 0; for (i=3;i<=exp_fd_max;i++) { count += exp_fs[i].valid; } if (count > 10) { exp_error(interp,"The system only has a finite number of ptys and you have many of them in use. The usual reason for this is that you forgot (or didn't know) to call \"wait\" after closing each of them."); return TCL_ERROR; } testfd = open("/",0); close(testfd); if (testfd != -1) { exp_error(interp,"The system has no more ptys. Ask your system administrator to create more."); } else { exp_error(interp,"- You have too many files are open. Close some files or increase your per-process descriptor limit."); } return(TCL_ERROR); } #ifdef PTYTRAP_DIES if (!pty_only) exp_slave_control(master,1); #endif /* PTYTRAP_DIES */ Tcl_SetVar2(interp,EXP_SPAWN_OUT,"slave,name",exp_pty_slave_name,0); } else { Tcl_Channel chan; int mode; Tcl_File tclReadFile, tclWriteFile; int rfd, wfd; if (echo) exp_log(0,"%s [open ...]\r\n",argv0); #if TCL7_4 rc = Tcl_GetOpenFile(interp,openarg,0,1,&readfilePtr); wc = Tcl_GetOpenFile(interp,openarg,1,1,&writefilePtr); /* fail only if both descriptors are bad */ if (rc == TCL_ERROR && wc == TCL_ERROR) { return TCL_ERROR; } master = fileno((rc == TCL_OK)?readfilePtr:writefilePtr); /* make a new copy of file descriptor */ if (-1 == (write_master = master = dup(master))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } /* if writefilePtr is different, dup that too */ if ((rc == TCL_OK) && (wc == TCL_OK) && (fileno(writefilePtr) != fileno(readfilePtr))) { if (-1 == (write_master = dup(fileno(writefilePtr)))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } exp_close_on_exec(write_master); } #endif if (!(chan = Tcl_GetChannel(interp,openarg,&mode))) { return TCL_ERROR; } if (!mode) { exp_error(interp,"channel is neither readable nor writable"); return TCL_ERROR; } if (mode & TCL_READABLE) { tclReadFile = Tcl_GetChannelFile(chan, TCL_READABLE); rfd = (int)Tcl_GetFileInfo(tclReadFile, (int *)0); } if (mode & TCL_WRITABLE) { tclWriteFile = Tcl_GetChannelFile(chan, TCL_WRITABLE); wfd = (int)Tcl_GetFileInfo(tclWriteFile, (int *)0); } master = ((mode & TCL_READABLE)?rfd:wfd); /* make a new copy of file descriptor */ if (-1 == (write_master = master = dup(master))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } /* if writefilePtr is different, dup that too */ if ((mode & TCL_READABLE) && (mode & TCL_WRITABLE) && (wfd != rfd)) { if (-1 == (write_master = dup(wfd))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } exp_close_on_exec(write_master); } /* * It would be convenient now to tell Tcl to close its * file descriptor. Alas, if involved in a pipeline, Tcl * will be unable to complete a wait on the process. * So simply remember that we meant to close it. We will * do so later in our own close routine. */ } /* much easier to set this, than remember all masters */ exp_close_on_exec(master); if (openarg || pty_only) { struct exp_f *f; f = fd_new(master,EXP_NOPID); if (openarg) { /* save file# handle */ f->tcl_handle = ckalloc(strlen(openarg)+1); strcpy(f->tcl_handle,openarg); f->tcl_output = write_master; #if 0 /* save fd handle for output */ if (wc == TCL_OK) { /* f->tcl_output = fileno(writefilePtr);*/ f->tcl_output = write_master; } else { /* if we actually try to write to it at some */ /* time in the future, then this will cause */ /* an error */ f->tcl_output = master; } #endif f->leaveopen = leaveopen; } if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name); /* make it appear as if process has been waited for */ f->sys_waited = TRUE; exp_wait_zero(&f->wait); /* tell user id of new process */ sprintf(buf,"%d",master); Tcl_SetVar(interp,EXP_SPAWN_ID_VARNAME,buf,0); if (!openarg) { char value[20]; int dummyfd1, dummyfd2; /* * open the slave side in the same process to support * the -pty flag. */ /* Start by working around a bug in Tcl's exec. It closes all the file descriptors from 3 to it's own fd_max which inappropriately closes our slave fd. To avoid this, open several dummy fds. Then exec's fds will fall below ours. Note that if you do something like pre-allocating a bunch before using them or generating a pipeline, then this code won't help. Instead you'll need to add the right number of explicit Tcl open's of /dev/null. The right solution is fix Tcl's exec so it is not so cavalier. */ dummyfd1 = open("/dev/null",0); dummyfd2 = open("/dev/null",0); if (0 > (f->slave_fd = getptyslave(ttycopy,ttyinit, stty_init))) { exp_error(interp,"open(slave pty): %s\r\n",Tcl_PosixError(interp)); return TCL_ERROR; } close(dummyfd1); close(dummyfd2); exp_slave_control(master,1); sprintf(value,"%d",f->slave_fd); Tcl_SetVar2(interp,EXP_SPAWN_OUT,"slave,fd",value,0); } sprintf(interp->result,"%d",EXP_NOPID); exp_debuglog("spawn: returns {%s}\r\n",interp->result); return TCL_OK; } if (NULL == (argv[0] = Tcl_TildeSubst(interp,argv[0],&dstring))) { goto parent_error; } if (-1 == pipe(sync_fds)) { exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp)); goto parent_error; } if (-1 == pipe(sync2_fds)) { close(sync_fds[0]); close(sync_fds[1]); exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp)); goto parent_error; } if (-1 == pipe(status_pipe)) { close(sync_fds[0]); close(sync_fds[1]); close(sync2_fds[0]); close(sync2_fds[1]); } if ((pid = fork()) == -1) { exp_error(interp,"fork: %s",Tcl_PosixError(interp)); goto parent_error; } if (pid) { /* parent */ struct exp_f *f; close(sync_fds[1]); close(sync2_fds[0]); close(status_pipe[1]); f = fd_new(master,pid); if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name); #ifdef CRAY setptypid(pid); #endif #if PTYTRAP_DIES #ifdef HAVE_PTYTRAP while (slave_opens) { int cc; cc = exp_wait_for_slave_open(master); #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) if (cc == TIOCSCTTY) slave_opens = 0; #endif if (cc == TIOCOPEN) slave_opens--; if (cc == -1) { exp_error(interp,"failed to trap slave pty"); goto parent_error; } } #if 0 /* trap initial ioctls in a feeble attempt to not block */ /* the initially. If the process itself ioctls */ /* /dev/tty, such blocks will be trapped later */ /* during normal event processing */ /* initial slave ioctl */ while (slave_write_ioctls) { int cc; cc = exp_wait_for_slave_open(master); #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) if (cc == TIOCSCTTY) slave_write_ioctls = 0; #endif if (cc & IOC_IN) slave_write_ioctls--; else if (cc == -1) { exp_error(interp,"failed to trap slave pty"); goto parent_error; } } #endif /*0*/ #endif /* HAVE_PTYTRAP */ #endif /* PTYTRAP_DIES */ /* * wait for slave to initialize pty before allowing * user to send to it */ exp_debuglog("parent: waiting for sync byte\r\n"); while (((rc = read(sync_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) { /* empty */; } if (rc == -1) { exp_errorlog("parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* turn on detection of eof */ exp_slave_control(master,1); /* * tell slave to go on now now that we have initialized pty */ exp_debuglog("parent: telling child to go ahead\r\n"); wc = write(sync2_fds[1]," ",1); if (wc == -1) { exp_errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } exp_debuglog("parent: now unsynchronized from child\r\n"); close(sync_fds[0]); close(sync2_fds[1]); /* see if child's exec worked */ retry: switch (read(status_pipe[0],&child_errno,sizeof child_errno)) { case -1: if (errno == EINTR) goto retry; /* well it's not really the child's errno */ /* but it can be treated that way */ child_errno = errno; break; case 0: /* child's exec succeeded */ child_errno = 0; break; default: /* child's exec failed; err contains exec's errno */ waitpid(pid, NULL, 0); /* in order to get Tcl to set errorcode, we must */ /* hand set errno */ errno = child_errno; exp_error(interp, "couldn't execute \"%s\": %s", argv[0],Tcl_PosixError(interp)); goto parent_error; } close(status_pipe[0]); /* tell user id of new process */ sprintf(buf,"%d",master); Tcl_SetVar(interp,EXP_SPAWN_ID_VARNAME,buf,0); sprintf(interp->result,"%d",pid); exp_debuglog("spawn: returns {%s}\r\n",interp->result); Tcl_DStringFree(&dstring); return(TCL_OK); parent_error: Tcl_DStringFree(&dstring); return TCL_ERROR; } /* child process - do not return from here! all errors must exit() */ close(sync_fds[0]); close(sync2_fds[1]); close(status_pipe[0]); exp_close_on_exec(status_pipe[1]); if (exp_dev_tty != -1) { close(exp_dev_tty); exp_dev_tty = -1; } #ifdef CRAY (void) close(master); #endif /* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */ /* is called. setpgrp works though. */ #if defined(POSIX) && !defined(ultrix) #define DO_SETSID #endif #ifdef __convex__ #define DO_SETSID #endif #ifdef DO_SETSID setsid(); #else #ifdef SYSV3 #ifndef CRAY setpgrp(); #endif /* CRAY */ #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,0); /* setpgrp(0,getpid());*/ /* make a new pgrp leader */ /* Pyramid lacks this defn */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* DO_SETSID */ /* save stderr elsewhere to avoid BSD4.4 bogosity that warns */ /* if stty finds dev(stderr) != dev(stdout) */ #ifndef WIN32_XXX /* save error fd while we're setting up new one */ errorfd = fcntl(2,F_DUPFD,3); #endif /* and here is the macro to restore it */ #ifndef WIN32_XXX #define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);} #else #define restore_error_fd #endif close(0); close(1); close(2); /* since we closed fd 0, open of pty slave must return fd 0 */ /* since getptyslave may have to run stty, (some of which work on fd */ /* 0 and some of which work on 1) do the dup's inside getptyslave. */ if (0 > (slave = getptyslave(ttycopy,ttyinit,stty_init))) { restore_error_fd exp_errorlog("open(slave pty): %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* sanity check */ if (slave != 0) { restore_error_fd exp_errorlog("getptyslave: slave = %d but expected 0\n",slave); exit(-1); } /* The test for hpux may have to be more specific. In particular, the */ /* code should be skipped on the hp9000s300 and hp9000s720 (but there */ /* is no documented define for the 720!) */ /*#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hpux)*/ #if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux) /* 4.3+BSD way to acquire controlling terminal */ /* according to Stevens - Adv. Prog..., p 642 */ /* Oops, it appears that the CIBAUD is on Linux also */ /* so let's try without... */ #ifdef __QNX__ if (tcsetct(0, getpid()) == -1) { #else if (ioctl(0,TIOCSCTTY,(char *)0) < 0) { #endif restore_error_fd exp_errorlog("failed to get controlling terminal using TIOCSCTTY"); exit(-1); } #endif #ifdef CRAY (void) setsid(); (void) ioctl(0,TCSETCTTY,0); (void) close(0); if (open("/dev/tty", O_RDWR) < 0) { restore_error_fd exp_errorlog("open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } (void) close(1); (void) close(2); (void) dup(0); (void) dup(0); setptyutmp(); /* create a utmp entry */ /* _CRAY2 code from Hal Peterson <[email protected]>, Cray Research, Inc. */ #ifdef _CRAY2 /* * Interpose a process between expect and the spawned child to * keep the slave side of the pty open to allow time for expect * to read the last output. This is a workaround for an apparent * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at * least). */ if ((pid = fork()) == -1) { restore_error_fd exp_errorlog("second fork: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } if (pid) { /* Intermediate process. */ int status; int timeout; char *t; /* How long should we wait? */ if (t = exp_get_var(interp,"pty_timeout")) timeout = atoi(t); else if (t = exp_get_var(interp,"timeout")) timeout = atoi(t)/2; else timeout = 5; /* Let the spawned process run to completion. */ while (wait(&status) < 0 && errno == EINTR) /* empty body */; /* Wait for the pty to clear. */ sleep(timeout); /* Duplicate the spawned process's status. */ if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); /* The kill may not have worked, but this will. */ exit(WEXITSTATUS(status)); } #endif /* _CRAY2 */ #endif /* CRAY */ if (console) exp_console_set(); #ifdef FULLTRAPS for (i=1;i<NSIG;i++) { if (traps[i] != SIG_ERR) { signal(i,traps[i]); } } #endif /* FULLTRAPS */ for (i=1;i<NSIG;i++) { signal(i,ignore[i]?SIG_IGN:SIG_DFL); } #if 0 /* avoid fflush of cmdfile since this screws up the parents seek ptr */ /* There is no portable way to fclose a shared read-stream!!!! */ if (exp_cmdfile && (exp_cmdfile != stdin)) (void) close(fileno(exp_cmdfile)); if (logfile) (void) fclose(logfile); if (debugfile) (void) fclose(debugfile); #endif /* (possibly multiple) masters are closed automatically due to */ /* earlier fcntl(,,CLOSE_ON_EXEC); */ /* tell parent that we are done setting up pty */ /* The actual char sent back is irrelevant. */ /* exp_debuglog("child: telling parent that pty is initialized\r\n");*/ wc = write(sync_fds[1]," ",1); if (wc == -1) { restore_error_fd exp_errorlog("child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync_fds[1]); /* wait for master to let us go on */ /* exp_debuglog("child: waiting for go ahead from parent\r\n"); */ /* close(master); /* force master-side close so we can read */ while (((rc = read(sync2_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) { /* empty */; } if (rc == -1) { restore_error_fd exp_errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync2_fds[0]); /* exp_debuglog("child: now unsynchronized from parent\r\n"); */ /* So much for close-on-exec. Tcl doesn't mark its files that way */ /* everything has to be closed explicitly. */ if (exp_close_in_child) (*exp_close_in_child)(); (void) execvp(argv[0],argv); #if 0 /* Unfortunately, by now we've closed fd's to stderr, logfile and debugfile. The only reasonable thing to do is to send back the error as part of the program output. This will be picked up in an expect or interact command. */ exp_errorlog("%s: %s\r\n",argv[0],Tcl_ErrnoMsg(errno)); #endif /* if exec failed, communicate the reason back to the parent */ write(status_pipe[1], &errno, sizeof errno); exit(-1); /*NOTREACHED*/ } /* Describe the processes created with Expect's fork. This allows us to wait on them later. This is maintained as a linked list. As additional procs are forked, new links are added. As procs disappear, links are marked so that we can reuse them later. */ struct forked_proc { int pid; WAIT_STATUS_TYPE wait_status; enum {not_in_use, wait_done, wait_not_done} link_status; struct forked_proc *next; } *forked_proc_base = 0; void fork_clear_all() { struct forked_proc *f; for (f=forked_proc_base;f;f=f->next) { f->link_status = not_in_use; } } void fork_init(f,pid) struct forked_proc *f; int pid; { f->pid = pid; f->link_status = wait_not_done; } /* make an entry for a new proc */ void fork_add(pid) int pid; { struct forked_proc *f; for (f=forked_proc_base;f;f=f->next) { if (f->link_status == not_in_use) break; } /* add new entry to the front of the list */ if (!f) { f = (struct forked_proc *)ckalloc(sizeof(struct forked_proc)); f->next = forked_proc_base; forked_proc_base = f; } fork_init(f,pid); } /* Provide a last-chance guess for this if not defined already */ #ifndef WNOHANG #define WNOHANG WNOHANG_BACKUP_VALUE #endif /* wait returns are a hodgepodge of things If wait fails, something seriously has gone wrong, for example: bogus arguments (i.e., incorrect, bogus spawn id) no children to wait on async event failed If wait succeeeds, something happened on a particular pid 3rd arg is 0 if successfully reaped (if signal, additional fields supplied) 3rd arg is -1 if unsuccessfully reaped (additional fields supplied) */ /*ARGSUSED*/ static int Exp_ForkCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int rc; if (argc > 1) { exp_error(interp,"usage: fork"); return(TCL_ERROR); } rc = fork(); if (rc == -1) { exp_error(interp,"fork: %s",Tcl_PosixError(interp)); return TCL_ERROR; } else if (rc == 0) { /* child */ exp_forked = TRUE; exp_getpid = exp_getpidproc(); fork_clear_all(); } else { /* parent */ fork_add(rc); } /* both child and parent follow remainder of code */ sprintf(interp->result,"%d",rc); exp_debuglog("fork: returns {%s}\r\n",interp->result); return(TCL_OK); } /*ARGSUSED*/ static int Exp_DisconnectCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { /* tell Saber to ignore non-use of ttyfd */ /*SUPPRESS 591*/ int ttyfd; if (argc > 1) { exp_error(interp,"usage: disconnect"); return(TCL_ERROR); } if (exp_disconnected) { exp_error(interp,"already disconnected"); return(TCL_ERROR); } if (!exp_forked) { exp_error(interp,"can only disconnect child process"); return(TCL_ERROR); } exp_disconnected = TRUE; /* ignore hangup signals generated by testing ptys in getptymaster */ /* and other places */ signal(SIGHUP,SIG_IGN); /* reopen prevents confusion between send/expect_user */ /* accidentally mapping to a real spawned process after a disconnect */ if (exp_fs[0].pid != EXP_NOPID) { exp_close(interp,0); open("/dev/null",0); exp_f_new(0, EXP_NOPID); } if (exp_fs[1].pid != EXP_NOPID) { exp_close(interp,1); open("/dev/null",1); exp_f_new(1, EXP_NOPID); } if (exp_fs[2].pid != EXP_NOPID) { /* reopen stderr saves error checking in error/log routines. */ exp_close(interp,2); open("/dev/null",1); exp_f_new(2, EXP_NOPID); } Tcl_UnsetVar(interp,"tty_spawn_id",TCL_GLOBAL_ONLY); #ifdef DO_SETSID setsid(); #else #ifdef SYSV3 /* put process in our own pgrp, and lose controlling terminal */ #ifdef sysV88 /* With setpgrp first, child ends up with closed stdio */ /* according to Dave Schmitt <[email protected]> */ if (fork()) exit(0); setpgrp(); #else setpgrp(); /*signal(SIGHUP,SIG_IGN); moved out to above */ if (fork()) exit(0); /* first child exits (as per Stevens, */ /* UNIX Network Programming, p. 79-80) */ /* second child process continues as daemon */ #endif #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,0); /* setpgrp(0,getpid());*/ /* put process in our own pgrp */ /* Pyramid lacks this defn */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { /* zap controlling terminal if we had one */ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* DO_SETSID */ return(TCL_OK); } /*ARGSUSED*/ static int Exp_OverlayCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int newfd, oldfd; int dash_name = 0; char *command; argc--; argv++; while (argc) { if (*argv[0] != '-') break; /* not a flag */ if (streq(*argv,"-")) { /* - by itself */ argc--; argv++; dash_name = 1; continue; } newfd = atoi(argv[0]+1); argc--; argv++; if (argc == 0) { exp_error(interp,"overlay -# requires additional argument"); return(TCL_ERROR); } oldfd = atoi(argv[0]); argc--; argv++; exp_debuglog("overlay: mapping fd %d to %d\r\n",oldfd,newfd); if (oldfd != newfd) (void) dup2(oldfd,newfd); else exp_debuglog("warning: overlay: old fd == new fd (%d)\r\n",oldfd); } if (argc == 0) { exp_error(interp,"need program name"); return(TCL_ERROR); } command = argv[0]; if (dash_name) { argv[0] = ckalloc(1+strlen(command)); sprintf(argv[0],"-%s",command); } signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); (void) execvp(command,argv); exp_error(interp,"execvp(%s): %s\r\n",argv[0],Tcl_PosixError(interp)); return(TCL_ERROR); } |
Added unix/expUnixPort.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * expUnixPort.h -- * * This header file handles porting issues that occur because of * differences between Windows and Unix. * * Copyright (c) 1997 Mitel, Inc. * Copyright (c) 1997 Gordon Chaffee * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef _EXPUNIXPORT_H #define _EXPUNIXPORT_H #include "expect_cf.h" #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #endif /* _EXPUNIXPORT_H */ |
Added unix/expUnixSpawnChan.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * expUnixSpawnChan.c -- * * Implements the Unix specific portion of the exp_spawn * channel id. */ #include "exp_port.h" #include "tclInt.h" #include "tclPort.h" #include "exp_command.h" /* *---------------------------------------------------------------------- * * ExpPlatformSpawnOutput -- * * Write routine for exp_spawn channel * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpPlatformSpawnOutput(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { ExpSpawnState *ssPtr = (ExpSpawnState *) instanceData; Tcl_Channel channelPtr = ssPtr->channelPtr; return (Tcl_GetChannelType(channelPtr)->outputProc) (Tcl_GetChannelInstanceData(channelPtr), bufPtr, toWrite, errorPtr); } |
Added unix/expUnixTty.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | /* exp_tty.c - tty support routines */ #include "expect_cf.h" #include <stdio.h> #include <signal.h> #include "string.h" #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif #include <sys/stat.h> #include <sys/types.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #include "tcl.h" #include "exp_prog.h" #include "exp_rename.h" #include "exp_tty.h" #include "exp_log.h" #include "exp_command.h" static int is_raw = FALSE; static int is_noecho = FALSE; int exp_ioctled_devtty = FALSE; int exp_stdin_is_tty; int exp_stdout_is_tty; /*static*/ extern exp_tty exp_tty_current, exp_tty_cooked; #define tty_current exp_tty_current #define tty_cooked exp_tty_cooked int exp_israw() { return is_raw; } int exp_isecho() { return !is_noecho; } /* if set == 1, set it to raw, else unset it */ void exp_tty_raw(set) int set; { if (set == 1) { is_raw = TRUE; #if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */ tty_current.c_iflag = 0; tty_current.c_oflag = 0; tty_current.c_lflag &= ECHO; /* disable everything but echo */ tty_current.c_cc[VMIN] = 1; tty_current.c_cc[VTIME] = 0; } else { tty_current.c_iflag = tty_cooked.c_iflag; tty_current.c_oflag = tty_cooked.c_oflag; /* tty_current.c_lflag = tty_cooked.c_lflag;*/ /* attempt 2 tty_current.c_lflag = tty_cooked.c_lflag & ~ECHO;*/ /* retain current echo setting */ tty_current.c_lflag = (tty_cooked.c_lflag & ~ECHO) | (tty_current.c_lflag & ECHO); tty_current.c_cc[VMIN] = tty_cooked.c_cc[VMIN]; tty_current.c_cc[VTIME] = tty_cooked.c_cc[VTIME]; #else # if defined(HAVE_SGTTYB) tty_current.sg_flags |= RAW; } else { tty_current.sg_flags = tty_cooked.sg_flags; # endif #endif is_raw = FALSE; } } void exp_tty_echo(set) int set; { if (set == 1) { is_noecho = FALSE; #if defined(HAVE_TERMIOS) || defined(HAVE_TERMIO) /* had POSIX too */ tty_current.c_lflag |= ECHO; } else { tty_current.c_lflag &= ~ECHO; #else tty_current.sg_flags |= ECHO; } else { tty_current.sg_flags &= ~ECHO; #endif is_noecho = TRUE; } } int exp_tty_set_simple(tty) exp_tty *tty; { #ifdef HAVE_TCSETATTR return(tcsetattr(exp_dev_tty, TCSADRAIN,tty)); #else return(ioctl (exp_dev_tty, TCSETSW ,tty)); #endif } int exp_tty_get_simple(tty) exp_tty *tty; { #ifdef HAVE_TCSETATTR return(tcgetattr(exp_dev_tty, tty)); #else return(ioctl (exp_dev_tty, TCGETS, tty)); #endif } /* returns 0 if nothing changed */ /* if something changed, the out parameters are changed as well */ int exp_tty_raw_noecho(interp,tty_old,was_raw,was_echo) Tcl_Interp *interp; exp_tty *tty_old; int *was_raw, *was_echo; { if (exp_disconnected) return(0); if (is_raw && is_noecho) return(0); if (exp_dev_tty == -1) return(0); *tty_old = tty_current; /* save old parameters */ *was_raw = is_raw; *was_echo = !is_noecho; exp_debuglog("tty_raw_noecho: was raw = %d echo = %d\r\n",is_raw,!is_noecho); exp_tty_raw(1); exp_tty_echo(-1); if (exp_tty_set_simple(&tty_current) == -1) { exp_errorlog("ioctl(raw): %s\r\n",Tcl_PosixError(interp)); exp_exit(interp,1); } exp_ioctled_devtty = TRUE; return(1); } /* returns 0 if nothing changed */ /* if something changed, the out parameters are changed as well */ int exp_tty_cooked_echo(interp,tty_old,was_raw,was_echo) Tcl_Interp *interp; exp_tty *tty_old; int *was_raw, *was_echo; { if (exp_disconnected) return(0); if (!is_raw && !is_noecho) return(0); if (exp_dev_tty == -1) return(0); *tty_old = tty_current; /* save old parameters */ *was_raw = is_raw; *was_echo = !is_noecho; exp_debuglog("tty_cooked_echo: was raw = %d echo = %d\r\n",is_raw,!is_noecho); exp_tty_raw(-1); exp_tty_echo(1); if (exp_tty_set_simple(&tty_current) == -1) { exp_errorlog("ioctl(noraw): %s\r\n",Tcl_PosixError(interp)); exp_exit(interp,1); } exp_ioctled_devtty = TRUE; return(1); } void exp_tty_set(interp,tty,raw,echo) Tcl_Interp *interp; exp_tty *tty; int raw; int echo; { if (exp_tty_set_simple(tty) == -1) { exp_errorlog("ioctl(set): %s\r\n",Tcl_PosixError(interp)); exp_exit(interp,1); } is_raw = raw; is_noecho = !echo; tty_current = *tty; exp_debuglog("tty_set: raw = %d, echo = %d\r\n",is_raw,!is_noecho); exp_ioctled_devtty = TRUE; } #if 0 /* avoids scoping problems */ void exp_update_cooked_from_current() { tty_cooked = tty_current; } int exp_update_real_tty_from_current() { return(exp_tty_set_simple(&tty_current)); } int exp_update_current_from_real_tty() { return(exp_tty_get_simple(&tty_current)); } #endif void exp_init_stdio() { exp_stdin_is_tty = isatty(0); exp_stdout_is_tty = isatty(1); setbuf(stdout,(char *)0); /* unbuffer stdout */ } /*ARGSUSED*/ void exp_tty_break(interp,fd) Tcl_Interp *interp; int fd; { #ifdef POSIX tcsendbreak(fd,0); #else # ifdef TIOCSBRK ioctl(fd,TIOCSBRK,0); exp_dsleep(interp,0.25); /* sleep for at least a quarter of a second */ ioctl(fd,TIOCCBRK,0); # else /* dunno how to do this - ignore */ # endif #endif } /* take strings with newlines and insert carriage-returns. This allows user */ /* to write send_user strings without always putting in \r. */ /* If len == 0, use strlen to compute it */ /* NB: if terminal is not in raw mode, nothing is done. */ char * exp_cook(s,len) char *s; int *len; /* current and new length of s */ { static int destlen = 0; static char *dest = 0; char *d; /* ptr into dest */ unsigned int need; if (s == 0) return("<null>"); if (!is_raw) return(s); /* worst case is every character takes 2 to represent */ need = 1 + 2*(len?*len:strlen(s)); if (need > destlen) { if (dest) ckfree(dest); dest = ckalloc(need); destlen = need; } for (d = dest;*s;s++) { if (*s == '\n') { *d++ = '\r'; *d++ = '\n'; } else { *d++ = *s; } } *d = '\0'; if (len) *len = d-dest; return(dest); } /* this stupidity because Tcl needs commands in writable space */ static char exec_cmd[] = "exec"; static char stty_cmd[] = "/bin/stty"; static int /* returns TCL_whatever */ exec_stty(interp,argc,argv,devtty) Tcl_Interp *interp; int argc; char **argv; int devtty; /* if true, redirect to /dev/tty */ { char **new_argv; int i; int rc; /* insert "system" at front, null at end, */ /* and optional redirect in middle, hence "+3" */ new_argv = (char **)ckalloc((3+argc)*sizeof(char *)); new_argv[0] = exec_cmd; new_argv[1] = stty_cmd; for (i=1;i<argc;i++) { new_argv[i+1] = argv[i]; } if (devtty) new_argv[++i] = #ifdef STTY_READS_STDOUT ">/dev/tty"; #else "</dev/tty"; #endif new_argv[i+1] = (char *)0; Tcl_ResetResult(interp); /* normally, I wouldn't set one of Tcl's own variables, but in this */ /* case, I only only want to see if Tcl resets it to non-NONE, */ /* and I don't know any other way of doing it */ Tcl_SetVar(interp,"errorCode","NONE",0); rc = Tcl_ExecCmd((ClientData)0,interp,argc+1+devtty,new_argv); ckfree((char *)new_argv); /* if stty-reads-stdout, stty will fail since Exec */ /* will detect the stderr. Only by examining errorCode */ /* can we tell if a real error occurred. */ #ifdef STTY_READS_STDOUT if (rc == TCL_ERROR) { char *ec = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY); if (ec && !streq(ec,"NONE")) return TCL_ERROR; } #endif return TCL_OK; } /*ARGSUSED*/ static int Exp_SttyCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { /* redirection symbol is not counted as a stty arg in terms */ /* of recognition. */ int saw_unknown_stty_arg = FALSE; int saw_known_stty_arg = FALSE; int no_args = TRUE; int rc = TCL_OK; int cooked = FALSE; int was_raw, was_echo; char **redirect; /* location of "<" */ char *infile = 0; int fd; /* (slave) fd of infile */ int master = -1; /* master fd of infile */ char **argv0 = argv; for (argv=argv0+1;*argv;argv++) { if (argv[0][0] == '<') { redirect = argv; infile = *(argv+1); if (!infile) { exp_errorlog("usage: < ttyname"); return TCL_ERROR; } if (streq(infile,"/dev/tty")) { infile = 0; *argv = 0; *(argv+1) = 0; argc -= 2; } else { master = exp_trap_off(infile); if (-1 == (fd = open(infile,2))) { exp_errorlog("couldn't open %s: %s", infile,Tcl_PosixError(interp)); return TCL_ERROR; } } break; } } if (!infile) { /* work on /dev/tty */ was_raw = exp_israw(); was_echo = exp_isecho(); exp_ioctled_devtty = TRUE; for (argv=argv0+1;*argv;argv++) { if (streq(*argv,"raw") || streq(*argv,"-cooked")) { exp_tty_raw(1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"-raw") || streq(*argv,"cooked")) { cooked = TRUE; exp_tty_raw(-1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"echo")) { exp_tty_echo(1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"-echo")) { exp_tty_echo(-1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"rows")) { if (*(argv+1)) { exp_win_rows_set(*(argv+1)); argv++; no_args = FALSE; } else { exp_win_rows_get(interp->result); return TCL_OK; } } else if (streq(*argv,"columns")) { if (*(argv+1)) { exp_win_columns_set(*(argv+1)); argv++; no_args = FALSE; } else { exp_win_columns_get(interp->result); return TCL_OK; } } else { saw_unknown_stty_arg = TRUE; } } /* if any unknown args, let real stty try */ if (saw_unknown_stty_arg || no_args) { /* let real stty try */ rc = exec_stty(interp,argc,argv0,1); /* find out what weird options user asked for */ if (exp_tty_get_simple(&tty_current) == -1) { exp_errorlog("ioctl(get): %s\r\n",Tcl_PosixError(interp)); exp_exit(interp,1); } if (cooked) { /* find out user's new defn of 'cooked' */ tty_cooked = tty_current; } } else if (saw_known_stty_arg) { if (exp_tty_set_simple(&tty_current) == -1) { if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) { exp_errorlog("stty: impossible in this context\n"); exp_errorlog("are you disconnected or in a batch, at, or cron script?"); /* user could've conceivably closed /dev/tty as well */ } exp_error(interp,"stty: ioctl(user): %s\r\n",Tcl_PosixError(interp)); rc = TCL_ERROR; } } /* if no result, make a crude one */ if (interp->result[0] == '\0') { sprintf(interp->result,"%sraw %secho", (was_raw?"":"-"), (was_echo?"":"-")); } } else { /* a different tty */ /* temporarily zap redirect */ char *redirect_save = *redirect; *redirect = 0; for (argv=argv0+1;*argv;argv++) { if (streq(*argv,"rows")) { if (*(argv+1)) { exp_win2_rows_set(fd,*(argv+1)); argv++; no_args = FALSE; } else { exp_win2_rows_get(fd,interp->result); goto done; } } else if (streq(*argv,"columns")) { if (*(argv+1)) { exp_win2_columns_set(fd,*(argv+1)); argv++; no_args = FALSE; } else { exp_win2_columns_get(fd,interp->result); goto done; } } else if (streq(*argv,"<")) { break; } else { saw_unknown_stty_arg = TRUE; break; } } /* restore redirect */ *redirect = redirect_save; close(fd); /* no more use for this, from now on */ /* pass by name */ if (saw_unknown_stty_arg || no_args) { #ifdef STTY_READS_STDOUT /* switch "<" to ">" */ char original_redirect_char = (*redirect)[0]; (*redirect)[0] = '>'; /* stderr unredirected so we can get it directly! */ #endif rc = exec_stty(interp,argc,argv0,0); #ifdef STTY_READS_STDOUT /* restore redirect - don't know if necessary */ (*redirect)[0] = original_redirect_char; #endif } } done: exp_trap_on(master); return rc; } /*ARGSUSED*/ static int Exp_SystemCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int result = TCL_OK; RETSIGTYPE (*old)(); /* save old sigalarm handler */ #define MAX_ARGLIST 10240 int i; WAIT_STATUS_TYPE waitStatus; int systemStatus ; int abnormalExit = FALSE; char buf[MAX_ARGLIST]; char *bufp = buf; int total_len = 0, arg_len; int stty_args_recognized = TRUE; int cmd_is_stty = FALSE; int cooked = FALSE; int was_raw, was_echo; if (argc == 1) return TCL_OK; if (streq(argv[1],"stty")) { exp_debuglog("system stty is deprecated, use stty\r\n"); cmd_is_stty = TRUE; was_raw = exp_israw(); was_echo = exp_isecho(); } if (argc > 2 && cmd_is_stty) { exp_ioctled_devtty = TRUE; for (i=2;i<argc;i++) { if (streq(argv[i],"raw") || streq(argv[i],"-cooked")) { exp_tty_raw(1); } else if (streq(argv[i],"-raw") || streq(argv[i],"cooked")) { cooked = TRUE; exp_tty_raw(-1); } else if (streq(argv[i],"echo")) { exp_tty_echo(1); } else if (streq(argv[i],"-echo")) { exp_tty_echo(-1); } else stty_args_recognized = FALSE; } /* if unknown args, fall thru and let real stty have a go */ if (stty_args_recognized) { #ifdef HAVE_TCSETATTR if (tcsetattr(exp_dev_tty,TCSADRAIN, &tty_current) == -1) { #else if (ioctl(exp_dev_tty, TCSETSW, &tty_current) == -1) { #endif if (exp_disconnected || (exp_dev_tty == -1) || !isatty(exp_dev_tty)) { exp_errorlog("system stty: impossible in this context\n"); exp_errorlog("are you disconnected or in a batch, at, or cron script?"); /* user could've conceivably closed /dev/tty as well */ } exp_error(interp,"system stty: ioctl(user): %s\r\n",Tcl_PosixError(interp)); return(TCL_ERROR); } if (cmd_is_stty) { sprintf(interp->result,"%sraw %secho", (was_raw?"":"-"), (was_echo?"":"-")); } return(TCL_OK); } } for (i = 1;i<argc;i++) { total_len += (1 + (arg_len = strlen(argv[i]))); if (total_len > MAX_ARGLIST) { exp_error(interp,"args too long (>=%d chars)", total_len); return(TCL_ERROR); } memcpy(bufp,argv[i],arg_len); bufp += arg_len; /* no need to check bounds, we accted for it earlier */ memcpy(bufp," ",1); bufp += 1; } *(bufp-1) = '\0'; old = signal(SIGCHLD, SIG_DFL); systemStatus = system(buf); signal(SIGCHLD, old); /* restore signal handler */ exp_debuglog("system(%s) = %d\r\n",buf,i); if (systemStatus == -1) { exp_error(interp,Tcl_PosixError(interp)); return TCL_ERROR; } *(int *)&waitStatus = systemStatus; if (!stty_args_recognized) { /* find out what weird options user asked for */ #ifdef HAVE_TCSETATTR if (tcgetattr(exp_dev_tty, &tty_current) == -1) { #else if (ioctl(exp_dev_tty, TCGETS, &tty_current) == -1) { #endif exp_errorlog("ioctl(get): %s\r\n",Tcl_PosixError(interp)); exp_exit(interp,1); } if (cooked) { /* find out user's new defn of 'cooked' */ tty_cooked = tty_current; } } if (cmd_is_stty) { sprintf(interp->result,"%sraw %secho", (was_raw?"":"-"), (was_echo?"":"-")); } /* following macros stolen from Tcl's tclUnix.h file */ /* we can't include the whole thing because it depends on other macros */ /* that come out of Tcl's Makefile, sigh */ #if 0 #undef WIFEXITED #ifndef WIFEXITED # define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0) #endif #undef WEXITSTATUS #ifndef WEXITSTATUS # define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #undef WIFSIGNALED #ifndef WIFSIGNALED # define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff))) #endif #undef WTERMSIG #ifndef WTERMSIG # define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f) #endif #undef WIFSTOPPED #ifndef WIFSTOPPED # define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177) #endif #undef WSTOPSIG #ifndef WSTOPSIG # define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #endif /* 0 */ /* stolen from Tcl. Again, this is embedded in another routine */ /* (CleanupChildren in tclUnixAZ.c) that we can't use directly. */ if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) { char msg1[20], msg2[20]; int pid = 0; /* fake a pid, since system() won't tell us */ result = TCL_ERROR; sprintf(msg1, "%d", pid); if (WIFEXITED(waitStatus)) { sprintf(msg2, "%d", WEXITSTATUS(waitStatus)); Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, (char *) NULL); abnormalExit = TRUE; } else if (WIFSIGNALED(waitStatus)) { char *p; p = Tcl_SignalMsg((int) (WTERMSIG(waitStatus))); Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, Tcl_SignalId((int) (WTERMSIG(waitStatus))), p, (char *) NULL); Tcl_AppendResult(interp, "child killed: ", p, "\n", (char *) NULL); } else if (WIFSTOPPED(waitStatus)) { char *p; p = Tcl_SignalMsg((int) (WSTOPSIG(waitStatus))); Tcl_SetErrorCode(interp, "CHILDSUSP", msg1, Tcl_SignalId((int) (WSTOPSIG(waitStatus))), p, (char *) NULL); Tcl_AppendResult(interp, "child suspended: ", p, "\n", (char *) NULL); } else { Tcl_AppendResult(interp, "child wait status didn't make sense\n", (char *) NULL); } } if (abnormalExit && (*interp->result == 0)) { Tcl_AppendResult(interp, "child process exited abnormally", (char *) NULL); } return result; } static struct exp_cmd_data cmd_data[] = { {"stty", Exp_SttyCmd, 0, 0}, {"system", Exp_SystemCmd, 0, 0}, {0}}; void exp_init_tty_cmds(interp) struct Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } |
Added unix/expUnixTty.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* expUnixTty.h - tty support definitions for Unix Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #ifndef __EXP_UNIX_TTY_H__ #define __EXP_UNIX_TTY_H__ #include "expect_cf.h" extern int exp_ioctled_devtty; void exp_tty_raw(); void exp_tty_echo(); void exp_tty_break(); int exp_tty_raw_noecho(); int exp_israw(); int exp_isecho(); void exp_tty_set(); int exp_tty_set_simple(); int exp_tty_get_simple(); #include "exp_tty_in.h" #endif /* __EXP_UNIX_TTY_H__ */ |
Added unix/exp_clib_orig.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 | /* exp_clib.c - top-level functions in the expect C library, libexpect.a Written by: Don Libes, [email protected], NIST, 12/3/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "exp_port.h" #include <stdio.h> #include <setjmp.h> #include <sys/types.h> #include <sys/ioctl.h> #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #ifdef CRAY # ifndef TCSETCTTY # if defined(HAVE_TERMIOS) # include <termios.h> # else # include <termio.h> # endif # endif #endif #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif #ifdef HAVE_STRREDIR_H #include <sys/strredir.h> # ifdef SRIOCSREDIR # undef TIOCCONS # endif #endif #include <signal.h> /*#include <memory.h> - deprecated - ANSI C moves them into string.h */ #include "string.h" #include <errno.h> #include "exp_rename.h" #define EXP_AVOID_INCLUDING_TCL_H #include "expect.h" #include "exp_int.h" #include "exp_printify.h" #ifdef NO_STDLIB_H #include "../compat/stdlib.h" #else #include <stdlib.h> /* for malloc */ #endif #define EXP_MATCH_MAX 2000 /* public */ char *exp_buffer = 0; char *exp_buffer_end = 0; char *exp_match = 0; char *exp_match_end = 0; int exp_match_max = EXP_MATCH_MAX; /* bytes */ int exp_full_buffer = FALSE; /* don't return on full buffer */ int exp_remove_nulls = TRUE; int exp_timeout = 10; /* seconds */ int exp_pty_timeout = 5; /* seconds - see CRAY below */ int exp_autoallocpty = TRUE; /* if TRUE, we do allocation */ int exp_pty[2]; /* master is [0], slave is [1] */ int exp_pid; char *exp_stty_init = 0; /* initial stty args */ int exp_ttycopy = TRUE; /* copy tty parms from /dev/tty */ int exp_ttyinit = TRUE; /* set tty parms to sane state */ int exp_console = FALSE; /* redirect console */ void (*exp_child_exec_prelude)() = 0; jmp_buf exp_readenv; /* for interruptable read() */ int exp_reading = FALSE; /* whether we can longjmp or not */ void debuglog(); int getptymaster(); int getptyslave(); int Exp_StringMatch(); #define sysreturn(x) return(errno = x, -1) void exp_init_pty(); /* The following functions are linked from the Tcl library. They don't cause anything else in the library to be dragged in, so it shouldn't cause any problems (e.g., bloat). The functions are relatively small but painful enough that I don't care to recode them. You may, if you absolutely want to get rid of any vestiges of Tcl. */ extern char *TclGetRegError(); extern void TclRegError(); char *Tcl_ErrnoMsg(); static unsigned int bufsiz = 2*EXP_MATCH_MAX; static struct f { int valid; char *buffer; /* buffer of matchable chars */ char *buffer_end; /* one beyond end of matchable chars */ /*char *match; /* start of matched string */ char *match_end; /* one beyond end of matched string */ int msize; /* size of allocate space */ /* actual size is one larger for null */ } *fs = 0; static int fd_alloc_max = -1; /* max fd allocated */ /* translate fd or fp to fd */ static struct f * fdfp2f(fd,fp) int fd; FILE *fp; { if (fd == -1) return(fs + fileno(fp)); else return(fs + fd); } #if 0 /* XXX */ struct exp_f * exp_f_new(interp,chan,spawnId,pid) Tcl_Interp *interp; Tcl_Channel chan; char *spawnId; int pid; #endif static struct f * fd_new(fd) int fd; { int i, low; struct f *fp; struct f *newfs; /* temporary, so we don't lose old fs */ if (fd > fd_alloc_max) { if (!fs) { /* no fd's yet allocated */ newfs = (struct f *)malloc(sizeof(struct f)*(fd+1)); low = 0; } else { /* enlarge fd table */ newfs = (struct f *)realloc((char *)fs,sizeof(struct f)*(fd+1)); low = fd_alloc_max+1; } fs = newfs; fd_alloc_max = fd; for (i = low; i <= fd_alloc_max; i++) { /* init new entries */ fs[i].valid = FALSE; } } fp = fs+fd; if (!fp->valid) { /* initialize */ fp->buffer = malloc((unsigned)(bufsiz+1)); if (!fp->buffer) return 0; fp->msize = bufsiz; fp->valid = TRUE; } fp->buffer_end = fp->buffer; fp->match_end = fp->buffer; return fp; } /* returns fd of master side of pty */ int exp_spawnv(file,argv) char *file; char *argv[]; /* some compiler complains about **argv? */ { int cc; int errorfd; /* place to stash fileno(stderr) in child */ /* while we're setting up new stderr */ int ttyfd; int sync_fds[2]; int sync2_fds[2]; char sync_byte; #ifdef PTYTRAP_DIES int slave_write_ioctls = 1; /* by default, slave will be write-ioctled this many times */ #endif static int first_time = TRUE; if (first_time) { first_time = FALSE; exp_init_pty(); exp_init_tty(); } if (!file || !argv) sysreturn(EINVAL); if (!argv[0] || strcmp(file,argv[0])) { exp_debuglog("expect: warning: file (%s) != argv[0] (%s)\n", file, argv[0]?argv[0]:""); } #ifdef PTYTRAP_DIES /* any extraneous ioctl's that occur in slave must be accounted for when trapping, see below in child half of fork */ #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) slave_write_ioctls++; #endif #endif /*PTYTRAP_DIES*/ if (exp_autoallocpty) { if (0 > (exp_pty[0] = getptymaster())) sysreturn(ENODEV); } fcntl(exp_pty[0],F_SETFD,1); /* close on exec */ #ifdef PTYTRAP_DIES exp_slave_control(exp_pty[0],1);*/ #endif if (!fd_new(exp_pty[0])) { errno = ENOMEM; return -1; } if (-1 == (pipe(sync_fds))) { return -1; } if (-1 == (pipe(sync2_fds))) { return -1; } if ((exp_pid = fork()) == -1) return(-1); if (exp_pid) { /* parent */ close(sync_fds[1]); close(sync2_fds[0]); if (!exp_autoallocpty) close(exp_pty[1]); #ifdef PTYTRAP_DIES #ifdef HAVE_PTYTRAP if (exp_autoallocpty) { /* trap initial ioctls in a feeble attempt to not */ /* block the initially. If the process itself */ /* ioctls /dev/tty, such blocks will be trapped */ /* later during normal event processing */ while (slave_write_ioctls) { int cc; cc = exp_wait_for_slave_open(exp_pty[0]); #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) if (cc == TIOCSCTTY) slave_write_ioctls = 0; #endif if (cc & IOC_IN) slave_write_ioctls--; else if (cc == -1) { printf("failed to trap slave pty"); return -1; } } } #endif #endif /*PTYTRAP_DIES*/ /* * wait for slave to initialize pty before allowing * user to send to it */ exp_debuglog("parent: waiting for sync byte\r\n"); cc = read(sync_fds[0],&sync_byte,1); if (cc == -1) { fprintf(stderr,"parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* turn on detection of eof */ exp_slave_control(exp_pty[0],1); /* * tell slave to go on now now that we have initialized pty */ exp_debuglog("parent: telling child to go ahead\r\n"); cc = write(sync2_fds[1]," ",1); if (cc == -1) { errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } exp_debuglog("parent: now unsynchronized from child\r\n"); close(sync_fds[0]); close(sync2_fds[1]); return(exp_pty[0]); } /* child process - do not return from here! all errors must exit() */ close(sync_fds[0]); close(sync2_fds[1]); #ifdef CRAY (void) close(exp_pty[0]); #endif /* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */ /* is called. setpgrp works though. */ #if defined(POSIX) && !defined(ultrix) #define DO_SETSID #endif #ifdef __convex__ #define DO_SETSID #endif #ifdef DO_SETSID setsid(); #else #ifdef SYSV3 #ifndef CRAY setpgrp(); #endif /* CRAY */ #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,0); /* setpgrp(0,getpid());*/ /* make a new pgrp leader */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* DO_SETSID */ /* save error fd while we're setting up new one */ errorfd = fcntl(2,F_DUPFD,3); /* and here is the macro to restore it */ #define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);} if (exp_autoallocpty) { close(0); close(1); close(2); /* since we closed fd 0, open of pty slave must return fd 0 */ if (0 > (exp_pty[1] = getptyslave(exp_ttycopy,exp_ttyinit, exp_stty_init))) { restore_error_fd fprintf(stderr,"open(slave pty): %s\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* sanity check */ if (exp_pty[1] != 0) { restore_error_fd fprintf(stderr,"getptyslave: slave = %d but expected 0\n", exp_pty[1]); exit(-1); } } else { if (exp_pty[1] != 0) { close(0); fcntl(exp_pty[1],F_DUPFD,0); } close(1); fcntl(0,F_DUPFD,1); close(2); fcntl(0,F_DUPFD,1); close(exp_pty[1]); } /* The test for hpux may have to be more specific. In particular, the */ /* code should be skipped on the hp9000s300 and hp9000s720 (but there */ /* is no documented define for the 720!) */ #if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux) /* 4.3+BSD way to acquire controlling terminal */ /* according to Stevens - Adv. Prog..., p 642 */ #ifdef __QNX__ /* posix in general */ if (tcsetct(0, getpid()) == -1) { #else if (ioctl(0,TIOCSCTTY,(char *)0) < 0) { #endif restore_error_fd fprintf(stderr,"failed to get controlling terminal using TIOCSCTTY"); exit(-1); } #endif #ifdef CRAY (void) setsid(); (void) ioctl(0,TCSETCTTY,0); (void) close(0); if (open("/dev/tty", O_RDWR) < 0) { restore_error_fd fprintf(stderr,"open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } (void) close(1); (void) close(2); (void) dup(0); (void) dup(0); setptyutmp(); /* create a utmp entry */ /* _CRAY2 code from Hal Peterson <[email protected]>, Cray Research, Inc. */ #ifdef _CRAY2 /* * Interpose a process between expect and the spawned child to * keep the slave side of the pty open to allow time for expect * to read the last output. This is a workaround for an apparent * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at * least). */ if ((pid = fork()) == -1) { restore_error_fd fprintf(stderr,"second fork: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } if (pid) { /* Intermediate process. */ int status; int timeout; char *t; /* How long should we wait? */ timeout = exp_pty_timeout; /* Let the spawned process run to completion. */ while (wait(&status) < 0 && errno == EINTR) /* empty body */; /* Wait for the pty to clear. */ sleep(timeout); /* Duplicate the spawned process's status. */ if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); /* The kill may not have worked, but this will. */ exit(WEXITSTATUS(status)); } #endif /* _CRAY2 */ #endif /* CRAY */ if (exp_console) { #ifdef SRIOCSREDIR int fd; if ((fd = open("/dev/console", O_RDONLY)) == -1) { restore_error_fd fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]); exit(-1); } if (ioctl(fd, SRIOCSREDIR, 0) == -1) { restore_error_fd fprintf(stderr, "spawn %s: cannot redirect console, check permissions of /dev/console\n",argv[0]); } close(fd); #endif #ifdef TIOCCONS int on = 1; if (ioctl(0,TIOCCONS,(char *)&on) == -1) { restore_error_fd fprintf(stderr, "spawn %s: cannot open console, check permissions of /dev/console\n",argv[0]); exit(-1); } #endif /* TIOCCONS */ } /* tell parent that we are done setting up pty */ /* The actual char sent back is irrelevant. */ /* exp_debuglog("child: telling parent that pty is initialized\r\n");*/ cc = write(sync_fds[1]," ",1); if (cc == -1) { restore_error_fd fprintf(stderr,"child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync_fds[1]); /* wait for master to let us go on */ /* exp_debuglog("child: waiting for go ahead from parent\r\n"); */ /* close(master); /* force master-side close so we can read */ cc = read(sync2_fds[0],&sync_byte,1); if (cc == -1) { restore_error_fd errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync2_fds[0]); /* exp_debuglog("child: now unsynchronized from parent\r\n"); */ /* (possibly multiple) masters are closed automatically due to */ /* earlier fcntl(,,CLOSE_ON_EXEC); */ /* just in case, allow user to explicitly close other files */ if (exp_close_in_child) (*exp_close_in_child)(); /* allow user to do anything else to child */ if (exp_child_exec_prelude) (*exp_child_exec_prelude)(); (void) execvp(argv[0],argv); /* Unfortunately, by now we've closed fd's to stderr, logfile and debugfile. The only reasonable thing to do is to send back the error as part of the program output. This will be picked up in an expect or interact command. */ fprintf(stderr,"execvp(%s): %s\n",file,Tcl_ErrnoMsg(errno)); exit(-1); /*NOTREACHED*/ } /* returns fd of master side of pty */ /*VARARGS*/ int exp_spawnl TCL_VARARGS_DEF(char *,arg1) /*exp_spawnl(va_alist)*/ /*va_dcl*/ { va_list args; /* problematic line here */ int i; char *arg, **argv; arg = TCL_VARARGS_START(char *,arg1,args); /*va_start(args);*/ for (i=1;;i++) { arg = va_arg(args,char *); if (!arg) break; } va_end(args); if (i == 0) sysreturn(EINVAL); if (!(argv = (char **)malloc((i+1)*sizeof(char *)))) sysreturn(ENOMEM); argv[0] = TCL_VARARGS_START(char *,arg1,args); /*va_start(args);*/ for (i=1;;i++) { argv[i] = va_arg(args,char *); if (!argv[i]) break; } i = exp_spawnv(argv[0],argv+1); free((char *)argv); return(i); } /* allow user-provided fd to be passed to expect funcs */ int exp_spawnfd(fd) int fd; { if (!fd_new(fd)) { errno = ENOMEM; return -1; } return fd; } /* remove nulls from s. Initially, the number of chars in s is c, */ /* not strlen(s). This count does not include the trailing null. */ /* returns number of nulls removed. */ static int rm_nulls(s,c) char *s; int c; { char *s2 = s; /* points to place in original string to put */ /* next non-null character */ int count = 0; int i; for (i=0;i<c;i++,s++) { if (0 == *s) { count++; continue; } if (count) *s2 = *s; s2++; } return(count); } static int i_read_errno;/* place to save errno, if i_read() == -1, so it doesn't get overwritten before we get to read it */ /*ARGSUSED*/ static void sigalarm_handler(n) int n; /* signal number, unused by us */ { #ifdef REARM_SIG signal(SIGALRM,sigalarm_handler); #endif longjmp(exp_readenv,1); } /* interruptable read */ static int i_read(fd,fp,buffer,length,timeout) int fd; FILE *fp; char *buffer; int length; int timeout; { int cc = -2; /* since setjmp insists on returning 1 upon longjmp(,0), */ /* longjmp(,2 (EXP_RESTART)) instead. */ /* no need to set alarm if -1 (infinite) or 0 (poll with */ /* guaranteed data) */ if (timeout > 0) alarm(timeout); /* restart read if setjmp returns 0 (first time) or 2 (EXP_RESTART). */ /* abort if setjmp returns 1 (EXP_ABORT). */ if (EXP_ABORT != setjmp(exp_readenv)) { exp_reading = TRUE; if (fd == -1) { int c; c = getc(fp); if (c == EOF) { /*fprintf(stderr,"<<EOF>>",c);fflush(stderr);*/ if (feof(fp)) cc = 0; else cc = -1; } else { /*fprintf(stderr,"<<%c>>",c);fflush(stderr);*/ buffer[0] = c; cc = 1; } } else { #ifndef HAVE_PTYTRAP cc = read(fd,buffer,length); #else # include <sys/ptyio.h> fd_set rdrs; fd_set excep; restart: FD_ZERO(&rdrs); FD_ZERO(&excep); FD_SET(fd,&rdrs); FD_SET(fd,&excep); if (-1 == (cc = select(fd+1, (SELECT_MASK_TYPE *)&rdrs, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)&excep, (struct timeval *)0))) { /* window refreshes trigger EINTR, ignore */ if (errno == EINTR) goto restart; } if (FD_ISSET(fd,&rdrs)) { cc = read(fd,buffer,length); } else if (FD_ISSET(fd,&excep)) { struct request_info ioctl_info; ioctl(fd,TIOCREQCHECK,&ioctl_info); if (ioctl_info.request == TIOCCLOSE) { cc = 0; /* indicate eof */ } else { ioctl(fd, TIOCREQSET, &ioctl_info); /* presumably, we trapped an open here */ goto restart; } } #endif /* HAVE_PTYTRAP */ } #if 0 /* can't get fread to return early! */ else { if (!(cc = fread(buffer,1,length,fp))) { if (ferror(fp)) cc = -1; } } #endif i_read_errno = errno; /* errno can be overwritten by the */ /* time we return */ } exp_reading = FALSE; if (timeout > 0) alarm(0); return(cc); } /* I tried really hard to make the following two functions share the code */ /* that makes the ecase array, but I kept running into a brick wall when */ /* passing var args into the funcs and then again into a make_cases func */ /* I would very much appreciate it if someone showed me how to do it right */ /* takes triplets of args, with a final "exp_last" arg */ /* triplets are type, pattern, and then int to return */ /* returns negative value if error (or EOF/timeout) occurs */ /* some negative values can also have an associated errno */ /* the key internal variables that this function depends on are: exp_buffer exp_buffer_end exp_match_end */ static int expectv(fd,fp,ecases) int fd; FILE *fp; struct exp_case *ecases; { int cc = 0; /* number of chars returned in a single read */ int buf_length; /* numbers of chars in exp_buffer */ int old_length; /* old buf_length */ int first_time = TRUE; /* force old buffer to be tested before */ /* additional reads */ int polled = 0; /* true if poll has caused read() to occur */ struct exp_case *ec; /* points to current ecase */ time_t current_time; /* current time (when we last looked)*/ time_t end_time; /* future time at which to give up */ int remtime; /* remaining time in timeout */ struct f *f; int return_val; int sys_error = 0; #define return_normally(x) {return_val = x; goto cleanup;} #define return_errno(x) {sys_error = x; goto cleanup;} f = fdfp2f(fd,fp); if (!f) return_errno(ENOMEM); exp_buffer = f->buffer; exp_buffer_end = f->buffer_end; exp_match_end = f->match_end; buf_length = exp_buffer_end - exp_match_end; if (buf_length) { /* * take end of previous match to end of buffer * and copy to beginning of buffer */ memmove(exp_buffer,exp_match_end,buf_length); } exp_buffer_end = exp_buffer + buf_length; *exp_buffer_end = '\0'; if (!ecases) return_errno(EINVAL); /* compile if necessary */ for (ec=ecases;ec->type != exp_end;ec++) { if ((ec->type == exp_regexp) && !ec->re) { TclRegError((char *)0); if (!(ec->re = TclRegComp(ec->pattern))) { fprintf(stderr,"regular expression %s is bad: %s",ec->pattern,TclGetRegError()); return_errno(EINVAL); } } } /* get the latest buffer size. Double the user input for two */ /* reasons. 1) Need twice the space in case the match */ /* straddles two bufferfuls, 2) easier to hack the division by */ /* two when shifting the buffers later on */ bufsiz = 2*exp_match_max; if (f->msize != bufsiz) { /* if truncated, forget about some data */ if (buf_length > bufsiz) { /* copy end of buffer down */ /* copy one less than what buffer can hold to avoid */ /* triggering buffer-full handling code below */ /* which will immediately dump the first half */ /* of the buffer */ memmove(exp_buffer,exp_buffer+(buf_length - bufsiz)+1, bufsiz-1); buf_length = bufsiz-1; } exp_buffer = realloc(exp_buffer,bufsiz+1); if (!exp_buffer) return_errno(ENOMEM); exp_buffer[buf_length] = '\0'; exp_buffer_end = exp_buffer + buf_length; f->msize = bufsiz; } /* some systems (i.e., Solaris) require fp be flushed when switching */ /* directions - do this again afterwards */ if (fd == -1) fflush(fp); if (exp_timeout != -1) signal(SIGALRM,sigalarm_handler); /* remtime and current_time updated at bottom of loop */ remtime = exp_timeout; time(¤t_time); end_time = current_time + remtime; for (;;) { /* when buffer fills, copy second half over first and */ /* continue, so we can do matches over multiple buffers */ if (buf_length == bufsiz) { int first_half, second_half; if (exp_full_buffer) { exp_debuglog("expect: full buffer\r\n"); exp_match = exp_buffer; exp_match_end = exp_buffer + buf_length; exp_buffer_end = exp_match_end; return_normally(EXP_FULLBUFFER); } first_half = bufsiz/2; second_half = bufsiz - first_half; memcpy(exp_buffer,exp_buffer+first_half,second_half); buf_length = second_half; exp_buffer_end = exp_buffer + second_half; } /* * always check first if pattern is already in buffer */ if (first_time) { first_time = FALSE; goto after_read; } /* * check for timeout */ if ((exp_timeout >= 0) && ((remtime < 0) || polled)) { exp_debuglog("expect: timeout\r\n"); exp_match_end = exp_buffer; return_normally(EXP_TIMEOUT); } /* * if timeout == 0, indicate a poll has * occurred so that next time through loop causes timeout */ if (exp_timeout == 0) { polled = 1; } cc = i_read(fd,fp, exp_buffer_end, bufsiz - buf_length, remtime); if (cc == 0) { exp_debuglog("expect: eof\r\n"); return_normally(EXP_EOF); /* normal EOF */ } else if (cc == -1) { /* abnormal EOF */ /* ptys produce EIO upon EOF - sigh */ if (i_read_errno == EIO) { /* convert to EOF indication */ exp_debuglog("expect: eof\r\n"); return_normally(EXP_EOF); } exp_debuglog("expect: error (errno = %d)\r\n",i_read_errno); return_errno(i_read_errno); } else if (cc == -2) { exp_debuglog("expect: timeout\r\n"); exp_match_end = exp_buffer; return_normally(EXP_TIMEOUT); } old_length = buf_length; buf_length += cc; exp_buffer_end += buf_length; if (logfile_all || (loguser && logfile)) { fwrite(exp_buffer + old_length,1,cc,logfile); } if (loguser) fwrite(exp_buffer + old_length,1,cc,stdout); if (debugfile) fwrite(exp_buffer + old_length,1,cc,debugfile); /* if we wrote to any logs, flush them */ if (debugfile) fflush(debugfile); if (loguser) { fflush(stdout); if (logfile) fflush(logfile); } /* remove nulls from input, so we can use C-style strings */ /* doing it here lets them be sent to the screen, just */ /* in case they are involved in formatting operations */ if (exp_remove_nulls) { buf_length -= rm_nulls(exp_buffer + old_length, cc); } /* cc should be decremented as well, but since it will not */ /* be used before being set again, there is no need */ exp_buffer_end = exp_buffer + buf_length; *exp_buffer_end = '\0'; exp_match_end = exp_buffer; after_read: exp_debuglog("expect: does {%s} match ",exp_printify(exp_buffer)); /* pattern supplied */ for (ec=ecases;ec->type != exp_end;ec++) { int matched = -1; exp_debuglog("{%s}? ",exp_printify(ec->pattern)); if (ec->type == exp_glob) { int offset; matched = Exp_StringMatch(exp_buffer,ec->pattern,&offset); if (matched >= 0) { exp_match = exp_buffer + offset; exp_match_end = exp_match + matched; } } else if (ec->type == exp_exact) { char *p = strstr(exp_buffer,ec->pattern); if (p) { matched = 1; exp_match = p; exp_match_end = p + strlen(ec->pattern); } } else if (ec->type == exp_null) { char *p; for (p=exp_buffer;p<exp_buffer_end;p++) { if (*p == 0) { matched = 1; exp_match = p; exp_match_end = p+1; } } } else { TclRegError((char *)0); if (TclRegExec(ec->re,exp_buffer,exp_buffer)) { matched = 1; exp_match = ec->re->startp[0]; exp_match_end = ec->re->endp[0]; } else if (TclGetRegError()) { fprintf(stderr,"r.e. match (pattern %s) failed: %s",ec->pattern,TclGetRegError()); } } if (matched != -1) { exp_debuglog("yes\nexp_buffer is {%s}\n", exp_printify(exp_buffer)); return_normally(ec->value); } else exp_debuglog("no\n"); } /* * Update current time and remaining time. * Don't bother if we are waiting forever or polling. */ if (exp_timeout > 0) { time(¤t_time); remtime = end_time - current_time; } } cleanup: f->buffer = exp_buffer; f->buffer_end = exp_buffer_end; f->match_end = exp_match_end; /* some systems (i.e., Solaris) require fp be flushed when switching */ /* directions - do this before as well */ if (fd == -1) fflush(fp); if (sys_error) { errno = sys_error; return -1; } return return_val; } int exp_fexpectv(fp,ecases) FILE *fp; struct exp_case *ecases; { return(expectv(-1,fp,ecases)); } int exp_expectv(fd,ecases) int fd; struct exp_case *ecases; { return(expectv(fd,(FILE *)0,ecases)); } /*VARARGS*/ int exp_expectl TCL_VARARGS_DEF(int,arg1) /*exp_expectl(va_alist)*/ /*va_dcl*/ { va_list args; int fd; struct exp_case *ec, *ecases; int i; enum exp_type type; fd = TCL_VARARGS_START(int,arg1,args); /* va_start(args);*/ /* fd = va_arg(args,int);*/ /* first just count the arg sets */ for (i=0;;i++) { type = va_arg(args,enum exp_type); if (type == exp_end) break; /* Ultrix 4.2 compiler refuses enumerations comparison!? */ if ((int)type < 0 || (int)type >= (int)exp_bogus) { fprintf(stderr,"bad type (set %d) in exp_expectl\n",i); sysreturn(EINVAL); } va_arg(args,char *); /* COMPUTED BUT NOT USED */ if (type == exp_compiled) { va_arg(args,regexp *); /* COMPUTED BUT NOT USED */ } va_arg(args,int); /* COMPUTED BUT NOT USED*/ } va_end(args); if (!(ecases = (struct exp_case *) malloc((1+i)*sizeof(struct exp_case)))) sysreturn(ENOMEM); /* now set up the actual cases */ fd = TCL_VARARGS_START(int,arg1,args); /*va_start(args);*/ /*va_arg(args,int);*/ /*COMPUTED BUT NOT USED*/ for (ec=ecases;;ec++) { ec->type = va_arg(args,enum exp_type); if (ec->type == exp_end) break; ec->pattern = va_arg(args,char *); if (ec->type == exp_compiled) { ec->re = va_arg(args,regexp *); } else { ec->re = 0; } ec->value = va_arg(args,int); } va_end(args); i = expectv(fd,(FILE *)0,ecases); for (ec=ecases;ec->type != exp_end;ec++) { /* free only if regexp and we compiled it for user */ if (ec->type == exp_regexp) { free((char *)ec->re); } } free((char *)ecases); return(i); } int exp_fexpectl TCL_VARARGS_DEF(FILE *,arg1) /*exp_fexpectl(va_alist)*/ /*va_dcl*/ { va_list args; FILE *fp; struct exp_case *ec, *ecases; int i; enum exp_type type; fp = TCL_VARARGS_START(FILE *,arg1,args); /*va_start(args);*/ /*fp = va_arg(args,FILE *);*/ /* first just count the arg-pairs */ for (i=0;;i++) { type = va_arg(args,enum exp_type); if (type == exp_end) break; /* Ultrix 4.2 compiler refuses enumerations comparison!? */ if ((int)type < 0 || (int)type >= (int)exp_bogus) { fprintf(stderr,"bad type (set %d) in exp_expectl\n",i); sysreturn(EINVAL); } va_arg(args,char *); /* COMPUTED BUT NOT USED */ if (type == exp_compiled) { va_arg(args,regexp *); /* COMPUTED BUT NOT USED */ } va_arg(args,int); /* COMPUTED BUT NOT USED*/ } va_end(args); if (!(ecases = (struct exp_case *) malloc((1+i)*sizeof(struct exp_case)))) sysreturn(ENOMEM); #if 0 va_start(args); va_arg(args,FILE *); /*COMPUTED, BUT NOT USED*/ #endif (void) TCL_VARARGS_START(FILE *,arg1,args); for (ec=ecases;;ec++) { ec->type = va_arg(args,enum exp_type); if (ec->type == exp_end) break; ec->pattern = va_arg(args,char *); if (ec->type == exp_compiled) { ec->re = va_arg(args,regexp *); } else { ec->re = 0; } ec->value = va_arg(args,int); } va_end(args); i = expectv(-1,fp,ecases); for (ec=ecases;ec->type != exp_end;ec++) { /* free only if regexp and we compiled it for user */ if (ec->type == exp_regexp) { free((char *)ec->re); } } free((char *)ecases); return(i); } /* like popen(3) but works in both directions */ FILE * exp_popen(program) char *program; { FILE *fp; int ec; if (0 > (ec = exp_spawnl("sh","sh","-c",program,(char *)0))) return(0); if (!(fp = fdopen(ec,"r+"))) return(0); setbuf(fp,(char *)0); return(fp); } #ifndef __WIN32__ int exp_disconnect() { int ttyfd; #ifndef EALREADY #define EALREADY 37 #endif /* presumably, no stderr, so don't bother with error message */ if (exp_disconnected) sysreturn(EALREADY); exp_disconnected = TRUE; freopen("/dev/null","r",stdin); freopen("/dev/null","w",stdout); freopen("/dev/null","w",stderr); #ifdef POSIX setsid(); #else #ifdef SYSV3 /* put process in our own pgrp, and lose controlling terminal */ setpgrp(); signal(SIGHUP,SIG_IGN); if (fork()) exit(0); /* first child exits (as per Stevens, */ /* UNIX Network Programming, p. 79-80) */ /* second child process continues as daemon */ #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,getpid()); /* put process in our own pgrp */ /* Pyramid lacks this defn */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { /* zap controlling terminal if we had one */ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* POSIX */ return(0); } #endif /* !__WIN32__ */ |
Added unix/exp_command.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 | /* exp_command.c - the bulk of the Expect commands Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "expect_cf.h" #include <stdio.h> #include <sys/types.h> /*#include <sys/time.h> seems to not be present on SVR3 systems */ /* and it's not used anyway as far as I can tell */ /* AIX insists that stropts.h be included before ioctl.h, because both */ /* define _IO but only ioctl.h checks first. Oddly, they seem to be */ /* defined differently! */ #ifdef HAVE_STROPTS_H # include <sys/stropts.h> #endif #ifndef WIN32 # include <sys/ioctl.h> #endif #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif #ifndef WIN32 # include <sys/file.h> #endif #include "exp_tty.h" #ifdef HAVE_SYS_WAIT_H /* ISC doesn't def WNOHANG unless _POSIX_SOURCE is def'ed */ # ifdef WNOHANG_REQUIRES_POSIX_SOURCE # define _POSIX_SOURCE # endif # include <sys/wait.h> # ifdef WNOHANG_REQUIRES_POSIX_SOURCE # undef _POSIX_SOURCE # endif #endif #include <errno.h> #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #ifdef HAVE_PTYTRAP #include <sys/ptyio.h> #endif #ifdef CRAY # ifndef TCSETCTTY # if defined(HAVE_TERMIOS) # include <termios.h> # else # include <termio.h> # endif # endif #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include <math.h> /* for log/pow computation in send -h */ #include <ctype.h> /* all this for ispunct! */ #include "tclInt.h" /* need OpenFile */ /*#include <varargs.h> tclInt.h drags in varargs.h. Since Pyramid */ /* objects to including varargs.h twice, just */ /* omit this one. */ #include "tcl.h" #include "tclPort.h" #include "string.h" #include "expect_tcl.h" #include "exp_rename.h" #include "exp_prog.h" #include "exp_command.h" #include "exp_log.h" #include "exp_event.h" #include "exp_pty.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #endif #define SPAWN_ID_VARNAME "spawn_id" int getptymaster(); int getptyslave(); int exp_forked = FALSE; /* whether we are child process */ /* the following are just reserved addresses, to be used as ClientData */ /* args to be used to tell commands how they were called. */ /* The actual values won't be used, only the addresses, but I give them */ /* values out of my irrational fear the compiler might collapse them all. */ static int sendCD_error = 2; /* called as send_error */ static int sendCD_user = 3; /* called as send_user */ static int sendCD_proc = 4; /* called as send or send_spawn */ static int sendCD_tty = 6; /* called as send_tty */ struct exp_f *exp_fs = 0; /* process array (indexed by spawn_id's) */ int exp_fd_max = -1; /* highest fd */ /* * expect_key is just a source for generating a unique stamp. As each * expect/interact command begins, it generates a new key and marks all * the spawn ids of interest with it. Then, if someone comes along and * marks them with yet a newer key, the old command will recognize this * reexamine the state of the spawned process. */ int expect_key = 0; /* * exp_configure_count is incremented whenever a spawned process is closed * or an indirect list is modified. This forces any (stack of) expect or * interact commands to reexamine the state of the world and adjust * accordingly. */ int exp_configure_count = 0; /* this message is required because fopen sometimes fails to set errno */ /* Apparently, it "does the user a favor" and doesn't even call open */ /* if the file name is bizarre enough. This means we can't handle fopen */ /* with the obvious trivial logic. */ static char *open_failed = "could not open - odd file name?"; #ifdef HAVE_PTYTRAP /* slaveNames provides a mapping from the pty slave names to our */ /* spawn id entry. This is needed only on HPs for stty, sigh. */ static Tcl_HashTable slaveNames; #endif /* HAVE_PTYTRAP */ #ifdef FULLTRAPS static void init_traps(traps) RETSIGTYPE (*traps[])(); { int i; for (i=1;i<NSIG;i++) { traps[i] = SIG_ERR; } } #endif /* Do not terminate format strings with \n!!! */ /*VARARGS*/ void exp_error TCL_VARARGS_DEF(Tcl_Interp *,arg1) /*exp_error(va_alist)*/ /*va_dcl*/ { Tcl_Interp *interp; char *fmt; va_list args; interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args); /*va_start(args);*/ /*interp = va_arg(args,Tcl_Interp *);*/ fmt = va_arg(args,char *); vsprintf(interp->result,fmt,args); va_end(args); } /* returns handle if fd is usable, 0 if not */ struct exp_f * exp_fd2f(interp,fd,opened,adjust,msg) Tcl_Interp *interp; int fd; int opened; /* check not closed */ int adjust; /* adjust buffer sizes */ char *msg; { if (fd >= 0 && fd <= exp_fd_max && (exp_fs[fd].valid)) { struct exp_f *f = exp_fs + fd; /* following is a little tricky, do not be tempted do the */ /* 'usual' boolean simplification */ if ((!opened) || !f->user_closed) { if (adjust) exp_adjust(f); return f; } } exp_error(interp,"%s: invalid spawn id (%d)",msg,fd); return(0); } #if 0 /* following routine is not current used, but might be later */ /* returns fd or -1 if no such entry */ static int pid_to_fd(pid) int pid; { int fd; for (fd=0;fd<=exp_fd_max;fd++) { if (exp_fs[fd].pid == pid) return(fd); } return 0; } #endif /* Tcl needs commands in writable space */ static char close_cmd[] = "close"; /* zero out the wait status field */ static void exp_wait_zero(status) WAIT_STATUS_TYPE *status; { int i; for (i=0;i<sizeof(WAIT_STATUS_TYPE);i++) { ((char *)status)[i] = 0; } } /* prevent an fd from being allocated */ void exp_busy(fd) int fd; { #ifndef WIN32_XXX int x = open("/dev/null",0); if (x != fd) { fcntl(x,F_DUPFD,fd); close(x); } exp_close_on_exec(fd); #endif } /* called just before an exp_f entry is about to be invalidated */ void exp_f_prep_for_invalidation(interp,f) Tcl_Interp *interp; struct exp_f *f; { int fd = f - exp_fs; exp_ecmd_remove_fd_direct_and_indirect(interp,fd); exp_configure_count++; if (f->buffer) { ckfree(f->buffer); f->buffer = 0; f->msize = 0; f->size = 0; f->printed = 0; f->echoed = 0; if (f->fg_armed) { exp_event_disarm(f-exp_fs); f->fg_armed = FALSE; } ckfree(f->lower); } f->fg_armed = FALSE; } /*ARGSUSED*/ void exp_trap_on(master) int master; { #ifdef HAVE_PTYTRAP if (master == -1) return; exp_slave_control(master,1); #endif /* HAVE_PTYTRAP */ } int exp_trap_off(name) char *name; { #ifdef HAVE_PTYTRAP int master; struct exp_f *f; int enable = 0; Tcl_HashEntry *entry = Tcl_FindHashEntry(&slaveNames,name); if (!entry) { exp_debuglog("exp_trap_off: no entry found for %s\n",name); return -1; } f = (struct exp_f *)Tcl_GetHashValue(entry); master = f - exp_fs; exp_slave_control(master,0); return master; #else return name[0]; /* pacify lint, use arg and return something */ #endif } /*ARGSUSED*/ void sys_close(fd,f) int fd; struct exp_f *f; { /* Ignore close errors. Some systems are really odd and */ /* return errors for no evident reason. Anyway, receiving */ /* an error upon pty-close doesn't mean anything anyway as */ /* far as I know. */ close(fd); f->sys_closed = TRUE; #ifdef HAVE_PTYTRAP if (f->slave_name) { Tcl_HashEntry *entry; entry = Tcl_FindHashEntry(&slaveNames,f->slave_name); Tcl_DeleteHashEntry(entry); ckfree(f->slave_name); f->slave_name = 0; } #endif } /* given a Tcl file identifier, close it */ static void close_tcl_file(interp,file_id) Tcl_Interp *interp; char *file_id; { char *argv[3]; Tcl_CmdInfo info; argv[0] = close_cmd; argv[1] = file_id; argv[2] = 0; Tcl_ResetResult(interp); Tcl_GetCommandInfo(interp,"close",&info); if (0 == Tcl_GetCommandInfo(interp,"close",&info)) { info.clientData = 0; } (void) Tcl_CloseCmd(info.clientData,interp,2,argv); } /* close all connections The kernel would actually do this by default, however Tcl is going to come along later and try to reap its exec'd processes. If we have inherited any via spawn -open, Tcl can hang if we don't close the connections first. */ void exp_close_all(interp) Tcl_Interp *interp; { int fd; for (fd=0;fd<=exp_fd_max;fd++) { if (exp_fs[fd].valid) { exp_close(interp,fd); } } } int exp_close(interp,fd) Tcl_Interp *interp; int fd; { struct exp_f *f = exp_fd2f(interp,fd,1,0,"close"); if (!f) return(TCL_ERROR); f->user_closed = TRUE; if (f->slave_fd != EXP_NOFD) close(f->slave_fd); #if 0 if (f->tcl_handle) { ckfree(f->tcl_handle); if ((f - exp_fs) != f->tcl_output) close(f->tcl_output); } #endif sys_close(fd,f); if (f->tcl_handle) { if ((f - exp_fs) != f->tcl_output) close(f->tcl_output); if (!f->leaveopen) { /* * Ignore errors from close; they report things like * broken pipeline, etc, which don't affect our * subsequent handling. */ close_tcl_file(interp,f->tcl_handle); ckfree(f->tcl_handle); f->tcl_handle = 0; } } exp_f_prep_for_invalidation(interp,f); if (f->user_waited) { f->valid = FALSE; } else { exp_busy(fd); f->sys_closed = FALSE; } return(TCL_OK); } static struct exp_f * fd_new(fd,pid) int fd; int pid; { int i, low; struct exp_f *newfs; /* temporary, so we don't lose old exp_fs */ /* resize table if nec */ if (fd > exp_fd_max) { if (!exp_fs) { /* no fd's yet allocated */ newfs = (struct exp_f *)ckalloc(sizeof(struct exp_f)*(fd+1)); low = 0; } else { /* enlarge fd table */ newfs = (struct exp_f *)ckrealloc((char *)exp_fs,sizeof(struct exp_f)*(fd+1)); low = exp_fd_max+1; } exp_fs = newfs; exp_fd_max = fd; for (i = low; i <= exp_fd_max; i++) { /* init new fd entries */ exp_fs[i].valid = FALSE; exp_fs[i].fd_ptr = (int *)ckalloc(sizeof(int)); *exp_fs[i].fd_ptr = i; /* exp_fs[i].ptr = (struct exp_f **)ckalloc(sizeof(struct exp_fs *));*/ } #if 0 for (i = 0; i <= exp_fd_max; i++) { /* update all indirect ptrs */ *exp_fs[i].ptr = exp_fs + i; } #endif } /* this could happen if user does "spawn -open stdin" I suppose */ if (exp_fs[fd].valid) return exp_fs+fd; /* close down old table entry if nec */ exp_fs[fd].pid = pid; exp_fs[fd].size = 0; exp_fs[fd].msize = 0; exp_fs[fd].buffer = 0; exp_fs[fd].printed = 0; exp_fs[fd].echoed = 0; exp_fs[fd].rm_nulls = exp_default_rm_nulls; exp_fs[fd].parity = exp_default_parity; exp_fs[fd].key = expect_key++; exp_fs[fd].force_read = FALSE; exp_fs[fd].fg_armed = FALSE; /* Master must be inited each time because Tcl could have alloc'd */ /* this fd and shut it down (deallocating the FileHandle) behind */ /* our backs */ exp_fs[fd].Master = Tcl_GetFile((ClientData)fd,TCL_UNIX_FD); exp_fs[fd].MasterOutput = 0; exp_fs[fd].Slave = 0; exp_fs[fd].tcl_handle = 0; exp_fs[fd].slave_fd = EXP_NOFD; #ifdef HAVE_PTYTRAP exp_fs[fd].slave_name = 0; #endif /* HAVE_PTYTRAP */ exp_fs[fd].umsize = exp_default_match_max; exp_fs[fd].valid = TRUE; exp_fs[fd].user_closed = FALSE; exp_fs[fd].sys_closed = FALSE; exp_fs[fd].user_waited = FALSE; exp_fs[fd].sys_waited = FALSE; exp_fs[fd].bg_interp = 0; exp_fs[fd].bg_status = unarmed; exp_fs[fd].bg_ecount = 0; return exp_fs+fd; } #if 0 void exp_global_init(eg,duration,location) struct expect_global *eg; int duration; int location; { eg->ecases = 0; eg->ecount = 0; eg->i_list = 0; eg->duration = duration; eg->location = location; } #endif void exp_init_spawn_id_vars(interp) Tcl_Interp *interp; { Tcl_SetVar(interp,"user_spawn_id",EXP_SPAWN_ID_USER_LIT,0); Tcl_SetVar(interp,"error_spawn_id",EXP_SPAWN_ID_ERROR_LIT,0); Tcl_SetVar(interp,"tty_spawn_id",dev_tty_str,0); /* note that the user_spawn_id is NOT /dev/tty which could */ /* (at least in theory anyway) be later re-opened on a different */ /* fd, while stdin might have been redirected away from /dev/tty */ if (exp_dev_tty != -1) { char dev_tty_str[10]; sprintf(dev_tty_str,"%d",exp_dev_tty); Tcl_SetVar(interp,"tty_spawn_id",dev_tty_str,0); } } void exp_init_spawn_ids() { /* note whether 0,1,2 are connected to a terminal so that if we */ /* disconnect, we can shut these down. We would really like to */ /* test if 0,1,2 are our controlling tty, but I don't know any */ /* way to do that portably. Anyway, the likelihood of anyone */ /* disconnecting after redirecting to a non-controlling tty is */ /* virtually zero. */ fd_new(0,isatty(0)?exp_getpid:EXP_NOPID); fd_new(1,isatty(1)?exp_getpid:EXP_NOPID); fd_new(2,isatty(2)?exp_getpid:EXP_NOPID); if (exp_dev_tty != -1) { fd_new(exp_dev_tty,exp_getpid); } /* really should be in interpreter() but silly to do on every call */ exp_adjust(&exp_fs[0]); } void exp_close_on_exec(fd) int fd; { #ifndef WIN32_XXX (void) fcntl(fd,F_SETFD,1); #endif } #define STTY_INIT "stty_init" #if 0 static void show_pgrp(fd,string) int fd; char *string; { int pgrp; fprintf(stderr,"getting pgrp for %s\n",string); if (-1 == ioctl(fd,TIOCGETPGRP,&pgrp)) perror("TIOCGETPGRP"); else fprintf(stderr,"%s pgrp = %d\n",string,pgrp); if (-1 == ioctl(fd,TIOCGPGRP,&pgrp)) perror("TIOCGPGRP"); else fprintf(stderr,"%s pgrp = %d\n",string,pgrp); if (-1 == tcgetpgrp(fd,pgrp)) perror("tcgetpgrp"); else fprintf(stderr,"%s pgrp = %d\n",string,pgrp); } static void set_pgrp(fd) int fd; { int pgrp = getpgrp(0); if (-1 == ioctl(fd,TIOCSETPGRP,&pgrp)) perror("TIOCSETPGRP"); if (-1 == ioctl(fd,TIOCSPGRP,&pgrp)) perror("TIOCSPGRP"); if (-1 == tcsetpgrp(fd,pgrp)) perror("tcsetpgrp"); } #endif /*ARGSUSED*/ static void set_slave_name(f,name) struct exp_f *f; char *name; { #ifdef HAVE_PTYTRAP int newptr; Tcl_HashEntry *entry; /* save slave name */ f->slave_name = ckalloc(strlen(exp_pty_slave_name)+1); strcpy(f->slave_name,exp_pty_slave_name); entry = Tcl_CreateHashEntry(&slaveNames,exp_pty_slave_name,&newptr); Tcl_SetHashValue(entry,(ClientData)f); #endif /* HAVE_PTYTRAP */ } /* arguments are passed verbatim to execvp() */ /*ARGSUSED*/ static int Exp_SpawnCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int slave; int pid; char **a; /* tell Saber to ignore non-use of ttyfd */ /*SUPPRESS 591*/ int errorfd; /* place to stash fileno(stderr) in child */ /* while we're setting up new stderr */ int ttyfd; int master; int write_master; /* write fd of Tcl-opened files */ int ttyinit = TRUE; int ttycopy = TRUE; int echo = TRUE; int console = FALSE; int pty_only = FALSE; #ifdef FULLTRAPS /* Allow user to reset signals in child */ /* The following array contains indicates */ /* whether sig should be DFL or IGN */ /* ERR is used to indicate no initialization */ RETSIGTYPE (*traps[NSIG])(); #endif int ignore[NSIG]; /* if true, signal in child is ignored */ /* if false, signal gets default behavior */ int i; /* trusty overused temporary */ char *argv0 = argv[0]; char *openarg = 0; int leaveopen = FALSE; FILE *readfilePtr; FILE *writefilePtr; int rc, wc; char *stty_init; int slave_write_ioctls = 1; /* by default, slave will be write-ioctled this many times */ int slave_opens = 3; /* by default, slave will be opened this many times */ /* first comes from initial allocation */ /* second comes from stty */ /* third is our own signal that stty is done */ int sync_fds[2]; int sync2_fds[2]; int status_pipe[2]; int child_errno; char sync_byte; char buf[4]; /* enough space for a string literal */ /* representing a file descriptor */ Tcl_DString dstring; Tcl_DStringInit(&dstring); #ifdef FULLTRAPS init_traps(&traps); #endif /* don't ignore any signals in child by default */ for (i=1;i<NSIG;i++) { ignore[i] = FALSE; } argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-nottyinit")) { ttyinit = FALSE; slave_write_ioctls--; slave_opens--; } else if (streq(*argv,"-nottycopy")) { ttycopy = FALSE; } else if (streq(*argv,"-noecho")) { echo = FALSE; } else if (streq(*argv,"-console")) { console = TRUE; } else if (streq(*argv,"-pty")) { pty_only = TRUE; } else if (streq(*argv,"-open")) { if (argc < 2) { exp_error(interp,"usage: -open file-identifier"); return TCL_ERROR; } openarg = argv[1]; argc--; argv++; } else if (streq(*argv,"-leaveopen")) { if (argc < 2) { exp_error(interp,"usage: -open file-identifier"); return TCL_ERROR; } openarg = argv[1]; leaveopen = TRUE; argc--; argv++; } else if (streq(*argv,"-ignore")) { int sig; if (argc < 2) { exp_error(interp,"usage: -ignore signal"); return TCL_ERROR; } sig = exp_string_to_signal(interp,argv[1]); if (sig == -1) { exp_error(interp,"usage: -ignore %s: unknown signal name",argv[1]); return TCL_ERROR; } ignore[sig] = TRUE; argc--; argv++; #ifdef FULLTRAPS } else if (streq(*argv,"-trap")) { /* argv[1] is action */ /* argv[2] is list of signals */ RETSIGTYPE (*sig_handler)(); int n; /* number of signals in list */ char **list; /* list of signals */ if (argc < 3) { exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN"); return TCL_ERROR; } if (0 == strcmp(argv[2],"SIG_DFL")) { sig_handler = SIG_DFL; } else if (0 == strcmp(argv[2],"SIG_IGN")) { sig_handler = SIG_IGN; } else { exp_error(interp,"usage: -trap siglist SIG_DFL or SIG_IGN"); return TCL_ERROR; } if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) { exp_errorlog("%s\r\n",interp->result); exp_error(interp,"usage: -trap {siglist} ..."); return TCL_ERROR; } for (i=0;i<n;i++) { int sig = exp_string_to_signal(interp,list[i]); if (sig == -1) { ckfree((char *)&list); return TCL_ERROR; } traps[sig] = sig_handler; } ckfree((char *)&list); argc--; argv++; argc--; argv++; #endif /*FULLTRAPS*/ } else break; } if (openarg && (argc != 0)) { exp_error(interp,"usage: -[leave]open [fileXX]"); return TCL_ERROR; } if (!pty_only && !openarg && (argc == 0)) { exp_error(interp,"usage: spawn [spawn-args] program [program-args]"); return(TCL_ERROR); } stty_init = exp_get_var(interp,STTY_INIT); if (stty_init) { slave_write_ioctls++; slave_opens++; } /* any extraneous ioctl's that occur in slave must be accounted for when trapping, see below in child half of fork */ #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) slave_write_ioctls++; slave_opens++; #endif exp_pty_slave_name = 0; Tcl_ReapDetachedProcs(); if (!openarg) { if (echo) { exp_log(0,"%s ",argv0); for (a = argv;*a;a++) { exp_log(0,"%s ",*a); } exp_nflog("\r\n",0); } if (0 > (master = getptymaster())) { /* * failed to allocate pty, try and figure out why * so we can suggest to user what to do about it. */ int count; int testfd; if (exp_pty_error) { exp_error(interp,"%s",exp_pty_error); return TCL_ERROR; } count = 0; for (i=3;i<=exp_fd_max;i++) { count += exp_fs[i].valid; } if (count > 10) { exp_error(interp,"The system only has a finite number of ptys and you have many of them in use. The usual reason for this is that you forgot (or didn't know) to call \"wait\" after closing each of them."); return TCL_ERROR; } testfd = open("/",0); close(testfd); if (testfd != -1) { exp_error(interp,"The system has no more ptys. Ask your system administrator to create more."); } else { exp_error(interp,"- You have too many files are open. Close some files or increase your per-process descriptor limit."); } return(TCL_ERROR); } #ifdef PTYTRAP_DIES if (!pty_only) exp_slave_control(master,1); #endif /* PTYTRAP_DIES */ #define SPAWN_OUT "spawn_out" Tcl_SetVar2(interp,SPAWN_OUT,"slave,name",exp_pty_slave_name,0); } else { Tcl_Channel chan; int mode; Tcl_File tclReadFile, tclWriteFile; int rfd, wfd; if (echo) exp_log(0,"%s [open ...]\r\n",argv0); #if TCL7_4 rc = Tcl_GetOpenFile(interp,openarg,0,1,&readfilePtr); wc = Tcl_GetOpenFile(interp,openarg,1,1,&writefilePtr); /* fail only if both descriptors are bad */ if (rc == TCL_ERROR && wc == TCL_ERROR) { return TCL_ERROR; } master = fileno((rc == TCL_OK)?readfilePtr:writefilePtr); /* make a new copy of file descriptor */ if (-1 == (write_master = master = dup(master))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } /* if writefilePtr is different, dup that too */ if ((rc == TCL_OK) && (wc == TCL_OK) && (fileno(writefilePtr) != fileno(readfilePtr))) { if (-1 == (write_master = dup(fileno(writefilePtr)))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } exp_close_on_exec(write_master); } #endif if (!(chan = Tcl_GetChannel(interp,openarg,&mode))) { return TCL_ERROR; } if (!mode) { exp_error(interp,"channel is neither readable nor writable"); return TCL_ERROR; } if (mode & TCL_READABLE) { tclReadFile = Tcl_GetChannelFile(chan, TCL_READABLE); rfd = (int)Tcl_GetFileInfo(tclReadFile, (int *)0); } if (mode & TCL_WRITABLE) { tclWriteFile = Tcl_GetChannelFile(chan, TCL_WRITABLE); wfd = (int)Tcl_GetFileInfo(tclWriteFile, (int *)0); } master = ((mode & TCL_READABLE)?rfd:wfd); /* make a new copy of file descriptor */ if (-1 == (write_master = master = dup(master))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } /* if writefilePtr is different, dup that too */ if ((mode & TCL_READABLE) && (mode & TCL_WRITABLE) && (wfd != rfd)) { if (-1 == (write_master = dup(wfd))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } exp_close_on_exec(write_master); } /* * It would be convenient now to tell Tcl to close its * file descriptor. Alas, if involved in a pipeline, Tcl * will be unable to complete a wait on the process. * So simply remember that we meant to close it. We will * do so later in our own close routine. */ } /* much easier to set this, than remember all masters */ exp_close_on_exec(master); if (openarg || pty_only) { struct exp_f *f; f = fd_new(master,EXP_NOPID); if (openarg) { /* save file# handle */ f->tcl_handle = ckalloc(strlen(openarg)+1); strcpy(f->tcl_handle,openarg); f->tcl_output = write_master; #if 0 /* save fd handle for output */ if (wc == TCL_OK) { /* f->tcl_output = fileno(writefilePtr);*/ f->tcl_output = write_master; } else { /* if we actually try to write to it at some */ /* time in the future, then this will cause */ /* an error */ f->tcl_output = master; } #endif f->leaveopen = leaveopen; } if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name); /* make it appear as if process has been waited for */ f->sys_waited = TRUE; exp_wait_zero(&f->wait); /* tell user id of new process */ sprintf(buf,"%d",master); Tcl_SetVar(interp,SPAWN_ID_VARNAME,buf,0); if (!openarg) { char value[20]; int dummyfd1, dummyfd2; /* * open the slave side in the same process to support * the -pty flag. */ /* Start by working around a bug in Tcl's exec. It closes all the file descriptors from 3 to it's own fd_max which inappropriately closes our slave fd. To avoid this, open several dummy fds. Then exec's fds will fall below ours. Note that if you do something like pre-allocating a bunch before using them or generating a pipeline, then this code won't help. Instead you'll need to add the right number of explicit Tcl open's of /dev/null. The right solution is fix Tcl's exec so it is not so cavalier. */ dummyfd1 = open("/dev/null",0); dummyfd2 = open("/dev/null",0); if (0 > (f->slave_fd = getptyslave(ttycopy,ttyinit, stty_init))) { exp_error(interp,"open(slave pty): %s\r\n",Tcl_PosixError(interp)); return TCL_ERROR; } close(dummyfd1); close(dummyfd2); exp_slave_control(master,1); sprintf(value,"%d",f->slave_fd); Tcl_SetVar2(interp,SPAWN_OUT,"slave,fd",value,0); } sprintf(interp->result,"%d",EXP_NOPID); exp_debuglog("spawn: returns {%s}\r\n",interp->result); return TCL_OK; } if (NULL == (argv[0] = Tcl_TildeSubst(interp,argv[0],&dstring))) { goto parent_error; } if (-1 == pipe(sync_fds)) { exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp)); goto parent_error; } if (-1 == pipe(sync2_fds)) { close(sync_fds[0]); close(sync_fds[1]); exp_error(interp,"too many programs spawned? could not create pipe: %s",Tcl_PosixError(interp)); goto parent_error; } if (-1 == pipe(status_pipe)) { close(sync_fds[0]); close(sync_fds[1]); close(sync2_fds[0]); close(sync2_fds[1]); } if ((pid = fork()) == -1) { exp_error(interp,"fork: %s",Tcl_PosixError(interp)); goto parent_error; } if (pid) { /* parent */ struct exp_f *f; close(sync_fds[1]); close(sync2_fds[0]); close(status_pipe[1]); f = fd_new(master,pid); if (exp_pty_slave_name) set_slave_name(f,exp_pty_slave_name); #ifdef CRAY setptypid(pid); #endif #if PTYTRAP_DIES #ifdef HAVE_PTYTRAP while (slave_opens) { int cc; cc = exp_wait_for_slave_open(master); #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) if (cc == TIOCSCTTY) slave_opens = 0; #endif if (cc == TIOCOPEN) slave_opens--; if (cc == -1) { exp_error(interp,"failed to trap slave pty"); goto parent_error; } } #if 0 /* trap initial ioctls in a feeble attempt to not block */ /* the initially. If the process itself ioctls */ /* /dev/tty, such blocks will be trapped later */ /* during normal event processing */ /* initial slave ioctl */ while (slave_write_ioctls) { int cc; cc = exp_wait_for_slave_open(master); #if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hp9000s300) if (cc == TIOCSCTTY) slave_write_ioctls = 0; #endif if (cc & IOC_IN) slave_write_ioctls--; else if (cc == -1) { exp_error(interp,"failed to trap slave pty"); goto parent_error; } } #endif /*0*/ #endif /* HAVE_PTYTRAP */ #endif /* PTYTRAP_DIES */ /* * wait for slave to initialize pty before allowing * user to send to it */ exp_debuglog("parent: waiting for sync byte\r\n"); while (((rc = read(sync_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) { /* empty */; } if (rc == -1) { exp_errorlog("parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* turn on detection of eof */ exp_slave_control(master,1); /* * tell slave to go on now now that we have initialized pty */ exp_debuglog("parent: telling child to go ahead\r\n"); wc = write(sync2_fds[1]," ",1); if (wc == -1) { exp_errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } exp_debuglog("parent: now unsynchronized from child\r\n"); close(sync_fds[0]); close(sync2_fds[1]); /* see if child's exec worked */ retry: switch (read(status_pipe[0],&child_errno,sizeof child_errno)) { case -1: if (errno == EINTR) goto retry; /* well it's not really the child's errno */ /* but it can be treated that way */ child_errno = errno; break; case 0: /* child's exec succeeded */ child_errno = 0; break; default: /* child's exec failed; err contains exec's errno */ waitpid(pid, NULL, 0); /* in order to get Tcl to set errorcode, we must */ /* hand set errno */ errno = child_errno; exp_error(interp, "couldn't execute \"%s\": %s", argv[0],Tcl_PosixError(interp)); goto parent_error; } close(status_pipe[0]); /* tell user id of new process */ sprintf(buf,"%d",master); Tcl_SetVar(interp,SPAWN_ID_VARNAME,buf,0); sprintf(interp->result,"%d",pid); exp_debuglog("spawn: returns {%s}\r\n",interp->result); Tcl_DStringFree(&dstring); return(TCL_OK); parent_error: Tcl_DStringFree(&dstring); return TCL_ERROR; } /* child process - do not return from here! all errors must exit() */ close(sync_fds[0]); close(sync2_fds[1]); close(status_pipe[0]); exp_close_on_exec(status_pipe[1]); if (exp_dev_tty != -1) { close(exp_dev_tty); exp_dev_tty = -1; } #ifdef CRAY (void) close(master); #endif /* ultrix (at least 4.1-2) fails to obtain controlling tty if setsid */ /* is called. setpgrp works though. */ #if defined(POSIX) && !defined(ultrix) #define DO_SETSID #endif #ifdef __convex__ #define DO_SETSID #endif #ifdef DO_SETSID setsid(); #else #ifdef SYSV3 #ifndef CRAY setpgrp(); #endif /* CRAY */ #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,0); /* setpgrp(0,getpid());*/ /* make a new pgrp leader */ /* Pyramid lacks this defn */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* DO_SETSID */ /* save stderr elsewhere to avoid BSD4.4 bogosity that warns */ /* if stty finds dev(stderr) != dev(stdout) */ #ifndef WIN32_XXX /* save error fd while we're setting up new one */ errorfd = fcntl(2,F_DUPFD,3); #endif /* and here is the macro to restore it */ #ifndef WIN32_XXX #define restore_error_fd {close(2);fcntl(errorfd,F_DUPFD,2);} #else #define restore_error_fd #endif close(0); close(1); close(2); /* since we closed fd 0, open of pty slave must return fd 0 */ /* since getptyslave may have to run stty, (some of which work on fd */ /* 0 and some of which work on 1) do the dup's inside getptyslave. */ if (0 > (slave = getptyslave(ttycopy,ttyinit,stty_init))) { restore_error_fd exp_errorlog("open(slave pty): %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } /* sanity check */ if (slave != 0) { restore_error_fd exp_errorlog("getptyslave: slave = %d but expected 0\n",slave); exit(-1); } /* The test for hpux may have to be more specific. In particular, the */ /* code should be skipped on the hp9000s300 and hp9000s720 (but there */ /* is no documented define for the 720!) */ /*#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(sun) && !defined(hpux)*/ #if defined(TIOCSCTTY) && !defined(sun) && !defined(hpux) /* 4.3+BSD way to acquire controlling terminal */ /* according to Stevens - Adv. Prog..., p 642 */ /* Oops, it appears that the CIBAUD is on Linux also */ /* so let's try without... */ #ifdef __QNX__ if (tcsetct(0, getpid()) == -1) { #else if (ioctl(0,TIOCSCTTY,(char *)0) < 0) { #endif restore_error_fd exp_errorlog("failed to get controlling terminal using TIOCSCTTY"); exit(-1); } #endif #ifdef CRAY (void) setsid(); (void) ioctl(0,TCSETCTTY,0); (void) close(0); if (open("/dev/tty", O_RDWR) < 0) { restore_error_fd exp_errorlog("open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } (void) close(1); (void) close(2); (void) dup(0); (void) dup(0); setptyutmp(); /* create a utmp entry */ /* _CRAY2 code from Hal Peterson <[email protected]>, Cray Research, Inc. */ #ifdef _CRAY2 /* * Interpose a process between expect and the spawned child to * keep the slave side of the pty open to allow time for expect * to read the last output. This is a workaround for an apparent * bug in the Unicos pty driver on Cray-2's under Unicos 6.0 (at * least). */ if ((pid = fork()) == -1) { restore_error_fd exp_errorlog("second fork: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } if (pid) { /* Intermediate process. */ int status; int timeout; char *t; /* How long should we wait? */ if (t = exp_get_var(interp,"pty_timeout")) timeout = atoi(t); else if (t = exp_get_var(interp,"timeout")) timeout = atoi(t)/2; else timeout = 5; /* Let the spawned process run to completion. */ while (wait(&status) < 0 && errno == EINTR) /* empty body */; /* Wait for the pty to clear. */ sleep(timeout); /* Duplicate the spawned process's status. */ if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); /* The kill may not have worked, but this will. */ exit(WEXITSTATUS(status)); } #endif /* _CRAY2 */ #endif /* CRAY */ if (console) exp_console_set(); #ifdef FULLTRAPS for (i=1;i<NSIG;i++) { if (traps[i] != SIG_ERR) { signal(i,traps[i]); } } #endif /* FULLTRAPS */ for (i=1;i<NSIG;i++) { signal(i,ignore[i]?SIG_IGN:SIG_DFL); } #if 0 /* avoid fflush of cmdfile since this screws up the parents seek ptr */ /* There is no portable way to fclose a shared read-stream!!!! */ if (exp_cmdfile && (exp_cmdfile != stdin)) (void) close(fileno(exp_cmdfile)); if (logfile) (void) fclose(logfile); if (debugfile) (void) fclose(debugfile); #endif /* (possibly multiple) masters are closed automatically due to */ /* earlier fcntl(,,CLOSE_ON_EXEC); */ /* tell parent that we are done setting up pty */ /* The actual char sent back is irrelevant. */ /* exp_debuglog("child: telling parent that pty is initialized\r\n");*/ wc = write(sync_fds[1]," ",1); if (wc == -1) { restore_error_fd exp_errorlog("child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync_fds[1]); /* wait for master to let us go on */ /* exp_debuglog("child: waiting for go ahead from parent\r\n"); */ /* close(master); /* force master-side close so we can read */ while (((rc = read(sync2_fds[0],&sync_byte,1)) < 0) && (errno == EINTR)) { /* empty */; } if (rc == -1) { restore_error_fd exp_errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno)); exit(-1); } close(sync2_fds[0]); /* exp_debuglog("child: now unsynchronized from parent\r\n"); */ /* So much for close-on-exec. Tcl doesn't mark its files that way */ /* everything has to be closed explicitly. */ if (exp_close_in_child) (*exp_close_in_child)(); (void) execvp(argv[0],argv); #if 0 /* Unfortunately, by now we've closed fd's to stderr, logfile and debugfile. The only reasonable thing to do is to send back the error as part of the program output. This will be picked up in an expect or interact command. */ exp_errorlog("%s: %s\r\n",argv[0],Tcl_ErrnoMsg(errno)); #endif /* if exec failed, communicate the reason back to the parent */ write(status_pipe[1], &errno, sizeof errno); exit(-1); /*NOTREACHED*/ } /*ARGSUSED*/ static int Exp_ExpPidCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { struct exp_f *f; int m = -1; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) goto usage; m = atoi(*argv); } else goto usage; } if (m == -1) { if (exp_update_master(interp,&m,0,0) == 0) return TCL_ERROR; } if (0 == (f = exp_fd2f(interp,m,1,0,"exp_pid"))) return TCL_ERROR; sprintf(interp->result,"%d",f->pid); return TCL_OK; usage: exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } /*ARGSUSED*/ static int Exp_GetpidDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { exp_debuglog("getpid is deprecated, use pid\r\n"); sprintf(interp->result,"%d",getpid()); return(TCL_OK); } /* returns current master (via out-parameter) */ /* returns f or 0, but note that since exp_fd2f calls tcl_error, this */ /* may be immediately followed by a "return(TCL_ERROR)"!!! */ struct exp_f * exp_update_master(interp,m,opened,adjust) Tcl_Interp *interp; int *m; int opened; int adjust; { char *s = exp_get_var(interp,SPAWN_ID_VARNAME); *m = (s?atoi(s):EXP_SPAWN_ID_USER); return(exp_fd2f(interp,*m,opened,adjust,(s?s:EXP_SPAWN_ID_USER_LIT))); } /*ARGSUSED*/ static int Exp_SleepCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { argc--; argv++; if (argc != 1) { exp_error(interp,"must have one arg: seconds"); return TCL_ERROR; } return(exp_dsleep(interp,(double)atof(*argv))); } /* write exactly this many bytes, i.e. retry partial writes */ /* returns 0 for success, -1 for failure */ static int exact_write(fd,buffer,rembytes) int fd; char *buffer; int rembytes; { int cc; while (rembytes) { if (-1 == (cc = write(fd,buffer,rembytes))) return(-1); if (0 == cc) { /* This shouldn't happen but I'm told that it does */ /* nonetheless (at least on SunOS 4.1.3). Since */ /* this is not a documented return value, the most */ /* reasonable thing is to complain here and retry */ /* in the hopes that is some transient condition. */ sleep(1); exp_debuglog("write() failed to write anything but returned - sleeping and retrying...\n"); } buffer += cc; rembytes -= cc; } return(0); } struct slow_arg { int size; double time; }; /* returns 0 for success, -1 for failure */ static int get_slow_args(interp,x) Tcl_Interp *interp; struct slow_arg *x; { int sc; /* return from scanf */ char *s = exp_get_var(interp,"send_slow"); if (!s) { exp_error(interp,"send -s: send_slow has no value"); return(-1); } if (2 != (sc = sscanf(s,"%d %lf",&x->size,&x->time))) { exp_error(interp,"send -s: found %d value(s) in send_slow but need 2",sc); return(-1); } if (x->size <= 0) { exp_error(interp,"send -s: size (%d) in send_slow must be positive", x->size); return(-1); } if (x->time <= 0) { exp_error(interp,"send -s: time (%f) in send_slow must be larger",x->time); return(-1); } return(0); } /* returns 0 for success, -1 for failure, pos. for Tcl return value */ static int slow_write(interp,fd,buffer,rembytes,arg) Tcl_Interp *interp; int fd; char *buffer; int rembytes; struct slow_arg *arg; { int rc; while (rembytes > 0) { int len; len = (arg->size<rembytes?arg->size:rembytes); if (0 > exact_write(fd,buffer,len)) return(-1); rembytes -= arg->size; buffer += arg->size; /* skip sleep after last write */ if (rembytes > 0) { rc = exp_dsleep(interp,arg->time); if (rc>0) return rc; } } return(0); } struct human_arg { float alpha; /* average interarrival time in seconds */ float alpha_eow; /* as above but for eow transitions */ float c; /* shape */ float min, max; }; /* returns -1 if error, 0 if success */ static int get_human_args(interp,x) Tcl_Interp *interp; struct human_arg *x; { int sc; /* return from scanf */ char *s = exp_get_var(interp,"send_human"); if (!s) { exp_error(interp,"send -h: send_human has no value"); return(-1); } if (5 != (sc = sscanf(s,"%f %f %f %f %f", &x->alpha,&x->alpha_eow,&x->c,&x->min,&x->max))) { if (sc == EOF) sc = 0; /* make up for overloaded return */ exp_error(interp,"send -h: found %d value(s) in send_human but need 5",sc); return(-1); } if (x->alpha < 0 || x->alpha_eow < 0) { exp_error(interp,"send -h: average interarrival times (%f %f) must be non-negative in send_human", x->alpha,x->alpha_eow); return(-1); } if (x->c <= 0) { exp_error(interp,"send -h: variability (%f) in send_human must be positive",x->c); return(-1); } x->c = 1/x->c; if (x->min < 0) { exp_error(interp,"send -h: minimum (%f) in send_human must be non-negative",x->min); return(-1); } if (x->max < 0) { exp_error(interp,"send -h: maximum (%f) in send_human must be non-negative",x->max); return(-1); } if (x->max < x->min) { exp_error(interp,"send -h: maximum (%f) must be >= minimum (%f) in send_human",x->max,x->min); return(-1); } return(0); } /* Compute random numbers from 0 to 1, for expect's send -h */ /* This implementation sacrifices beauty for portability */ static float unit_random() { /* current implementation is pathetic but works */ /* 99991 is largest prime in my CRC - can't hurt, eh? */ return((float)(1+(rand()%99991))/99991.0); } void exp_init_unit_random() { srand(getpid()); } /* This function is my implementation of the Weibull distribution. */ /* I've added a max time and an "alpha_eow" that captures the slight */ /* but noticable change in human typists when hitting end-of-word */ /* transitions. */ /* returns 0 for success, -1 for failure, pos. for Tcl return value */ static int human_write(interp,fd,buffer,arg) Tcl_Interp *interp; int fd; char *buffer; struct human_arg *arg; { char *sp; float t; float alpha; int wc; int in_word = TRUE; exp_debuglog("human_write: avg_arr=%f/%f 1/shape=%f min=%f max=%f\r\n", arg->alpha,arg->alpha_eow,arg->c,arg->min,arg->max); for (sp = buffer;*sp;sp++) { /* use the end-of-word alpha at eow transitions */ if (in_word && (ispunct(*sp) || isspace(*sp))) alpha = arg->alpha_eow; else alpha = arg->alpha; in_word = !(ispunct(*sp) || isspace(*sp)); t = alpha * pow(-log((double)unit_random()),arg->c); /* enforce min and max times */ if (t<arg->min) t = arg->min; else if (t>arg->max) t = arg->max; /*fprintf(stderr,"\nwriting <%c> but first sleep %f seconds\n",*sp,t);*/ /* skip sleep before writing first character */ if (sp != buffer) { wc = exp_dsleep(interp,(double)t); if (wc > 0) return wc; } wc = write(fd,sp,1); if (0 > wc) return(wc); } return(0); } struct exp_i *exp_i_pool = 0; struct exp_fd_list *exp_fd_list_pool = 0; #define EXP_I_INIT_COUNT 10 #define EXP_FD_INIT_COUNT 10 struct exp_i * exp_new_i() { int n; struct exp_i *i; if (!exp_i_pool) { /* none avail, generate some new ones */ exp_i_pool = i = (struct exp_i *)ckalloc( EXP_I_INIT_COUNT * sizeof(struct exp_i)); for (n=0;n<EXP_I_INIT_COUNT-1;n++,i++) { i->next = i+1; } i->next = 0; } /* now that we've made some, unlink one and give to user */ i = exp_i_pool; exp_i_pool = exp_i_pool->next; i->value = 0; i->variable = 0; i->fd_list = 0; i->ecount = 0; i->next = 0; return i; } struct exp_fd_list * exp_new_fd(val) int val; { int n; struct exp_fd_list *fd; if (!exp_fd_list_pool) { /* none avail, generate some new ones */ exp_fd_list_pool = fd = (struct exp_fd_list *)ckalloc( EXP_FD_INIT_COUNT * sizeof(struct exp_fd_list)); for (n=0;n<EXP_FD_INIT_COUNT-1;n++,fd++) { fd->next = fd+1; } fd->next = 0; } /* now that we've made some, unlink one and give to user */ fd = exp_fd_list_pool; exp_fd_list_pool = exp_fd_list_pool->next; fd->fd = val; return fd; } void exp_free_fd(fd_first) struct exp_fd_list *fd_first; { struct exp_fd_list *fd, *penultimate; if (!fd_first) return; /* link entire chain back in at once by first finding last pointer */ /* making that point back to pool, and then resetting pool to this */ /* run to end */ for (fd = fd_first;fd;fd=fd->next) { penultimate = fd; } penultimate->next = exp_fd_list_pool; exp_fd_list_pool = fd_first; } /* free a single fd */ void exp_free_fd_single(fd) struct exp_fd_list *fd; { fd->next = exp_fd_list_pool; exp_fd_list_pool = fd; } void exp_free_i(interp,i,updateproc) Tcl_Interp *interp; struct exp_i *i; Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */ { if (i->next) exp_free_i(interp,i->next,updateproc); exp_free_fd(i->fd_list); if (i->direct == EXP_INDIRECT) { Tcl_UntraceVar(interp,i->variable, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES, updateproc,(ClientData)i); } /* here's the long form if duration & direct free(var) free(val) PERM DIR 1 PERM INDIR 1 1 TMP DIR TMP INDIR 1 Also if i->variable was a bogus variable name, i->value might not be set, so test i->value to protect this TMP in this case does NOT mean from the "expect" command. Rather it means "an implicit spawn id from any expect or expect_XXX command". In other words, there was no variable name provided. */ if (i->value && (((i->direct == EXP_DIRECT) && (i->duration == EXP_PERMANENT)) || ((i->direct == EXP_INDIRECT) && (i->duration == EXP_TEMPORARY)))) { ckfree(i->value); } else if (i->duration == EXP_PERMANENT) { if (i->value) ckfree(i->value); if (i->variable) ckfree(i->variable); } i->next = exp_i_pool; exp_i_pool = i; } /* generate a descriptor for a "-i" flag */ /* cannot fail */ struct exp_i * exp_new_i_complex(interp,arg,duration,updateproc) Tcl_Interp *interp; char *arg; /* spawn id list or a variable containing a list */ int duration; /* if we have to copy the args */ /* should only need do this in expect_before/after */ Tcl_VarTraceProc *updateproc; /* proc to invoke if indirect is written */ { struct exp_i *i; char **stringp; i = exp_new_i(); i->direct = (isdigit(arg[0]) || (arg[0] == '-'))?EXP_DIRECT:EXP_INDIRECT; if (i->direct == EXP_DIRECT) { stringp = &i->value; } else { stringp = &i->variable; } i->duration = duration; if (duration == EXP_PERMANENT) { *stringp = ckalloc(strlen(arg)+1); strcpy(*stringp,arg); } else { *stringp = arg; } i->fd_list = 0; exp_i_update(interp,i); /* if indirect, ask Tcl to tell us when variable is modified */ if (i->direct == EXP_INDIRECT) { Tcl_TraceVar(interp, i->variable, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES, updateproc, (ClientData) i); } return i; } void exp_i_add_fd(i,fd) struct exp_i *i; int fd; { struct exp_fd_list *new_fd; new_fd = exp_new_fd(fd); new_fd->next = i->fd_list; i->fd_list = new_fd; } /* this routine assumes i->fd is meaningful */ void exp_i_parse_fds(i) struct exp_i *i; { char *p = i->value; /* reparse it */ while (1) { int m; int negative = 0; int valid_spawn_id = 0; m = 0; while (isspace(*p)) p++; for (;;p++) { if (*p == '-') negative = 1; else if (isdigit(*p)) { m = m*10 + (*p-'0'); valid_spawn_id = 1; } else if (*p == '\0' || isspace(*p)) break; } /* we either have a spawn_id or whitespace at end of string */ /* skip whitespace end-of-string */ if (!valid_spawn_id) break; if (negative) m = -m; exp_i_add_fd(i,m); } } /* updates a single exp_i struct */ void exp_i_update(interp,i) Tcl_Interp *interp; struct exp_i *i; { char *p; /* string representation of list of spawn ids */ if (i->direct == EXP_INDIRECT) { p = Tcl_GetVar(interp,i->variable,TCL_GLOBAL_ONLY); if (!p) { p = ""; exp_debuglog("warning: indirect variable %s undefined",i->variable); } if (i->value) { if (streq(p,i->value)) return; /* replace new value with old */ ckfree(i->value); } i->value = ckalloc(strlen(p)+1); strcpy(i->value,p); exp_free_fd(i->fd_list); i->fd_list = 0; } else { /* no free, because this should only be called on */ /* "direct" i's once */ i->fd_list = 0; } exp_i_parse_fds(i); } struct exp_i * exp_new_i_simple(fd,duration) int fd; int duration; /* if we have to copy the args */ /* should only need do this in expect_before/after */ { struct exp_i *i; i = exp_new_i(); i->direct = EXP_DIRECT; i->duration = duration; exp_i_add_fd(i,fd); return i; } /*ARGSUSED*/ static int Exp_SendLogCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *string; int len; argv++; argc--; if (argc) { if (streq(*argv,"--")) { argc--; argv++; } } if (argc != 1) { exp_error(interp,"usage: send [args] string"); return TCL_ERROR; } string = *argv; len = strlen(string); if (debugfile) fwrite(string,1,len,debugfile); if (logfile) fwrite(string,1,len,logfile); return(TCL_OK); } /* I've rewritten this to be unbuffered. I did this so you could shove */ /* large files through "send". If you are concerned about efficiency */ /* you should quote all your send args to make them one single argument. */ /*ARGSUSED*/ static int Exp_SendCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int m = -1; /* spawn id (master) */ int rc; /* final result of this procedure */ struct human_arg human_args; struct slow_arg slow_args; #define SEND_STYLE_STRING_MASK 0x07 /* mask to detect a real string arg */ #define SEND_STYLE_PLAIN 0x01 #define SEND_STYLE_HUMAN 0x02 #define SEND_STYLE_SLOW 0x04 #define SEND_STYLE_ZERO 0x10 #define SEND_STYLE_BREAK 0x20 int send_style = SEND_STYLE_PLAIN; int want_cooked = TRUE; char *string; /* string to send */ int len; /* length of string to send */ int zeros; /* count of how many ascii zeros to send */ char *i_masters = 0; struct exp_fd_list *fd; struct exp_i *i; char *arg; argv++; argc--; while (argc) { arg = *argv; if (arg[0] != '-') break; arg++; if (exp_flageq1('-',arg)) { /* "--" */ argc--; argv++; break; } else if (exp_flageq1('i',arg)) { /* "-i" */ argc--; argv++; if (argc==0) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } i_masters = *argv; argc--; argv++; continue; } else if (exp_flageq1('h',arg)) { /* "-h" */ argc--; argv++; if (-1 == get_human_args(interp,&human_args)) return(TCL_ERROR); send_style = SEND_STYLE_HUMAN; continue; } else if (exp_flageq1('s',arg)) { /* "-s" */ argc--; argv++; if (-1 == get_slow_args(interp,&slow_args)) return(TCL_ERROR); send_style = SEND_STYLE_SLOW; continue; } else if (exp_flageq("null",arg,1) || exp_flageq1('0',arg)) { argc--; argv++; /* "-null" */ if (!*argv) zeros = 1; else { zeros = atoi(*argv); argc--; argv++; if (zeros < 1) return TCL_OK; } send_style = SEND_STYLE_ZERO; string = "<zero(s)>"; continue; } else if (exp_flageq("raw",arg,1)) { /* "-raw" */ argc--; argv++; want_cooked = FALSE; continue; } else if (exp_flageq("break",arg,1)) { /* "-break" */ argc--; argv++; send_style = SEND_STYLE_BREAK; string = "<break>"; continue; } else { exp_error(interp,"usage: unrecognized flag <-%.80s>",arg); return TCL_ERROR; } } if (send_style & SEND_STYLE_STRING_MASK) { if (argc != 1) { exp_error(interp,"usage: send [args] string"); return TCL_ERROR; } string = *argv; } len = strlen(string); if (clientData == &sendCD_user) m = 1; else if (clientData == &sendCD_error) m = 2; else if (clientData == &sendCD_tty) m = exp_dev_tty; else if (!i_masters) { /* we really do want to check if it is open */ /* but since stdin could be closed, we have to first */ /* get the fd and then convert it from 0 to 1 if necessary */ if (0 == exp_update_master(interp,&m,0,0)) return(TCL_ERROR); } /* if master != -1, then it holds desired master */ /* else i_masters does */ if (m != -1) { i = exp_new_i_simple(m,EXP_TEMPORARY); } else { i = exp_new_i_complex(interp,i_masters,FALSE,(Tcl_VarTraceProc *)0); } #define send_to_stderr (clientData == &sendCD_error) #define send_to_proc (clientData == &sendCD_proc) #define send_to_user ((clientData == &sendCD_user) || \ (clientData == &sendCD_tty)) if (send_to_proc) { want_cooked = FALSE; exp_debuglog("send: sending \"%s\" to {",dprintify(string)); /* if closing brace doesn't appear, that's because an error */ /* was encountered before we could send it */ } else { if (debugfile) fwrite(string,1,len,debugfile); if ((send_to_user && logfile_all) || logfile) fwrite(string,1,len,logfile); } for (fd=i->fd_list;fd;fd=fd->next) { m = fd->fd; if (send_to_proc) { exp_debuglog(" %d ",m); } /* true if called as Send with user_spawn_id */ if (exp_is_stdinfd(m)) m = 1; /* check validity of each - i.e., are they open */ if (0 == exp_fd2f(interp,m,1,0,"send")) { rc = TCL_ERROR; goto finish; } /* Check if Tcl is using a different fd for output */ if (exp_fs[m].tcl_handle) { m = exp_fs[m].tcl_output; } if (want_cooked) string = exp_cook(string,&len); switch (send_style) { case SEND_STYLE_PLAIN: rc = exact_write(m,string,len); break; case SEND_STYLE_SLOW: rc = slow_write(interp,m,string,len,&slow_args); break; case SEND_STYLE_HUMAN: rc = human_write(interp,m,string,&human_args); break; case SEND_STYLE_ZERO: for (;zeros>0;zeros--) rc = write(m,"",1); /* catching error on last write is sufficient */ rc = ((rc==1) ? 0 : -1); /* normal is 1 not 0 */ break; case SEND_STYLE_BREAK: exp_tty_break(interp,m); rc = 0; break; } if (rc != 0) { if (rc == -1) { exp_error(interp,"write(spawn_id=%d): %s",m,Tcl_PosixError(interp)); rc = TCL_ERROR; } goto finish; } } if (send_to_proc) exp_debuglog("}\r\n"); rc = TCL_OK; finish: exp_free_i(interp,i,(Tcl_VarTraceProc *)0); return rc; } /*ARGSUSED*/ static int Exp_LogFileCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static Tcl_DString dstring; static int first_time = TRUE; static int current_append; /* true if currently appending */ static char *openarg = 0; /* Tcl file identifier from -open */ static int leaveopen = FALSE; /* true if -leaveopen was used */ int old_logfile_all = logfile_all; FILE *old_logfile = logfile; char *old_openarg = openarg; int old_leaveopen = leaveopen; int aflag = FALSE; int append = TRUE; char *filename = 0; char *type; FILE *writefilePtr; int usage_error_occurred = FALSE; openarg = 0; leaveopen = FALSE; if (first_time) { Tcl_DStringInit(&dstring); first_time = FALSE; } #define usage_error if (0) ; else {\ usage_error_occurred = TRUE;\ goto error;\ } /* when this function returns, we guarantee that if logfile_all */ /* is TRUE, then logfile is non-zero */ argv++; argc--; for (;argc>0;argc--,argv++) { if (streq(*argv,"-open")) { if (!argv[1]) usage_error; openarg = ckalloc(strlen(argv[1])+1); strcpy(openarg,argv[1]); argc--; argv++; } else if (streq(*argv,"-leaveopen")) { if (!argv[1]) usage_error; openarg = ckalloc(strlen(argv[1])+1); strcpy(openarg,argv[1]); leaveopen = TRUE; argc--; argv++; } else if (streq(*argv,"-a")) { aflag = TRUE; } else if (streq(*argv,"-info")) { if (logfile) { if (logfile_all) strcat(interp->result,"-a "); if (!current_append) strcat(interp->result,"-noappend "); strcat(interp->result,Tcl_DStringValue(&dstring)); } return TCL_OK; } else if (streq(*argv,"-noappend")) { append = FALSE; } else break; } if (argc == 1) { filename = argv[0]; } else if (argc > 1) { /* too many arguments */ usage_error } if (openarg && filename) { usage_error } if (aflag && !(openarg || filename)) { usage_error } logfile = 0; logfile_all = aflag; current_append = append; type = (append?"a":"w"); if (filename) { filename = Tcl_TildeSubst(interp,filename,&dstring); if (filename == NULL) { goto error; } else { /* Tcl_TildeSubst doesn't store into dstring */ /* if no ~, so force string into dstring */ /* this is only needed so that next time around */ /* we can get dstring for -info if necessary */ if (Tcl_DStringValue(&dstring)[0] == '\0') { Tcl_DStringAppend(&dstring,filename,-1); } } errno = 0; if (NULL == (logfile = fopen(filename,type))) { char *msg; if (errno == 0) { msg = open_failed; } else { msg = Tcl_PosixError(interp); } exp_error(interp,"%s: %s",filename,msg); Tcl_DStringFree(&dstring); goto error; } } else if (openarg) { int cc; int fd; Tcl_Channel chan; int mode; Tcl_File tclWriteFile; Tcl_DStringTrunc(&dstring,0); #if TCL7_4 cc = Tcl_GetOpenFile(interp,openarg,1,1,&writefilePtr); if (cc == TCL_ERROR) goto error; if (-1 == (fd = dup(fileno(writefilePtr)))) { exp_error(interp,"dup: %s",Tcl_PosixError(interp)); goto error; } #endif if (!(chan = Tcl_GetChannel(interp,openarg,&mode))) { return TCL_ERROR; } if (!(mode & TCL_WRITABLE)) { exp_error(interp,"channel is not writable"); } tclWriteFile = Tcl_GetChannelFile(chan, TCL_WRITABLE); fd = dup((int)Tcl_GetFileInfo(tclWriteFile, (int *)0)); if (!(logfile = fdopen(fd,type))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); close(fd); goto error; } if (leaveopen) { Tcl_DStringAppend(&dstring,"-leaveopen ",-1); } else { Tcl_DStringAppend(&dstring,"-open ",-1); } Tcl_DStringAppend(&dstring,openarg,-1); /* * It would be convenient now to tell Tcl to close its * file descriptor. Alas, if involved in a pipeline, Tcl * will be unable to complete a wait on the process. * So simply remember that we meant to close it. We will * do so later in our own close routine. */ } if (logfile) { setbuf(logfile,(char *)0); exp_close_on_exec(fileno(logfile)); } if (old_logfile) { fclose(old_logfile); } if (old_openarg) { if (!old_leaveopen) { close_tcl_file(interp,old_openarg); } ckfree((char *)old_openarg); } return TCL_OK; error: if (old_logfile) { logfile = old_logfile; logfile_all = old_logfile_all; } if (openarg) ckfree(openarg); openarg = old_openarg; leaveopen = old_leaveopen; if (usage_error_occurred) { exp_error(interp,"usage: log_file [-info] [-noappend] [[-a] file] [-[leave]open [open ...]]"); } return TCL_ERROR; } /*ARGSUSED*/ static int Exp_LogUserCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int old_loguser = loguser; if (argc == 0 || (argc == 2 && streq(argv[1],"-info"))) { /* do nothing */ } else if (argc == 2) { if (0 == atoi(argv[1])) loguser = FALSE; else loguser = TRUE; } else { exp_error(interp,"usage: [-info|1|0]"); } sprintf(interp->result,"%d",old_loguser); return(TCL_OK); } #ifdef TCL_DEBUGGER /*ARGSUSED*/ static int Exp_DebugCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int now = FALSE; /* soon if FALSE, now if TRUE */ int exp_tcl_debugger_was_available = exp_tcl_debugger_available; if (argc > 3) goto usage; if (argc == 1) { sprintf(interp->result,"%d",exp_tcl_debugger_available); return TCL_OK; } argv++; while (*argv) { if (streq(*argv,"-now")) { now = TRUE; argv++; } else break; } if (!*argv) { if (now) { Dbg_On(interp,1); exp_tcl_debugger_available = 1; } else { goto usage; } } else if (streq(*argv,"0")) { Dbg_Off(interp); exp_tcl_debugger_available = 0; } else { Dbg_On(interp,now); exp_tcl_debugger_available = 1; } sprintf(interp->result,"%d",exp_tcl_debugger_was_available); return(TCL_OK); usage: exp_error(interp,"usage: [[-now] 1|0]"); return TCL_ERROR; } #endif /*ARGSUSED*/ static int Exp_ExpInternalCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static Tcl_DString dstring; static int first_time = TRUE; int fopened = FALSE; if (first_time) { Tcl_DStringInit(&dstring); first_time = FALSE; } if (argc > 1 && streq(argv[1],"-info")) { if (debugfile) { sprintf(interp->result,"-f %s ", Tcl_DStringValue(&dstring)); } strcat(interp->result,((exp_is_debugging==0)?"0":"1")); return TCL_OK; } argv++; argc--; while (argc) { if (!streq(*argv,"-f")) break; argc--;argv++; if (argc < 1) goto usage; if (debugfile) fclose(debugfile); argv[0] = Tcl_TildeSubst(interp, argv[0],&dstring); if (argv[0] == NULL) goto error; else { /* Tcl_TildeSubst doesn't store into dstring */ /* if no ~, so force string into dstring */ /* this is only needed so that next time around */ /* we can get dstring for -info if necessary */ if (Tcl_DStringValue(&dstring)[0] == '\0') { Tcl_DStringAppend(&dstring,argv[0],-1); } } errno = 0; if (NULL == (debugfile = fopen(*argv,"a"))) { char *msg; if (errno == 0) { msg = open_failed; } else { msg = Tcl_PosixError(interp); } exp_error(interp,"%s: %s",*argv,msg); goto error; } setbuf(debugfile,(char *)0); exp_close_on_exec(fileno(debugfile)); fopened = TRUE; argc--;argv++; } if (argc != 1) goto usage; /* if no -f given, close file */ if (fopened == FALSE && debugfile) { fclose(debugfile); debugfile = 0; Tcl_DStringFree(&dstring); } exp_is_debugging = atoi(*argv); return(TCL_OK); usage: exp_error(interp,"usage: [-f file] expr"); error: Tcl_DStringFree(&dstring); return TCL_ERROR; } char *exp_onexit_action = 0; /*ARGSUSED*/ static int Exp_ExitCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int value = 0; argv++; if (*argv) { if (exp_flageq(*argv,"-onexit",3)) { argv++; if (*argv) { int len = strlen(*argv); if (exp_onexit_action) ckfree(exp_onexit_action); exp_onexit_action = ckalloc(len + 1); strcpy(exp_onexit_action,*argv); } else if (exp_onexit_action) { Tcl_AppendResult(interp,exp_onexit_action,(char *)0); } return TCL_OK; } else if (exp_flageq(*argv,"-noexit",3)) { argv++; exp_exit_handlers((ClientData)interp); return TCL_OK; } } if (*argv) { if (Tcl_GetInt(interp, *argv, &value) != TCL_OK) { return TCL_ERROR; } } exp_exit(interp,value); /*NOTREACHED*/ } /*ARGSUSED*/ static int Exp_CloseCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int onexec_flag = FALSE; /* true if -onexec seen */ int close_onexec; int slave_flag = FALSE; #if 0 int slave; #endif int m = -1; int argc_orig = argc; char **argv_orig = argv; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } m = atoi(*argv); } else if (streq(*argv,"-slave")) { slave_flag = TRUE; } else if (streq(*argv,"-onexec")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -onexec 0|1"); return(TCL_ERROR); } onexec_flag = TRUE; close_onexec = atoi(*argv); } else break; } if (argc) { /* doesn't look like our format, it must be a Tcl-style file */ /* handle. Lucky that formats are easily distinguishable. */ /* Historical note: we used "close" long before there was a */ /* Tcl builtin by the same name. */ Tcl_CmdInfo info; Tcl_ResetResult(interp); if (0 == Tcl_GetCommandInfo(interp,"close",&info)) { info.clientData = 0; } return(Tcl_CloseCmd(info.clientData,interp,argc_orig,argv_orig)); } if (m == -1) { if (exp_update_master(interp,&m,1,0) == 0) return(TCL_ERROR); } if (slave_flag) { struct exp_f *f = exp_fd2f(interp,m,1,0,"-slave"); if (!f) return TCL_ERROR; if (f->slave_fd) { close(f->slave_fd); f->slave_fd = EXP_NOFD; exp_slave_control(m,1); return TCL_OK; } else { exp_error(interp,"no such slave"); return TCL_ERROR; } } if (onexec_flag) { /* heck, don't even bother to check if fd is open or a real */ /* spawn id, nothing else depends on it */ #ifndef WIN32_XXX fcntl(m,F_SETFD,close_onexec); #endif return TCL_OK; } return(exp_close(interp,m)); } /*ARGSUSED*/ static void tcl_tracer(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv) ClientData clientData; Tcl_Interp *interp; int level; char *command; int (*cmdProc)(); ClientData cmdClientData; int argc; char *argv[]; { int i; /* come out on stderr, by using errorlog */ exp_errorlog("%2d",level); for (i = 0;i<level;i++) exp_nferrorlog(" ",0/*ignored - satisfy lint*/); exp_errorlog("%s\r\n",command); } /*ARGSUSED*/ static int Exp_StraceCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { static int trace_level = 0; static Tcl_Trace trace_handle; if (argc > 1 && streq(argv[1],"-info")) { sprintf(interp->result,"%d",trace_level); return TCL_OK; } if (argc != 2) { exp_error(interp,"usage: trace level"); return(TCL_ERROR); } /* tracing already in effect, undo it */ if (trace_level > 0) Tcl_DeleteTrace(interp,trace_handle); /* get and save new trace level */ trace_level = atoi(argv[1]); if (trace_level > 0) trace_handle = Tcl_CreateTrace(interp, trace_level,tcl_tracer,(ClientData)0); return(TCL_OK); } /* following defn's are stolen from tclUnix.h */ /* * The type of the status returned by wait varies from UNIX system * to UNIX system. The macro below defines it: */ #if 0 #ifndef NO_UNION_WAIT # define WAIT_STATUS_TYPE union wait #else # define WAIT_STATUS_TYPE int #endif #endif /* 0 */ /* * following definitions stolen from tclUnix.h * (should have been made public!) * Supply definitions for macros to query wait status, if not already * defined in header files above. */ #if 0 #ifndef WIFEXITED # define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0) #endif #ifndef WEXITSTATUS # define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #ifndef WIFSIGNALED # define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff))) #endif #ifndef WTERMSIG # define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f) #endif #ifndef WIFSTOPPED # define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177) #endif #ifndef WSTOPSIG # define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff) #endif #endif /* 0 */ /* end of stolen definitions */ /* Describe the processes created with Expect's fork. This allows us to wait on them later. This is maintained as a linked list. As additional procs are forked, new links are added. As procs disappear, links are marked so that we can reuse them later. */ struct forked_proc { int pid; WAIT_STATUS_TYPE wait_status; enum {not_in_use, wait_done, wait_not_done} link_status; struct forked_proc *next; } *forked_proc_base = 0; void fork_clear_all() { struct forked_proc *f; for (f=forked_proc_base;f;f=f->next) { f->link_status = not_in_use; } } void fork_init(f,pid) struct forked_proc *f; int pid; { f->pid = pid; f->link_status = wait_not_done; } /* make an entry for a new proc */ void fork_add(pid) int pid; { struct forked_proc *f; for (f=forked_proc_base;f;f=f->next) { if (f->link_status == not_in_use) break; } /* add new entry to the front of the list */ if (!f) { f = (struct forked_proc *)ckalloc(sizeof(struct forked_proc)); f->next = forked_proc_base; forked_proc_base = f; } fork_init(f,pid); } /* Provide a last-chance guess for this if not defined already */ #ifndef WNOHANG #define WNOHANG WNOHANG_BACKUP_VALUE #endif /* wait returns are a hodgepodge of things If wait fails, something seriously has gone wrong, for example: bogus arguments (i.e., incorrect, bogus spawn id) no children to wait on async event failed If wait succeeeds, something happened on a particular pid 3rd arg is 0 if successfully reaped (if signal, additional fields supplied) 3rd arg is -1 if unsuccessfully reaped (additional fields supplied) */ /*ARGSUSED*/ static int Exp_WaitCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int master_supplied = FALSE; int m; /* master waited for */ struct exp_f *f; /* ditto */ struct forked_proc *fp = 0; /* handle to a pure forked proc */ struct exp_f ftmp; /* temporary memory for either f or fp */ int nowait = FALSE; int result = 0; /* 0 means child was successfully waited on */ /* -1 means an error occurred */ /* -2 means no eligible children to wait on */ #define NO_CHILD -2 argv++; argc--; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (argc==0) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } master_supplied = TRUE; m = atoi(*argv); } else if (streq(*argv,"-nowait")) { nowait = TRUE; } } if (!master_supplied) { if (0 == exp_update_master(interp,&m,0,0)) return TCL_ERROR; } if (m != EXP_SPAWN_ID_ANY) { if (0 == exp_fd2f(interp,m,0,0,"wait")) { return TCL_ERROR; } f = exp_fs + m; /* check if waited on already */ /* things opened by "open" or set with -nowait */ /* are marked sys_waited already */ if (!f->sys_waited) { if (nowait) { /* should probably generate an error */ /* if SIGCHLD is trapped. */ /* pass to Tcl, so it can do wait */ /* in background */ Tcl_DetachPids(1,&f->pid); exp_wait_zero(&f->pid); } else { while (1) { if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(rc); } result = Tcl_WaitPid(f->pid,&f->wait,0); if (result == f->pid) break; if (result == -1) { if (errno == EINTR) continue; else break; } } } } /* * Now have Tcl reap anything we just detached. * This also allows procs user has created with "exec &" * and and associated with an "exec &" process to be reaped. */ Tcl_ReapDetachedProcs(); exp_rearm_sigchld(interp); /* new */ } else { /* wait for any of our own spawned processes */ /* we call waitpid rather than wait to avoid running into */ /* someone else's processes. Yes, according to Ousterhout */ /* this is the best way to do it. */ for (m=0;m<=exp_fd_max;m++) { f = exp_fs + m; if (!f->valid) continue; if (f->pid == exp_getpid) continue; /* skip ourself */ if (f->user_waited) continue; /* one wait only! */ if (f->sys_waited) break; restart: result = waitpid(f->pid,&f->wait,WNOHANG); if (result == f->pid) break; if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart; else break; } } /* if it's not a spawned process, maybe its a forked process */ for (fp=forked_proc_base;fp;fp=fp->next) { if (fp->link_status == not_in_use) continue; restart2: result = waitpid(fp->pid,&fp->wait_status,WNOHANG); if (result == fp->pid) { m = -1; /* DOCUMENT THIS! */ break; } if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart2; else break; } } if (m > exp_fd_max) { result = NO_CHILD; /* no children */ Tcl_ReapDetachedProcs(); } exp_rearm_sigchld(interp); } /* sigh, wedge forked_proc into an exp_f structure so we don't * have to rewrite remaining code (too much) */ if (fp) { f = &ftmp; f->pid = fp->pid; f->wait = fp->wait_status; } /* non-portable assumption that pid_t can be printed with %d */ if (result == -1) { sprintf(interp->result,"%d %d -1 %d POSIX %s %s", f->pid,m,errno,Tcl_ErrnoId(),Tcl_ErrnoMsg(errno)); result = TCL_OK; } else if (result == NO_CHILD) { interp->result = "no children"; return TCL_ERROR; } else { sprintf(interp->result,"%d %d 0 %d", f->pid,m,WEXITSTATUS(f->wait)); if (WIFSIGNALED(f->wait)) { Tcl_AppendElement(interp,"CHILDKILLED"); Tcl_AppendElement(interp,Tcl_SignalId((int)(WTERMSIG(f->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WTERMSIG(f->wait)))); } else if (WIFSTOPPED(f->wait)) { Tcl_AppendElement(interp,"CHILDSUSP"); Tcl_AppendElement(interp,Tcl_SignalId((int) (WSTOPSIG(f->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WSTOPSIG(f->wait)))); } } if (fp) { fp->link_status = not_in_use; return ((result == -1)?TCL_ERROR:TCL_OK); } f->sys_waited = TRUE; f->user_waited = TRUE; /* if user has already called close, make sure fd really is closed */ /* and forget about this entry entirely */ if (f->user_closed) { if (!f->sys_closed) { sys_close(m,f); } f->valid = FALSE; } return ((result == -1)?TCL_ERROR:TCL_OK); } /*ARGSUSED*/ static int Exp_ForkCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int rc; if (argc > 1) { exp_error(interp,"usage: fork"); return(TCL_ERROR); } rc = fork(); if (rc == -1) { exp_error(interp,"fork: %s",Tcl_PosixError(interp)); return TCL_ERROR; } else if (rc == 0) { /* child */ exp_forked = TRUE; exp_getpid = getpid(); fork_clear_all(); } else { /* parent */ fork_add(rc); } /* both child and parent follow remainder of code */ sprintf(interp->result,"%d",rc); exp_debuglog("fork: returns {%s}\r\n",interp->result); return(TCL_OK); } /*ARGSUSED*/ static int Exp_DisconnectCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { /* tell Saber to ignore non-use of ttyfd */ /*SUPPRESS 591*/ int ttyfd; if (argc > 1) { exp_error(interp,"usage: disconnect"); return(TCL_ERROR); } if (exp_disconnected) { exp_error(interp,"already disconnected"); return(TCL_ERROR); } if (!exp_forked) { exp_error(interp,"can only disconnect child process"); return(TCL_ERROR); } exp_disconnected = TRUE; /* ignore hangup signals generated by testing ptys in getptymaster */ /* and other places */ signal(SIGHUP,SIG_IGN); /* reopen prevents confusion between send/expect_user */ /* accidentally mapping to a real spawned process after a disconnect */ if (exp_fs[0].pid != EXP_NOPID) { exp_close(interp,0); open("/dev/null",0); fd_new(0, EXP_NOPID); } if (exp_fs[1].pid != EXP_NOPID) { exp_close(interp,1); open("/dev/null",1); fd_new(1, EXP_NOPID); } if (exp_fs[2].pid != EXP_NOPID) { /* reopen stderr saves error checking in error/log routines. */ exp_close(interp,2); open("/dev/null",1); fd_new(2, EXP_NOPID); } Tcl_UnsetVar(interp,"tty_spawn_id",TCL_GLOBAL_ONLY); #ifdef DO_SETSID setsid(); #else #ifdef SYSV3 /* put process in our own pgrp, and lose controlling terminal */ #ifdef sysV88 /* With setpgrp first, child ends up with closed stdio */ /* according to Dave Schmitt <[email protected]> */ if (fork()) exit(0); setpgrp(); #else setpgrp(); /*signal(SIGHUP,SIG_IGN); moved out to above */ if (fork()) exit(0); /* first child exits (as per Stevens, */ /* UNIX Network Programming, p. 79-80) */ /* second child process continues as daemon */ #endif #else /* !SYSV3 */ #ifdef MIPS_BSD /* required on BSD side of MIPS OS <[email protected]> */ # include <sysv/sys.s> syscall(SYS_setpgrp); #endif setpgrp(0,0); /* setpgrp(0,getpid());*/ /* put process in our own pgrp */ /* Pyramid lacks this defn */ #ifdef TIOCNOTTY ttyfd = open("/dev/tty", O_RDWR); if (ttyfd >= 0) { /* zap controlling terminal if we had one */ (void) ioctl(ttyfd, TIOCNOTTY, (char *)0); (void) close(ttyfd); } #endif /* TIOCNOTTY */ #endif /* SYSV3 */ #endif /* DO_SETSID */ return(TCL_OK); } /*ARGSUSED*/ static int Exp_OverlayCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int newfd, oldfd; int dash_name = 0; char *command; argc--; argv++; while (argc) { if (*argv[0] != '-') break; /* not a flag */ if (streq(*argv,"-")) { /* - by itself */ argc--; argv++; dash_name = 1; continue; } newfd = atoi(argv[0]+1); argc--; argv++; if (argc == 0) { exp_error(interp,"overlay -# requires additional argument"); return(TCL_ERROR); } oldfd = atoi(argv[0]); argc--; argv++; exp_debuglog("overlay: mapping fd %d to %d\r\n",oldfd,newfd); if (oldfd != newfd) (void) dup2(oldfd,newfd); else exp_debuglog("warning: overlay: old fd == new fd (%d)\r\n",oldfd); } if (argc == 0) { exp_error(interp,"need program name"); return(TCL_ERROR); } command = argv[0]; if (dash_name) { argv[0] = ckalloc(1+strlen(command)); sprintf(argv[0],"-%s",command); } signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); (void) execvp(command,argv); exp_error(interp,"execvp(%s): %s\r\n",argv[0],Tcl_PosixError(interp)); return(TCL_ERROR); } #if 0 /*ARGSUSED*/ int cmdReady(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char num[4]; /* can hold up to "999 " */ char buf[1024]; /* can easily hold 256 spawn_ids! */ int i, j; int *masters, *masters2; int timeout = get_timeout(); if (argc < 2) { exp_error(interp,"usage: ready spawn_id1 [spawn_id2 ...]"); return(TCL_ERROR); } masters = (int *)ckalloc((argc-1)*sizeof(int)); masters2 = (int *)ckalloc((argc-1)*sizeof(int)); for (i=1;i<argc;i++) { j = atoi(argv[i]); if (!exp_fd2f(interp,j,1,"ready")) { ckfree(masters); return(TCL_ERROR); } masters[i-1] = j; } j = i-1; if (TCL_ERROR == ready(masters,i-1,masters2,&j,&timeout)) return(TCL_ERROR); /* pack result back into out-array */ buf[0] = '\0'; for (i=0;i<j;i++) { sprintf(num,"%d ",masters2[i]); /* note extra blank */ strcat(buf,num); } ckfree(masters); ckfree(masters2); Tcl_Return(interp,buf,TCL_VOLATILE); return(TCL_OK); } #endif /*ARGSUSED*/ int Exp_InterpreterCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc != 1) { exp_error(interp,"no arguments allowed"); return(TCL_ERROR); } return(exp_interpreter(interp)); /* errors and ok, are caught by exp_interpreter() and discarded */ /* to return TCL_OK, type "return" */ } /* this command supercede's Tcl's builtin CONTINUE command */ /*ARGSUSED*/ int Exp_ExpContinueDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc == 1) return(TCL_CONTINUE); else if (argc == 2) { if (streq(argv[1],"-expect")) { exp_debuglog("continue -expect is deprecated, use exp_continue\r\n"); return(EXP_CONTINUE); } } exp_error(interp,"usage: continue [-expect]\n"); return(TCL_ERROR); } /* this command supercede's Tcl's builtin CONTINUE command */ /*ARGSUSED*/ int Exp_ExpContinueCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { if (argc == 1) { return EXP_CONTINUE; } else if ((argc == 2) && (0 == strcmp(argv[1],"-continue_timer"))) { return EXP_CONTINUE_TIMER; } exp_error(interp,"usage: exp_continue [-continue_timer]\n"); return(TCL_ERROR); } /* most of this is directly from Tcl's definition for return */ /*ARGSUSED*/ int Exp_InterReturnCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { /* let Tcl's return command worry about args */ /* if successful (i.e., TCL_RETURN is returned) */ /* modify the result, so that we will handle it specially */ int result = Tcl_ReturnCmd(clientData,interp,argc,argv); if (result == TCL_RETURN) result = EXP_TCL_RETURN; return result; } /*ARGSUSED*/ int Exp_OpenCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { struct exp_f *f; int m = -1; int m2; int leaveopen = FALSE; Tcl_Channel chan; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } m = atoi(*argv); } else if (streq(*argv,"-leaveopen")) { leaveopen = TRUE; argc--; argv++; } else break; } if (m == -1) { if (exp_update_master(interp,&m,0,0) == 0) return TCL_ERROR; } if (0 == (f = exp_fd2f(interp,m,1,0,"exp_open"))) return TCL_ERROR; /* make a new copy of file descriptor */ if (-1 == (m2 = dup(m))) { exp_error(interp,"fdopen: %s",Tcl_PosixError(interp)); return TCL_ERROR; } if (!leaveopen) { /* remove from Expect's memory in anticipation of passing to Tcl */ if (f->pid != EXP_NOPID) { Tcl_DetachPids(1,&f->pid); f->pid = EXP_NOPID; f->sys_waited = f->user_waited = TRUE; } exp_close(interp,m); } chan = Tcl_MakeFileChannel( (ClientData)m2, (ClientData)m2, TCL_READABLE|TCL_WRITABLE); Tcl_RegisterChannel(interp, chan); Tcl_AppendResult(interp, Tcl_GetChannelName(chan), (char *) NULL); return TCL_OK; } /* return 1 if a string is substring of a flag */ /* this version is the code used by the macro that everyone calls */ int exp_flageq_code(flag,string,minlen) char *flag; char *string; int minlen; /* at least this many chars must match */ { for (;*flag;flag++,string++,minlen--) { if (*string == '\0') break; if (*string != *flag) return 0; } if (*string == '\0' && minlen <= 0) return 1; return 0; } void exp_create_commands(interp,c) Tcl_Interp *interp; struct exp_cmd_data *c; { Interp *iPtr = (Interp *) interp; char cmdnamebuf[80]; for (;c->name;c++) { int create = FALSE; /* if already defined, don't redefine */ if (c->flags & EXP_REDEFINE) create = TRUE; else if (!Tcl_FindHashEntry(&iPtr->commandTable,c->name)) { create = TRUE; } if (create) { Tcl_CreateCommand(interp,c->name,c->proc, c->data,exp_deleteProc); } if (!(c->name[0] == 'e' && c->name[1] == 'x' && c->name[2] == 'p') && !(c->flags & EXP_NOPREFIX)) { sprintf(cmdnamebuf,"exp_%s",c->name); Tcl_CreateCommand(interp,cmdnamebuf,c->proc, c->data,exp_deleteProc); } } } static struct exp_cmd_data cmd_data[] = { {"close", Exp_CloseCmd, 0, EXP_REDEFINE}, #ifdef TCL_DEBUGGER {"debug", Exp_DebugCmd, 0, 0}, #endif {"exp_internal",Exp_ExpInternalCmd, 0, 0}, {"disconnect", Exp_DisconnectCmd, 0, 0}, {"exit", Exp_ExitCmd, 0, EXP_REDEFINE}, {"continue", Exp_ExpContinueDeprecatedCmd,0,EXP_NOPREFIX|EXP_REDEFINE}, {"exp_continue",Exp_ExpContinueCmd,0, 0}, {"fork", Exp_ForkCmd, 0, 0}, {"exp_pid", Exp_ExpPidCmd, 0, 0}, {"getpid", Exp_GetpidDeprecatedCmd,0, 0}, {"interpreter", Exp_InterpreterCmd, 0, 0}, {"log_file", Exp_LogFileCmd, 0, 0}, {"log_user", Exp_LogUserCmd, 0, 0}, {"exp_open", Exp_OpenCmd, 0, 0}, {"overlay", Exp_OverlayCmd, 0, 0}, {"inter_return",Exp_InterReturnCmd, 0, 0}, {"send", Exp_SendCmd, (ClientData)&sendCD_proc, 0}, {"send_spawn", Exp_SendCmd, (ClientData)&sendCD_proc, 0},/*deprecat*/ {"send_error", Exp_SendCmd, (ClientData)&sendCD_error, 0}, {"send_log", Exp_SendLogCmd, 0, 0}, {"send_tty", Exp_SendCmd, (ClientData)&sendCD_tty, 0}, {"send_user", Exp_SendCmd, (ClientData)&sendCD_user, 0}, {"sleep", Exp_SleepCmd, 0, 0}, {"spawn", Exp_SpawnCmd, 0, 0}, {"strace", Exp_StraceCmd, 0, 0}, {"wait", Exp_WaitCmd, 0, 0}, {0}}; void exp_init_most_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); #ifdef HAVE_PTYTRAP Tcl_InitHashTable(&slaveNames,TCL_STRING_KEYS); #endif /* HAVE_PTYTRAP */ exp_close_in_child = exp_close_tcl_files; } |
Added unix/exp_console.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* exp_console.c - grab console. This stuff is in a separate file to avoid unpleasantness of AIX (3.2.4) .h files which provide no way to reference TIOCCONS and include both sys/ioctl.h and sys/sys/stropts.h without getting some sort of warning from the compiler. The problem is that both define _IO but only ioctl.h checks to see if it is defined first. This would suggest that it is sufficient to include ioctl.h after stropts.h. Unfortunately, ioctl.h, having seen that _IO is defined, then fails to define other important things (like _IOW). Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "expect_cf.h" #include <stdio.h> #include <sys/ioctl.h> #ifdef HAVE_STRREDIR_H #include <sys/strredir.h> # ifdef SRIOCSREDIR # undef TIOCCONS # endif #endif #ifdef HAVE_SYS_FCNTL_H #include <sys/fcntl.h> #endif #include "tcl.h" #include "exp_rename.h" #include "exp_prog.h" #include "exp_log.h" static void exp_console_manipulation_failed(s) char *s; { exp_errorlog("expect: spawn: cannot %s console, check permissions of /dev/console\n",s); exit(-1); } void exp_console_set() { #ifdef SRIOCSREDIR int fd; if ((fd = open("/dev/console", O_RDONLY)) == -1) { exp_console_manipulation_failed("open"); } if (ioctl(fd, SRIOCSREDIR, 0) == -1) { exp_console_manipulation_failed("redirect"); } close(fd); #endif #ifdef TIOCCONS int on = 1; if (ioctl(0,TIOCCONS,(char *)&on) == -1) { exp_console_manipulation_failed("redirect"); } #endif /*TIOCCONS*/ } |
Added unix/exp_poll.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | /* exp_poll.c - This file contains UNIX specific procedures for * poll-based notifier, which is the lowest-level part of the Tcl * event loop. This file works together with ../generic/tclNotify.c. * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and * NIST would appreciate credit if this program or parts of it are * used. * * Written by Don Libes, NIST, 2/6/90 * Rewritten by Don Libes, 2/96 for new Tcl notifier paradigm. * */ #include "tclInt.h" #include "tclPort.h" #include <signal.h> #include <poll.h> #include <sys/types.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif /* * The information below is used to provide read, write, and * exception masks to select during calls to Tcl_DoOneEvent. */ /* Some systems require that the poll array be non-empty. Alas, Tcl * provides no initialization opportunity to dynamically allocate it, * so provide a 1-elt array for starters. It will be ignored as soon * as it grows larger. */ static struct pollfd initialFdArray; static struct pollfd *fdArray = &initialFdArray; static int fdsInUse = 0; /* space in use */ static int fdsMaxSpace = 1; /* space that has actually been allocated */ /* *---------------------------------------------------------------------- * * Tcl_WatchFile -- * * Arrange for Tcl_DoOneEvent to include this file in the masks * for the next call to select. This procedure is invoked by * event sources, which are in turn invoked by Tcl_DoOneEvent * before it invokes select. * * Results: * None. * * Side effects: * * The notifier will generate a file event when the I/O channel * given by fd next becomes ready in the way indicated by mask. * If fd is already registered then the old mask will be replaced * with the new one. Once the event is sent, the notifier will * not send any more events about the fd until the next call to * Tcl_NotifyFile. * * Assumption for poll implementation: Tcl_WatchFile is presumed NOT * to be called on the same file descriptior without intervening calls * to Tcl_DoOneEvent. * *---------------------------------------------------------------------- */ void Tcl_WatchFile(file, mask) Tcl_File file; /* Generic file handle for a stream. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions to wait for * in select. */ { int fd, type; int cur_fd_index = fdsInUse; fd = (int) Tcl_GetFileInfo(file, &type); if (type != TCL_UNIX_FD) { panic("Tcl_WatchFile: unexpected file type"); } fdsInUse++; if (fdsInUse > fdsMaxSpace) { if (fdArray != &initialFdArray) ckfree((char *)fdArray); fdArray = (struct pollfd *)ckalloc(fdsInUse*sizeof(struct pollfd)); fdsMaxSpace = fdsInUse; } fdArray[cur_fd_index].fd = fd; /* I know that POLLIN/OUT is right. But I have no idea if POLLPRI * corresponds well to TCL_EXCEPTION. */ if (mask & TCL_READABLE) { fdArray[cur_fd_index].events = POLLIN; } if (mask & TCL_WRITABLE) { fdArray[cur_fd_index].events = POLLOUT; } if (mask & TCL_EXCEPTION) { fdArray[cur_fd_index].events = POLLPRI; } } /* *---------------------------------------------------------------------- * * Tcl_FileReady -- * * Indicates what conditions (readable, writable, etc.) were * present on a file the last time the notifier invoked select. * This procedure is typically invoked by event sources to see * if they should queue events. * * Results: * The return value is 0 if none of the conditions specified by mask * was true for fd the last time the system checked. If any of the * conditions were true, then the return value is a mask of those * that were true. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_FileReady(file, mask) Tcl_File file; /* Generic file handle for a stream. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions caller cares about. */ { int index, result, type, fd; fd_mask bit; fd = (int) Tcl_GetFileInfo(file, &type); if (type != TCL_UNIX_FD) { panic("Tcl_FileReady: unexpected file type"); } result = 0; if ((mask & TCL_READABLE) && (fdArray[fd].revents & POLLIN)) { result |= TCL_READABLE; } if ((mask & TCL_WRITABLE) && (fdArray[fd].revents & POLLOUT)) { result |= TCL_WRITABLE; } /* I have no idea if this is right ... */ if ((mask & TCL_EXCEPTION) && (fdArray[fd].revents & (POLLPRI|POLLERR|POLLHUP|POLLNVAL))) { result |= TCL_EXCEPTION; } return result; } /* *---------------------------------------------------------------------- * * Tcl_WaitForEvent -- * * This procedure does the lowest level wait for events in a * platform-specific manner. It uses information provided by * previous calls to Tcl_WatchFile, plus the timePtr argument, * to determine what to wait for and how long to wait. * * Results: * None. * * Side effects: * May put the process to sleep for a while, depending on timePtr. * When this procedure returns, an event of interest to the application * has probably, but not necessarily, occurred. * *---------------------------------------------------------------------- */ void Tcl_WaitForEvent(timePtr) Tcl_Time *timePtr; /* Specifies the maximum amount of time * that this procedure should block before * returning. The time is given as an * interval, not an absolute wakeup time. * NULL means block forever. */ { int timeout; struct timeval *timeoutPtr; /* no need to clear revents */ if (timePtr == NULL) { timeout = -1; } else { timeout = timePtr->sec*1000 + timePtr->usec/1000; } poll(fdsInUse,fdArray,timeout); fdsInUse = 0; } /* *---------------------------------------------------------------------- * * Tcl_Sleep -- * * Delay execution for the specified number of milliseconds. * * Results: * None. * * Side effects: * Time passes. * *---------------------------------------------------------------------- */ void Tcl_Sleep(ms) int ms; /* Number of milliseconds to sleep. */ { static struct timeval delay; Tcl_Time before, after; /* * The only trick here is that select appears to return early * under some conditions, so we have to check to make sure that * the right amount of time really has elapsed. If it's too * early, go back to sleep again. */ TclGetTime(&before); after = before; after.sec += ms/1000; after.usec += (ms%1000)*1000; if (after.usec > 1000000) { after.usec -= 1000000; after.sec += 1; } while (1) { delay.tv_sec = after.sec - before.sec; delay.tv_usec = after.usec - before.usec; if (delay.tv_usec < 0) { delay.tv_usec += 1000000; delay.tv_sec -= 1; } /* * Special note: must convert delay.tv_sec to int before comparing * to zero, since delay.tv_usec is unsigned on some platforms. */ if ((((int) delay.tv_sec) < 0) || ((delay.tv_usec == 0) && (delay.tv_sec == 0))) { break; } /* poll understands milliseconds, sigh */ poll(0,fdArray,delay.tv_sec*1000 + delay.tv_usec/1000); TclGetTime(&before); } } |
Added unix/exp_pty.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | /* exp_pty.c - generic routines to allocate and test ptys Written by: Don Libes, NIST, 3/9/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "expect_cf.h" #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif #include <sys/types.h> #include <sys/stat.h> #ifdef TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #include <signal.h> #include <setjmp.h> #include <sys/file.h> #define EXP_AVOID_INCLUDING_TCL_H 1 #include "expect_comm.h" #include "exp_rename.h" #include "exp_pty.h" #include <errno.h> void debuglog(); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifdef O_NOCTTY #define RDWR ((O_RDWR)|(O_NOCTTY)) #else #define RDWR O_RDWR #endif static int locked = FALSE; static char lock[] = "/tmp/ptylock.XXXX"; /* XX is replaced by pty id */ static char locksrc[50] = "/tmp/expect.pid"; /* pid is replaced by real pid */ /* locksrc is used as the link source, i.e., something to link from */ static int i_read_errno;/* place to save errno, if i_read() == -1, so it doesn't get overwritten before we get to read it */ static jmp_buf env; /* for interruptable read() */ static int env_valid = FALSE; /* whether we can longjmp or not */ /* sigalarm_handler and i_read are here just for supporting the sanity */ /* checking of pty slave devices. I have only seen this happen on BSD */ /* systems, but it may need to be done to the other pty implementations */ /* as well. */ /* Note that this code is virtually replicated from other code in expect */ /* At some point, I'll dump one, but not until I'm satisfied no other */ /* changes are needed */ /*ARGSUSED*/ static RETSIGTYPE sigalarm_handler(n) int n; /* unused, for compatibility with STDC */ { #ifdef REARM_SIG signal(SIGALRM,sigalarm_handler); #endif /* check env_valid first to protect us from the alarm occurring */ /* in the window between i_read and alarm(0) */ if (env_valid) longjmp(env,1); } /* interruptable read */ static int i_read(fd,buffer,length,timeout) int fd; char *buffer; int length; int timeout; { int cc = -2; /* since setjmp insists on returning 1 upon longjmp(,0), */ /* longjmp(,2) instead. */ /* restart read if setjmp returns 0 (first time) or 2. */ /* abort if setjmp returns 1. */ alarm(timeout); if (1 != setjmp(env)) { env_valid = TRUE; cc = read(fd,buffer,length); } env_valid = FALSE; i_read_errno = errno; /* errno can be overwritten by the */ /* time we return */ alarm(0); return(cc); } static RETSIGTYPE (*oldAlarmHandler)(); static RETSIGTYPE (*oldHupHandler)(); static time_t current_time; /* time when testing began */ /* if TRUE, begin testing, else end testing */ /* returns -1 for failure, 0 for success */ int exp_pty_test_start() { int lfd; /* locksrc file descriptor */ oldAlarmHandler = signal(SIGALRM,sigalarm_handler); #ifndef O_NOCTTY /* Ignore hangup signals generated by pty testing */ /* when running in background with no control tty. */ /* Very few systems don't define O_NOCTTY. Only one */ /* I know of is Next. */ oldAlarmHandler = signal(SIGHUP,SIG_IGN); #endif time(¤t_time); /* recreate locksrc to prevent locks from 'looking old', so */ /* that they are not deleted (later on in this code) */ sprintf(locksrc,"/tmp/expect.%d",getpid()); (void) unlink(locksrc); if (-1 == (lfd = creat(locksrc,0777))) { static char buf[256]; exp_pty_error = buf; sprintf(exp_pty_error,"can't create %s, errno = %d\n",locksrc, errno); return(-1); } close(lfd); return 0; } void exp_pty_test_end() { signal(SIGALRM,oldAlarmHandler); #ifndef O_NOCTTY signal(SIGALRM,oldHupHandler); #endif (void) unlink(locksrc); } /* returns non-negative if successful */ int exp_pty_test(master_name,slave_name,bank,num) char *master_name; char *slave_name; int bank; char *num; /* string representation of number */ { int master, slave; int cc; char c; /* make a lock file to prevent others (for now only */ /* expects) from allocating pty while we are playing */ /* with it. This allows us to rigorously test the */ /* pty is usable. */ if (exp_pty_lock(bank,num) == 0) { exp_debuglog("pty master (%s) is locked...skipping\r\n",master_name); return(-1); } /* verify no one else is using slave by attempting */ /* to read eof from master side */ if (0 > (master = open(master_name,RDWR))) return(-1); #ifdef __QNX__ /* QNX ptys don't have a lot of the same properties such as read 0 at EOF, etc */ /* if 1 should pacify C compiler without using nested ifdefs */ if (1) return master; #endif #ifdef HAVE_PTYTRAP if (access(slave_name, R_OK|W_OK) != 0) { exp_debuglog("could not open slave for pty master (%s)...skipping\r\n", master_name); (void) close(master); return -1; } return(master); #else if (0 > (slave = open(slave_name,RDWR))) { (void) close(master); return -1; } (void) close(slave); cc = i_read(master,&c,1,10); (void) close(master); if (!(cc == 0 || cc == -1)) { exp_debuglog("%s slave open, skipping\r\n",slave_name); locked = FALSE; /* leave lock file around so Expect's avoid */ /* retrying this pty for near future */ return -1; } /* verify no one else is using master by attempting */ /* to read eof from slave side */ if (0 > (master = open(master_name,RDWR))) return(-1); if (0 > (slave = open(slave_name,RDWR))) { (void) close(master); return -1; } (void) close(master); cc = i_read(slave,&c,1,10); (void) close(slave); if (!(cc == 0 || cc == -1)) { exp_debuglog("%s master open, skipping\r\n",master_name); return -1; } /* seems ok, let's use it */ exp_debuglog("using master pty %s\n",master_name); return(open(master_name,RDWR)); #endif } void exp_pty_unlock() { if (locked) { (void) unlink(lock); locked = FALSE; } } /* returns 1 if successfully locked, 0 otherwise */ int exp_pty_lock(bank,num) int bank; char *num; /* string representation of number */ { struct stat statbuf; if (locked) { unlink(lock); locked = FALSE; } sprintf(lock,"/tmp/ptylock.%c%s",bank,num); if ((0 == stat(lock,&statbuf)) && (statbuf.st_mtime+3600 < current_time)) { (void) unlink(lock); } if (-1 == (link(locksrc,lock))) locked = FALSE; else locked = TRUE; return locked; } |
Added unix/exp_pty.h.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* exp_pty.h - declarations for pty allocation and testing Written by: Don Libes, NIST, 3/9/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ int exp_pty_test_start(); void exp_pty_test_end(); int exp_pty_test(); void exp_pty_unlock(); int exp_pty_lock(); extern char *exp_pty_slave_name; |
Added unix/exp_select.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | /* exp_select.c - select() interface for Expect Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* suppress file-empty warnings produced by some compilers */ void exp_unused() {} #if 0 /* WHOLE FILE!!!! */ #include "expect_cf.h" #include <stdio.h> #include <errno.h> #include <sys/types.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif #ifdef HAVE_SYSSELECT_H # include <sys/select.h> /* Intel needs this for timeval */ #endif #ifdef HAVE_PTYTRAP # include <sys/ptyio.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef _AIX /* AIX has some unusual definition of FD_SET */ #include <sys/select.h> #endif #if !defined( FD_SET ) && defined( HAVE_SYS_BSDTYPES_H ) /* like AIX, ISC has it's own definition of FD_SET */ # include <sys/bsdtypes.h> #endif /* ! FD_SET && HAVE_SYS_BSDTYPES_H */ #include "tcl.h" #include "exp_prog.h" #include "exp_command.h" /* for struct exp_f defs */ #include "exp_event.h" #ifdef HAVE_SYSCONF_H #include <sys/sysconfig.h> #endif #ifndef FD_SET #define FD_SET(fd,fdset) (fdset)->fds_bits[0] |= (1<<(fd)) #define FD_CLR(fd,fdset) (fdset)->fds_bits[0] &= ~(1<<(fd)) #define FD_ZERO(fdset) (fdset)->fds_bits[0] = 0 #define FD_ISSET(fd,fdset) (((fdset)->fds_bits[0]) & (1<<(fd))) #ifndef AUX2 typedef struct fd_set { long fds_bits[1]; /* any implementation so pathetic as to not define FD_SET will just */ /* have to suffer with only 32 bits worth of fds */ } fd_set; #endif /* AUX2 */ #endif static struct timeval zerotime = {0, 0}; static struct timeval anytime = {0, 0}; /* can be changed by user */ /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; int *masters; int n; /* # of masters */ int *master_out; /* 1st event master, not set if none */ int timeout; /* seconds */ int key; { static rr = 0; /* round robin ptr */ int i; /* index into in-array */ struct timeval *t; fd_set rdrs; fd_set excep; /* FIXME: This is really gross, but the folks at Lynx said their select is * way hosed and to ignore all exceptions. */ #ifdef __Lynx__ #define EXCEP 0 #else #define EXCEP &excep #endif for (i=0;i<n;i++) { struct exp_f *f; int m; rr++; if (rr >= n) rr = 0; m = masters[rr]; f = exp_fs + m; if (f->key != key) { f->key = key; f->force_read = FALSE; *master_out = m; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { *master_out = m; return(EXP_DATA_OLD); } } if (timeout >= 0) { t = &anytime; t->tv_sec = timeout; } else { t = NULL; } restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); /* anything in the environment could have changed */ return EXP_RECONFIGURE; } FD_ZERO(&rdrs); FD_ZERO(&excep); for (i = 0;i < n;i++) { FD_SET(masters[i],&rdrs); FD_SET(masters[i],&excep); } /* The reason all fd masks are (seemingly) redundantly cast to */ /* SELECT_MASK_TYPE is that the HP defines its mask in terms of */ /* of int * and yet defines FD_SET in terms of fd_set. */ if (-1 == select(exp_fd_max+1, (SELECT_MASK_TYPE *)&rdrs, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)EXCEP, t)) { /* window refreshes trigger EINTR, ignore */ if (errno == EINTR) goto restart; else if (errno == EBADF) { /* someone is rotten */ for (i=0;i<n;i++) { fd_set suspect; FD_ZERO(&suspect); FD_SET(masters[i],&suspect); if (-1 == select(exp_fd_max+1, (SELECT_MASK_TYPE *)&suspect, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &zerotime)) { exp_error(interp,"invalid spawn_id (%d)\r",masters[i]); return(EXP_TCLERROR); } } } else { /* not prepared to handle anything else */ exp_error(interp,"select: %s\r",Tcl_PosixError(interp)); return(EXP_TCLERROR); } } for (i=0;i<n;i++) { rr++; if (rr >= n) rr = 0; /* ">" catches previous readys that */ /* used more fds then we're using now */ if (FD_ISSET(masters[rr],&rdrs)) { *master_out = masters[rr]; return(EXP_DATA_NEW); /*#ifdef HAVE_PTYTRAP*/ } else if (FD_ISSET(masters[rr], &excep)) { #ifndef HAVE_PTYTRAP *master_out = masters[rr]; return(EXP_EOF); #else struct request_info ioctl_info; if (ioctl(masters[rr],TIOCREQCHECK,&ioctl_info) < 0) { exp_debuglog("ioctl error on TIOCREQCHECK: %s",Tcl_ErrnoMsg(errno)); break; } if (ioctl_info.request == TIOCCLOSE) { /* eof */ *master_out = masters[rr]; return(EXP_EOF); } if (ioctl(masters[rr], TIOCREQSET, &ioctl_info) < 0) exp_debuglog("ioctl error on TIOCREQSET after ioctl or open on slave: %s", Tcl_ErrnoMsg(errno)); /* presumably, we trapped an open here */ goto restart; #endif /* HAVE_PTYTRAP */ } } return(EXP_TIMEOUT); } /*ARGSUSED*/ int exp_get_next_event_info(interp,fd,ready_mask) Tcl_Interp *interp; int fd; int ready_mask; { /* this function is only used when running with Tk */ /* hence, it is merely a stub in this file but to */ /* pacify lint, return something */ return 0; } int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { struct timeval t; t.tv_sec = sec; t.tv_usec = (sec - t.tv_sec) * 1000000L; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return rc; } if (-1 == select(1, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &t) && errno == EINTR) goto restart; return TCL_OK; } #if 0 int /* returns TCL_XXX */ exp_usleep(interp,usec) Tcl_Interp *interp; long usec; /* microseconds */ { struct timeval t; t.tv_sec = usec/1000000L; t.tv_usec = usec%1000000L; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); } if (-1 == select(1, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, &t) && errno == EINTR) goto restart; return TCL_OK; } #endif /*0*/ /* set things up for later calls to event handler */ void exp_init_event() { #if 0 #ifdef _SC_OPEN_MAX maxfds = sysconf(_SC_OPEN_MAX); #else maxfds = getdtablesize(); #endif #endif exp_event_exit = 0; } #endif /* WHOLE FILE !!!! */ |
Added unix/exp_simple.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | /* * tclUnixNotify.c -- * * This file contains Unix-specific procedures for the notifier, * which is the lowest-level part of the Tcl event loop. This file * works together with ../generic/tclNotify.c. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ static char sccsid[] = "@(#) tclUnixNotify.c 1.27 96/01/19 10:30:23"; #include "tclInt.h" #include "tclPort.h" #include <signal.h> /* * The information below is used to provide read, write, and * exception masks to select during calls to Tcl_DoOneEvent. */ static fd_mask checkMasks[3*MASK_SIZE]; /* This array is used to build up the masks * to be used in the next call to select. * Bits are set in response to calls to * Tcl_WatchFile. */ static fd_mask readyMasks[3*MASK_SIZE]; /* This array reflects the readable/writable * conditions that were found to exist by the * last call to select. */ static int numFdBits; /* Number of valid bits in checkMasks * (one more than highest fd for which * Tcl_WatchFile has been called). */ /* *---------------------------------------------------------------------- * * Tcl_WatchFile -- * * Arrange for Tcl_DoOneEvent to include this file in the masks * for the next call to select. This procedure is invoked by * event sources, which are in turn invoked by Tcl_DoOneEvent * before it invokes select. * * Results: * None. * * Side effects: * * The notifier will generate a file event when the I/O channel * given by fd next becomes ready in the way indicated by mask. * If fd is already registered then the old mask will be replaced * with the new one. Once the event is sent, the notifier will * not send any more events about the fd until the next call to * Tcl_NotifyFile. * *---------------------------------------------------------------------- */ void Tcl_WatchFile(file, mask) Tcl_File file; /* Generic file handle for a stream. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions to wait for * in select. */ { int fd, type, index; fd_mask bit; fd = (int) Tcl_GetFileInfo(file, &type); if (type != TCL_UNIX_FD) { panic("Tcl_WatchFile: unexpected file type"); } if (fd >= FD_SETSIZE) { panic("Tcl_WatchFile can't handle file id %d", fd); } index = fd/(NBBY*sizeof(fd_mask)); bit = 1 << (fd%(NBBY*sizeof(fd_mask))); if (mask & TCL_READABLE) { checkMasks[index] |= bit; } if (mask & TCL_WRITABLE) { (checkMasks+MASK_SIZE)[index] |= bit; } if (mask & TCL_EXCEPTION) { (checkMasks+2*(MASK_SIZE))[index] |= bit; } if (numFdBits <= fd) { numFdBits = fd+1; } } /* *---------------------------------------------------------------------- * * Tcl_FileReady -- * * Indicates what conditions (readable, writable, etc.) were * present on a file the last time the notifier invoked select. * This procedure is typically invoked by event sources to see * if they should queue events. * * Results: * The return value is 0 if none of the conditions specified by mask * was true for fd the last time the system checked. If any of the * conditions were true, then the return value is a mask of those * that were true. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Tcl_FileReady(file, mask) Tcl_File file; /* Generic file handle for a stream. */ int mask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, and TCL_EXCEPTION: * indicates conditions caller cares about. */ { int index, result, type, fd; fd_mask bit; fd = (int) Tcl_GetFileInfo(file, &type); if (type != TCL_UNIX_FD) { panic("Tcl_FileReady: unexpected file type"); } index = fd/(NBBY*sizeof(fd_mask)); bit = 1 << (fd%(NBBY*sizeof(fd_mask))); result = 0; if ((mask & TCL_READABLE) && (readyMasks[index] & bit)) { result |= TCL_READABLE; } if ((mask & TCL_WRITABLE) && ((readyMasks+MASK_SIZE)[index] & bit)) { result |= TCL_WRITABLE; } if ((mask & TCL_EXCEPTION) && ((readyMasks+(2*MASK_SIZE))[index] & bit)) { result |= TCL_EXCEPTION; } return result; } /* *---------------------------------------------------------------------- * * Tcl_WaitForEvent -- * * This procedure does the lowest level wait for events in a * platform-specific manner. It uses information provided by * previous calls to Tcl_WatchFile, plus the timePtr argument, * to determine what to wait for and how long to wait. * * Results: * None. * * Side effects: * May put the process to sleep for a while, depending on timePtr. * When this procedure returns, an event of interest to the application * has probably, but not necessarily, occurred. * *---------------------------------------------------------------------- */ void Tcl_WaitForEvent(timePtr) Tcl_Time *timePtr; /* Specifies the maximum amount of time * that this procedure should block before * returning. The time is given as an * interval, not an absolute wakeup time. * NULL means block forever. */ { struct timeval timeout, *timeoutPtr; int numFound; memcpy((VOID *) readyMasks, (VOID *) checkMasks, 3*MASK_SIZE*sizeof(fd_mask)); if (timePtr == NULL) { timeoutPtr = NULL; } else { timeoutPtr = &timeout; timeout.tv_sec = timePtr->sec; timeout.tv_usec = timePtr->usec; } numFound = select(numFdBits, (SELECT_MASK *) &readyMasks[0], (SELECT_MASK *) &readyMasks[MASK_SIZE], (SELECT_MASK *) &readyMasks[2*MASK_SIZE], timeoutPtr); /* * Some systems don't clear the masks after an error, so * we have to do it here. */ if (numFound == -1) { memset((VOID *) readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask)); } /* * Reset the check masks in preparation for the next call to * select. */ numFdBits = 0; memset((VOID *) checkMasks, 0, 3*MASK_SIZE*sizeof(fd_mask)); } /* *---------------------------------------------------------------------- * * Tcl_Sleep -- * * Delay execution for the specified number of milliseconds. * * Results: * None. * * Side effects: * Time passes. * *---------------------------------------------------------------------- */ void Tcl_Sleep(ms) int ms; /* Number of milliseconds to sleep. */ { static struct timeval delay; Tcl_Time before, after; /* * The only trick here is that select appears to return early * under some conditions, so we have to check to make sure that * the right amount of time really has elapsed. If it's too * early, go back to sleep again. */ TclGetTime(&before); after = before; after.sec += ms/1000; after.usec += (ms%1000)*1000; if (after.usec > 1000000) { after.usec -= 1000000; after.sec += 1; } while (1) { delay.tv_sec = after.sec - before.sec; delay.tv_usec = after.usec - before.usec; if (delay.tv_usec < 0) { delay.tv_usec += 1000000; delay.tv_sec -= 1; } /* * Special note: must convert delay.tv_sec to int before comparing * to zero, since delay.tv_usec is unsigned on some platforms. */ if ((((int) delay.tv_sec) < 0) || ((delay.tv_usec == 0) && (delay.tv_sec == 0))) { break; } (void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0, (SELECT_MASK *) 0, &delay); TclGetTime(&before); } } #if 0 /* WHOLE FILE */ /* interact (with only one process) - give user keyboard control Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ /* This file exists for deficient versions of UNIX that lack select, poll, or some other multiplexing hook. Instead, this code uses two processes per spawned process. One sends characters from the spawnee to the spawner; a second send chars the other way. This will work on any UNIX system. The only sacrifice is that it doesn't support multiple processes. Eventually, it should catch SIGCHLD on dead processes and do the right thing. But it is pretty gruesome to imagine so many processes to do all this. If you change it successfully, please mail back the changes to me. - Don */ #include "expect_cf.h" #include <stdio.h> #include <sys/types.h> #include <sys/time.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #include "tcl.h" #include "exp_prog.h" #include "exp_command.h" /* for struct exp_f defs */ #include "exp_event.h" /*ARGSUSED*/ void exp_arm_background_filehandler(m) int m; { } /*ARGSUSED*/ void exp_disarm_background_filehandler(m) int m; { } /*ARGSUSED*/ void exp_disarm_background_filehandler_force(m) int m; { } /*ARGSUSED*/ void exp_unblock_background_filehandler(m) int m; { } /*ARGSUSED*/ void exp_block_background_filehandler(m) int m; { } /*ARGSUSED*/ void exp_event_disarm(fd) int fd; { } /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ /*ARGSUSED*/ int exp_get_next_event(interp,masters, n,master_out,timeout,key) Tcl_Interp *interp; int *masters; int n; /* # of masters */ int *master_out; /* 1st event master, not set if none */ int timeout; /* seconds */ int key; { int m; struct exp_f *f; if (n > 1) { exp_error(interp,"expect not compiled with multiprocess support"); /* select a different INTERACT_TYPE in Makefile */ return(TCL_ERROR); } m = *master_out = masters[0]; f = exp_fs + m; if (f->key != key) { f->key = key; f->force_read = FALSE; return(EXP_DATA_OLD); } else if ((!f->force_read) && (f->size != 0)) { return(EXP_DATA_OLD); } return(EXP_DATA_NEW); } /*ARGSUSED*/ int exp_get_next_event_info(interp,fd,ready_mask) Tcl_Interp *interp; int fd; int ready_mask; { } /* There is no portable way to do sub-second sleeps on such a system, so */ /* do the next best thing (without a busy loop) and fake it: sleep the right */ /* amount of time over the long run. Note that while "subtotal" isn't */ /* reinitialized, it really doesn't matter for such a gross hack as random */ /* scheduling pauses will easily introduce occasional one second delays. */ int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { static double subtotal = 0; int seconds; subtotal += sec; if (subtotal < 1) return TCL_OK; seconds = subtotal; subtotal -= seconds; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(rc); } sleep(seconds); return TCL_OK; } #if 0 /* There is no portable way to do sub-second sleeps on such a system, so */ /* do the next best thing (without a busy loop) and fake it: sleep the right */ /* amount of time over the long run. Note that while "subtotal" isn't */ /* reinitialized, it really doesn't matter for such a gross hack as random */ /* scheduling pauses will easily introduce occasional one second delays. */ int /* returns TCL_XXX */ exp_usleep(interp,usec) Tcl_Interp *interp; long usec; /* microseconds */ { static subtotal = 0; int seconds; subtotal += usec; if (subtotal < 1000000) return TCL_OK; seconds = subtotal/1000000; subtotal = subtotal%1000000; restart: if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); } sleep(seconds); return TCL_OK; } #endif /*0*/ /* set things up for later calls to event handler */ void exp_init_event() { exp_event_exit = 0; } #endif /* WHOLE FILE! */ |
Added unix/exp_trap.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | /* exp_trap.c - Expect's trap command Written by: Don Libes, NIST, 9/1/93 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "expect_cf.h" #include <stdio.h> #include <signal.h> #include <sys/types.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #include "tcl.h" #include "exp_rename.h" #include "exp_prog.h" #include "exp_command.h" #include "exp_log.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #endif #define NO_SIG 0 static struct trap { char *action; /* Tcl command to execute upon sig */ /* Each is handled by the eval_trap_action */ int mark; /* TRUE if signal has occurred */ Tcl_Interp *interp; /* interp to use or 0 if we should use the */ /* interpreter active at the time the sig */ /* is processed */ int code; /* return our new code instead of code */ /* available when signal is processed */ char *name; /* name of signal */ int reserved; /* if unavailable for trapping */ } traps[NSIG]; int sigchld_count = 0; /* # of sigchlds caught but not yet processed */ static int eval_trap_action(); static int got_sig; /* this records the last signal received */ /* it is only a hint and can be wiped out */ /* by multiple signals, but it will always */ /* be left with a valid signal that is */ /* pending */ static Tcl_AsyncHandler async_handler; static char * signal_to_string(sig) int sig; { if (sig <= 0 || sig > NSIG) return("SIGNAL OUT OF RANGE"); return(traps[sig].name); } /* current sig being processed by user sig handler */ static int current_sig = NO_SIG; int exp_nostack_dump = FALSE; /* TRUE if user has requested unrolling of */ /* stack with no trace */ /*ARGSUSED*/ static int tophalf(clientData,interp,code) ClientData clientData; Tcl_Interp *interp; int code; { struct trap *trap; /* last trap processed */ int rc; int i; Tcl_Interp *sig_interp; /* extern Tcl_Interp *exp_interp;*/ exp_debuglog("sighandler: handling signal(%d)\r\n",got_sig); if (got_sig <= 0 || got_sig >= NSIG) { exp_errorlog("caught impossible signal %d\r\n",got_sig); abort(); } /* start to work on this sig. got_sig can now be overwritten */ /* and it won't cause a problem */ current_sig = got_sig; trap = &traps[current_sig]; trap->mark = FALSE; /* decrement below looks dangerous */ /* Don't we need to temporarily block bottomhalf? */ if (current_sig == SIGCHLD) { sigchld_count--; exp_debuglog("sigchld_count-- == %d\n",sigchld_count); } if (!trap->action) { /* In this one case, we let ourselves be called when no */ /* signaler predefined, since we are calling explicitly */ /* from another part of the program, and it is just simpler */ if (current_sig == 0) return code; exp_errorlog("caught unexpected signal: %s (%d)\r\n", signal_to_string(current_sig),current_sig); abort(); } if (trap->interp) { /* if trap requested original interp, use it */ sig_interp = trap->interp; } else if (!interp) { /* else if another interp is available, use it */ sig_interp = interp; } else { /* fall back to exp_interp */ sig_interp = exp_interp; } rc = eval_trap_action(sig_interp,current_sig,trap,code); current_sig = NO_SIG; /* * scan for more signals to process */ /* first check for additional SIGCHLDs */ if (sigchld_count) { got_sig = SIGCHLD; traps[SIGCHLD].mark = TRUE; Tcl_AsyncMark(async_handler); } else { got_sig = -1; for (i=1;i<NSIG;i++) { if (traps[i].mark) { got_sig = i; Tcl_AsyncMark(async_handler); break; } } } return rc; } #ifdef REARM_SIG int sigchld_sleep; static int rearm_sigchld = FALSE; /* TRUE if sigchld needs to be */ /* rearmed (i.e., because it has /* just gone off) */ static int rearming_sigchld = FALSE; #endif /* called upon receipt of a user-declared signal */ static void bottomhalf(sig) int sig; { #ifdef REARM_SIG /* * tiny window of death if same signal should arrive here * before we've reinstalled it */ /* In SV, sigchld must be rearmed after wait to avoid recursion */ if (sig != SIGCHLD) { signal(sig,bottomhalf); } else { /* request rearm */ rearm_sigchld = TRUE; if (rearming_sigchld) sigchld_sleep = TRUE; } #endif traps[sig].mark = TRUE; got_sig = sig; /* just a hint - can be wiped out by another */ Tcl_AsyncMark(async_handler); /* if we are called while this particular async is being processed */ /* original async_proc will turn off "mark" so that when async_proc */ /* is recalled, it will see that nothing was left to do */ /* In case of SIGCHLD though, we must recall it as many times as * we have received it. */ if (sig == SIGCHLD) { sigchld_count++; /* exp_debuglog(stderr,"sigchld_count++ == %d\n",sigchld_count);*/ } #if 0 /* if we are doing an i_read, restart it */ if (env_valid && (sig != 0)) longjmp(env,2); #endif } /*ARGSUSED*/ void exp_rearm_sigchld(interp) Tcl_Interp *interp; { #ifdef REARM_SIG if (rearm_sigchld) { rearm_sigchld = FALSE; rearming_sigchld = TRUE; signal(SIGCHLD,bottomhalf); } rearming_sigchld = FALSE; /* if the rearming immediately caused another SIGCHLD, slow down */ /* It's probably one of Tcl's intermediary pipeline processes that */ /* Tcl hasn't caught up with yet. */ if (sigchld_sleep) { exp_dsleep(interp,0.2); sigchld_sleep = FALSE; } #endif } void exp_init_trap() { int i; for (i=1;i<NSIG;i++) { traps[i].name = Tcl_SignalId(i); traps[i].action = 0; traps[i].reserved = FALSE; } /* * fix up any special cases */ #if defined(SIGCLD) /* Tcl names it SIGCLD, not good for portable scripts */ traps[SIGCLD].name = "SIGCHLD"; #endif #if defined(SIGALRM) traps[SIGALRM].reserved = TRUE; #endif #if defined(SIGKILL) traps[SIGKILL].reserved = TRUE; #endif #if defined(SIGSTOP) traps[SIGSTOP].reserved = TRUE; #endif async_handler = Tcl_AsyncCreate(tophalf,(ClientData)0); } /* given signal index or name as string, */ /* returns signal index or -1 if bad arg */ int exp_string_to_signal(interp,s) Tcl_Interp *interp; char *s; { int sig; char *name; /* try interpreting as an integer */ if (1 == sscanf(s,"%d",&sig)) { if (sig > 0 && sig < NSIG) return sig; } else { /* try interpreting as a string */ for (sig=1;sig<NSIG;sig++) { name = traps[sig].name; if (streq(s,name) || streq(s,name+3)) return(sig); } } exp_error(interp,"invalid signal %s",s); return -1; } /*ARGSUSED*/ int Exp_TrapCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *action = 0; int n; /* number of signals in list */ char **list; /* list of signals */ int len; /* length of action */ int i; int show_name = FALSE; /* if user asked for current sig by name */ int show_number = FALSE;/* if user asked for current sig by number */ int show_max = FALSE; /* if user asked for NSIG-1 */ int rc = TCL_OK; int new_code = FALSE; /* if action result should overwrite orig */ Tcl_Interp *new_interp = interp;/* interp in which to evaluate */ /* action when signal occurs */ argc--; argv++; while (*argv) { if (streq(*argv,"-code")) { argc--; argv++; new_code = TRUE; } else if (streq(*argv,"-interp")) { argc--; argv++; new_interp = 0; } else if (streq(*argv,"-name")) { argc--; argv++; show_name = TRUE; } else if (streq(*argv,"-number")) { argc--; argv++; show_number = TRUE; } else if (streq(*argv,"-max")) { argc--; argv++; show_max = TRUE; } else break; } if (show_name || show_number || show_max) { if (argc > 0) goto usage_error; if (show_max) { sprintf(interp->result,"%d",NSIG-1); return TCL_OK; } if (current_sig == NO_SIG) { exp_error(interp,"no signal in progress"); return TCL_ERROR; } if (show_name) { /* skip over "SIG" */ interp->result = signal_to_string(current_sig) + 3; } else { sprintf(interp->result,"%d",current_sig); } return TCL_OK; } if (argc == 0 || argc > 2) goto usage_error; if (argc == 1) { int sig = exp_string_to_signal(interp,*argv); if (sig == -1) return TCL_ERROR; if (traps[sig].action) { Tcl_AppendResult(interp,traps[sig].action,(char *)0); } else { interp->result = "SIG_DFL"; } return TCL_OK; } action = *argv; /* argv[1] is the list of signals - crack it open */ if (TCL_OK != Tcl_SplitList(interp,argv[1],&n,&list)) { exp_errorlog("%s\r\n",interp->result); goto usage_error; } for (i=0;i<n;i++) { int sig = exp_string_to_signal(interp,list[i]); if (sig == -1) { rc = TCL_ERROR; break; } if (traps[sig].reserved) { exp_error(interp,"cannot trap %s",signal_to_string(sig)); rc = TCL_ERROR; break; } #if 0 #ifdef TCL_DEBUGGER if (sig == SIGINT && exp_tcl_debugger_available) { exp_debuglog("trap: cannot trap SIGINT while using debugger\r\n"); continue; } #endif /* TCL_DEBUGGER */ #endif exp_debuglog("trap: setting up signal %d (\"%s\")\r\n",sig,list[i]); if (traps[sig].action) ckfree(traps[sig].action); if (streq(action,"SIG_DFL")) { /* should've been free'd by now if nec. */ traps[sig].action = 0; signal(sig,SIG_DFL); #ifdef REARM_SIG if (sig == SIGCHLD) rearm_sigchld = FALSE; #endif /*REARM_SIG*/ } else { len = 1 + strlen(action); traps[sig].action = ckalloc(len); memcpy(traps[sig].action,action,len); traps[sig].interp = new_interp; traps[sig].code = new_code; if (streq(action,"SIG_IGN")) { signal(sig,SIG_IGN); } else signal(sig,bottomhalf); } } ckfree((char *)list); return(rc); usage_error: exp_error(interp,"usage: trap [command or SIG_DFL or SIG_IGN] {list of signals}"); return TCL_ERROR; } /* called by tophalf() to process the given signal */ static int eval_trap_action(interp,sig,trap,oldcode) Tcl_Interp *interp; int sig; struct trap *trap; int oldcode; { int code_flag; int newcode; Tcl_DString ei; /* errorInfo */ char *eip; Tcl_DString ec; /* errorCode */ char *ecp; Tcl_DString ir; /* interp->result */ exp_debuglog("async event handler: Tcl_Eval(%s)\r\n",trap->action); /* save to prevent user from redefining trap->code while trap */ /* is executing */ code_flag = trap->code; if (!code_flag) { /* * save return values */ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY); if (eip) { Tcl_DStringInit(&ei); eip = Tcl_DStringAppend(&ei,eip,-1); } ecp = Tcl_GetVar(interp,"errorCode",TCL_GLOBAL_ONLY); if (ecp) { Tcl_DStringInit(&ec); ecp = Tcl_DStringAppend(&ec,ecp,-1); } /* I assume interp->result is always non-zero, right? */ Tcl_DStringInit(&ir); Tcl_DStringAppend(&ir,interp->result,-1); } newcode = Tcl_GlobalEval(interp,trap->action); /* * if new code is to be ignored (usual case - see "else" below) * allow only OK/RETURN from trap, otherwise complain */ if (code_flag) { exp_debuglog("return value = %d for trap %s, action %s\r\n", newcode,signal_to_string(sig),trap->action); if (*interp->result != 0) { exp_errorlog("%s\r\n",interp->result); /* * Check errorinfo and see if it contains -nostack. * This shouldn't be necessary, but John changed the * top level interp so that it distorts arbitrary * return values into TCL_ERROR, so by the time we * get back, we'll have lost the value of errorInfo */ eip = Tcl_GetVar(interp,"errorInfo",TCL_GLOBAL_ONLY); exp_nostack_dump = (eip && (0 == strncmp("-nostack",eip,8))); } } else if (newcode != TCL_OK && newcode != TCL_RETURN) { if (newcode != TCL_ERROR) { exp_error(interp,"return value = %d for trap %s, action %s\r\n",newcode,signal_to_string(sig),trap->action); } Tcl_BackgroundError(interp); } if (!code_flag) { /* * restore values */ Tcl_ResetResult(interp); /* turns off Tcl's internal */ /* flags: ERR_IN_PROGRESS, ERROR_CODE_SET */ if (eip) { Tcl_AddErrorInfo(interp,eip); Tcl_DStringFree(&ei); } else { Tcl_UnsetVar(interp,"errorInfo",0); } /* restore errorCode. Note that Tcl_AddErrorInfo (above) */ /* resets it to NONE. If the previous value is NONE, it's */ /* important to avoid calling Tcl_SetErrorCode since this */ /* with cause Tcl to set its internal ERROR_CODE_SET flag. */ if (ecp) { if (!streq("NONE",ecp)) Tcl_SetErrorCode(interp,ecp,(char *)0); Tcl_DStringFree(&ec); } else { Tcl_UnsetVar(interp,"errorCode",0); } Tcl_DStringResult(interp,&ir); Tcl_DStringFree(&ir); newcode = oldcode; /* note that since newcode gets overwritten here by old code */ /* it is possible to return in the middle of a trap by using */ /* "return" (or "continue" for that matter)! */ } return newcode; } static struct exp_cmd_data cmd_data[] = { {"trap", Exp_TrapCmd, (ClientData)EXP_SPAWN_ID_BAD, 0}, {0}}; void exp_init_trap_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } |
Added unix/exp_tty_comm.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* exp_tty_comm.c - tty support routines common to both Expect program and library */ #include "expect_cf.h" #include <stdio.h> #include "exp_tty.h" #include "exp_rename.h" #define EXP_AVOID_INCLUDING_TCL_H #include "expect_comm.h" #include "exp_log.h" #ifndef TRUE #define FALSE 0 #define TRUE 1 #endif int exp_disconnected = FALSE; /* not disc. from controlling tty */ /*static*/ exp_tty exp_tty_current, exp_tty_cooked; #define tty_current exp_tty_current #define tty_cooked exp_tty_cooked void exp_init_tty() { extern exp_tty exp_tty_original; /* save original user tty-setting in 'cooked', just in case user */ /* asks for it without earlier telling us what cooked means to them */ tty_cooked = exp_tty_original; /* save our current idea of the terminal settings */ tty_current = exp_tty_original; } |
Added unix/exp_tty_in.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* exp_tty_in.h - internal tty support definitions */ /* Definitions for handling termio inclusion are localized here */ /* This file should be included only if direct access to tty structures are */ /* required. This file is necessary to avoid mismatch between gcc's and */ /* vendor's include files */ /* Written by Rob Savoye <[email protected]>. Mon Feb 22 11:16:53 RMT 1993 */ #ifndef __EXP_TTY_IN_H__ #define __EXP_TTY_IN_H__ #include "expect_cf.h" #ifdef __MACHTEN__ #include "sys/types.h" #endif /* * Set up some macros to isolate tty differences */ /* On some hosts, termio is incomplete (broken) and sgtty is a better choice. At the same time, termio has some definitions for modern stuff like window sizes that sgtty lacks - that's why termio.h is included even when we claim the basic style is sgtty */ /* test for pyramid may be unnecessary, but only Pyramid people have */ /* complained - notably [email protected] (Rick) */ #if defined(pyr) && defined(HAVE_TERMIO) && defined(HAVE_SGTTYB) #undef HAVE_SGTTYB #endif /* on ISC SVR3.2, termios is skeletal and termio is a better choice. */ /* sgttyb must also be avoided because it redefines same things that */ /* termio does */ /* note that both SVR3.2 and AIX lacks TCGETS or TCGETA in termios.h */ /* but SVR3.2 lacks both TCSETATTR and TCGETS/A */ #if defined(HAVE_TERMIO) && defined(HAVE_TERMIOS) && !defined(HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H) && !defined(HAVE_TCSETATTR) # undef HAVE_TERMIOS # undef HAVE_SGTTYB #endif #if defined(HAVE_TERMIO) && !defined(HAVE_TERMIOS) # include <termio.h> # undef POSIX # define TERMINAL termio # ifndef TCGETS # define TCGETS TCGETA # define TCSETS TCSETA # define TCSETSW TCSETAW # define TCSETSF TCSETAF # endif #endif #if defined(HAVE_SGTTYB) && !defined(HAVE_TERMIOS) # undef HAVE_TERMIO # undef POSIX #ifndef TCGETS # define TCGETS TIOCGETP # define TCSETS TIOCSETP #endif #ifndef TCSETSW # define TCSETSW TIOCSETN #endif # define TERMINAL sgttyb # ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> # else # include <fcntl.h> # endif # include <sgtty.h> # include <sys/ioctl.h> #endif #if defined(HAVE_TERMIOS) # undef HAVE_TERMIO # undef HAVE_SGTTYB # include <termios.h> # define TERMINAL termios # if !defined(TCGETS) || !defined(TCSETS) # define TCGETS TCGETA # define TCSETS TCSETA # define TCSETSW TCSETAW # define TCSETSF TCSETAF # endif #endif /* This section was written by: Don Libes, NIST, 2/6/90 */ typedef struct TERMINAL exp_tty; extern exp_tty exp_tty_original; extern exp_tty exp_tty_current; extern exp_tty exp_tty_cooked; #endif /* __EXP_TTY_IN_H__ */ |
Added unix/expect_cf.h.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | /* * Check for headers */ #ifndef __EXPECT_CF_H__ #define __EXPECT_CF_H__ #undef NO_STDLIB_H /* Tcl requires this name */ #undef HAVE_STDARG_H #undef HAVE_VARARGS_H #undef HAVE_STROPTS_H #undef HAVE_SYSCONF_H #undef HAVE_SYS_FCNTL_H #undef HAVE_SYS_WAIT_H #undef HAVE_SYS_BSDTYPES_H /* nice ISC special */ #undef HAVE_SYS_SELECT_H /* nice ISC special */ #undef HAVE_SYS_TIME_H /* nice ISC special */ #undef HAVE_SYS_PTEM_H /* SCO needs this for window size */ #undef HAVE_STRREDIR_H /* Solaris needs this for console redir */ #undef HAVE_STRPTY_H /* old-style Dynix ptys need this */ #undef HAVE_UNISTD_H #undef HAVE_SYSMACROS_H #undef HAVE_TIOCGWINSZ_IN_TERMIOS_H #undef HAVE_TCGETS_OR_TCGETA_IN_TERMIOS_H #undef pid_t #undef RETSIGTYPE #undef TIME_WITH_SYS_TIME /* ok to include both time.h and sys/time.h */ /* * This section is for compile macros needed by * everything else. */ /* * Check for functions */ #undef HAVE_MEMCPY #undef HAVE_SYSCONF #undef SIMPLE_EVENT #undef HAVE_STRFTIME #undef HAVE_MEMMOVE #undef HAVE_TIMEZONE /* timezone() a la Pyramid */ #undef HAVE_STRCHR #ifndef HAVE_STRCHR #define strchr(s,c) index(s,c) #endif /* HAVE_STRCHR */ /* * timezone */ #undef HAVE_SV_TIMEZONE /* * wait status type */ #undef NO_UNION_WAIT #undef WNOHANG_REQUIRES_POSIX_SOURCE /* * Signal stuff. Setup the return type * and if signals need to be re-armed. */ /*#ifndef RETSIGTYPE*/ /*#define RETSIGTYPE void*/ /*#endif*/ #undef REARM_SIG /* * Generate correct type for select mask */ #ifndef SELECT_MASK_TYPE #define SELECT_MASK_TYPE fd_set #endif /* * Check how stty works */ #undef STTY_READS_STDOUT /* * Check for tty/pty functions and structures */ #undef POSIX #undef HAVE_TCSETATTR #undef HAVE_TERMIO #undef HAVE_TERMIOS #undef HAVE_SGTTYB #undef HAVE__GETPTY #undef HAVE_GETPTY #undef HAVE_OPENPTY #undef HAVE_PTC #undef HAVE_PTC_PTS #undef HAVE_PTYM #undef HAVE_PTYTRAP #undef HAVE_PTMX #undef HAVE_PTMX_BSD #undef HAVE_SCO_CLIST_PTYS /* * Special hacks */ #undef CONVEX #undef SOLARIS #ifdef SOLARIS #define __EXTENSIONS__ #endif /* SOLARIS */ #undef WNOHANG_BACKUP_VALUE #endif /* __EXPECT_CF_H__ */ |
Added unix/fixcat.
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!expect -- # Synopsis: fixcat # Author: Don Libes # Description: test to see if /bin/cat is unbuffered (i.e., -u is needed) # Return 0 if buffered, 1 if unbuffered. # # If this file is sitting in an architecture-specific library directory, # then it serves as a marker that your /bin/cat buffers by default. # test for when catting to/from files log_user 0 spawn -open [open "|cat" "r+"] send "\r" expect "\r" {exit 1} # test for when catting to real tty #log_user 0 #spawn /bin/cat #send "\r" #expect "\r\n\r\n" {exit 1} |
Added unix/fixline1.
> > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | #!expect -- # Synopsis: fixline1 newpath < input > output # Author: Don Libes # Description: change first line of script to reflect new binary # try to match any of the following first lines #!expect ... #!../expect ... #!expectk ... #!foo/bar/expectk ... # regsub "^#!(.*/)*(.*)" [gets stdin] "#!$argv/\\2" line1 puts -nonewline "$line1\n[read stdin]" |
Added unix/install-sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | #! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 |
Added unix/pkgIndex.in.
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # Tcl package index file, version 1.0 # This file is generated by the "pkg_mkIndex" command # and sourced either when an application starts up or # by a "package unknown" script. It invokes the # "package ifneeded" command to set up package-related # information so that packages will be loaded automatically # in response to "package require" commands. When this # script is sourced, the variable $dir must contain the # full path name of this file's directory. package ifneeded Expect @EXP_VERSION_FULL@ "tclPkgSetup @exec_prefix@/lib Expect @EXP_VERSION_FULL@ { {@EXP_SHARED_LIB_FILE@ load {debug disconnect exp_close exp_continue exp_debug exp_disconnect exp_exit exp_fork exp_getpid exp_inter_return exp_interact exp_internal exp_interpreter exp_log_file exp_log_user exp_match_max exp_open exp_overlay exp_parity exp_pid exp_remove_nulls exp_send exp_send_error exp_send_log exp_send_spawn exp_send_tty exp_send_user exp_sleep exp_spawn exp_strace exp_stty exp_system exp_timestamp exp_trap exp_version exp_wait expect expect_after expect_background expect_before expect_tty expect_user expect_version fork getpid inter_return interact interpreter log_file log_user match_max overlay parity prompt1 prompt2 remove_nulls send send_error send_log send_spawn send_tty send_user sleep spawn strace stty system timestamp trap wait}} }" |
Added unix/pty_sgttyb.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | /* pty_bsd.c - routines to allocate ptys - BSD version Written by: Don Libes, NIST, 2/6/90 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include <stdio.h> /* tmp for debugging */ #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #include <sys/types.h> #include <sys/stat.h> /*** #include <sys/ioctl.h> ***/ #include <sys/file.h> #include <signal.h> #include <setjmp.h> #include "expect_cf.h" #include "exp_rename.h" #include "exp_tty.h" #include "exp_pty.h" void debuglog(); #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static char master_name[] = "/dev/ptyXX"; /* master */ static char slave_name[] = "/dev/ttyXX"; /* slave */ static char *tty_type; /* ptr to char [pt] denoting whether it is a pty or tty */ static char *tty_bank; /* ptr to char [p-z] denoting which bank it is */ static char *tty_num; /* ptr to char [0-f] denoting which number it is */ char *exp_pty_slave_name; char *exp_pty_error; static void pty_stty(s,name) char *s; /* args to stty */ char *name; /* name of pty */ { #define MAX_ARGLIST 10240 char buf[MAX_ARGLIST]; /* overkill is easier */ RETSIGTYPE (*old)(); /* save old sigalarm handler */ #ifdef STTY_READS_STDOUT sprintf(buf,"/bin/stty %s > %s",s,name); #else sprintf(buf,"/bin/stty %s < %s",s,name); #endif old = signal(SIGCHLD, SIG_DFL); system(buf); signal(SIGCHLD, old); /* restore signal handler */ } int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */ static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */ #ifdef TIOCGWINSZ static struct winsize winsize = {0, 0}; #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) static struct ttysize winsize = {0, 0}; #endif exp_tty exp_tty_original; #define GET_TTYTYPE 0 #define SET_TTYTYPE 1 static void ttytype(request,fd,ttycopy,ttyinit,s) int request; int fd; /* following are used only if request == SET_TTYTYPE */ int ttycopy; /* if true, copy from /dev/tty */ int ttyinit; /* if true, initialize to sane state */ char *s; /* stty args */ { static struct tchars tc; /* special characters */ static struct ltchars lc; /* local special characters */ static struct winsize win; /* window size */ static int lb; /* local modes */ static int l; /* line discipline */ if (request == GET_TTYTYPE) { if (-1 == ioctl(fd, TIOCGETP, (char *)&exp_tty_original) || -1 == ioctl(fd, TIOCGETC, (char *)&tc) || -1 == ioctl(fd, TIOCGETD, (char *)&l) || -1 == ioctl(fd, TIOCGLTC, (char *)&lc) || -1 == ioctl(fd, TIOCLGET, (char *)&lb) || -1 == ioctl(fd, TIOCGWINSZ, (char *)&win)) { knew_dev_tty = FALSE; exp_dev_tty = -1; } #ifdef TIOCGWINSZ ioctl(fd,TIOCGWINSZ,&winsize); #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) ioctl(fd,TIOCGSIZE,&winsize); #endif } else { /* type == SET_TTYTYPE */ if (ttycopy && knew_dev_tty) { (void) ioctl(fd, TIOCSETP, (char *)&exp_tty_current); (void) ioctl(fd, TIOCSETC, (char *)&tc); (void) ioctl(fd, TIOCSLTC, (char *)&lc); (void) ioctl(fd, TIOCLSET, (char *)&lb); (void) ioctl(fd, TIOCSETD, (char *)&l); (void) ioctl(fd, TIOCSWINSZ, (char *)&win); #ifdef TIOCSWINSZ ioctl(fd,TIOCSWINSZ,&winsize); #endif #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ) ioctl(fd,TIOCGSIZE,&winsize); #endif } #ifdef __CENTERLINE__ #undef DFLT_STTY #define DFLT_STTY "sane" #endif /* Apollo Domain doesn't need this */ #ifdef DFLT_STTY if (ttyinit) { /* overlay parms originally supplied by Makefile */ pty_stty(DFLT_STTY,slave_name); } #endif /* lastly, give user chance to override any terminal parms */ if (s) { pty_stty(s,slave_name); } } } void exp_init_pty() { tty_type = & slave_name[strlen("/dev/")]; tty_bank = &master_name[strlen("/dev/pty")]; tty_num = &master_name[strlen("/dev/ptyp")]; exp_dev_tty = open("/dev/tty",O_RDWR); #if experimental /* code to allocate force expect to get a controlling tty */ /* even if it doesn't start with one (i.e., under cron). */ /* This code is not necessary, but helpful for testing odd things. */ if (exp_dev_tty == -1) { /* give ourselves a controlling tty */ int master = getptymaster(); fcntl(master,F_SETFD,1); /* close-on-exec */ setpgrp(0,0); close(0); close(1); getptyslave(exp_get_var(exp_interp,"stty_init")); close(2); fcntl(0,F_DUPFD,2); /* dup 0 onto 2 */ } #endif knew_dev_tty = (exp_dev_tty != -1); if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0); } /* returns fd of master end of pseudotty */ int getptymaster() { int master = -1; char *hex, *bank; struct stat statbuf; exp_pty_error = 0; if (exp_pty_test_start() == -1) return -1; for (bank = "pqrstuvwxyzPQRSTUVWXYZ";*bank;bank++) { *tty_bank = *bank; *tty_num = '0'; if (stat(master_name, &statbuf) < 0) break; for (hex = "0123456789abcdef";*hex;hex++) { *tty_num = *hex; /* generate slave name from master */ strcpy(slave_name,master_name); *tty_type = 't'; master = exp_pty_test(master_name,slave_name, *tty_bank,tty_num); if (master >= 0) goto done; } } done: exp_pty_test_end(); exp_pty_slave_name = slave_name; return(master); } /* see comment in pty_termios.c */ /*ARGSUSED*/ void exp_slave_control(master,control) int master; int control; { } int getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave; if (0 > (slave = open(slave_name, O_RDWR))) return(-1); if (0 == slave) { /* if opened in a new process, slave will be 0 (and */ /* ultimately, 1 and 2 as well) */ /* duplicate 0 onto 1 and 2 to prepare for stty */ fcntl(0,F_DUPFD,1); fcntl(0,F_DUPFD,2); } ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args); (void) exp_pty_unlock(); return(slave); } void exp_pty_exit() { /* a stub so we can do weird things on the cray */ } |
Added unix/pty_termios.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | /* pty_termios.c - routines to allocate ptys - termios version Written by: Don Libes, NIST, 2/6/90 This file is in the public domain. However, the author and NIST would appreciate credit if you use this file or parts of it. */ #include <stdio.h> #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #include "expect_cf.h" /* The following functions are linked from the Tcl library. They don't cause anything else in the library to be dragged in, so it shouldn't cause any problems (e.g., bloat). The functions are relatively small but painful enough that I don't care to recode them. You may, if you absolutely want to get rid of any vestiges of Tcl. */ extern char *TclGetRegError(); #if defined(HAVE_PTYM) && defined(HAVE_PTMX) /* * HP-UX 10.0 with streams (optional) have both PTMX and PTYM. I don't * know which is preferred but seeing as how the HP trap stuff is so * unusual, it is probably safer to stick with the native HP pty support, * too. */ #undef HAVE_PTMX #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include <sys/types.h> #include <sys/stat.h> #ifdef NO_STDLIB_H #include "../compat/stdlib.h" #else #include <stdlib.h> #endif #ifdef HAVE_SYSMACROS_H #include <sys/sysmacros.h> #endif #ifdef HAVE_PTYTRAP #include <sys/ptyio.h> #endif #include <sys/file.h> #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif #if defined(_SEQUENT_) # include <sys/strpty.h> #endif #ifdef HAVE_PTMX # include <sys/stropts.h> #endif #include "exp_win.h" #include "exp_tty.h" #include "exp_rename.h" #include "exp_pty.h" void debuglog(); #include <errno.h> /*extern char *sys_errlist[];*/ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* Convex getpty is different than older-style getpty */ /* Convex getpty is really just a cover function that does the traversal */ /* across the domain of pty names. It makes no attempt to verify that */ /* they can actually be used. Indded, the logic in the man page is */ /* wrong because it will allow you to allocate ptys that your own account */ /* already has in use. */ #if defined(HAVE_GETPTY) && defined(CONVEX) #undef HAVE_GETPTY #define HAVE_CONVEX_GETPTY extern char *getpty(); static char *master_name; static char slave_name[] = "/dev/ptyXX"; static char *tty_bank; /* ptr to char [p-z] denoting which bank it is */ static char *tty_num; /* ptr to char [0-f] denoting which number it is */ #endif #if defined(_SEQUENT_) static char *master_name, *slave_name; #endif /* _SEQUENT */ /* very old SGIs prefer _getpty over ptc */ #if defined(HAVE__GETPTY) && defined(HAVE_PTC) && !defined(HAVE_GETPTY) #undef HAVE_PTC #endif #if defined(HAVE_PTC) static char slave_name[] = "/dev/ttyqXXX"; /* some machines (e.g., SVR4.0 StarServer) have all of these and */ /* HAVE_PTC works best */ #undef HAVE_GETPTY #undef HAVE__GETPTY #endif #if defined(HAVE__GETPTY) || defined(HAVE_PTC_PTS) || defined(HAVE_PTMX) static char *slave_name; #endif #if defined(HAVE_GETPTY) #include <sys/vty.h> static char master_name[MAXPTYNAMELEN]; static char slave_name[MAXPTYNAMELEN]; #endif #if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY) #ifdef HAVE_PTYM /* strange order and missing d is intentional */ static char banks[] = "pqrstuvwxyzabcefghijklo"; static char master_name[] = "/dev/ptym/ptyXXXX"; static char slave_name[] = "/dev/pty/ttyXXXX"; static char *slave_bank; static char *slave_num; #else static char banks[] = "pqrstuvwxyzPQRSTUVWXYZ"; static char master_name[] = "/dev/ptyXX"; static char slave_name [] = "/dev/ttyXX"; #endif /* HAVE_PTYM */ static char *tty_type; /* ptr to char [pt] denoting whether it is a pty or tty */ static char *tty_bank; /* ptr to char [p-z] denoting which bank it is */ static char *tty_num; /* ptr to char [0-f] denoting which number it is */ #endif #if defined(HAVE_SCO_CLIST_PTYS) # define MAXPTYNAMELEN 64 static char master_name[MAXPTYNAMELEN]; static char slave_name[MAXPTYNAMELEN]; #endif /* HAVE_SCO_CLIST_PTYS */ #ifdef HAVE_OPENPTY static char master_name[64]; static char slave_name[64]; #endif char *exp_pty_slave_name; char *exp_pty_error; #if 0 static void pty_stty(s,name) char *s; /* args to stty */ char *name; /* name of pty */ { #define MAX_ARGLIST 10240 char buf[MAX_ARGLIST]; /* overkill is easier */ RETSIGTYPE (*old)(); /* save old sigalarm handler */ int pid; old = signal(SIGCHLD, SIG_DFL); switch (pid = fork()) { case 0: /* child */ exec_stty("/bin/stty","/bin/stty",s); break; case -1: /* fail */ default: /* parent */ waitpid(pid); break; } signal(SIGCHLD, old); /* restore signal handler */ } exec_stty(s) char *s; { char *args[50]; char *cp; int argi = 0; int quoting = FALSE; int in_token = FALSE; /* TRUE if we are reading a token */ args[0] = cp = s; while (*s) { if (quoting) { if (*s == '\\' && *(s+1) == '"') { /* quoted quote */ s++; /* get past " */ *cp++ = *s++; } else if (*s == '\"') { /* close quote */ end_token quoting = FALSE; } else *cp++ = *s++; /* suck up anything */ } else if (*s == '\"') { /* open quote */ in_token = TRUE; quoting = TRUE; s++; } else if (isspace(*s)) { end_token } else { *cp++ = *s++; in_token = TRUE; } } end_token args[argi] = (char *) 0; /* terminate argv */ execvp(args[0],args); } #endif /*0*/ static void pty_stty(s,name) char *s; /* args to stty */ char *name; /* name of pty */ { #define MAX_ARGLIST 10240 char buf[MAX_ARGLIST]; /* overkill is easier */ RETSIGTYPE (*old)(); /* save old sigalarm handler */ #ifdef STTY_READS_STDOUT sprintf(buf,"/bin/stty %s > %s",s,name); #else sprintf(buf,"/bin/stty %s < %s",s,name); #endif old = signal(SIGCHLD, SIG_DFL); system(buf); signal(SIGCHLD, old); /* restore signal handler */ } int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */ static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */ exp_tty exp_tty_original; #define GET_TTYTYPE 0 #define SET_TTYTYPE 1 static void ttytype(request,fd,ttycopy,ttyinit,s) int request; int fd; /* following are used only if request == SET_TTYTYPE */ int ttycopy; /* true/false, copy from /dev/tty */ int ttyinit; /* if true, initialize to sane state */ char *s; /* stty args */ { if (request == GET_TTYTYPE) { #ifdef HAVE_TCSETATTR if (-1 == tcgetattr(fd, &exp_tty_original)) { #else if (-1 == ioctl(fd, TCGETS, (char *)&exp_tty_original)) { #endif knew_dev_tty = FALSE; exp_dev_tty = -1; } exp_window_size_get(fd); } else { /* type == SET_TTYTYPE */ if (ttycopy && knew_dev_tty) { #ifdef HAVE_TCSETATTR (void) tcsetattr(fd, TCSADRAIN, &exp_tty_current); #else (void) ioctl(fd, TCSETS, (char *)&exp_tty_current); #endif exp_window_size_set(fd); } #ifdef __CENTERLINE__ #undef DFLT_STTY #define DFLT_STTY "sane" #endif /* Apollo Domain doesn't need this */ #ifdef DFLT_STTY if (ttyinit) { /* overlay parms originally supplied by Makefile */ /* As long as BSD stty insists on stdout == stderr, we can no longer write */ /* diagnostics to parent stderr, since stderr has is now child's */ /* Maybe someday they will fix stty? */ /* exp_debuglog("getptyslave: (default) stty %s\n",DFLT_STTY);*/ pty_stty(DFLT_STTY,slave_name); } #endif /* lastly, give user chance to override any terminal parms */ if (s) { /* give user a chance to override any terminal parms */ /* exp_debuglog("getptyslave: (user-requested) stty %s\n",s);*/ pty_stty(s,slave_name); } } } void exp_init_pty() { #if !defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) && !defined(HAVE_PTC) && !defined(HAVE_PTC_PTS) && !defined(HAVE_PTMX) && !defined(HAVE_CONVEX_GETPTY) && !defined(_SEQUENT_) && !defined(HAVE_SCO_CLIST_PTYS) && !defined(HAVE_OPENPTY) #ifdef HAVE_PTYM static char dummy; tty_bank = &master_name[strlen("/dev/ptym/pty")]; tty_num = &master_name[strlen("/dev/ptym/ptyX")]; slave_bank = &slave_name[strlen("/dev/pty/tty")]; slave_num = &slave_name[strlen("/dev/pty/ttyX")]; #else tty_bank = &master_name[strlen("/dev/pty")]; tty_num = &master_name[strlen("/dev/ptyp")]; tty_type = &slave_name[strlen("/dev/")]; #endif #endif /* HAVE_PTYM */ exp_dev_tty = open("/dev/tty",O_RDWR); knew_dev_tty = (exp_dev_tty != -1); if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0); } #ifndef R_OK /* 3b2 doesn't define these according to [email protected]. */ #define R_OK 04 #define W_OK 02 #endif int getptymaster() { char *hex, *bank; struct stat stat_buf; int master = -1; int slave = -1; int num; exp_pty_error = 0; #define TEST_PTY 1 #if defined(HAVE_PTMX) || defined(HAVE_PTMX_BSD) #undef TEST_PTY #if defined(HAVE_PTMX_BSD) if ((master = open("/dev/ptmx_bsd", O_RDWR)) == -1) return(-1); #else if ((master = open("/dev/ptmx", O_RDWR)) == -1) return(-1); #endif if ((slave_name = (char *)ptsname(master)) == NULL || unlockpt(master) || grantpt(master)) { close(master); return(-1); } #ifdef TIOCFLUSH (void) ioctl(master,TIOCFLUSH,(char *)0); #endif /* TIOCFLUSH */ exp_pty_slave_name = slave_name; return(master); #endif #if defined(HAVE__GETPTY) /* SGI needs it this way */ #undef TEST_PTY slave_name = _getpty(&master, O_RDWR, 0600, 0); if (slave_name == NULL) return (-1); exp_pty_slave_name = slave_name; return(master); #endif #if defined(HAVE_PTC) && !defined(HAVE__GETPTY) /* old SGI, version 3 */ #undef TEST_PTY master = open("/dev/ptc", O_RDWR); if (master >= 0) { int ptynum; if (fstat(master, &stat_buf) < 0) { close(master); return(-1); } ptynum = minor(stat_buf.st_rdev); sprintf(slave_name,"/dev/ttyq%d",ptynum); } exp_pty_slave_name = slave_name; return(master); #endif #if defined(HAVE_GETPTY) && !defined(HAVE__GETPTY) #undef TEST_PTY master = getpty(master_name, slave_name, O_RDWR); /* is it really necessary to verify slave side is usable? */ exp_pty_slave_name = slave_name; return master; #endif #if defined(HAVE_PTC_PTS) #undef TEST_PTY master = open("/dev/ptc",O_RDWR); if (master >= 0) { /* never fails */ slave_name = ttyname(master); } exp_pty_slave_name = slave_name; return(master); #endif #if defined(_SEQUENT_) #undef TEST_PTY /* old-style SEQUENT, new-style uses ptmx */ master = getpseudotty(&slave_name, &master_name); exp_pty_slave_name = slave_name; return(master); #endif /* _SEQUENT_ */ #if defined(HAVE_OPENPTY) #undef TEST_PTY if (openpty(&master, &slave, master_name, 0, 0) != 0) { close(master); close(slave); return -1; } strcpy(slave_name, ttyname(slave)); exp_pty_slave_name = slave_name; close(slave); return master; #endif /* HAVE_OPENPTY */ #if defined(TEST_PTY) /* * all pty allocation mechanisms after this require testing */ if (exp_pty_test_start() == -1) return -1; #if !defined(HAVE_CONVEX_GETPTY) && !defined(HAVE_PTYM) && !defined(HAVE_SCO_CLIST_PTYS) for (bank = banks;*bank;bank++) { *tty_bank = *bank; *tty_num = '0'; if (stat(master_name, &stat_buf) < 0) break; for (hex = "0123456789abcdef";*hex;hex++) { *tty_num = *hex; strcpy(slave_name,master_name); *tty_type = 't'; master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num); if (master >= 0) goto done; } } #endif #ifdef HAVE_SCO_CLIST_PTYS for (num = 0; ; num++) { char num_str [16]; sprintf (num_str, "%d", num); sprintf (master_name, "%s%s", "/dev/ptyp", num_str); if (stat (master_name, &stat_buf) < 0) break; sprintf (slave_name, "%s%s", "/dev/ttyp", num_str); master = exp_pty_test (master_name, slave_name, 0, num_str); if (master >= 0) goto done; } #endif #ifdef HAVE_PTYM /* systems with PTYM follow this idea: /dev/ptym/pty[a-ce-z][0-9a-f] master pseudo terminals /dev/pty/tty[a-ce-z][0-9a-f] slave pseudo terminals /dev/ptym/pty[a-ce-z][0-9][0-9] master pseudo terminals /dev/pty/tty[a-ce-z][0-9][0-9] slave pseudo terminals SPPUX (Convex's HPUX compatible) follows the PTYM convention but extends it: /dev/ptym/pty[a-ce-z][0-9][0-9][0-9] master pseudo terminals /dev/pty/tty[a-ce-z][0-9][0-9][0-9] slave pseudo terminals The code does not distinguish between HPUX and SPPUX because there is no reason to. HPUX will merely fail the extended SPPUX tests. In fact, most SPPUX systems will fail simply because few systems will actually have the extended ptys. However, the tests are fast so it is no big deal. */ /* * pty[a-ce-z][0-9a-f] */ for (bank = banks;*bank;bank++) { *tty_bank = *bank; sprintf(tty_num,"0"); if (stat(master_name, &stat_buf) < 0) break; *(slave_num+1) = '\0'; for (hex = "0123456789abcdef";*hex;hex++) { *tty_num = *hex; *slave_bank = *tty_bank; *slave_num = *tty_num; master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num); if (master >= 0) goto done; } } /* * tty[p-za-ce-o][0-9][0-9] */ for (bank = banks;*bank;bank++) { *tty_bank = *bank; sprintf(tty_num,"00"); if (stat(master_name, &stat_buf) < 0) break; for (num = 0; num<100; num++) { *slave_bank = *tty_bank; sprintf(tty_num,"%02d",num); strcpy(slave_num,tty_num); master = exp_pty_test(master_name,slave_name,tty_bank,tty_num); if (master >= 0) goto done; } } /* * tty[p-za-ce-o][0-9][0-9][0-9] */ for (bank = banks;*bank;bank++) { *tty_bank = *bank; sprintf(tty_num,"000"); if (stat(master_name, &stat_buf) < 0) break; for (num = 0; num<1000; num++) { *slave_bank = *tty_bank; sprintf(tty_num,"%03d",num); strcpy(slave_num,tty_num); master = exp_pty_test(master_name,slave_name,tty_bank,tty_num); if (master >= 0) goto done; } } #endif /* HAVE_PTYM */ #if defined(HAVE_CONVEX_GETPTY) for (;;) { if ((master_name = getpty()) == NULL) return -1; strcpy(slave_name,master_name); slave_name[5] = 't';/* /dev/ptyXY ==> /dev/ttyXY */ tty_bank = &slave_name[8]; tty_num = &slave_name[9]; master = exp_pty_test(master_name,slave_name,*tty_bank,tty_num); if (master >= 0) goto done; } #endif done: exp_pty_test_end(); exp_pty_slave_name = slave_name; return(master); #endif /* defined(TEST_PTY) */ } /* if slave is opened in a child, slave_control(1) must be executed after */ /* master is opened (when child is opened is irrelevent) */ /* if slave is opened in same proc as master, slave_control(1) must executed */ /* after slave is opened */ /*ARGSUSED*/ void exp_slave_control(master,control) int master; int control; /* if 1, enable pty trapping of close/open/ioctl */ { #ifdef HAVE_PTYTRAP ioctl(master, TIOCTRAP, &control); #endif /* HAVE_PTYTRAP */ } int getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave, slave2; char buf[10240]; if (0 > (slave = open(slave_name, O_RDWR))) return(-1); #if defined(HAVE_PTMX_BSD) if (ioctl (slave, I_LOOK, buf) != 0) if (ioctl (slave, I_PUSH, "ldterm")) { exp_debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno)); } #else #if defined(HAVE_PTMX) if (ioctl(slave, I_PUSH, "ptem")) { exp_debuglog("ioctl(%s,I_PUSH,\"ptem\") = %s\n",Tcl_ErrnoMsg(errno)); } if (ioctl(slave, I_PUSH, "ldterm")) { exp_debuglog("ioctl(%s,I_PUSH,\"ldterm\") = %s\n",Tcl_ErrnoMsg(errno)); } if (ioctl(slave, I_PUSH, "ttcompat")) { exp_debuglog("ioctl(%s,I_PUSH,\"ttcompat\") = %s\n",Tcl_ErrnoMsg(errno)); } #endif #endif if (0 == slave) { /* if opened in a new process, slave will be 0 (and */ /* ultimately, 1 and 2 as well) */ /* duplicate 0 onto 1 and 2 to prepare for stty */ fcntl(0,F_DUPFD,1); fcntl(0,F_DUPFD,2); } ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args); #if 0 #ifdef HAVE_PTYTRAP /* do another open, to tell master that slave is done fiddling */ /* with pty and master does not have to wait to do further acks */ if (0 > (slave2 = open(slave_name, O_RDWR))) return(-1); close(slave2); #endif /* HAVE_PTYTRAP */ #endif (void) exp_pty_unlock(); return(slave); } #ifdef HAVE_PTYTRAP #include <sys/ptyio.h> #include <sys/time.h> /* This function attempts to deal with HP's pty interface. This function simply returns an indication of what was trapped (or -1 for failure), the parent deals with the details. Originally, I tried to just trap open's but that is not enough. When the pty is initialized, ioctl's are generated and if not trapped will hang the child if no further trapping is done. (This could occur if parent spawns a process and then immediatley does a close.) So instead, the parent must trap the ioctl's. It probably suffices to trap the write ioctl's (and tiocsctty which some hp's need) - conceivably, stty could be smart enough not to do write's if the tty settings are already correct. In that case, we'll have to rethink this. Suggestions from HP engineers encouraged. I cannot imagine how this interface was intended to be used! */ int exp_wait_for_slave_open(fd) int fd; { fd_set excep; struct timeval t; struct request_info ioctl_info; int rc; int found = 0; int maxfds = sysconf(_SC_OPEN_MAX); t.tv_sec = 30; /* 30 seconds */ t.tv_usec = 0; FD_ZERO(&excep); FD_SET(fd,&excep); rc = select(maxfds, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)0, (SELECT_MASK_TYPE *)&excep, &t); if (rc != 1) { exp_debuglog("spawned process never started, errno = %d\n",errno); return(-1); } if (ioctl(fd,TIOCREQCHECK,&ioctl_info) < 0) { exp_debuglog("ioctl(TIOCREQCHECK) failed, errno = %d\n",errno); return(-1); } found = ioctl_info.request; exp_debuglog("trapped pty op = %x",found); if (found == TIOCOPEN) { exp_debuglog(" TIOCOPEN"); } else if (found == TIOCCLOSE) { exp_debuglog(" TIOCCLOSE"); } #ifdef TIOCSCTTY if (found == TIOCSCTTY) { exp_debuglog(" TIOCSCTTY"); } #endif if (found & IOC_IN) { exp_debuglog(" IOC_IN (set)"); } else if (found & IOC_OUT) { exp_debuglog(" IOC_OUT (get)"); } exp_debuglog("\n"); if (ioctl(fd, TIOCREQSET, &ioctl_info) < 0) { exp_debuglog("ioctl(TIOCREQSET) failed, errno = %d\n",errno); return(-1); } return(found); } #endif void exp_pty_exit() { /* a stub so we can do weird things on the cray */ } |
Added unix/pty_unicos.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | /* pty_unicos.c - routines to allocate ptys - for CRAY UNICOS 5.1 and 6.0 */ /* Original by: Don Libes, NIST, 2/6/90 Hacked for Unicos 5.1 by: Frank Terhaar-Yonkers, US EPA, 1/10/91 Hacked for Unicos 6.0 by: Pete TerMaat, [email protected], 3/27/91 Design and implementation of this program was paid for by U.S. tax dollars. Therefore it is public domain. However, the author and NIST would appreciate credit if this program or parts of it are used. */ #include "expect_cf.h" #include <stdio.h> #include <signal.h> #if defined(SIGCLD) && !defined(SIGCHLD) #define SIGCHLD SIGCLD #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #else extern int fork(), execl(), wait(); #endif #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/file.h> #ifdef HAVE_SYS_FCNTL_H # include <sys/fcntl.h> #else # include <fcntl.h> #endif /*#if CRAY>=60*/ #if defined(HAVE_TERMIOS) # include <sys/termios.h> #else # include <sys/termio.h> /*#endif /* 60 */*/ #endif /* defined(HAVE_TERMIOS) */ #if CRAY>=70 && defined(_CRAY2) #include <sys/session.h> #endif /* 70 */ #include <sys/pty.h> #include <pwd.h> #include <utmp.h> #include <signal.h> #include "exp_tty.h" #include "exp_rename.h" #ifdef HAVE_SYSCONF_H #include <sys/sysconfig.h> #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif /* MAXHOSTNAMELEN */ static char linep[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; static char linet[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; static int lowpty; static int highpty; static int realuid; static int realgid; static int *ptys; static char myname[32]; static char hostname[MAXHOSTNAMELEN]; char *exp_pty_slave_name; char *exp_pty_error; static void pty_stty(s,name) char *s; /* args to stty */ char *name; /* name of pty */ { #define MAX_ARGLIST 10240 char buf[MAX_ARGLIST]; /* overkill is easier */ RETSIGTYPE (*old)(); /* save old sigalarm handler */ #ifdef STTY_READS_STDOUT sprintf(buf,"/bin/stty %s > %s",s,name); #else sprintf(buf,"/bin/stty %s < %s",s,name); #endif old = signal(SIGCHLD, SIG_DFL); system(buf); signal(SIGCHLD, old); /* restore signal handler */ } int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */ static int knew_dev_tty;/* true if we had our hands on /dev/tty at any time */ #ifdef TIOCGWINSZ static struct winsize winsize = {0, 0}; #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) static struct ttysize winsize = {0, 0}; #endif /*struct termio exp_tty_original;*/ exp_tty exp_tty_original; #define GET_TTYTYPE 0 #define SET_TTYTYPE 1 static void ttytype(request,fd,ttycopy,ttyinit,s) int request; int fd; /* following are used only if request == SET_TTYTYPE */ int ttycopy; /* true/false, copy from /dev/tty */ int ttyinit; /* if true, initialize to sane state */ char *s; /* stty args, used only if request == SET_TTYTYPE */ { if (request == GET_TTYTYPE) { if (-1 == ioctl(fd, TCGETA, (char *)&exp_tty_original)) { knew_dev_tty = FALSE; exp_dev_tty = -1; } #ifdef TIOCGWINSZ ioctl(fd,TIOCGWINSZ,&winsize); #endif #if defined(TIOCGSIZE) && !defined(TIOCGWINSZ) ioctl(fd,TIOCGSIZE,&winsize); #endif } else { /* type == SET_TTYTYPE */ if (ttycopy && knew_dev_tty) { (void) ioctl(fd, TCSETA, (char *)&exp_tty_current); #ifdef TIOCSWINSZ ioctl(fd,TIOCSWINSZ,&winsize); #endif #if defined(TIOCSSIZE) && !defined(TIOCSWINSZ) ioctl(fd,TIOCGSIZE,&winsize); #endif } if (ttyinit) { /* overlay parms originally supplied by Makefile */ pty_stty(DFLT_STTY,linet); } /* lastly, give user chance to override any terminal parms */ if (s) { pty_stty(s,linet); } } } void exp_init_pty() { int npty; char *myline; lowpty=0; #ifdef _SC_CRAY_NPTY highpty=sysconf(_SC_CRAY_NPTY); #else highpty=128; #endif /* _SC_CRAY_NPTY */ ptys = (int *) malloc(sizeof(int)*(highpty+1)); if (ptys == NULL) { fprintf(stderr,"exp_init_pty: couldn't allocate pty array\n"); exit(1); } for (npty = lowpty;npty <= highpty;npty++) ptys[npty] = 0; realuid=getuid(); /* get REAL uid */ realgid=getgid(); /* get REAL uid */ exp_dev_tty = open("/dev/tty",O_RDWR); knew_dev_tty = (exp_dev_tty != -1); if (knew_dev_tty) ttytype(GET_TTYTYPE,exp_dev_tty,0,0,(char *)0); /* * Acquire (as root) current user name and host. */ (void) cuserid(myname); (void) gethostname(hostname,sizeof(hostname)); /* * Set the real and effective userids to root using 'setuid'. Then * set the real and effective userids to the actual user using * 'setreuid'. This allows using 'seteuid' to go back and forth from * root and the actual userid. Don't ask me why it works. */ setuid(0); setreuid(realuid,realuid); } /* returns fd of master end of pseudotty */ int getptymaster() { struct stat sb; int master; int npty; exp_pty_error = 0; exp_debuglog("getptymaster: lowpty=%d highpty=%d\n",lowpty,highpty); for (npty = lowpty; npty <= highpty; npty++) { if (seteuid(0) == -1) { /* we need to be root! */ exp_debuglog("getptymaster: seteuid root errno=%d\n", errno); } (void) sprintf(linep, "/dev/pty/%03d", npty); master = open(linep, O_RDWR); if (master < 0) { exp_debuglog("getptymaster: open linep=%s errno=%d\n", linep,errno); continue; } (void) sprintf(linet, "/dev/ttyp%03d", npty); if(stat(linet, &sb) < 0) { exp_debuglog("getptymaster: stat linet=%s errno=%d\n", linet,errno); (void) close(master); continue; } if (sb.st_uid || sb.st_gid || sb.st_mode != 0600) { if (chown(linet, realuid, realgid) == -1) { exp_debuglog("getptymaster: chown linet=%s errno=%d\n", linet,errno); } if (chmod(linet, 0600) == -1) { exp_debuglog("getptymaster: chmod linet=%s errno=%d\n", linet,errno); } (void)close(master); master = open(linep, 2); if (master < 0) { exp_debuglog("getptymaster: reopen linep=%s errno=%d\n", linep,errno); continue; } } if (seteuid(realuid) == -1) { /* back to who we are! */ exp_debuglog("getptymaster: seteuid user errno=%d\n", errno); } if (access(linet, R_OK|W_OK) != 0) { exp_debuglog("getptymaster: access linet=%s errno=%d\n", linet,errno); (void) close(master); continue; } exp_debuglog("getptymaster: allocated %s\n",linet); ptys[npty] = -1; exp_pty_slave_name = linet; return(master); } if (seteuid(realuid) == -1) { /* back to who we are! */ exp_debuglog("getptymaster: seteuid user errno=%d\n",errno); } return(-1); } /* see comment in pty_termios.c */ /*ARGSUSED*/ void exp_slave_control(master,control) int master; int control; { } int getptyslave(ttycopy,ttyinit,stty_args) int ttycopy; int ttyinit; char *stty_args; { int slave; if (0 > (slave = open(linet, O_RDWR))) { exp_debuglog("getptyslave: open linet=%s errno=%d\n",linet,errno); return(-1); } /* sanity check - if slave not 0, skip rest of this and return */ /* to what will later be detected as an error in caller */ if (0 != slave) { exp_debuglog("getptyslave: slave fd not 0\n"); return(slave); } if (0 == slave) { /* if opened in a new process, slave will be 0 (and */ /* ultimately, 1 and 2 as well) */ /* duplicate 0 onto 1 and 2 to prepare for stty */ fcntl(0,F_DUPFD,1); fcntl(0,F_DUPFD,2); } ttytype(SET_TTYTYPE,slave,ttycopy,ttyinit,stty_args); return(slave); } setptyutmp() { struct utmp utmp; if (seteuid(0) == -1) { /* Need to be root */ exp_debuglog("setptyutmp: setuid root errno=%d\n",errno); return(-1); } (void) time(&utmp.ut_time); utmp.ut_type = USER_PROCESS; utmp.ut_pid = getpid(); strncpy(utmp.ut_user,myname,sizeof(utmp.ut_user)); strncpy(utmp.ut_host,hostname,sizeof(utmp.ut_host)); strncpy(utmp.ut_line,linet+5,sizeof(utmp.ut_line)); strncpy(utmp.ut_id,linet+8,sizeof(utmp.ut_id)); if (pututline(&utmp) == NULL) { exp_debuglog("setptyutmp: pututline failed\n"); } endutent(); if (seteuid(realuid) == -1) exp_debuglog("setptyutmp: seteuid user errno=%d\n",errno); return(0); } setptypid(pid) int pid; { int npty; for (npty = lowpty; npty <= highpty; npty++) { if (ptys[npty] < 0) { exp_debuglog("setptypid: ttyp%03d pid=%d\n",npty,pid); ptys[npty] = pid; break; } } } ttyp_reset() { int npty; if (seteuid(0) == -1) { /* we need to be root! */ exp_debuglog("ttyp_reset: seteuid root errno=%d\n",errno); } for (npty = lowpty; npty <= highpty; npty++) { if (ptys[npty] <= 0) continue; (void) sprintf(linet, "/dev/ttyp%03d", npty); exp_debuglog("ttyp_reset: resetting %s, killing %d\n", linet,ptys[npty]); if (chown(linet,0,0) == -1) { exp_debuglog("ttyp_reset: chown %s errno=%d\n",linet,errno); } if (chmod(linet, 0666) == -1) { exp_debuglog("ttyp_reset: chmod %s errno=%d\n",linet,errno); } resetptyutmp(); if (kill(ptys[npty],SIGKILL) == -1) { exp_debuglog("ttyp_reset: kill pid=%d errno=%d\n", ptys[npty],errno); } } if (seteuid(realuid) == -1) { /* Back to who we really are */ exp_debuglog("ttyp_reset: seteuid user errno=%d\n",errno); } } void exp_pty_exit() { ttyp_reset(); } resetptyutmp() { struct utmp utmp; (void) setutent (); /* set up entry to search for */ (void) strncpy(utmp.ut_id, linet + strlen(linet) - 4, sizeof (utmp.ut_id)); utmp.ut_type = USER_PROCESS; /* position to entry in utmp file */ if(getutid(&utmp) == NULL) { exp_debuglog("resetptyutmp: no utmp entry for %s\n",linet); return(-1); /* no utmp entry for this line ??? */ } /* set up the new entry */ strncpy(utmp.ut_name,"",sizeof(utmp.ut_name)); strncpy(utmp.ut_host,"",sizeof(utmp.ut_host)); time(&utmp.ut_time); utmp.ut_type = DEAD_PROCESS; utmp.ut_exit.e_exit = 0; /* write out the entry */ pututline(&utmp); /* close the file */ (void) endutent(); return(0); } |
Added unix/vgrindefs.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # vgrindefs for Expect # Author: Brian Fitzgerald <[email protected]> # Department of Mechanical Engineering # Rensselaer Polytechnic Institute # Date: Sat, 12 Oct 91 13:41:36 EDT # # To install this file, append it to /usr/lib/vgrindefs # # vgrind is a troff pretty-printer. For example, to use it on a Sun with the # Adobe Transcript package, install this file and do: # # setenv TROFF ptroff # vgrind -lexpect file # expect|tcl:\ :pb=(^|;)\d?proc\d\p\d:\ :id=!$%&'()*+,-./\:<=>?@^_`|}~:\ :bb={:be=}:\ :cb=#:ce=$:\ :sb=":se=\e":\ :kw=debug disconnect exit\ expect expect_user expect_before expect_after expect_version\ fork\ interact log_file log_user overlay\ send send_spawn send_user send_log send_error\ spawn system trace trap wait\ break case catch concat continue error eval exec expr file for foreach\ format glob global history if then else index info length list print\ proc range rename return scan set source string time uplevel upvar: |
Added win/.gitignore.
> > > > > > > | 1 2 3 4 5 6 7 | *.ncb *.opt *.plg Debug DebugU Release ReleaseU |
Added win/Dbg_cf.h.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* This file is only to be included by the Debugger itself. */ /* Applications should only include Dbg.h. */ /* * Check for headers */ #ifndef __NIST_DBG_CF_H__ #define __NIST_DBG_CF_H__ #undef NO_STDLIB_H /* Tcl requires this name */ /* * Check for functions */ #define HAVE_STRCHR #endif /* __NIST_DBG_CF_H__ */ |
Added win/Mcl/.gitignore.
> > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 | ReleaseA ReleaseAS ReleaseU DebugA DebugAS DebugU .#* Mcl.plg Mcl.opt Mcl.ncb lib |
Added win/Mcl/ChangeLog.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | 2001-11-18 David Gravereaux <[email protected]> * src/CMclMailbox.cpp: 2001-11-07 eratta change. See http://www.bearcanyon.com/mtbook/errata.htm#source 2000-09-16 davidg * include/CMclLinkedLists.h: Put back the protected access to CMclLinkedList for both CMclStack and CMclQueue templates as I would like to offer the internals to derived classes * .cvsignore: * CMcl.h: * CMclAutoLock.cpp: * CMclAutoLock.h: * CMclAutoPtr.cpp: * CMclAutoPtr.h: * CMclCritSec.cpp: * CMclCritSec.h: * CMclEvent.cpp: * CMclEvent.h: * CMclGlobal.cpp: * CMclGlobal.h: * CMclKernel.cpp: * CMclKernel.h: * CMclLinkedLists.h: * CMclMailbox.cpp: * CMclMailbox.h: * CMclMonitor.cpp: * CMclMonitor.h: * CMclMutex.cpp: * CMclMutex.h: * CMclSemaphore.cpp: * CMclSemaphore.h: * CMclSharedMemory.cpp: * CMclSharedMemory.h: * CMclThread.cpp: * CMclThread.h: * CMclWaitableCollection.cpp: * CMclWaitableCollection.h: * CMclWaitableObject.h: * Mcl.dsp: * Mcl.dsw: * include/CMcl.h: * include/CMclAutoLock.h: * include/CMclAutoPtr.h: * include/CMclCritSec.h: * include/CMclEvent.h: * include/CMclGlobal.h: * include/CMclKernel.h: * include/CMclLinkedLists.h: * include/CMclMailbox.h: * include/CMclMonitor.h: * include/CMclMutex.h: * include/CMclSemaphore.h: * include/CMclSharedMemory.h: * include/CMclThread.h: * include/CMclWaitableCollection.h: * include/CMclWaitableObject.h: * src/CMclAutoLock.cpp: * src/CMclAutoPtr.cpp: * src/CMclCritSec.cpp: * src/CMclEvent.cpp: * src/CMclGlobal.cpp: * src/CMclKernel.cpp: * src/CMclMailbox.cpp: * src/CMclMonitor.cpp: * src/CMclMutex.cpp: * src/CMclSemaphore.cpp: * src/CMclSharedMemory.cpp: * src/CMclThread.cpp: * src/CMclWaitableCollection.cpp: moving around sources * lib/Mcl.lib: * lib/mcld.lib: * lib/mclu.lib: * lib/mclud.lib: distributing binaries * readme.txt: added a readme * Mcl.dsp: added some missing commandline options 2000-08-06 davidg * .cvsignore: * Mcl.dsp: gotcha... irc_engine now compiles.. next it gets converted to using Tcl Tcp channels for sockets. 2000-04-19 davygrvy * .cvsignore: no message 2000-02-02 davygrvy * CMcl.h: * CMclAutoLock.cpp: * CMclAutoLock.h: * CMclAutoPtr.cpp: * CMclAutoPtr.h: * CMclCritSec.cpp: * CMclCritSec.h: * CMclEvent.cpp: * CMclEvent.h: * CMclGlobal.cpp: * CMclGlobal.h: * CMclKernel.cpp: * CMclKernel.h: * CMclLinkedLists.h: * CMclMailbox.cpp: * CMclMailbox.h: * CMclMonitor.cpp: * CMclMonitor.h: * CMclMutex.cpp: * CMclMutex.h: * CMclSemaphore.cpp: * CMclSemaphore.h: * CMclSharedMemory.cpp: * CMclSharedMemory.h: * CMclThread.cpp: * CMclThread.h: * CMclWaitableCollection.cpp: * CMclWaitableCollection.h: * CMclWaitableObject.h: * Mcl.dsp: initial import * CMcl.h: * CMclAutoLock.cpp: * CMclAutoLock.h: * CMclAutoPtr.cpp: * CMclAutoPtr.h: * CMclCritSec.cpp: * CMclCritSec.h: * CMclEvent.cpp: * CMclEvent.h: * CMclGlobal.cpp: * CMclGlobal.h: * CMclKernel.cpp: * CMclKernel.h: * CMclLinkedLists.h: * CMclMailbox.cpp: * CMclMailbox.h: * CMclMonitor.cpp: * CMclMonitor.h: * CMclMutex.cpp: * CMclMutex.h: * CMclSemaphore.cpp: * CMclSemaphore.h: * CMclSharedMemory.cpp: * CMclSharedMemory.h: * CMclThread.cpp: * CMclThread.h: * CMclWaitableCollection.cpp: * CMclWaitableCollection.h: * CMclWaitableObject.h: * Mcl.dsp: Initial revision |
Added win/Mcl/Mcl.dsp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | # Microsoft Developer Studio Project File - Name="Mcl" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=Mcl - Win32 Debug Static !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "Mcl.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "Mcl.mak" CFG="Mcl - Win32 Debug Static" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "Mcl - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "Mcl - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE "Mcl - Win32 Debug Unicode" (based on "Win32 (x86) Static Library") !MESSAGE "Mcl - Win32 Release Unicode" (based on "Win32 (x86) Static Library") !MESSAGE "Mcl - Win32 Release Static" (based on "Win32 (x86) Static Library") !MESSAGE "Mcl - Win32 Debug Static" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "Mcl - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir ".\lib" # PROP BASE Intermediate_Dir ".\ReleaseA" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\ReleaseA" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo/out:".\lib\mcl.lib" # ADD LIB32 /nologo !ELSEIF "$(CFG)" == "Mcl - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir ".\lib" # PROP BASE Intermediate_Dir ".\DebugA" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\DebugA" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:".\lib\mcld.lib" # ADD LIB32 /nologo /out:".\lib\mcld.lib" !ELSEIF "$(CFG)" == "Mcl - Win32 Debug Unicode" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir ".\lib" # PROP BASE Intermediate_Dir ".\DebugU" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\DebugU" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c # ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:".\lib\mclud.lib" # ADD LIB32 /nologo /out:".\lib\mclud.lib" !ELSEIF "$(CFG)" == "Mcl - Win32 Release Unicode" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir ".\lib" # PROP BASE Intermediate_Dir ".\ReleaseU" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\ReleaseU" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_UNICODE" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:".\lib\mclu.lib" # ADD LIB32 /nologo /out:".\lib\mclu.lib" !ELSEIF "$(CFG)" == "Mcl - Win32 Release Static" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Mcl___Win32_Release_Static" # PROP BASE Intermediate_Dir "Mcl___Win32_Release_Static" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\ReleaseAS" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /G5 /MT /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:".\lib\mcls.lib" !ELSEIF "$(CFG)" == "Mcl - Win32 Debug Static" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Mcl___Win32_Debug_Static" # PROP BASE Intermediate_Dir "Mcl___Win32_Debug_Static" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir ".\lib" # PROP Intermediate_Dir ".\DebugAS" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /G5 /MTd /W3 /GX /Z7 /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:".\lib\mcld.lib" # ADD LIB32 /nologo /out:".\lib\mclsd.lib" !ENDIF # Begin Target # Name "Mcl - Win32 Release" # Name "Mcl - Win32 Debug" # Name "Mcl - Win32 Debug Unicode" # Name "Mcl - Win32 Release Unicode" # Name "Mcl - Win32 Release Static" # Name "Mcl - Win32 Debug Static" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" # Begin Source File SOURCE=.\src\CMclAutoLock.cpp # End Source File # Begin Source File SOURCE=.\src\CMclAutoPtr.cpp # End Source File # Begin Source File SOURCE=.\src\CMclCritSec.cpp # End Source File # Begin Source File SOURCE=.\src\CMclEvent.cpp # End Source File # Begin Source File SOURCE=.\src\CMclGlobal.cpp # End Source File # Begin Source File SOURCE=.\src\CMclKernel.cpp # End Source File # Begin Source File SOURCE=.\src\CMclMailbox.cpp # End Source File # Begin Source File SOURCE=.\src\CMclMonitor.cpp # End Source File # Begin Source File SOURCE=.\src\CMclMutex.cpp # End Source File # Begin Source File SOURCE=.\src\CMclSemaphore.cpp # End Source File # Begin Source File SOURCE=.\src\CMclSharedMemory.cpp # End Source File # Begin Source File SOURCE=.\src\CMclThread.cpp # End Source File # Begin Source File SOURCE=.\src\CMclWaitableCollection.cpp # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" # Begin Source File SOURCE=.\include\CMcl.h # End Source File # Begin Source File SOURCE=.\include\CMclAutoLock.h # End Source File # Begin Source File SOURCE=.\include\CMclAutoPtr.h # End Source File # Begin Source File SOURCE=.\include\CMclCritSec.h # End Source File # Begin Source File SOURCE=.\include\CMclEvent.h # End Source File # Begin Source File SOURCE=.\include\CMclGlobal.h # End Source File # Begin Source File SOURCE=.\include\CMclKernel.h # End Source File # Begin Source File SOURCE=.\include\CMclLinkedLists.h # End Source File # Begin Source File SOURCE=.\include\CMclMailbox.h # End Source File # Begin Source File SOURCE=.\include\CMclMonitor.h # End Source File # Begin Source File SOURCE=.\include\CMclMutex.h # End Source File # Begin Source File SOURCE=.\include\CMclSemaphore.h # End Source File # Begin Source File SOURCE=.\include\CMclSharedMemory.h # End Source File # Begin Source File SOURCE=.\include\CMclThread.h # End Source File # Begin Source File SOURCE=.\include\CMclWaitableCollection.h # End Source File # Begin Source File SOURCE=.\include\CMclWaitableObject.h # End Source File # End Group # End Target # End Project |
Added win/Mcl/Mcl.dsw.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "Mcl"=.\Mcl.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### |
Added win/Mcl/help/MCL.HLP.
cannot compute difference between binary files
Added win/Mcl/help/MCL4MFC.HLP.
cannot compute difference between binary files
Added win/Mcl/help/Mcl C++ Class Library.chm.
cannot compute difference between binary files
Added win/Mcl/help/Mcl4Mfc C++ Class Library.chm.
cannot compute difference between binary files
Added win/Mcl/help/mcl.CNT.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | :Base MCL.HLP :Title Mcl/Mcl4Mfc C++ Class Libraries Help :Index Mcl4Mfc C++ Class Library Reference=Mcl4mfc.hlp 1 Mcl C++ Class Library Reference 2 Introduction=Mcl_C___Class_Library_Reference 2 CMclAutoLock Class 3 CMclAutoLock Description=CMclAutoLock 3 CMclAutoLock::CMclAutoLock=CMclAutoLock__CMclAutoLock 3 CMclAutoLock::~CMclAutoLock=CMclAutoLock___CMclAutoLock 2 CMclCondition Class 3 CMclCondition Description=CMclCondition 3 CMclCondition::CMclCondition=CMclCondition__CMclCondition 3 CMclCondition::~CMclCondition=CMclCondition___CMclCondition 3 CMclCondition::Condition=CMclCondition__Condition 3 CMclCondition::SignalEvent=CMclCondition__SignalEvent 3 CMclCondition::WaitForEvent=CMclCondition__WaitForEvent 2 CMclCritSec Class 3 CMclCritSec Description=CMclCritSec 3 CMclCritSec::CMclCritSec=CMclCritSec__CMclCritSec 3 CMclCritSec::~CMclCritSec=CMclCritSec___CMclCritSec 3 CMclCritSec::Enter=CMclCritSec__Enter 3 CMclCritSec::Leave=CMclCritSec__Leave 2 CMclDerivedAutoPtr Class 3 CMclDerivedAutoPtr Description=CMclDerivedAutoPtr 3 CMclDerivedAutoPtr::CMclDerivedAutoPtr=CMclDerivedAutoPtr__CMclDerivedAutoPtr 3 CMclDerivedAutoPtr::operator *=RTF_TOPIC_872844507 3 CMclDerivedAutoPtr::operator ==CMclDerivedAutoPtr__operator__ 3 CMclDerivedAutoPtr::operator ->=CMclDerivedAutoPtr__operator___ 2 CMclEvent Class 3 CMclEvent Description=CMclEvent 3 CMclEvent::CMclEvent=CMclEvent__CMclEvent 3 CMclEvent::Pulse=CMclEvent__Pulse 3 CMclEvent::Reset=CMclEvent__Reset 3 CMclEvent::Set=CMclEvent__Set 2 CMclEventAutoPtr Class 3 CMclEventAutoPtr Description=CMclEventAutoPtr 2 CMclKernel Class 3 CMclKernel Description=CMclKernel 3 CMclKernel::~CMclKernel=CMclKernel___CMclKernel 3 CMclKernel::CMclKernel=CMclKernel__CMclKernel 3 CMclKernel::GetHandle=CMclKernel__GetHandle 3 CMclKernel::m_dwStatus=CMclKernel__m_dwStatus 3 CMclKernel::m_hHandle=CMclKernel__m_hHandle 3 CMclKernel::operator HANDLE=CMclKernel__operator_HANDLE 3 CMclKernel::Status=CMclKernel__Status 3 CMclKernel::ThrowError=CMclKernel__ThrowError 3 CMclKernel::Wait=CMclKernel__Wait 3 CMclKernel::WaitForTwo=CMclKernel__WaitForTwo 2 CMclKernelAutoPtr Class 3 CMclKernelAutoPtr Description=CMclKernelAutoPtr 3 CMclKernelAutoPtr::~CMclKernelAutoPtr=CMclKernelAutoPtr___CMclKernelAutoPtr 3 CMclKernelAutoPtr::CMclKernelAutoPtr=CMclKernelAutoPtr__CMclKernelAutoPtr 3 CMclKernelAutoPtr::GetHandle=CMclKernelAutoPtr__GetHandle 3 CMclKernelAutoPtr::IsNull=CMclKernelAutoPtr__IsNull 3 CMclKernelAutoPtr::m_pObjectPtr=CMclKernelAutoPtr__m_pObjectPtr 3 CMclKernelAutoPtr::operator *=CMclKernelAutoPtr__operator__ 3 CMclKernelAutoPtr::operator ->=CMclKernelAutoPtr__operator___ 3 CMclKernelAutoPtr::Reset=CMclKernelAutoPtr__Reset 3 CMclKernelAutoPtr::Status=CMclKernelAutoPtr__Status 2 CMclLinkedList Class 3 CMclLinkedList Description=CMclLinkedList 3 CMclLinkedList::~CMclLinkedList=CMclLinkedList___CMclLinkedList 3 CMclLinkedList::AddToFreeList=CMclLinkedList__AddToFreeList 3 CMclLinkedList::AllocateListNode=CMclLinkedList__AllocateListNode 3 CMclLinkedList::Cleanup=CMclLinkedList__Cleanup 3 CMclLinkedList::CMclLinkedList=CMclLinkedList__CMclLinkedList 3 CMclLinkedList::CMclLinkedListDataNode=CMclLinkedList__CMclLinkedListDataNode 3 CMclLinkedList::CMclLinkedListNode=CMclLinkedList__CMclLinkedListNode 3 CMclLinkedList::CMclLinkedListSentinelNode=CMclLinkedList__CMclLinkedListSentinelNode 3 CMclLinkedList::GetFromHeadOfList=CMclLinkedList__GetFromHeadOfList 3 CMclLinkedList::GetFromTailOfList=CMclLinkedList__GetFromTailOfList 3 CMclLinkedList::m_cCritSec=CMclLinkedList__m_cCritSec 3 CMclLinkedList::m_cNotEmpty=CMclLinkedList__m_cNotEmpty 3 CMclLinkedList::m_dwStatus=CMclLinkedList__m_dwStatus 3 CMclLinkedList::m_FreeNode=CMclLinkedList__m_FreeNode 3 CMclLinkedList::m_MasterNode=CMclLinkedList__m_MasterNode 3 CMclLinkedList::PutOnHeadOfList=CMclLinkedList__PutOnHeadOfList 3 CMclLinkedList::PutOnTailOfList=CMclLinkedList__PutOnTailOfList 3 CMclLinkedList::Status=CMclLinkedList__Status 2 CMclLinkedListDataNode Class 3 CMclLinkedListDataNode::CMclLinkedListDataNode=CMclLinkedListDataNode__CMclLinkedListDataNode 3 CMclLinkedListDataNode::GetData=CMclLinkedListDataNode__GetData 3 CMclLinkedListDataNode::m_data=CMclLinkedListDataNode__m_data 3 CMclLinkedListDataNode::SetData=CMclLinkedListDataNode__SetData 3 CMclLinkedListNode::GetData=CMclLinkedListNode__GetData 3 CMclLinkedListNode::m_pNext=CMclLinkedListNode__m_pNext 3 CMclLinkedListNode::m_pPrev=CMclLinkedListNode__m_pPrev 3 CMclLinkedListNode::SetData=CMclLinkedListNode__SetData 2 CMclLinkedListSentinelNode Class 3 CMclLinkedListSentinelNode::GetData=CMclLinkedListSentinelNode__GetData 3 CMclLinkedListSentinelNode::SetData=CMclLinkedListSentinelNode__SetData 2 CMclMailbox Class 3 CMclMailbox Description=CMclMailbox 3 CMclMailbox::~CMclMailbox=CMclMailbox___CMclMailbox 3 CMclMailbox::CMclMailbox=CMclMailbox__CMclMailbox 3 CMclMailbox::Get=CMclMailbox__Get 3 CMclMailbox::GetAlertable=CMclMailbox__GetAlertable 3 CMclMailbox::GetProperties=CMclMailbox__GetProperties 3 CMclMailbox::IsCreator=CMclMailbox__IsCreator 3 CMclMailbox::Post=CMclMailbox__Post 3 CMclMailbox::PostAlertable=CMclMailbox__PostAlertable 3 CMclMailbox::Status=CMclMailbox__Status 2 CMclMonitor Class 3 CMclMonitor Description=CMclMonitor 3 CMclMonitor::~CMclMonitor=CMclMonitor___CMclMonitor 3 CMclMonitor::CMclMonitor=CMclMonitor__CMclMonitor 3 CMclMonitor::Enter=CMclMonitor__Enter 3 CMclMonitor::Leave=CMclMonitor__Leave 3 CMclMonitor::Status=CMclMonitor__Status 3 CMclMonitor::WaitForCondition=CMclMonitor__WaitForCondition 2 CMclMutex Class 3 CMclMutex Description=CMclMutex 3 CMclMutex::CMclMutex=CMclMutex__CMclMutex 3 CMclMutex::Release=CMclMutex__Release 3 CMclMutexAutoPtr=CMclMutexAutoPtr 2 CMclQueue Class 3 CMclQueue Description=CMclQueue 3 CMclQueue::Get=CMclQueue__Get 3 CMclQueue::Put=CMclQueue__Put 3 CMclQueue::Status=CMclQueue__Status 2 CMclSemaphore Class 3 CMclSemaphore Description=CMclSemaphore 3 CMclSemaphore::CMclSemaphore=CMclSemaphore__CMclSemaphore 3 CMclSemaphore::Release=CMclSemaphore__Release 2 CMclSemaphoreAutoPtr Class 3 CMclSemaphoreAutoPtr Description=CMclSemaphoreAutoPtr 2 CMclSharedMemory Class 3 CMclSharedMemory Description=CMclSharedMemory 3 CMclSharedMemory::~CMclSharedMemory=CMclSharedMemory___CMclSharedMemory 3 CMclSharedMemory::CMclSharedMemory=CMclSharedMemory__CMclSharedMemory 3 CMclSharedMemory::GetPtr=CMclSharedMemory__GetPtr 3 CMclSharedMemory::IsCreator=CMclSharedMemory__IsCreator 3 CMclSharedMemory::Status=CMclSharedMemory__Status 2 CMclStack Class 3 CMclStack Description=CMclStack 3 CMclStack::Pop=CMclStack__Pop 3 CMclStack::Push=CMclStack__Push 3 CMclStack::Status=CMclStack__Status 2 CMclThread Class 3 CMclThread Description=CMclThread 3 CMclThread::CMclThread=CMclThread__CMclThread 3 CMclThread::GetExitCode=CMclThread__GetExitCode 3 CMclThread::GetPriority=CMclThread__GetPriority 3 CMclThread::GetThreadId=CMclThread__GetThreadId 3 CMclThread::m_pcThreadHandler=CMclThread__m_pcThreadHandler 3 CMclThread::m_uiThreadID=CMclThread__m_uiThreadID 3 CMclThread::Resume=CMclThread__Resume 3 CMclThread::SetPriority=CMclThread__SetPriority 3 CMclThread::Suspend=CMclThread__Suspend 3 CMclThread::Terminate=CMclThread__Terminate 2 CMclThreadAutoPtr Class 3 CMclThreadAutoPtr Description=CMclThreadAutoPtr 2 CMclThreadHandler Class 3 CMclThreadHandler Description=CMclThreadHandler 3 CMclThreadHandler::~CMclThreadHandler=CMclThreadHandler___CMclThreadHandler 3 CMclThreadHandler::ThreadHandlerProc=CMclThreadHandler__ThreadHandlerProc 2 CMclWaitableCollection Class 3 CMclWaitableCollection=CMclWaitableCollection 3 CMclWaitableCollection::~CMclWaitableCollection=CMclWaitableCollection___CMclWaitableCollection 3 CMclWaitableCollection::AddCollection=CMclWaitableCollection__AddCollection 3 CMclWaitableCollection::AddObject=CMclWaitableCollection__AddObject 3 CMclWaitableCollection::CMclWaitableCollection=CMclWaitableCollection__CMclWaitableCollection 3 CMclWaitableCollection::GetCount=CMclWaitableCollection__GetCount 3 CMclWaitableCollection::operator ==CMclWaitableCollection__operator__ 3 CMclWaitableCollection::Wait=CMclWaitableCollection__Wait 2 CMclWaitableObject Class 3 CMclWaitableObject Description=CMclWaitableObject 3 CMclWaitableObject::GetHandle=CMclWaitableObject__GetHandle 3 CMclWaitableObject::Status=CMclWaitableObject__Status 2 Utility Functions 3 CMclIsValidHandle=CMclIsValidHandle 3 CMclThrowError=CMclThrowError 3 CMclWaitAbandoned=CMclWaitAbandoned 3 CMclWaitAbandonedIndex=CMclWaitAbandonedIndex 3 CMclWaitFailed=CMclWaitFailed 3 CMclWaitSucceeded=CMclWaitSucceeded 3 CMclWaitSucceededIndex=CMclWaitSucceededIndex 3 CMclWaitTimeout=CMclWaitTimeout :Include D:\books\win32threads\Help\mcl4mfc.CNT |
Added win/Mcl/help/mcl4mfc.CNT.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | :Base MCL4MFC.HLP :Title Mcl4Mfc C+ Class Library Reference 1 Mcl4Mfc C++ Class Library 2 [email protected] 2 CMcl4MfcGUIThread Class 3 CMcl4MfcGUIThread [email protected] 3 CMcl4MfcGUIThread:: CMcl4MfcGUIThread=CMcl4MfcGUIThread___CMcl4MfcGUIThread@Mcl4mfc.hlp 3 CMcl4MfcGUIThread::[email protected] 3 CMcl4MfcGUIThread::PostThreadMessage=CMcl4MfcGUIThread__PostThreadMessage@Mcl4mfc.hlp 3 CMcl4MfcGUIThread::[email protected] 3 CMcl4MfcGUIThread::[email protected] 2 CMcl4MfcGUIThreadAutoPtr Class 3 CMcl4MfcGUIThreadAutoPtr [email protected] 2 CMcl4MfcThread Class 3 CMcl4MfcThread [email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::PreTranslateMessage=CMcl4MfcThread__PreTranslateMessage@Mcl4mfc.hlp 3 CMcl4MfcThread::ProcessMessageFilter=CMcl4MfcThread__ProcessMessageFilter@Mcl4mfc.hlp 3 CMcl4MfcThread::ProcessWndProcException=CMcl4MfcThread__ProcessWndProcException@Mcl4mfc.hlp 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 3 CMcl4MfcThread::[email protected] 2 CMcl4MfcThreadAutoPtr Class 3 CMcl4MfcThreadAutoPtr [email protected] 2 CMcl4MfcWorkerThread Class 3 CMcl4MfcWorkerThread [email protected] 3 CMcl4MfcWorkerThread::CMcl4MfcWorkerThread=CMcl4MfcWorkerThread__CMcl4MfcWorkerThread@Mcl4mfc.hlp 3 CMcl4MfcWorkerThread::m_pcThreadHandler=CMcl4MfcWorkerThread__m_pcThreadHandler@Mcl4mfc.hlp 3 CMcl4MfcWorkerThread::[email protected] 3 CMcl4MfcWorkerThreadAutoPtr=CMcl4MfcWorkerThreadAutoPtr@Mcl4mfc.hlp 2 CMclWinThread Class 3 CMclWinThread [email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::MfcPreTranslateMessage=CMclWinThread__MfcPreTranslateMessage@Mcl4mfc.hlp 3 CMclWinThread::MfcProcessMessageFilter=CMclWinThread__MfcProcessMessageFilter@Mcl4mfc.hlp 3 CMclWinThread::MfcProcessWndProcException=CMclWinThread__MfcProcessWndProcException@Mcl4mfc.hlp 3 CMclWinThread::[email protected] 3 CMclWinThread::[email protected] 3 CMclWinThread::PreTranslateMessage=CMclWinThread__PreTranslateMessage@Mcl4mfc.hlp 3 CMclWinThread::ProcessMessageFilter=CMclWinThread__ProcessMessageFilter@Mcl4mfc.hlp 3 CMclWinThread::ProcessWndProcException=CMclWinThread__ProcessWndProcException@Mcl4mfc.hlp 3 CMclWinThread::[email protected] |
Added win/Mcl/include/CMcl.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // // FILE: CMcl.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCL_H__ #define __CMCL_H__ #include "CMclGlobal.h" #include "CMclKernel.h" #include "CMclMutex.h" #include "CMclSemaphore.h" #include "CMclEvent.h" #include "CMclThread.h" #include "CMclCritSec.h" #include "CMclAutoLock.h" #include "CMclAutoPtr.h" #include "CMclMonitor.h" #include "CMclSharedMemory.h" #include "CMclWaitableCollection.h" #include "CMclMailbox.h" #include "CMclLinkedLists.h" #endif |
Added win/Mcl/include/CMclAutoLock.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // // FILE: CMclAutoLock.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLAUTOLOCK_H__ #define __CMCLAUTOLOCK_H__ #include "CMclGlobal.h" #include "CMclMutex.h" #include "CMclCritSec.h" class CMclAutoLock { private: HANDLE m_hMutexHandle; CRITICAL_SECTION *m_pCritSec; CMclMutex *m_pcMutex; CMclCritSec *m_pcCritSec; public: // constructors... CMclAutoLock( HANDLE hMutexHandle); CMclAutoLock( CMclMutex & rCMclMutex); CMclAutoLock( CRITICAL_SECTION * pCritSec); CMclAutoLock( CMclCritSec & rCMclCritSec); // destructor... ~CMclAutoLock(void); }; #endif |
Added win/Mcl/include/CMclAutoPtr.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | // // FILE: CMclAutoPtr.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLAUTOPTR_H__ #define __CMCLAUTOPTR_H__ #include "CMclGlobal.h" #include "CMclWaitableObject.h" #include "CMclKernel.h" #include "CMclThread.h" #include "CMclMutex.h" #include "CMclSemaphore.h" #include "CMclEvent.h" class CMclKernelAutoPtr { protected: CMclKernel *m_pObjectPtr; public: // constructor... CMclKernelAutoPtr(CMclKernel *pObjectPtr = NULL); // destructor is pure virtual to make this class abstract... virtual ~CMclKernelAutoPtr() = 0; // dereferencing operator... CMclKernel * operator->() const; // indirection operator... CMclKernel & operator*() const; // get the handle of the internal object... HANDLE GetHandle(void) const; // read the current status of the internal object... DWORD Status(void) const; // test the internal pointer for NULL... BOOL IsNull(void) const; protected: // Reset member function performs pointer assignment // is protected so internal pointer cannot be of a different // type for derived classes... void Reset(CMclKernel *pObjectPtr); private: // these functions have no implementation since they can // never be called... // copying and passing by copy are not allowed... // this prevents confusion of internal object ownership... CMclKernelAutoPtr(CMclKernelAutoPtr & rhs); // assigning one auto pointer to another is not allowed, // this prevents confusion of internal object ownership... CMclKernelAutoPtr & operator= (CMclKernelAutoPtr & rhs); }; // all of our auto pointers are instances of this template class // which is derived from the CMclKernelAutoPtr abstract base class... template <class T> class CMclDerivedAutoPtr : public CMclKernelAutoPtr { public: // constructor... CMclDerivedAutoPtr(T *pObjectPtr = NULL) : CMclKernelAutoPtr(pObjectPtr) { }; // pointer assignment... CMclDerivedAutoPtr<T> & operator= (T *pObjectPtr) { Reset(pObjectPtr); return *this; }; // dereferencing operator... T * operator->() const { // we can safely return a casted pointer because // we know the pointer type was checked by the constructor // at compile time... return static_cast<T *>(m_pObjectPtr); }; // indirection operator... T & operator*() const { // we can safely return a casted pointer because // we know the pointer type was checked by the constructor // at compile time... return *(static_cast<T *>(m_pObjectPtr)); }; }; // typedef's for the autopointers we need in the library... typedef CMclDerivedAutoPtr<CMclThread> CMclThreadAutoPtr; typedef CMclDerivedAutoPtr<CMclMutex> CMclMutexAutoPtr; typedef CMclDerivedAutoPtr<CMclSemaphore> CMclSemaphoreAutoPtr; typedef CMclDerivedAutoPtr<CMclEvent> CMclEventAutoPtr; #endif |
Added win/Mcl/include/CMclCritSec.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // // FILE: CMclCritSec.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLCRITSEC_H__ #define __CMCLCRITSEC_H__ #include "CMclGlobal.h" class CMclCritSec { private: CRITICAL_SECTION m_CritSec; public: // constructor creates a CRITICAL_SECTION inside // the C++ object... CMclCritSec(void); // destructor... virtual ~CMclCritSec(); // enter the critical section... void Enter(void); // leave the critical section... void Leave(void); // return a pointer to the internal // critical section... CRITICAL_SECTION *GetCritSec(void); }; #endif |
Added win/Mcl/include/CMclEvent.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // // FILE: CMclEvent.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLEVENT_H__ #define __CMCLEVENT_H__ #include "CMclGlobal.h" #include "CMclKernel.h" class CMclEvent : public CMclKernel { public: // constructor creates an event object... CMclEvent( BOOL bManualReset = FALSE, BOOL bInitialState = FALSE, LPCTSTR lpName = NULL, LPSECURITY_ATTRIBUTES lpEventAttributes = NULL); // constructor opens an existing named event, // you must check the status after using this constructor, // it will NOT throw an error exception if the object cannot be opened... CMclEvent( LPCTSTR lpName, BOOL bInheritHandle = FALSE, DWORD dwDesiredAccess = EVENT_ALL_ACCESS); // operations on event object... BOOL Set(void); BOOL Reset(void); BOOL Pulse(void); }; #endif |
Added win/Mcl/include/CMclGlobal.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | // // FILE: CMclGlobal.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLGLOBAL_H__ #define __CMCLGLOBAL_H__ #define _WINSOCKAPI_ // Forcefully prevents inclusion of winsock.h #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef _WINSOCKAPI_ #undef WIN32_LEAN_AND_MEAN #include <process.h> #include <winerror.h> #include <tchar.h> // forward class declarations to make the compiler happy... class CMclWaitableObject; class CMclWaitableCollection; class CMclKernel; class CMclMutex; class CMclSemaphore; class CMclEvent; class CMclThread; class CMclCritSec; class CMclAutoLock; class CMclMonitor; class CMclSharedMemory; class CMclMailbox; // defined symbol determines if CMclThrowError throws exceptions // or just prints debug error messages... #ifndef __CMCL_THROW_EXCEPTIONS__ #define __CMCL_THROW_EXCEPTIONS__ TRUE #endif // for higher level objects which might have to check internal // object status when exceptions are disabled, these macros can be useful... // PTR is the smart pointer to check for NULL, // STATUS is the variable in which to store an error code if an error is detected... #if __CMCL_THROW_EXCEPTIONS__ #define CMCL_CHECK_AUTOPTR_OBJECT(PTR,STATUS) if ((PTR).IsNull()) { CMclThrowError(ERROR_OUTOFMEMORY); } #else #define CMCL_CHECK_AUTOPTR_OBJECT(PTR,STATUS) if ((PTR).IsNull()) { (STATUS) = ERROR_OUTOFMEMORY; return; } #endif // SCODE is the return value to check, // STATUS is the variable in which to store an error code if an error is detected... #if __CMCL_THROW_EXCEPTIONS__ #define CMCL_CHECK_CREATION_STATUS(SCODE,STATUS) {} #else #define CMCL_CHECK_CREATION_STATUS(SCODE,STATUS) if (((SCODE)!=NO_ERROR)&&((SCODE)!=ERROR_ALREADY_EXISTS)) { STATUS = (SCODE); return; } #endif // error handling macro and function... #ifdef UNICODE #define ASUNICODE(_str) L#_str #define CMclThrowError(dwStatus) CMclInternalThrowError((dwStatus), ASUNICODE(__FILE__), __LINE__) #else #define CMclThrowError(dwStatus) CMclInternalThrowError((dwStatus), __FILE__, __LINE__) #endif extern void CMclInternalThrowError( DWORD dwStatus, LPCTSTR lpFilename, int line); // check handle for NULL and INVALID_HANDLE inline BOOL CMclIsValidHandle( HANDLE hHandle) { return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE)); } // validate wait return codes... inline BOOL CMclWaitSucceeded( DWORD dwWaitResult, DWORD dwHandleCount) { return ((dwWaitResult >= WAIT_OBJECT_0) && (dwWaitResult < WAIT_OBJECT_0 + dwHandleCount)); } inline BOOL CMclWaitAbandoned( DWORD dwWaitResult, DWORD dwHandleCount) { return ((dwWaitResult >= WAIT_ABANDONED_0) && (dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount)); } inline BOOL CMclWaitTimeout( DWORD dwWaitResult) { return (dwWaitResult == WAIT_TIMEOUT); } inline BOOL CMclWaitFailed( DWORD dwWaitResult) { return (dwWaitResult == WAIT_FAILED); } // compute object indices for waits... inline DWORD CMclWaitSucceededIndex( DWORD dwWaitResult) { return (dwWaitResult - WAIT_OBJECT_0); } inline DWORD CMclWaitAbandonedIndex( DWORD dwWaitResult) { return (dwWaitResult - WAIT_ABANDONED_0); } #endif |
Added win/Mcl/include/CMclKernel.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | // // FILE: CMclKernel.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLKERNEL_H__ #define __CMCLKERNEL_H__ #include "CMclGlobal.h" #include "CMclWaitableObject.h" class CMclKernel : public CMclWaitableObject { protected: HANDLE m_hHandle; DWORD m_dwStatus; protected: // constructor... CMclKernel(); // error handling... void ThrowError( DWORD dwStatus); public: // destructor is virtual to make CMclKernel an abstract base class... virtual ~CMclKernel() = 0; // read the creation status of the internal kernel object... DWORD Status(void) const; // wait on the current kernel object... DWORD Wait( DWORD dwMilliseconds); // wait on the current object and one other... DWORD WaitForTwo( CMclWaitableObject &rCMclWaitableObject, BOOL bWaitAll, DWORD dwMilliseconds); // get the internal handle... HANDLE GetHandle(void) const; // another way to get the internal handle... operator HANDLE() const; private: // these functions have no implementation since they can // never be called... // copying and passing by copy are not allowed... // this prevents confusion of internal object ownership... CMclKernel(CMclKernel & rhs); // assigning one object to another is not allowed, // this prevents confusion of internal object ownership... CMclKernel & operator= (CMclKernel & rhs); }; #endif |
Added win/Mcl/include/CMclLinkedLists.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | // // FILE: CMclLinkedLists.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLLINKEDLISTS_H__ #define __CMCLLINKEDLISTS_H__ #include "CMclGlobal.h" #include "CMclSemaphore.h" #include "CMclCritSec.h" // this linked list template class can be instantiated for // any type which has an accessable copy constructor and // assignment operator... template <class T> class CMclLinkedList { protected: // abstract node class... class CMclLinkedListNode { public: CMclLinkedListNode *m_pNext; CMclLinkedListNode *m_pPrev; virtual void SetData( T & rData) = 0; virtual void GetData( T & rData) = 0; }; // derived class for master and free list nodes... class CMclLinkedListSentinelNode : public CMclLinkedListNode { public: virtual void SetData( T & rData) { // this function should never be called... // the data type you're storing might need a copy constructor CMclThrowError(ERROR_ACCESS_DENIED); }; virtual void GetData( T & rData) { // this function should never be called... // the data type you're storing might need a copy constructor CMclThrowError(ERROR_ACCESS_DENIED); }; }; // derived class for data nodes... class CMclLinkedListDataNode : public CMclLinkedListNode { public: T m_data; CMclLinkedListDataNode( T & rData) : m_data(rData) { return; }; virtual void SetData( T & rData) { m_data = rData; }; virtual void GetData( T & rData) { rData = m_data; }; }; CMclLinkedListSentinelNode m_MasterNode; CMclLinkedListSentinelNode m_FreeNode; CMclCritSec m_cCritSec; CMclSemaphore m_csNotEmpty; DWORD m_dwStatus; public: CMclLinkedList() : m_dwStatus(NO_ERROR), m_csNotEmpty( 0, 0x7FFFFFFF), m_cCritSec() { CMCL_CHECK_CREATION_STATUS(m_csNotEmpty.Status(), m_dwStatus); // both the master and free nodes point to themselves // to indicate that the lists are empty... m_MasterNode.m_pNext = m_MasterNode.m_pPrev = &m_MasterNode; m_FreeNode.m_pNext = m_FreeNode.m_pPrev = &m_FreeNode; }; ~CMclLinkedList() { Cleanup(); }; BOOL PutOnHeadOfList( T & rData) { // acquire the list critical section lock... CMclAutoLock autoLock(m_cCritSec); // get a free list node and attach the data to it... CMclLinkedListNode *pNewNode = AllocateListNode(rData); if (pNewNode == NULL) { // this is a memory allocation failure... CMclThrowError(ERROR_OUTOFMEMORY); return FALSE; } // put the node at the head of the list... pNewNode->m_pNext = m_MasterNode.m_pNext; m_MasterNode.m_pNext->m_pPrev = pNewNode; pNewNode->m_pPrev = &m_MasterNode; m_MasterNode.m_pNext = pNewNode; // add one to the semaphore count which tracks the // number of elements in the list... m_csNotEmpty.Release(1); return TRUE; }; BOOL PutOnTailOfList( T & rData) { // acquire the list critical section lock... CMclAutoLock autoLock(m_cCritSec); // get a free list node and attach the data to it... CMclLinkedListNode *pNewNode = AllocateListNode(rData); if (pNewNode == NULL) { // this is a memory allocation failure... CMclThrowError(ERROR_OUTOFMEMORY); return FALSE; } // put the node at the tail of the list... m_MasterNode.m_pPrev->m_pNext = pNewNode; pNewNode->m_pPrev = m_MasterNode.m_pPrev; m_MasterNode.m_pPrev = pNewNode; pNewNode->m_pNext = &m_MasterNode; // add one to the semaphore count which tracks the // number of elements in the list... m_csNotEmpty.Release(1); return TRUE; }; BOOL GetFromHeadOfList( T & rData, DWORD dwTimeout, CMclEvent *pInterrupt = NULL) { // wait until there is an element on the list or the // interrupt event is signaled... if (pInterrupt) { m_dwStatus = pInterrupt->WaitForTwo( m_csNotEmpty, FALSE, dwTimeout); if (!CMclWaitSucceeded(m_dwStatus, 2)) return FALSE; if (CMclWaitSucceededIndex(m_dwStatus) == 0) return FALSE; } else { m_dwStatus = m_csNotEmpty.Wait(dwTimeout); if (!CMclWaitSucceeded(m_dwStatus, 1)) return FALSE; } // acquire the list critical section lock... CMclAutoLock autoLock(m_cCritSec); // take the node off the head of the list... CMclLinkedListNode *pNode = m_MasterNode.m_pNext; m_MasterNode.m_pNext = pNode->m_pNext; pNode->m_pNext->m_pPrev = &m_MasterNode; // copy the data from the list node... pNode->GetData(rData); // add the list node to the free list... AddToFreeList(pNode); // all done... return TRUE; }; BOOL GetFromTailOfList( T & rData, DWORD dwTimeout, CMclEvent *pInterrupt = NULL) { // wait until there is an element on the list or the // interrupt event is signaled... if (pInterrupt) { m_dwStatus = pInterrupt->WaitForTwo( m_csNotEmpty, FALSE, dwTimeout); if (!CMclWaitSucceeded(m_dwStatus, 2)) return FALSE; if (CMclWaitSucceededIndex(m_dwStatus) == 0) return FALSE; } else { m_dwStatus = m_csNotEmpty.Wait(dwTimeout); if (!CMclWaitSucceeded(m_dwStatus, 1)) return FALSE; } // acquire the list critical section lock... CMclAutoLock autoLock(m_cCritSec); // take the node off the tail of the list... CMclLinkedListNode *pNode = m_MasterNode.m_pPrev; m_MasterNode.m_pPrev = pNode->m_pPrev; pNode->m_pPrev->m_pNext = &m_MasterNode; // copy the data from the list node... pNode->GetData(rData); // add the list node to the free list... AddToFreeList(pNode); // all done... return TRUE; }; DWORD Status(void) { return m_dwStatus; }; protected: void AddToFreeList(CMclLinkedListNode *pFreeNode) { // attach node to the end of the free list... m_FreeNode.m_pPrev->m_pNext = pFreeNode; pFreeNode->m_pPrev = m_FreeNode.m_pPrev; m_FreeNode.m_pPrev = pFreeNode; pFreeNode->m_pNext = &m_FreeNode; }; CMclLinkedListNode *AllocateListNode( T & rData) { // grab a node off the free list, or create // a new one if none are available... CMclLinkedListNode *pNode = m_FreeNode.m_pNext; if (pNode != &m_FreeNode) { pNode->m_pPrev->m_pNext = pNode->m_pNext; pNode->m_pNext->m_pPrev = pNode->m_pPrev; pNode->m_pPrev = pNode; pNode->m_pNext = pNode; pNode->SetData(rData); } else { pNode = new CMclLinkedListDataNode(rData); } return pNode; }; void Cleanup(void) { // delete all of the list nodes on the master list... CMclLinkedListNode *pNode = m_MasterNode.m_pNext; while (pNode != &m_MasterNode) { CMclLinkedListNode *pOldNode = pNode; pNode = pNode->m_pNext; delete pOldNode; } // delete all of the list nodes on the free list... pNode = m_FreeNode.m_pNext; while (pNode != &m_FreeNode) { CMclLinkedListNode *pOldNode = pNode; pNode = pNode->m_pNext; delete pOldNode; } }; }; template <class T> class CMclQueue : protected CMclLinkedList<T> { public: CMclQueue(){}; // copying and passing by copy are not allowed... // this prevents confusion of internal object ownership... // // if this symbol is undefined, then you are accidentally copying it. CMclQueue(CMclQueue &cpy); virtual BOOL Put( T & rData) { return PutOnTailOfList(rData); }; virtual BOOL Get( T & rData, DWORD dwTimeout = INFINITE, CMclEvent *pInterrupt = NULL) { return GetFromHeadOfList( rData, dwTimeout, pInterrupt); }; DWORD Status(void) { return CMclLinkedList<T>::Status(); }; }; template <class T> class CMclStack : protected CMclLinkedList<T> { public: CMclStack() {}; // copying and passing by copy are not allowed... // this prevents confusion of internal object ownership... // // if this symbol is undefined, then you are accidentally copying it. CMclStack(CMclStack &cpy); virtual BOOL Push( T & rData) { return PutOnHeadOfList(rData); }; virtual BOOL Pop( T & rData, DWORD dwTimeout = INFINITE, CMclEvent *pInterrupt = NULL) { return GetFromHeadOfList( rData, dwTimeout, pInterrupt); }; DWORD Status(void) { return CMclLinkedList<T>::Status(); }; }; #endif |
Added win/Mcl/include/CMclMailbox.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | // // FILE: CMclMailbox.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLMAILBOX_H__ #define __CMCLMAILBOX_H__ #include "CMclGlobal.h" #include "CMclWaitableCollection.h" #include "CMclSharedMemory.h" #include "CMclMutex.h" #include "CMclSemaphore.h" #include "CMclAutoPtr.h" class CMclMailbox { private: struct MailboxHdr { DWORD dwMaxDepth; DWORD cbMsgSize; DWORD dwBaseOffset; DWORD dwHeadIndex; DWORD dwTailIndex; }; private: CMclSharedMemory m_cSharedMemory; MailboxHdr *m_pHdr; void *m_pBase; CMclMutexAutoPtr m_cGuardMutexAPtr; CMclSemaphoreAutoPtr m_cFreeCountSemaphoreAPtr; CMclSemaphoreAutoPtr m_cPendingCountSemaphoreAPtr; DWORD m_dwStatus; BOOL m_bIsCreator; public: // create the mailbox if it doesn't exist and open it... CMclMailbox( DWORD dwMaxDepth, DWORD cbMsgSize, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpMailboxAttributes = NULL); // just open the mailbox... CMclMailbox( LPCTSTR lpszName); // ensure that the destructor is virtual for derived classes... virtual ~CMclMailbox(); // query for status after construction if exceptions are disabled... DWORD Status(void) const; // determines if this object created the mailbox... BOOL IsCreator(void); // read the message size and depth properties of the mailbox... BOOL GetProperties( LPDWORD lpdwDepth, LPDWORD lpcbMsgSize); // post a message to the mailbox, wait until there is a free slot // or the timeout expires... BOOL Post( const void *lpMsg, DWORD dwTimeout = INFINITE); // post a message to the mailbox, wait until a message can be written, // return FALSE immediately without posting if the pInterrupt event is signaled... BOOL PostAlertable( const void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout = INFINITE); // post a message to the mailbox, wait until the message can be posted, // or any of the objects in the collection is signaled, or the // timeout expires... // WAIT_OBJECT_0 is the mailbox, with the waitable objects in the collection // being (WAIT_OBJECT_0 + 1) to (WAIT_OBJECT_0 + rCollection.GetCount())... DWORD PostAlertable( const void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout = INFINITE); // get a message from the mailbox, wait until there is a message // or the timeout expires... BOOL Get( void *lpMsg, DWORD dwTimeout = INFINITE); // get a message from the mailbox, wait until a message can be read, // return FALSE immediately without getting if the pInterrupt event is signaled... BOOL GetAlertable( void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout = INFINITE); // get a message from the mailbox, wait until a message can be read, // or any of the objects in the collection is signaled, or the // timeout expires... // WAIT_OBJECT_0 is the mailbox, with the waitable objects in the collection // being (WAIT_OBJECT_0 + 1) to (WAIT_OBJECT_0 + rCollection.GetCount())... DWORD GetAlertable( void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout = INFINITE); private: inline void IncrementHead(void); inline void IncrementTail(void); inline void *GetHeadPtr(void); inline void *GetTailPtr(void); void CreateGuardMutexName( LPTSTR lpszName, LPCTSTR lpszBasename); void CreateFreeCountSemaphoreName( LPTSTR lpszName, LPCTSTR lpszBasename); void CreatePendingCountSemaphoreName( LPTSTR lpszName, LPCTSTR lpszBasename); }; #endif |
Added win/Mcl/include/CMclMonitor.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | // // FILE: CMclMonitor.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLMONITOR_H__ #define __CMCLMONITOR_H__ #include "CMclGlobal.h" #include "CMclEvent.h" #include "CMclSemaphore.h" class CMclCondition { friend class CMclMonitor; private: CMclEvent m_cEvent; public: CMclCondition(); virtual ~CMclCondition(); private: // wait on the internal event... void WaitForEvent(void); // signal the internal event... void SignalEvent(void); // this needs to be overloaded for each condition... virtual BOOL Condition(void) = 0; }; class CMclMonitor { private: // private internal linked list class for tracking // the outstanding condition objects... class CMclConditionNode { public: CMclCondition *m_pcCondition; CMclConditionNode *m_pcnNext; CMclConditionNode *m_pcnPrev; public: CMclConditionNode(CMclCondition *pcCondition); }; private: // master monitor gatekeeper semaphore, // we use a semaphore as a mutex because we need // the ability for a thread to release a mutex that // it did not wait on, and Win32 Mutexes are owned and // prohibit this behaviour... CMclSemaphore m_csMutex; // condition list master node... CMclConditionNode m_cnMaster; // free list master node... CMclConditionNode m_cnFree; // constructor status... DWORD m_dwStatus; public: CMclMonitor(); // virtual destructor does nothing, is simply a placeholder // for derived classes... virtual ~CMclMonitor(); // procedures to control access to the monitor... void Enter(void); void Leave(void); BOOL WaitForCondition( CMclCondition *pcCondition); // query for status after construction if exceptions are disabled... DWORD Status(void) const; private: void LeaveAndScanConditions(void); void AppendConditionNode( CMclConditionNode *pcnNewNode); void RemoveConditionNode( CMclConditionNode *pcnOldNode); void AddToFreeList(CMclConditionNode *pcnFreeNode); CMclConditionNode *AllocateNodeForCondition(CMclCondition *pcCondition); void Cleanup(void); }; #endif |
Added win/Mcl/include/CMclMutex.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // // FILE: CMclMutex.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLMUTEX_H__ #define __CMCLMUTEX_H__ #include "CMclGlobal.h" #include "CMclKernel.h" class CMclMutex : public CMclKernel { public: // constructors create a mutex object... CMclMutex( BOOL bInitialOwner = FALSE, LPCTSTR lpName = NULL, LPSECURITY_ATTRIBUTES lpMutexAttributes = NULL); // constructor opens an existing named mutex... // you must check the status after using this constructor, // it will NOT throw an error exception if the object cannot be opened... CMclMutex( LPCTSTR lpName, BOOL bInheritHandle = FALSE, DWORD dwDesiredAccess = MUTEX_ALL_ACCESS); // release a lock on a mutex... BOOL Release(void); }; #endif |
Added win/Mcl/include/CMclSemaphore.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // // FILE: CMclSemaphore.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLSEMAPHORE_H__ #define __CMCLSEMAPHORE_H__ #include "CMclGlobal.h" #include "CMclKernel.h" class CMclSemaphore : public CMclKernel { public: // constructor creates a semaphore object... CMclSemaphore( int nInitialCount, int nMaximumCount, LPCTSTR lpName = NULL, LPSECURITY_ATTRIBUTES lpSemaphoreAttributes = NULL); // constructor opens an existing named semaphore... // you must check the status after using this constructor, // it will NOT throw an error exception if the object cannot be opened... CMclSemaphore( LPCTSTR lpName, BOOL bInheritHandle = FALSE, DWORD dwDesiredAccess = SEMAPHORE_ALL_ACCESS); // increase the count on a semaphore... BOOL Release( LONG lReleaseCount, LONG *plPreviousCount = NULL); }; #endif |
Added win/Mcl/include/CMclSharedMemory.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | // // FILE: CMclSharedMemory.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLSHAREDMEMORY_H__ #define __CMCLSHAREDMEMORY_H__ #include "CMclGlobal.h" class CMclSharedMemory { private: void *m_lpSharedMemory; HANDLE m_hMapping; BOOL m_bIsCreator; DWORD m_dwStatus; public: // constructor requires a size with an optional name, it will // create the shared memory area if it doesn't already exist, // if it does exist and the requested size is larger than the current // size, the size of the shared memory area will grow to the requested size... CMclSharedMemory( LONG lSize, LPCTSTR lpName, LPSECURITY_ATTRIBUTES lpSharedMemoryAttributes = NULL); // constructor requires just a name, opens the shared memory // area if it exists, you must check the status of this object to // see if it succeeded or failed, it will NOT throw an exception if // the named shared memory area does not exist... CMclSharedMemory( LPCTSTR lpName); // destructor is virtual to allow easy use of // derived classes... virtual ~CMclSharedMemory(); // query for status after construction if exceptions are disabled... DWORD Status(void) const; // basic access function returns a void pointer // to the shared memory, derived classes can add functions // to return pointers to higher level structures or structure // members by first getting the base pointer through this function... void *GetPtr(void); // function to tell if this object created the shared memory area... BOOL IsCreator(void); }; #endif |
Added win/Mcl/include/CMclThread.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | // // FILE: CMclThread.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLTHREAD_H__ #define __CMCLTHREAD_H__ #include "CMclGlobal.h" #include "CMclKernel.h" // forward declaration for CMclThreadHandler... class CMclThread; // CMclThreadHandler encapsulates the thread procedure for a // CMclThread object, each instantiation of a thread handler can // be used by multiple threads at a time but the base CMclThreadHandler // class does NOT provide any internal synchronization for multiple threads // using a single instance simultaneously. A derived class could provide // this internal synchronization however... class CMclThreadHandler { public: // destructor does nothing, it is simply a placeholder for // ensure the destructors of derived classes are virtual... virtual ~CMclThreadHandler(); // This is a pure virtual function with no implementation // it must be implemented in a derived class. // The "this" object // inside ThreadHandlerProc() will be the CMclThreadHandler derived // object itself. // The procedure should return the exit code of the thread when finished... virtual unsigned ThreadHandlerProc(void) = 0; }; class CMclThread : public CMclKernel { protected: unsigned int m_uiThreadID; CMclThreadHandler *m_pcThreadHandler; public: // only the thread handler reference needs to // be supplied since the other arguments have default values... CMclThread( CMclThreadHandler *pcThreadHandler, unsigned uInitFlag = 0, LPSECURITY_ATTRIBUTES lpSecurity = NULL, unsigned uStackSize = 0); // suspend the thread... DWORD Suspend(void); // resume the thread... DWORD Resume(void); // terminate the thread... BOOL Terminate( DWORD dwExitCode); // read a thread's exit code... BOOL GetExitCode( DWORD *pdwExitCode); // set a thread's priority... BOOL SetPriority( int nPriority); // read a thread's priority... int GetPriority(void); // get the internal thread id... DWORD GetThreadId(void); private: // this is a static function used to kick-start the thread handler... static unsigned _stdcall CallThreadHandlerProc(void *pThreadHandler); }; #endif |
Added win/Mcl/include/CMclWaitableCollection.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | // // FILE: CMclWaitableCollection.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLWAITABLECOLLECTION_H__ #define __CMCLWAITABLECOLLECTION_H__ #include "CMclGlobal.h" #include "CMclEvent.h" #include "CMclWaitableObject.h" class CMclWaitableCollection { private: HANDLE m_aObjectHandles[MAXIMUM_WAIT_OBJECTS]; LONG m_lObjects; public: CMclWaitableCollection(); // destructor does nothing, simply a placeholder // for derived class virtual destructors... virtual ~CMclWaitableCollection(); // copy constructor... CMclWaitableCollection(CMclWaitableCollection & rhs); // assignment operator... CMclWaitableCollection & operator= (CMclWaitableCollection & rhs); // get the number of handles in the collection... LONG GetCount(void) const; // add the handle from a pointer to a waitable object to our collection... BOOL AddObject(const CMclWaitableObject *pObject); // add the handle from a reference to a waitable object to our collection... BOOL AddObject(const CMclWaitableObject & rObject); // add the event handle from a reference to a waitable object to our collection... BOOL AddObject(const CMclEvent & ceEvent); // add a raw handle to our collection... BOOL AddObject(const HANDLE hHandle); // add collection adds all the objects from the given collection // to this collection... BOOL AddCollection(const CMclWaitableCollection & rCollection); // wait for some handles in the collection to become signaled // or the timeout to expire... DWORD Wait( BOOL bWaitAll, DWORD dwMilliseconds) const; }; #endif |
Added win/Mcl/include/CMclWaitableObject.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // // FILE: CMclWaitableObject.h // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #ifndef __CMCLWAITABLEOBJECT_H__ #define __CMCLWAITABLEOBJECT_H__ #include "CMclGlobal.h" class CMclWaitableObject { // class has no member data, it's only purpose is to provide // a base class for waitable objects which have internal HANDLES // and Status... // class needs no construtor, since it has no members... public: // get the internal handle... // this member function is virtual to assure // this function appears in all derived classes // and pure (= 0) so that this class cannot be instantiated... virtual HANDLE GetHandle(void) const = 0; // get the internal object status... // this member function is virtual to assure // this function appears in all derived classes // and pure (= 0) so that this class cannot be instantiated... virtual DWORD Status(void) const = 0; }; #endif |
Added win/Mcl/readme.txt.
> > > > > > > | 1 2 3 4 5 6 7 | Mcl is a Multithreading Class Library for Win32 written by Aaron Cohen and Mike Woodring. see http://www.bearcanyon.com/mtbook/errata.htm#source and http://www.oreilly.com/catalog/multithread/ This code *here* differs from the Nov 07, 2001 update in minor ways. |
Added win/Mcl/src/CMclAutoLock.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | // // FILE: CMclAutoLock.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclAutoLock.h" // constructors... CMclAutoLock::CMclAutoLock( HANDLE hMutexHandle) { m_pCritSec = NULL; m_pcCritSec = NULL; m_pcMutex = NULL; m_hMutexHandle = hMutexHandle; ::WaitForSingleObject( m_hMutexHandle, INFINITE); } CMclAutoLock::CMclAutoLock( CMclMutex & rCMclMutex) { m_pCritSec = NULL; m_pcCritSec = NULL; m_hMutexHandle = NULL; m_pcMutex = &rCMclMutex; m_pcMutex->Wait(INFINITE); } CMclAutoLock::CMclAutoLock( CRITICAL_SECTION * pCritSec) { m_hMutexHandle = NULL; m_pcMutex = NULL; m_pcCritSec = NULL; m_pCritSec = pCritSec; ::EnterCriticalSection(m_pCritSec); } CMclAutoLock::CMclAutoLock( CMclCritSec & rCMclCritSec) { m_hMutexHandle = NULL; m_pcMutex = NULL; m_pCritSec = NULL; m_pcCritSec = &rCMclCritSec; m_pcCritSec->Enter(); } // destructor... CMclAutoLock::~CMclAutoLock(void) { BOOL bStatus = TRUE; if (m_hMutexHandle) { bStatus = ::ReleaseMutex(m_hMutexHandle); } else if (m_pcMutex) { bStatus = m_pcMutex->Release(); } else if (m_pCritSec) { ::LeaveCriticalSection(m_pCritSec); } else { m_pcCritSec->Leave(); } if (!bStatus) { CMclThrowError( ::GetLastError()); } } |
Added win/Mcl/src/CMclAutoPtr.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | // // FILE: CMclAutoPtr.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclAutoPtr.h" ///////////////////////////////////////////////////////////////////////// // CMclKernelAutoPtr ///////////////////////////////////////////////////////////////////////// // can construct a kernel auto pointer with a valid internal object // or a NULL... CMclKernelAutoPtr::CMclKernelAutoPtr(CMclKernel *pObjectPtr) { m_pObjectPtr = pObjectPtr; } // deleting the auto pointer deletes what the internal pointer points to... CMclKernelAutoPtr::~CMclKernelAutoPtr() { // no check needed since deleting a NULL // pointer is okay in C++... delete m_pObjectPtr; } void CMclKernelAutoPtr::Reset(CMclKernel *pObjectPtr) { // we don't need to check for NULL in C++... if (m_pObjectPtr != pObjectPtr) delete m_pObjectPtr; m_pObjectPtr = pObjectPtr; } // dereferencing operator... CMclKernel * CMclKernelAutoPtr::operator->() const { return m_pObjectPtr; } // indirection operator... CMclKernel & CMclKernelAutoPtr::operator*() const { return *m_pObjectPtr; } // get the handle of the internal object... HANDLE CMclKernelAutoPtr::GetHandle(void) const { return m_pObjectPtr->GetHandle(); } // read the current status of the internal object... DWORD CMclKernelAutoPtr::Status(void) const { return m_pObjectPtr->Status(); } BOOL CMclKernelAutoPtr::IsNull(void) const { return (m_pObjectPtr == NULL); } |
Added win/Mcl/src/CMclCritSec.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // // FILE: CMclCritSec.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclCritSec.h" // constructor creates a CRITICAL_SECTION inside // the C++ object... CMclCritSec::CMclCritSec(void) { ::InitializeCriticalSection( &m_CritSec); } // destructor... CMclCritSec::~CMclCritSec() { ::DeleteCriticalSection( &m_CritSec); } // enter the critical section... void CMclCritSec::Enter(void) { ::EnterCriticalSection( &m_CritSec); } // leave the critical section... void CMclCritSec::Leave(void) { ::LeaveCriticalSection( &m_CritSec); } CRITICAL_SECTION *CMclCritSec::GetCritSec(void) { return &m_CritSec; } |
Added win/Mcl/src/CMclEvent.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | // // FILE: CMclEvent.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclEvent.h" // constructor creates an event object... CMclEvent::CMclEvent( BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName, LPSECURITY_ATTRIBUTES lpEventAttributes) { m_hHandle = ::CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName); if (CMclIsValidHandle(m_hHandle)) { if (lpName) m_dwStatus = GetLastError(); else m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); ThrowError(m_dwStatus); } } // constructor opens an existing named event... CMclEvent::CMclEvent( LPCTSTR lpName, BOOL bInheritHandle, DWORD dwDesiredAccess) { m_hHandle = ::OpenEvent( dwDesiredAccess, bInheritHandle, lpName); if (CMclIsValidHandle(m_hHandle)) { m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); } } // operations on event object... BOOL CMclEvent::Set(void) { return ::SetEvent(m_hHandle); } BOOL CMclEvent::Reset(void) { return ::ResetEvent(m_hHandle); } BOOL CMclEvent::Pulse(void) { return ::PulseEvent(m_hHandle); } |
Added win/Mcl/src/CMclGlobal.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // // FILE: CMclGlobal.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclGlobal.h" void CMclInternalThrowError( DWORD dwStatus, LPCTSTR lpFilename, int line) { #ifdef _DEBUG // print the error for debug builds... TCHAR string[2*MAX_PATH]; wsprintf( string, __TEXT("CMcl Library Win32 Error 0x%08x(%d) at %s line %d\n"), dwStatus, dwStatus, lpFilename, line); OutputDebugString(string); #endif #if __CMCL_THROW_EXCEPTIONS__ // throw exception for fatal errors... throw dwStatus; #endif } |
Added win/Mcl/src/CMclKernel.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | // // FILE: CMclKernel.cpp // // Copyright (c) 1997 by Aaron Michael Cohen // ///////////////////////////////////////////////////////////////////////// #include "CMclKernel.h" #include "CMclAutoPtr.h" CMclKernel::CMclKernel() { m_hHandle = NULL; m_dwStatus = ERROR_INVALID_HANDLE; } CMclKernel::~CMclKernel() { if (CMclIsValidHandle(m_hHandle)) { ::CloseHandle(m_hHandle); m_hHandle = NULL; } } void CMclKernel::ThrowError( DWORD dwStatus) { CMclThrowError(dwStatus); } DWORD CMclKernel::Status(void) const { return m_dwStatus; } DWORD CMclKernel::Wait( DWORD dwMilliseconds) { return ::WaitForSingleObject( m_hHandle, dwMilliseconds); } // wait on the current object and one other... DWORD CMclKernel::WaitForTwo( CMclWaitableObject &rCMclWaitableObject, BOOL bWaitAll, DWORD dwMilliseconds) { HANDLE handles[2]; // the current object... handles[0] = m_hHandle; // the parameter object... handles[1] = rCMclWaitableObject.GetHandle(); // wait for the objects... return ::WaitForMultipleObjects( 2, handles, bWaitAll, dwMilliseconds); } HANDLE CMclKernel::GetHandle(void) const { if (this != NULL) return m_hHandle; else return NULL; } CMclKernel::operator HANDLE() const { return GetHandle(); } |
Added win/Mcl/src/CMclMailbox.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | // // FILE: CMclMailbox.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclMailbox.h" CMclMailbox::CMclMailbox( DWORD dwMaxDepth, DWORD cbMsgSize, LPCTSTR lpszName, LPSECURITY_ATTRIBUTES lpMailboxAttributes) : m_cSharedMemory( dwMaxDepth * cbMsgSize + sizeof(MailboxHdr), lpszName, lpMailboxAttributes), m_pHdr(NULL), m_pBase(NULL), m_cGuardMutexAPtr(NULL), m_cFreeCountSemaphoreAPtr(NULL), m_cPendingCountSemaphoreAPtr(NULL), m_dwStatus(NO_ERROR), m_bIsCreator(FALSE) { // temporary buffer for our names... TCHAR szName[MAX_PATH]; // check the status of the shared memory object in case // exceptions are disabled... CMCL_CHECK_CREATION_STATUS(m_cSharedMemory.Status(), m_dwStatus); // create the name for the guard mutex... CreateGuardMutexName( szName, lpszName); // create the guard mutex... // check for errors in case exceptions are disabled... m_cGuardMutexAPtr = new CMclMutex( TRUE, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cGuardMutexAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cGuardMutexAPtr->Status(), m_dwStatus); // check if we are the creator of the guard mutex... if (m_cGuardMutexAPtr->Status() == ERROR_ALREADY_EXISTS) { // in this case we don't own the mutex because we did not // create it so we need to wait for it to prevent race conditions // with other objects created at about the same time, // this ensure that the creating object always finishes its // constructor first... m_cGuardMutexAPtr->Wait(INFINITE); m_bIsCreator = FALSE; } else { // we own the mutex now... m_bIsCreator = TRUE; } // create the name for the free count semaphore... CreateFreeCountSemaphoreName( szName, lpszName); // create the free count semaphore... // check for errors in case exceptions are disabled... m_cFreeCountSemaphoreAPtr = new CMclSemaphore( dwMaxDepth, dwMaxDepth, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cFreeCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cFreeCountSemaphoreAPtr->Status(), m_dwStatus); // create the name for the pending count semaphore... CreatePendingCountSemaphoreName( szName, lpszName); // create the pending count semaphore... // check for errors in case exceptions are disabled... m_cPendingCountSemaphoreAPtr = new CMclSemaphore( 0, dwMaxDepth, szName, lpMailboxAttributes); CMCL_CHECK_AUTOPTR_OBJECT(m_cPendingCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cPendingCountSemaphoreAPtr->Status(), m_dwStatus); // store pointer to beginning of shared memory... m_pHdr = (MailboxHdr *) m_cSharedMemory.GetPtr(); // store pointer to base of mailbox slots... m_pBase = (void *) ((BYTE *) m_pHdr + sizeof(MailboxHdr)); // initialize the mailbox slots if we are the creator of the shared memory... // if we are the creator of the shared memory, we are the creator of the // guard mutex and we initially own it... if (m_bIsCreator) { m_pHdr->dwMaxDepth = dwMaxDepth; m_pHdr->cbMsgSize = cbMsgSize; m_pHdr->dwBaseOffset = sizeof(MailboxHdr); m_pHdr->dwHeadIndex = 0; m_pHdr->dwTailIndex = 0; } // we need to release the guard mutex whether or not // we are the creator... m_cGuardMutexAPtr->Release(); if (!m_bIsCreator) { // it is an error for a second object to try to open the // mailbox with different message buffer parameters, so check for this condition... if ((m_pHdr->dwMaxDepth != dwMaxDepth) || (m_pHdr->cbMsgSize != cbMsgSize)) { m_dwStatus = ERROR_INVALID_PARAMETER; CMclThrowError(m_dwStatus); return; } } } CMclMailbox::CMclMailbox( LPCTSTR lpszName) : m_cSharedMemory(lpszName), m_pHdr(NULL), m_pBase(NULL), m_cGuardMutexAPtr(NULL), m_cFreeCountSemaphoreAPtr(NULL), m_cPendingCountSemaphoreAPtr(NULL), m_dwStatus(NO_ERROR), m_bIsCreator(FALSE) { // we are definitely NOT the creator of the mailbox here... // check the status of the shared memory object in case // exceptions are disabled... CMCL_CHECK_CREATION_STATUS(m_cSharedMemory.Status(), m_dwStatus); // temporary buffer for our names... TCHAR szName[MAX_PATH]; // create the name for the guard mutex... CreateGuardMutexName( szName, lpszName); // create the guard mutex... // check for errors in case exceptions are disabled... m_cGuardMutexAPtr = new CMclMutex(szName); CMCL_CHECK_AUTOPTR_OBJECT(m_cGuardMutexAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cGuardMutexAPtr->Status(), m_dwStatus); // to maintain synchronization with the other constructor, // we need to acquire the mutex before returning control // to the user to prevent race conditions... m_cGuardMutexAPtr->Wait(INFINITE); // create the name for the free count semaphore... CreateFreeCountSemaphoreName( szName, lpszName); // create the free count semaphore... // check for errors in case exceptions are disabled... m_cFreeCountSemaphoreAPtr = new CMclSemaphore( szName); CMCL_CHECK_AUTOPTR_OBJECT(m_cFreeCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cFreeCountSemaphoreAPtr->Status(), m_dwStatus); // create the name for the pending count semaphore... CreatePendingCountSemaphoreName( szName, lpszName); // create the pending count semaphore... m_cPendingCountSemaphoreAPtr = new CMclSemaphore( szName); CMCL_CHECK_AUTOPTR_OBJECT(m_cPendingCountSemaphoreAPtr, m_dwStatus); CMCL_CHECK_CREATION_STATUS(m_cPendingCountSemaphoreAPtr->Status(), m_dwStatus); // store pointer to beginning of shared memory... m_pHdr = (MailboxHdr *) m_cSharedMemory.GetPtr(); // store pointer to base of mailbox slots... m_pBase = (void *) ((BYTE *) m_pHdr + sizeof(MailboxHdr)); // the creation constructor must have finished, so we // can release the guard mutex... m_cGuardMutexAPtr->Release(); } CMclMailbox::~CMclMailbox() { // this is a place holder for derived classes, // the CMcl class objects should clean up automatically... return; } DWORD CMclMailbox::Status(void) const { return m_dwStatus; } BOOL CMclMailbox::IsCreator(void) { return m_bIsCreator; } BOOL CMclMailbox::GetProperties( LPDWORD lpdwDepth, LPDWORD lpcbMsgSize) { if (m_pHdr) { *lpdwDepth = m_pHdr->dwMaxDepth; *lpcbMsgSize = m_pHdr->cbMsgSize; return TRUE; } else { return FALSE; } } BOOL CMclMailbox::Post( const void *lpMsg, DWORD dwTimeout) { DWORD dwStatus = m_cFreeCountSemaphoreAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( GetTailPtr(), lpMsg, m_pHdr->cbMsgSize); IncrementTail(); m_cGuardMutexAPtr->Release(); // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cPendingCountSemaphoreAPtr->Release(1); } } return (CMclWaitSucceeded(dwStatus, 1)); } BOOL CMclMailbox::Get( void *lpMsg, DWORD dwTimeout) { DWORD dwStatus = m_cPendingCountSemaphoreAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return (CMclWaitSucceeded(dwStatus, 1)); } BOOL CMclMailbox::PostAlertable( const void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout) { BOOL bStatus = FALSE; DWORD dwStatus = pInterrupt->WaitForTwo( *m_cFreeCountSemaphoreAPtr, FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, 2) && (CMclWaitSucceededIndex(dwStatus) == (WAIT_OBJECT_0 + 1))) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( GetTailPtr(), lpMsg, m_pHdr->cbMsgSize); IncrementTail(); m_cGuardMutexAPtr->Release(); bStatus = TRUE; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cPendingCountSemaphoreAPtr->Release(1); } } return bStatus; } BOOL CMclMailbox::GetAlertable( void *lpMsg, CMclEvent *pInterrupt, DWORD dwTimeout) { BOOL bStatus = FALSE; DWORD dwStatus = pInterrupt->WaitForTwo( *m_cPendingCountSemaphoreAPtr, FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, 2) && (CMclWaitSucceededIndex(dwStatus) == (WAIT_OBJECT_0 + 1))) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); bStatus = TRUE; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return bStatus; } DWORD CMclMailbox::PostAlertable( const void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout) { CMclWaitableCollection cCollection; cCollection.AddObject(*m_cFreeCountSemaphoreAPtr); cCollection.AddCollection(rCollection); int nObjects = cCollection.GetCount(); DWORD dwStatus = cCollection.Wait( FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, nObjects) && (CMclWaitSucceededIndex(dwStatus) == WAIT_OBJECT_0)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( GetTailPtr(), lpMsg, m_pHdr->cbMsgSize); IncrementTail(); m_cGuardMutexAPtr->Release(); dwStatus = WAIT_OBJECT_0; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cPendingCountSemaphoreAPtr->Release(1); } } return dwStatus; } DWORD CMclMailbox::GetAlertable( void *lpMsg, const CMclWaitableCollection & rCollection, DWORD dwTimeout) { CMclWaitableCollection cCollection; cCollection.AddObject(*m_cPendingCountSemaphoreAPtr); cCollection.AddCollection(rCollection); int nObjects = cCollection.GetCount(); DWORD dwStatus = cCollection.Wait( FALSE, dwTimeout); if (CMclWaitSucceeded( dwStatus, nObjects) && (CMclWaitSucceededIndex(dwStatus) == WAIT_OBJECT_0)) { dwStatus = m_cGuardMutexAPtr->Wait(dwTimeout); if (CMclWaitSucceeded(dwStatus, 1) || CMclWaitAbandoned(dwStatus, 1)) { CopyMemory( lpMsg, GetHeadPtr(), m_pHdr->cbMsgSize); IncrementHead(); m_cGuardMutexAPtr->Release(); dwStatus = WAIT_OBJECT_0; // Nov 7, 2001: only release semaphore if // we've actually place something in the mailbox. // Previously, the following line of code was outside // this if block. // // Thanks to Johan Vanslembrouck for finding and // reporting this bug. // m_cFreeCountSemaphoreAPtr->Release(1); } } return dwStatus; } void CMclMailbox::IncrementHead(void) { m_pHdr->dwHeadIndex = (m_pHdr->dwHeadIndex + 1) % m_pHdr->dwMaxDepth; } void CMclMailbox::IncrementTail(void) { m_pHdr->dwTailIndex = (m_pHdr->dwTailIndex + 1) % m_pHdr->dwMaxDepth; } void * CMclMailbox::GetHeadPtr(void) { return (void *) ((BYTE *) m_pBase + (m_pHdr->dwHeadIndex * m_pHdr->cbMsgSize)); } void * CMclMailbox::GetTailPtr(void) { return (void *) ((BYTE *) m_pBase + (m_pHdr->dwTailIndex * m_pHdr->cbMsgSize)); } void CMclMailbox::CreateGuardMutexName( LPTSTR lpszName, LPCTSTR lpszBasename) { wsprintf( lpszName, TEXT("%s::%s"), TEXT("MailboxGuardMutex"), lpszBasename); } void CMclMailbox::CreateFreeCountSemaphoreName( LPTSTR lpszName, LPCTSTR lpszBasename) { wsprintf( lpszName, TEXT("%s::%s"), TEXT("MailboxFreeCountSemaphore"), lpszBasename); } void CMclMailbox::CreatePendingCountSemaphoreName( LPTSTR lpszName, LPCTSTR lpszBasename) { wsprintf( lpszName, TEXT("%s::%s"), TEXT("MailboxPendingCountSemaphore"), lpszBasename); } |
Added win/Mcl/src/CMclMonitor.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | // // FILE: CMclMonitor.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclMonitor.h" ////////////////////////////////////////////////// // CMclCondition abstract base class // ////////////////////////////////////////////////// // constructor initializes an auto-reset event... CMclCondition::CMclCondition() : m_cEvent(FALSE) { return; } // virtual destructor does nothing, is simply a placeholder CMclCondition::~CMclCondition() { return; } void CMclCondition::WaitForEvent(void) { m_cEvent.Wait(INFINITE); } void CMclCondition::SignalEvent(void) { // it is very important the the event be set here and not // pulsed. there is a small time window inside WaitForCondition() // between where the event might be signaled before the thread // calls WaitForEvent(). anyway, this is an auto-reset event so the // signal state will be cleared after the thread resumes... m_cEvent.Set(); } ///////////////////////////////////////////////////// // CMclMonitor::CMclConditionNode utility class // ///////////////////////////////////////////////////// CMclMonitor::CMclConditionNode::CMclConditionNode( CMclCondition *pcCondition) { m_pcCondition = pcCondition; m_pcnNext = NULL; m_pcnPrev = NULL; } /////////////////////////// // CMclMonitor class // /////////////////////////// CMclMonitor::CMclMonitor() : m_cnMaster(NULL), m_cnFree(NULL), m_csMutex(1,1), m_dwStatus(NO_ERROR) { CMCL_CHECK_CREATION_STATUS(m_csMutex.Status(), m_dwStatus); m_cnMaster.m_pcnNext = m_cnMaster.m_pcnPrev = &m_cnMaster; m_cnFree.m_pcnNext = m_cnFree.m_pcnPrev = &m_cnFree; return; } CMclMonitor::~CMclMonitor() { Cleanup(); } void CMclMonitor::Enter(void) { m_csMutex.Wait(INFINITE); } void CMclMonitor::Leave(void) { LeaveAndScanConditions(); } BOOL CMclMonitor::WaitForCondition( CMclCondition *pcCondition) { if (pcCondition->Condition() == FALSE) { // the condition is FALSE, so we'll put the // condition on the monitor list... // create a new list node... CMclConditionNode *pNewNode = AllocateNodeForCondition(pcCondition); if (pNewNode == NULL) { // this is a memory allocation failure... CMclThrowError(ERROR_OUTOFMEMORY); return FALSE; } // put the node on the list... AppendConditionNode(pNewNode); // leave the monitor by resuming a waiting // thread or just releasing the semaphore... // this could cause other threads to execute // which might release our condition event // before we even get a chance to wait for it, // therefore the event must be set and not // pulsed in CMclCondition::SignalEvent()... LeaveAndScanConditions(); // wait for the event... pcCondition->WaitForEvent(); } return TRUE; } void CMclMonitor::LeaveAndScanConditions(void) { // traverse the list of CMclConditionNodes, // looking for a condition which is TRUE... CMclConditionNode *pNode = m_cnMaster.m_pcnNext; while (pNode != &m_cnMaster) { if (pNode->m_pcCondition->Condition()) { break; } pNode = pNode->m_pcnNext; } if (pNode != &m_cnMaster) { // we have found a node with a true condition, // remove the node and signal the condition... CMclCondition *pcCondition = pNode->m_pcCondition; RemoveConditionNode(pNode); AddToFreeList(pNode); pcCondition->SignalEvent(); } else { // no nodes are ready to be signaled, so just // release the mutual exclusion semaphore... m_csMutex.Release(1); } } void CMclMonitor::AppendConditionNode( CMclConditionNode *pcnNewNode) { m_cnMaster.m_pcnPrev->m_pcnNext = pcnNewNode; pcnNewNode->m_pcnPrev = m_cnMaster.m_pcnPrev; m_cnMaster.m_pcnPrev = pcnNewNode; pcnNewNode->m_pcnNext = &m_cnMaster; } void CMclMonitor::RemoveConditionNode( CMclConditionNode *pcnOldNode) { pcnOldNode->m_pcnPrev->m_pcnNext = pcnOldNode->m_pcnNext; pcnOldNode->m_pcnNext->m_pcnPrev = pcnOldNode->m_pcnPrev; } void CMclMonitor::AddToFreeList(CMclConditionNode *pcnFreeNode) { // reinitialize the node's condition... pcnFreeNode->m_pcCondition = NULL; // add the node to the free list... m_cnFree.m_pcnPrev->m_pcnNext = pcnFreeNode; pcnFreeNode->m_pcnPrev = m_cnFree.m_pcnPrev; m_cnFree.m_pcnPrev = pcnFreeNode; pcnFreeNode->m_pcnNext = &m_cnFree; } CMclMonitor::CMclConditionNode *CMclMonitor::AllocateNodeForCondition(CMclCondition *pcCondition) { CMclConditionNode *pNode = m_cnFree.m_pcnNext; if (pNode != &m_cnFree) { // if there are any nodes on the list, // remove the first one from the list to use... pNode->m_pcnPrev->m_pcnNext = pNode->m_pcnNext; pNode->m_pcnNext->m_pcnPrev = pNode->m_pcnPrev; pNode->m_pcCondition = pcCondition; pNode->m_pcnPrev = pNode; pNode->m_pcnNext = pNode; } else { // otherwise allocate a new one... pNode = new CMclConditionNode(pcCondition); } // return the initialized node... return pNode; } void CMclMonitor::Cleanup(void) { // traverse the list of active condition nodes, // deleting each node... CMclConditionNode *pNode = m_cnMaster.m_pcnNext; while (pNode != &m_cnMaster) { CMclConditionNode *pOldNode = pNode; pNode = pNode->m_pcnNext; delete pOldNode; } // traverse the list of free nodes, // deleting each node... pNode = m_cnFree.m_pcnNext; while (pNode != &m_cnFree) { CMclConditionNode *pOldNode = pNode; pNode = pNode->m_pcnNext; delete pOldNode; } } DWORD CMclMonitor::Status(void) const { return m_dwStatus; } |
Added win/Mcl/src/CMclMutex.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // // FILE: CMclMutex.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclMutex.h" // constructor creates a mutex allowing creation parameters to be specified... CMclMutex::CMclMutex( BOOL bInitialOwner, LPCTSTR lpName, LPSECURITY_ATTRIBUTES lpMutexAttributes) { m_hHandle = ::CreateMutex( lpMutexAttributes, bInitialOwner, lpName); if (CMclIsValidHandle(m_hHandle)) { if (lpName) m_dwStatus = GetLastError(); else m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); ThrowError(m_dwStatus); } } // constructor opens an existing named mutex... CMclMutex::CMclMutex( LPCTSTR lpName, BOOL bInheritHandle, DWORD dwDesiredAccess) { m_hHandle = ::OpenMutex( dwDesiredAccess, bInheritHandle, lpName); if (CMclIsValidHandle(m_hHandle)) { m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); } } // release a lock on a mutex... BOOL CMclMutex::Release(void) { return ::ReleaseMutex(m_hHandle); } |
Added win/Mcl/src/CMclSemaphore.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | // // FILE: CMclSemaphore.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclSemaphore.h" // constructor creates a semaphore object... CMclSemaphore::CMclSemaphore( int nInitialCount, int nMaximumCount, LPCTSTR lpName, LPSECURITY_ATTRIBUTES lpSemaphoreAttributes) { m_hHandle = ::CreateSemaphore( lpSemaphoreAttributes, nInitialCount, nMaximumCount, lpName); if (CMclIsValidHandle(m_hHandle)) { if (lpName) m_dwStatus = GetLastError(); else m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); ThrowError(m_dwStatus); } } // constructor opens an existing named semaphore... CMclSemaphore::CMclSemaphore( LPCTSTR lpName, BOOL bInheritHandle, DWORD dwDesiredAccess) { m_hHandle = ::OpenSemaphore( dwDesiredAccess, bInheritHandle, lpName); if (CMclIsValidHandle(m_hHandle)) { m_dwStatus = NO_ERROR; } else { m_dwStatus = GetLastError(); } } // increase the count on a semaphore... BOOL CMclSemaphore::Release( LONG lReleaseCount, LONG *plPreviousCount) { LONG lPreviousCount; BOOL bStatus = ::ReleaseSemaphore( m_hHandle, lReleaseCount, &lPreviousCount); if (bStatus && plPreviousCount) { *plPreviousCount = lPreviousCount; } return bStatus; } |
Added win/Mcl/src/CMclSharedMemory.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | // // FILE: CMclSharedMemory.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclSharedMemory.h" CMclSharedMemory::CMclSharedMemory( LONG lSize, LPCTSTR lpName, LPSECURITY_ATTRIBUTES lpSharedMemoryAttributes) : m_lpSharedMemory(NULL), m_bIsCreator(FALSE), m_dwStatus(NO_ERROR) { m_hMapping = ::CreateFileMapping( (HANDLE) 0xFFFFFFFF, lpSharedMemoryAttributes, PAGE_READWRITE, 0, lSize, lpName); if (CMclIsValidHandle(m_hMapping)) { m_dwStatus = GetLastError(); if (m_dwStatus == ERROR_ALREADY_EXISTS) { m_bIsCreator = FALSE; } else { m_bIsCreator = TRUE; } } else { m_dwStatus = ::GetLastError(); CMclThrowError(m_dwStatus); } m_lpSharedMemory = (void *) ::MapViewOfFile( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (m_lpSharedMemory == NULL) { // unable to map memory into address space, perhaps our address space is full? // this is a fatal error, close handle and throw exeption m_dwStatus = ::GetLastError(); CMclThrowError(m_dwStatus); } } CMclSharedMemory::CMclSharedMemory( LPCTSTR lpName) : m_lpSharedMemory(NULL), m_bIsCreator(FALSE), m_dwStatus(NO_ERROR) { m_hMapping = ::OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, lpName); if (CMclIsValidHandle(m_hMapping)) { m_dwStatus = NO_ERROR; } else { m_dwStatus = ::GetLastError(); return; } m_lpSharedMemory = (void *) ::MapViewOfFile( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (m_lpSharedMemory == NULL) { // unable to map memory into address space, perhaps our address space is full? m_dwStatus = ::GetLastError(); } } CMclSharedMemory::~CMclSharedMemory() { if (m_lpSharedMemory) { ::UnmapViewOfFile(m_lpSharedMemory); m_lpSharedMemory = NULL; } // close the file mapping handle... if (m_hMapping) { ::CloseHandle(m_hMapping); } } DWORD CMclSharedMemory::Status(void) const { return m_dwStatus; } void * CMclSharedMemory::GetPtr(void) { return m_lpSharedMemory; } BOOL CMclSharedMemory::IsCreator(void) { return m_bIsCreator; } |
Added win/Mcl/src/CMclThread.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | // // FILE: CMclThread.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclThread.h" #include <stdlib.h> // for errno declaration // destructor does nothing, it is simply a placeholder for // ensure the destructors of derived classes are virtual... CMclThreadHandler::~CMclThreadHandler() { return; } // constructor creates a thread C++ object and // creates the kernel thread object which begins executing // at the ThreadHandlerProc of the cThreadHandler object... CMclThread::CMclThread( CMclThreadHandler *pcThreadHandler, unsigned uInitFlag, LPSECURITY_ATTRIBUTES lpSecurity, unsigned uStackSize) : m_pcThreadHandler(pcThreadHandler) { // create the thread, saving the thread HANDLE, identifier, and // setting the status, call the class static function to forward // the thread on to the thread handler... m_hHandle = (HANDLE) _beginthreadex( lpSecurity, uStackSize, CallThreadHandlerProc, m_pcThreadHandler, uInitFlag, &m_uiThreadID); if (CMclIsValidHandle(m_hHandle)) { m_dwStatus = NO_ERROR; } else { // throw thread creation error... m_dwStatus = errno; ThrowError(m_dwStatus); } } unsigned _stdcall CMclThread::CallThreadHandlerProc(void *pThreadHandler) { // the constructor calls us here to start the thread, we need to // use the argument and convert it to a CMclThreadHandler so that // we can call the CMclThreadHandler::ThreadHandlerProc() as a member // function... CMclThreadHandler *pcHandler = static_cast<CMclThreadHandler *>(pThreadHandler); // call the handler procedure and return the exit code... return pcHandler->ThreadHandlerProc(); } // suspend the thread... DWORD CMclThread::Suspend(void) { return ::SuspendThread( m_hHandle); } // resume the thread... DWORD CMclThread::Resume(void) { return ::ResumeThread( m_hHandle); } // terminate the thread... BOOL CMclThread::Terminate( DWORD dwExitCode) { return ::TerminateThread( m_hHandle, dwExitCode); } // read a thread's exit code... BOOL CMclThread::GetExitCode( DWORD *pdwExitCode) { return ::GetExitCodeThread( m_hHandle, pdwExitCode); } // set a thread's priority... BOOL CMclThread::SetPriority( int nPriority) { return ::SetThreadPriority( m_hHandle, nPriority); } // read a thread's priority... int CMclThread::GetPriority( void) { return ::GetThreadPriority( m_hHandle); } // return the thread's identifier... DWORD CMclThread::GetThreadId(void) { return static_cast<DWORD>(m_uiThreadID); } |
Added win/Mcl/src/CMclWaitableCollection.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | // // FILE: CMclWaitableCollection.cpp // // Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring // ///////////////////////////////////////////////////////////////////////// #include "CMclWaitableCollection.h" CMclWaitableCollection::CMclWaitableCollection() { m_lObjects = 0; } CMclWaitableCollection::~CMclWaitableCollection() { // must implement virtual destructor... return; } CMclWaitableCollection::CMclWaitableCollection(CMclWaitableCollection & rhs) { // copy constructor uses assignment operator... *this = rhs; } CMclWaitableCollection & CMclWaitableCollection::operator= (CMclWaitableCollection & rhs) { if (this == &rhs) return (*this); for (int i = 0; i < rhs.m_lObjects; i++) { m_aObjectHandles[i] = rhs.m_aObjectHandles[i]; } m_lObjects = rhs.m_lObjects; return *this; } LONG CMclWaitableCollection::GetCount(void) const { return m_lObjects; } BOOL CMclWaitableCollection::AddObject(const CMclWaitableObject *pObject) { // make sure that we are not full... if (m_lObjects == MAXIMUM_WAIT_OBJECTS) return FALSE; // add the object's HANDLE to our wait list... m_aObjectHandles[m_lObjects++] = pObject->GetHandle(); return TRUE; } BOOL CMclWaitableCollection::AddObject(const CMclWaitableObject & rObject) { // make sure that we are not full... if (m_lObjects == MAXIMUM_WAIT_OBJECTS) return FALSE; // add the object's HANDLE to our wait list... m_aObjectHandles[m_lObjects++] = rObject.GetHandle(); return TRUE; } BOOL CMclWaitableCollection::AddObject(const CMclEvent & ceEvent) { // make sure that we are not full... if (m_lObjects == MAXIMUM_WAIT_OBJECTS) return FALSE; // add the HANDLE to our wait list... m_aObjectHandles[m_lObjects++] = ceEvent.GetHandle(); return TRUE; }; BOOL CMclWaitableCollection::AddObject(const HANDLE hHandle) { // make sure that we are not full... if (m_lObjects == MAXIMUM_WAIT_OBJECTS) return FALSE; // add the HANDLE to our wait list... m_aObjectHandles[m_lObjects++] = hHandle; return TRUE; } BOOL CMclWaitableCollection::AddCollection( const CMclWaitableCollection & rCollection) { for (int i = 0; i < rCollection.m_lObjects; i++) { if (!AddObject(rCollection.m_aObjectHandles[i])) return FALSE; } return TRUE; } DWORD CMclWaitableCollection::Wait( BOOL bWaitAll, DWORD dwMilliseconds) const { // check the number of objects... if (m_lObjects == 0) { return WAIT_FAILED; } // wait for the objects... return ::WaitForMultipleObjects( m_lObjects, m_aObjectHandles, bWaitAll, dwMilliseconds); } |
Added win/MsvcDbgControl.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /* ---------------------------------------------------------------------------- * MsvcDbgControl.cpp -- * * Debugger friendly replacements for CreateProcess() on the parent side * and GetCommandLine() on the child side. * * This stuff may not be perfect, but the intent is to avoid all * the manual-ness of having to set a specific commandline by hand * while debugging the system. * * See the note on line 259 for needing to set a soft break on the * child side. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.sf.net/ * http://expect.nist.gov/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: MsvcDbgControl.cpp,v 1.1.2.6 2002/03/12 04:37:39 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <atlbase.h> extern CComModule _Module; #include <atlcom.h> #include <initguid.h> #include <comdef.h> #include <ObjModel\appauto.h> #include <ObjModel\appdefs.h> #include <ObjModel\appguid.h> #include <ObjModel\dbgauto.h> #include <ObjModel\dbgguid.h> #include <ObjModel\dbgdefs.h> CRITICAL_SECTION cs; CRITICAL_SECTION *pcs = 0L; //Uninitialize COM and VC++ static void VCDbgClose(void *token) { IApplication *pApp = reinterpret_cast<IApplication *>(token); // Quit from Visual C++ pApp->Quit(); pApp = 0L; // Uninitialize COM libraries CoUninitialize(); } static char * bstr2oem(BSTR bstr) { int size, len = SysStringLen(bstr); char *buf; size = WideCharToMultiByte(CP_OEMCP, 0, bstr, len, 0, 0, NULL, NULL); buf = new char [size+1]; len = WideCharToMultiByte(CP_OEMCP, 0, bstr, len, buf, size, NULL, NULL); *(buf+len) = '\0'; return buf; } static int nameMangledAndTooCPlusPlusishToBeExternC (const CHAR *wrkspace, Tcl_DString *cmdline, void **token) { IApplication *pApp = reinterpret_cast<IApplication *>(*token); VARIANT_BOOL visibility = VARIANT_TRUE; HRESULT hr; DWORD dwRet; CComPtr<IDispatch> iDisp = NULL; size_t i; int thePid = -1; if (pApp == 0L) { // Initialize COM libraries hr = CoInitialize(NULL); if(FAILED(hr)) { OutputDebugString("Failed to initialize the COM libraries\n"); return thePid; } // Obtain the IApplication pointer hr = CoCreateInstance(CLSID_Application, NULL, CLSCTX_LOCAL_SERVER, IID_IApplication, token); if(FAILED(hr)) { OutputDebugString("Failed to create an instance of MSDEV\n"); CoUninitialize(); return thePid; } // reset pApp. Only a convenience. pApp = reinterpret_cast<IApplication *>(*token); // Set the visibility of MSDEV to TRUE hr = pApp->put_Visible(visibility); if(FAILED(hr)) { OutputDebugString("Failed to set visibility of MSDEV\n"); //Uninitialize COM libraries and quit from Visual C++ VCDbgClose(*token); return thePid; } for (i = (strlen(wrkspace) - 1);; i--) { if (wrkspace[i] == '\\') { break; } } i++; // Set the current directory CComBSTR dir(i, wrkspace); hr = pApp->put_CurrentDirectory(dir); if(FAILED(hr)) { OutputDebugString("Failed to set current directory\n"); //Uninitialize COM libraries and quit from Visual C++ VCDbgClose(*token); return thePid; } // Obtain the IDocuments pointer using smart pointer classes pApp->get_Documents(&iDisp); CComQIPtr<IDocuments, &IID_IDocuments> pDocs(iDisp); // Open the slavedrv workspace CComBSTR fname(wrkspace+i); CComVariant type="Auto"; CComVariant read="False"; iDisp=NULL; hr = pDocs->Open(fname,type,read,&iDisp); if(FAILED(hr)) { OutputDebugString("Failed to open the workspace\n"); // Uninitialize COM libraries and quit from Visual C++ VCDbgClose(*token); return thePid; } } // Obtain the IDebugger pointer. pApp->get_Debugger(&iDisp); CComQIPtr<IDebugger, &IID_IDebugger> pDebug(iDisp); if (pcs == 0L) { InitializeCriticalSection(pcs = &cs); } // We need to syncronize entry as we're using a kernel event by name. EnterCriticalSection(&cs); // Create the event we'll block for. HANDLE event1 = CreateEvent(0L, FALSE, FALSE, "SpawnStartup"); hr = pDebug->Go(); if(FAILED(hr)) { OutputDebugString("Failed to start the debugger\n"); // Uninitialize COM libraries and quit from Visual C++ VCDbgClose(pApp); goto end; } // Wait forever as we might need to rebuild or some such. // Just because Go() returned doesn't mean it's running... dwRet = WaitForSingleObject(event1, INFINITE); if (dwRet != WAIT_OBJECT_0) goto end; // Just to make sure AppB hit the soft break. Sleep(300); // Now that the child hit the soft break, ask it what its pid // global variable has in it. { CComBSTR askpid("pid"); CComBSTR gotpid; char *keyName; HKEY root; hr = pDebug->Evaluate(askpid, &gotpid); thePid = _wtoi(gotpid.m_str); keyName = bstr2oem(gotpid); RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Tomasoft\\MsDevDbgCtrl", 0, REG_NONE, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0L, &root, 0L); // Save the commandline in the registry using the PID as the key. RegSetValueEx(root, keyName, 0, REG_SZ, (BYTE *) Tcl_DStringValue(cmdline), Tcl_DStringLength(cmdline)); delete keyName; RegFlushKey(root); RegCloseKey(root); } // continue AppB from the soft break. hr = pDebug->Go(); end: CloseHandle(event1); LeaveCriticalSection(&cs); return thePid; } extern "C" int MsvcDbg_Launch(const CHAR *wrkspace, Tcl_DString *cmdline, void **token) { // Protect from all the COM wierdness taken us down __try { return nameMangledAndTooCPlusPlusishToBeExternC(wrkspace, cmdline, token); } __except(EXCEPTION_EXECUTE_HANDLER) { return -1; } } |
Added win/MsvcDbgControl.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* ---------------------------------------------------------------------------- * MsvcDbgControl.h -- * * Debugger friendly replacements for CreateProcess() on the parent side * and GetCommandLine() on the child side. * * This stuff may not be perfect, but the intent is to avoid all * the manual-ness of having to set a specific commandline by hand * while debugging the system. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: MsvcDbgControl.h,v 1.1.2.4 2002/03/09 01:17:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef INC_MsvcDbgControl_h__ #define INC_MsvcDbgControl_h__ #include <windows.h> extern TCL_CPP int MsvcDbg_Launch(const CHAR *wrkspace, Tcl_DString *cmdline, void **token); #endif |
Added win/TclAdapter.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | /* ------------------------------------------------------------------------------ * TclAdapter.hpp -- * * Defines one templated class for doing the grunt work for making * C++ extensions. * * Copyright (c) 1999-2001 TomaSoft Engineering * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: TclAdapter.hpp,v 1.1.2.1 2002/03/11 00:31:56 davygrvy Exp $ ------------------------------------------------------------------------------ */ #ifndef INC_TclAdapter_hpp__ #define INC_TclAdapter_hpp__ #include "tcl.h" // We need at least the Tcl_Obj interface that was started in 8.0 #if TCL_MAJOR_VERSION < 8 # error "we need Tcl 8.0 or greater to build this" // Check for Stubs compatibility when asked for it. #elif defined(USE_TCL_STUBS) && TCL_MAJOR_VERSION == 8 && \ (TCL_MINOR_VERSION == 0 || \ (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL != TCL_FINAL_RELEASE)) # error "Stubs interface doesn't work in 8.0 and alpha/beta 8.1; only 8.1.0+" #endif #ifdef _MSC_VER // Only do this when MSVC++ is compiling us. # ifdef USE_TCL_STUBS // Mark this .obj as needing tcl's Stubs library. # pragma comment(lib, "tclstub" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # if !defined(_MT) || !defined(_DLL) || defined(_DEBUG) // This fixes a bug with how the Stubs library was compiled. // The requirement for msvcrt.lib from tclstubXX.lib should // be removed. # pragma comment(linker, "-nodefaultlib:msvcrt.lib") # endif # else // Mark this .obj needing the import library # pragma comment(lib, "tcl" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # endif #endif // We only need one Win32 API in here so we can be super defensive // with the destructor. #ifdef __WIN32__ # include <windows.h> # ifdef _MSC_VER # pragma comment (lib, "kernel32.lib") # endif #endif // short cut #define NewTclCmd(a,b,c) \ Tcl_CreateObjCommand((a), (b), CmdDemux, CmdInfo((c), this), CmdDelete) namespace Tcl { template <class T> class Adapter { typedef struct { T *ext; int (T::*cmd)(int, struct Tcl_Obj * CONST []); } MPLEXDATA, *LPMPLEXDATA; protected: Adapter(Tcl_Interp *_interp); ~Adapter(); Tcl_Interp *interp; virtual void DoCleanup(void) = 0; // Create the multiplexor data that we save in the ClientData portion // of the Tcl command. ClientData CmdInfo(int (T::*cmd)(int, struct Tcl_Obj * CONST []), T *that) { LPMPLEXDATA mplex = new MPLEXDATA; mplex->ext = that; mplex->cmd = cmd; return static_cast <ClientData>(mplex); } static Tcl_InterpDeleteProc InterpDeleting; static Tcl_ExitProc Exiting; static Tcl_ObjCmdProc CmdDemux; static Tcl_CmdDeleteProc CmdDelete; }; template <class T> Adapter<T>::Adapter(Tcl_Interp *_interp) : interp(_interp) { Tcl_CallWhenDeleted(interp, InterpDeleting, this); Tcl_CreateExitHandler(Exiting, this); } template <class T> Adapter<T>::~Adapter() { Tcl_DeleteExitHandler(Exiting, this); } template <class T> void Adapter<T>::InterpDeleting (ClientData clientData, Tcl_Interp *) { T *adapt = static_cast <T *>(clientData); adapt->DoCleanup(); delete adapt; } template <class T> void Adapter<T>::Exiting (ClientData clientData) { #ifdef __WIN32__ // It can happen that the HEAP could have already been unloaded from an // awkward teardown caused by a Ctrl+C or other. Win32 seems to do a // teardown in reverse order and by the time Tcl knows what's going on // and Tcl_Finalize calls the exit handlers, this extension's data has // already been unloaded by the OS. Do a quick legal check on the // pointer first. if (IsBadReadPtr(clientData, sizeof(T *))) return; #endif delete static_cast <T *>(clientData); } template <class T> int Adapter<T>::CmdDemux (ClientData clientData, Tcl_Interp *, int objc, struct Tcl_Obj * CONST objv[]) { LPMPLEXDATA demux = static_cast <LPMPLEXDATA>(clientData); // We aleady know what the interp pointer is (saved in the class // instance), so don't bother with it here. Call the member function // of the extension instance as saved in the MPLEXDATA struct when we // created this command using the somewhat obscure C++ pointer-to- // member method. // // This is a demultiplexor or 'demux' for short. return ((demux->ext) ->* (demux->cmd)) (objc,objv); } template <class T> void Adapter<T>::CmdDelete (ClientData clientData) { // clean-up the MPLEXDATA structure from the commands. delete static_cast <LPMPLEXDATA>(clientData); } } #endif |
Added win/TclHash.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | /* ------------------------------------------------------------------------------ * TclHash.hpp -- * * Tcl's hash table done as a template. * * Copyright (c) 1999-2001 David Gravereaux * * See the file "license.txt" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: TclHash.hpp,v 1.1.2.1 2002/03/12 16:42:07 davygrvy Exp $ ------------------------------------------------------------------------------ */ #ifndef INC_tclhash_hpp__ #define INC_tclhash_hpp__ #include "tcl.h" namespace Tcl { template <class T, int keytype = TCL_STRING_KEYS> class Hash { public: Hash () { Tcl_InitHashTable(&HashTbl, keytype); } ~Hash () { Tcl_DeleteHashTable(&HashTbl); } Tcl_Obj *Stats (); int Add (void *key, T result); int Find (void *key, T *result); int Delete (void *key); int Top (T *result); int Next (T *result); protected: Tcl_HashSearch HashSrch; Tcl_HashTable HashTbl; }; template <class T, int keytype> Tcl_Obj *Hash<T, keytype>::Stats () { char *stats; Tcl_Obj *oStats; stats = Tcl_HashStats(&HashTbl); oStats = Tcl_NewStringObj(stats, -1); ckfree(stats); return oStats; } template <class T, int keytype> int Hash<T, keytype>::Add (void *key, T result) { int created; Tcl_HashEntry *entryPtr; entryPtr = Tcl_CreateHashEntry(&HashTbl, static_cast<const char *>(key), &created); if (!created) { return TCL_ERROR; } Tcl_SetHashValue(entryPtr, result); return TCL_OK; } template <class T, int keytype> int Hash<T, keytype>::Find (void *key, T *result) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FindHashEntry(&HashTbl, static_cast<const char *>(key)); if (entryPtr == 0L) { return TCL_ERROR; } if (result != 0L) { *result = static_cast<T>(Tcl_GetHashValue(entryPtr)); } return TCL_OK; } template <class T, int keytype> int Hash<T, keytype>::Delete (void *key) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FindHashEntry(&HashTbl, static_cast<const char *>(key)); if (entryPtr == 0L) { return TCL_ERROR; } Tcl_DeleteHashEntry(entryPtr); return TCL_OK; } template <class T, int keytype> int Hash<T, keytype>::Top (T *result) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_FirstHashEntry(&HashTbl, &HashSrch); if (entryPtr == 0L) { return TCL_ERROR; } if (result != 0L) { *result = static_cast<T>(Tcl_GetHashValue(entryPtr)); } return TCL_OK; } template <class T, int keytype> int Hash<T, keytype>::Next (T *result) { Tcl_HashEntry *entryPtr; entryPtr = Tcl_NextHashEntry(&HashSrch); if (entryPtr == 0L) { return TCL_ERROR; } if (result != 0L) { *result = static_cast<T>(Tcl_GetHashValue(entryPtr)); } return TCL_OK; } }; // namespace Tcl #endif // #ifndef INC_tclhash_hpp__ |
Added win/debugger.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 | /* * debugger.c -- * * This is sample code that was used for testing. The code has * been migrated into expWinSlaveDrv.c, but it is still very useful * on it own. * * Copyright (c) 1997 by Mitel Corporation * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Notes: * This code does not keep track of console handles. It does prints * mode changes. expWinSlaveDrv.c keeps track of changes. */ /* * Even though we won't have access to most of the commands, use the * same headers */ #include "tcl.h" #include "tclPort.h" #include "expWin.h" #include <assert.h> HANDLE HProcess; /* handle to subprocess */ DWORD PSubprocessMemory; /* Pointer to allocated memory in subprocess */ #define SINGLE_STEP_BIT 0x100; /* This only works on the x86 processor */ typedef struct _ExpThreadInfo { HANDLE hThread; DWORD dwThreadId; DWORD nargs; DWORD args[16]; /* Space for saving 16 args. We need this * space while we are waiting for the return * value for the function. */ struct _ExpThreadInfo *nextPtr; } ExpThreadInfo; /* * List of threads in the subprocess */ static ExpThreadInfo *ThreadList = NULL; typedef void (ExpDebBreakProc) (ExpThreadInfo *threadInfo, DWORD ret); typedef struct _ExpDebBreakInfo { PUCHAR funcName; /* Name of function to intercept */ DWORD nargs; /* Number of arguments */ ExpDebBreakProc *breakProc; /* Function to call when a breakpoint is hit */ } ExpDebBreakInfo; typedef struct _ExpDebBreakpoint { BOOL returning; /* Is this a returning breakpoint? */ UCHAR code; /* Original code */ PVOID codePtr; /* Address of original code */ UINT retCodeOffset; /* Offset in allocated page for breakpoint * on return */ DWORD origRetAddr; /* Original return address */ ExpDebBreakInfo *breakInfo; /* Information about the breakpoint */ ExpThreadInfo *threadInfo; /* If this breakpoint is for a specific * thread */ struct _ExpDebBreakpoint *nextPtr; } ExpDebBreakpoint; /* * List of breakpoints in the subprocess */ static ExpDebBreakpoint *BreakpointList = NULL; static PVOID AllocProcessMemory(HANDLE hProcess, DWORD numBytes); static ExpDebBreakInfo *CheckAddBreakpoint(PCHAR funcName); static void OnBreakpoint(LPDEBUG_EVENT); static void OnCreateProcess(LPDEBUG_EVENT); static void OnCreateThread(LPDEBUG_EVENT); static void OnFirstBreakpoint(LPDEBUG_EVENT); static void OnGetStdHandle(ExpThreadInfo *threadInfo, DWORD ret); static void OnLoadDll(LPDEBUG_EVENT); static void OnOpenConsoleW(ExpThreadInfo *threadInfo, DWORD ret); static void OnWriteConsoleA(ExpThreadInfo *threadInfo, DWORD ret); static void OnWriteConsoleW(ExpThreadInfo *threadInfo, DWORD ret); static void OnSingleStep(LPDEBUG_EVENT); static void OnSetConsoleMode(ExpThreadInfo *threadInfo, DWORD ret); static BOOL ReadSubprocessMemory(LPVOID addr, LPVOID buf, DWORD len); static int ReadSubprocessStringA(PVOID base, PCHAR buf, int buflen); static int ReadSubprocessStringW(PVOID base, PWCHAR buf, int buflen); static BOOL WriteSubprocessMemory(LPVOID addr, LPVOID buf, DWORD len); /* *---------------------------------------------------------------------- * * main -- * * Main entry point from Windows. The arguments to this program * are used to create the subprocess that this will control. * * argv[1] is the program we will run, and all the following * are its arguments. * * Results: * None * * Side Effects: * The launch of this program will have caused a console to be * allocated. This will then send commands to subprocesses. * *---------------------------------------------------------------------- */ void main(int argc, char **argv) { DWORD dwResult; Tcl_Pid slavePid; /* Process identifier of slave */ DWORD globalPid; /* Globally unique identifier of slave */ DEBUG_EVENT debEvent; /* debugging event info. */ DWORD dwContinueStatus; /* exception continuation */ if (argc < 2) { fprintf(stderr, "Usage: %s progname ...\n"); exit(1); } dwResult = ExpCreateProcess(argc-1, &argv[1], NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE, &slavePid, &globalPid); if (dwResult) { fprintf(stderr, "Unable to create process %s\n", argv[1]); exit(1); } HProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, globalPid); if (HProcess == NULL) { fprintf(stderr, "Unable to debug process %s\n", argv[1]); exit(1); } dwContinueStatus = DBG_CONTINUE; for(;;) { /* * Wait for a debugging event to occur. The second parameter * indicates that the function does not return until * a debugging event occurs. */ WaitForDebugEvent(&debEvent, INFINITE); /* Process the debugging event code. */ switch (debEvent.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: /* * Process the exception code. When handling * exceptions, remember to set the continuation * status parameter (dwContinueStatus). This value * is used by the ContinueDebugEvent function. */ switch (debEvent.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: /* * First chance: Pass this on to the kernel. * Last chance: Display an appropriate error. */ dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; break; case EXCEPTION_BREAKPOINT: { static BOOL firstBreakpoint = 1; if (firstBreakpoint) { firstBreakpoint = 0; OnFirstBreakpoint(&debEvent); } else { OnBreakpoint(&debEvent); } break; } case EXCEPTION_SINGLE_STEP: OnSingleStep(&debEvent); break; case EXCEPTION_DATATYPE_MISALIGNMENT: /* * First chance: Pass this on to the kernel. * Last chance: Display an appropriate error. */ dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; break; case DBG_CONTROL_C: /* * First chance: Pass this on to the kernel. * Last chance: Display an appropriate error. */ dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; break; default: dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; } break; case CREATE_THREAD_DEBUG_EVENT: OnCreateThread(&debEvent); break; case CREATE_PROCESS_DEBUG_EVENT: OnCreateProcess(&debEvent); break; case EXIT_THREAD_DEBUG_EVENT: /* Display the thread's exit code. */ break; case EXIT_PROCESS_DEBUG_EVENT: /* Display the process's exit code. */ exit(0); break; case LOAD_DLL_DEBUG_EVENT: OnLoadDll(&debEvent); break; case UNLOAD_DLL_DEBUG_EVENT: /* * Display a message that the DLL has * been unloaded. */ break; case OUTPUT_DEBUG_STRING_EVENT: /* Display the output debugging string. */ break; } /* Resume executing the thread that reported the debugging event. */ ContinueDebugEvent(debEvent.dwProcessId, debEvent.dwThreadId, dwContinueStatus); } exit(0); } /* *---------------------------------------------------------------------- * * OnCreateProcess -- * * This routine is called when a CREATE_PROCESS_DEBUG_EVENT * occurs. * * Results: * None * *---------------------------------------------------------------------- */ void OnCreateProcess(LPDEBUG_EVENT pDebEvent) { /* * As needed, examine or change the registers of the * process's initial thread with the GetThreadContext and * SetThreadContext functions; read from and write to the * process's virtual memory with the ReadProcessMemory and * WriteProcessMemory functions; and suspend and resume * thread execution with the SuspendThread and ResumeThread * functions. */ ExpThreadInfo *threadInfo; LPCREATE_PROCESS_DEBUG_INFO info = &pDebEvent->u.CreateProcessInfo; PVOID ptr; threadInfo = (ExpThreadInfo *) malloc(sizeof(ExpThreadInfo)); threadInfo->dwThreadId = pDebEvent->dwThreadId; threadInfo->hThread = info->hThread; threadInfo->nextPtr = ThreadList; ThreadList = threadInfo; if (info->lpImageName) { /* * This info->lpImageName is a pointer to the name of the * DLL in the process space of the subprocess */ if (ReadSubprocessMemory(info->lpImageName, &ptr, sizeof(PVOID)) && ptr) { if (info->fUnicode) { WCHAR name[256]; ReadSubprocessStringW(ptr, name, 256); printf("0x%08x: Loaded %S\n", info->lpBaseOfImage, name); } else { CHAR name[256]; ReadSubprocessStringA(ptr, name, 256); printf("0x%08x: Loaded %S\n", info->lpBaseOfImage, name); } } else { printf("Loaded unknown Executable"); } if (info->dwDebugInfoFileOffset) { printf(" with debugging info at offset 0x%08x\n", info->dwDebugInfoFileOffset); } } else { printf("Starting unknown process\n"); } } /* *---------------------------------------------------------------------- * * OnCreateThread -- * * This routine is called when a CREATE_THREAD_DEBUG_EVENT * occurs. * * Results: * None * *---------------------------------------------------------------------- */ void OnCreateThread(LPDEBUG_EVENT pDebEvent) { /* * As needed, examine or change the thread's registers * with the GetThreadContext and SetThreadContext functions; * and suspend and resume thread execution with the * SuspendThread and ResumeThread functions. */ ExpThreadInfo *threadInfo; threadInfo = (ExpThreadInfo *) malloc(sizeof(ExpThreadInfo)); threadInfo->dwThreadId = pDebEvent->dwThreadId; threadInfo->hThread = pDebEvent->u.CreateThread.hThread; threadInfo->nextPtr = ThreadList; ThreadList = threadInfo; } /* *---------------------------------------------------------------------- * * OnFirstBreakpoint -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_BREAKPOINT, and it is the * first one to occur in the program. This happens when the * process finally gets loaded into memory and is about to * start. * * Results: * None * *---------------------------------------------------------------------- */ static void OnFirstBreakpoint(LPDEBUG_EVENT pDebEvent) { DWORD i; UCHAR buf[4]; DWORD base; printf("Hit first breakpoint\n"); /* * Set up the memory that will serve as the place for our * intercepted function return */ PSubprocessMemory = (DWORD) AllocProcessMemory(HProcess, 4096); base = PSubprocessMemory; buf[0] = 0xcc; /* INT 3 */ buf[1] = 0xc3; /* RET */ buf[2] = 0x00; /* Unused */ buf[3] = 0x00; /* Unused */ for (i = 0; i < 4096; i += sizeof(DWORD)) { WriteSubprocessMemory((PVOID) (base + i), buf, sizeof(DWORD)); } return; } static ExpDebBreakpoint *LastBreakpoint = NULL; /* *---------------------------------------------------------------------- * * OnBreakpoint -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_BREAKPOINT. * * Results: * None * * Notes: * XXX: Maybe should only deal with this on a first chance * exception. * *---------------------------------------------------------------------- */ static void OnBreakpoint(LPDEBUG_EVENT pDebEvent) { LPEXCEPTION_DEBUG_INFO exceptInfo; CONTEXT context; ExpThreadInfo *tinfo; ExpDebBreakpoint *pbinfo, *binfo; PDWORD pdw; DWORD i; DWORD dw; for (tinfo = ThreadList; tinfo != NULL; tinfo = tinfo->nextPtr) { if (pDebEvent->dwThreadId == tinfo->dwThreadId) { break; } } assert(tinfo != NULL); exceptInfo = &pDebEvent->u.Exception; pbinfo = NULL; for (binfo = BreakpointList; binfo != NULL; pbinfo = binfo, binfo = binfo->nextPtr) { if (binfo->codePtr == exceptInfo->ExceptionRecord.ExceptionAddress) { if (binfo->threadInfo == NULL) { break; } if (binfo->threadInfo == tinfo) { break; } } } assert(binfo != NULL); context.ContextFlags = CONTEXT_FULL; GetThreadContext(tinfo->hThread, &context); if (! binfo->returning) { ExpDebBreakpoint *bpt; /* * Get the arguments to the function and store them in the thread * specific data structure. */ for (pdw = tinfo->args, i=0; i < binfo->breakInfo->nargs; i++, pdw++) { ReadSubprocessMemory((PVOID) (context.Esp+(4*(i+1))), pdw, sizeof(DWORD)); } tinfo->nargs = binfo->breakInfo->nargs; #if 0 /* * Add an additional return address on the stack. This is to our * return area. */ context.Esp -= 4; #endif bpt = (ExpDebBreakpoint *) malloc(sizeof(ExpDebBreakpoint)); ReadSubprocessMemory((PVOID) context.Esp, &bpt->origRetAddr, sizeof(DWORD)); dw = PSubprocessMemory + binfo->retCodeOffset; WriteSubprocessMemory((PVOID) context.Esp, &dw, sizeof(DWORD)); bpt->returning = TRUE; bpt->codePtr = (PVOID) (PSubprocessMemory + binfo->retCodeOffset); bpt->retCodeOffset = 0; /* Doesn't matter */ bpt->breakInfo = binfo->breakInfo; bpt->threadInfo = tinfo; bpt->nextPtr = BreakpointList; BreakpointList = bpt; /* * Now, we need to restore the original code for this breakpoint. * Put the program counter back, then do a single-step and put * the breakpoint back again. */ WriteSubprocessMemory(binfo->codePtr, &binfo->code, sizeof(UCHAR)); context.EFlags |= SINGLE_STEP_BIT; context.Eip--; LastBreakpoint = binfo; } else { /* * Make the callback with the params and the return value */ binfo->breakInfo->breakProc(tinfo, context.Eax); /* * Set the instruction pointer to the original return address * and continue. */ context.Eip = binfo->origRetAddr; if (pbinfo == NULL) { BreakpointList = binfo->nextPtr; } else { pbinfo->nextPtr = binfo->nextPtr; } free(binfo); } SetThreadContext(tinfo->hThread, &context); } /* *---------------------------------------------------------------------- * * OnSingleStep -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_SINGLE_STEP. * * Results: * None * * Notes: * XXX: Maybe should only deal with this on a first chance * exception. * *---------------------------------------------------------------------- */ static void OnSingleStep(LPDEBUG_EVENT pDebEvent) { UCHAR code; /* * Now, we need to restore the breakpoint that we had removed. */ code = 0xcc; WriteSubprocessMemory(LastBreakpoint->codePtr, &code, sizeof(UCHAR)); } /* *---------------------------------------------------------------------- * * OnLoadDll -- * * This routine is called when a LOAD_DLL_DEBUG_EVENT is seen * * Results: * None * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ void OnLoadDll(LPDEBUG_EVENT pDebEvent) { WORD w; DWORD dw; DWORD ImageHdrOffset; PIMAGE_FILE_HEADER pfh; /* File header image in subprocess memory */ PIMAGE_SECTION_HEADER psh; PIMAGE_OPTIONAL_HEADER poh; IMAGE_DATA_DIRECTORY dataDir; PIMAGE_EXPORT_DIRECTORY ped; IMAGE_EXPORT_DIRECTORY exportDir; DWORD n; DWORD base; CHAR funcName[256]; CHAR dllname[256]; PVOID ptr, namePtr, funcPtr; DWORD p; LPLOAD_DLL_DEBUG_INFO info = &pDebEvent->u.LoadDll; ExpDebBreakInfo *debBreakInfo; int unknown = 0; if (info->lpImageName) { /* * This info->lpImageName is a pointer to the name of the * DLL in the process space of the subprocess */ if (ReadSubprocessMemory(info->lpImageName, &ptr, sizeof(PVOID)) && ptr) { if (info->fUnicode) { WCHAR name[256]; ReadSubprocessStringW(ptr, name, 256); printf("0x%08x: Loaded %S\n", info->lpBaseOfDll, name); } else { CHAR name[256]; ReadSubprocessStringA(ptr, name, 256); printf("0x%08x: Loaded %S\n", info->lpBaseOfDll, name); } } else { /* printf("Loaded unknown DLL"); */ unknown = 1; } if (info->dwDebugInfoFileOffset) { printf(" with debugging info at offset 0x%08x\n", info->dwDebugInfoFileOffset); } } base = (DWORD) info->lpBaseOfDll; /* * Check for the DOS signature */ ReadSubprocessMemory(info->lpBaseOfDll, &w, sizeof(WORD)); if (w != IMAGE_DOS_SIGNATURE) return; /* * Skip over the DOS signature and check the NT signature */ p = base; p += 15 * sizeof(DWORD); ptr = (PVOID) p; ReadSubprocessMemory((PVOID) p, &ImageHdrOffset, sizeof(DWORD)); p = base; p += ImageHdrOffset; ReadSubprocessMemory((PVOID) p, &dw, sizeof(DWORD)); if (dw != IMAGE_NT_SIGNATURE) { return; } ImageHdrOffset += sizeof(DWORD); p += sizeof(DWORD); pfh = (PIMAGE_FILE_HEADER) p; ptr = &pfh->SizeOfOptionalHeader; ReadSubprocessMemory(ptr, &w, sizeof(WORD)); /* * We want to find the exports section. It can be found in the * data directory that is part of the IMAGE_OPTIONAL_HEADER */ if (!w) return; p += sizeof(IMAGE_FILE_HEADER); poh = (PIMAGE_OPTIONAL_HEADER) p; /* * Find the number of entries in the data directory */ ptr = &poh->NumberOfRvaAndSizes; ReadSubprocessMemory(ptr, &dw, sizeof(DWORD)); if (dw == 0) return; /* * Read the export data directory */ ptr = &poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; ReadSubprocessMemory(ptr, &dataDir, sizeof(IMAGE_DATA_DIRECTORY)); /* * This points us to the exports section */ ptr = (PVOID) (base + dataDir.VirtualAddress); ped = (PIMAGE_EXPORT_DIRECTORY) ptr; ReadSubprocessMemory(ptr, &exportDir, sizeof(IMAGE_EXPORT_DIRECTORY)); /* * See if this is a DLL we are interested in */ ptr = &ped->Name; ReadSubprocessMemory(ptr, &dw, sizeof(DWORD)); ptr = (PVOID) (base + dw); ReadSubprocessStringA(ptr, dllname, sizeof(dllname)); /* * We now have the DLL name, even if it was unknown. */ if (unknown) { printf("0x%08x: Loaded %s\n", info->lpBaseOfDll, dllname); } if (stricmp(dllname, "kernel32.dll") != 0) { return; } ptr = (PVOID) (base + (DWORD) exportDir.AddressOfNames); for (n = 0; n < exportDir.NumberOfNames; n++) { /* * Look for SetConsoleMode() so we can set a breakpoint on * it. */ ReadSubprocessMemory(ptr, &dw, sizeof(DWORD)); namePtr = (PVOID) (base + dw); /* * Now, we should hopefully have a pointer to the name of the * function, so lets get it. */ ReadSubprocessStringA(namePtr, funcName, sizeof(funcName)); /* printf("%s\n", funcName); */ debBreakInfo = CheckAddBreakpoint(funcName); if (debBreakInfo) { /* * Set a breakpoint and save the original code. */ ExpDebBreakpoint *bpt; UCHAR code; static DWORD offset = 0; funcPtr = (PVOID) (base + n*sizeof(DWORD) + (DWORD) exportDir.AddressOfFunctions); ReadSubprocessMemory(funcPtr, &dw, sizeof(DWORD)); funcPtr = (PVOID) (base + dw); /* * Now, we have a pointer to the function in subprocess. */ bpt = (ExpDebBreakpoint *) malloc(sizeof(ExpDebBreakpoint)); bpt->returning = FALSE; bpt->codePtr = funcPtr; bpt->retCodeOffset = offset; bpt->breakInfo = debBreakInfo; bpt->threadInfo = NULL; offset += sizeof(DWORD); bpt->nextPtr = BreakpointList; BreakpointList = bpt; ReadSubprocessMemory(funcPtr, &bpt->code, sizeof(UCHAR)); code = 0xcc; /* Breakpoint opcode on i386 */ WriteSubprocessMemory(funcPtr, &code, sizeof(UCHAR)); } ptr = (PVOID) (sizeof(DWORD) + (ULONG) ptr); } /* * The IMAGE_SECTION_HEADER comes after the IMAGE_OPTIONAL_HEADER * (if the IMAGE_OPTIONAL_HEADER exists) */ p += w; psh = (PIMAGE_SECTION_HEADER) p; } #if 0 typedef void (ExpDebBreakProc) (HANDLE hThread, DWORD nargs, PDWORD args, DWORD ret, PCONTEXT); typedef struct _ExpDebBreakFunc { PUCHAR funcName; /* Name of function to intercept */ DWORD nargs; /* Number of arguments, 0 if we only care * about the return value */ ExpDebBreakProc *breakProc; /* Function to call when a breakpoint is hit */ } ExpDebBreakFunc; #endif ExpDebBreakInfo BreakArray[] = { {"GetStdHandle", 1, OnGetStdHandle}, {"OpenConsoleW", 4, OnOpenConsoleW}, {"SetConsoleMode", 2, OnSetConsoleMode}, {"WriteConsoleA", 5, OnWriteConsoleA}, {"WriteConsoleW", 5, OnWriteConsoleW}, {NULL, 0, NULL} }; /* *---------------------------------------------------------------------- * * CheckAddBreakpoint -- * * Read through an ?alphabetized? list of names and * add a breakpoint if the function name matches one * of them. * * Results: * None * *---------------------------------------------------------------------- */ static ExpDebBreakInfo * CheckAddBreakpoint(PCHAR funcName) { ExpDebBreakInfo *info; info = BreakArray; while (info->funcName) { if (strcmp(funcName, info->funcName) == 0) { break; } info++; } if (info->funcName) return info; return NULL; } /* *---------------------------------------------------------------------- * * OnOpenConsoleW -- * * This function gets called when an OpenConsoleW breakpoint * is hit. There is one big problem with this function--we * don't really know what the arguments are since there is * no documented use of it. It takes four arguments, so the * current guess is: * * HANDLE OpenConsoleW(DWORD DWORD dwDesiredAccess, * DWORD dwShareMode, * LPSECURITY_ATTRIBUTES lpSecurityAttributes, * DWORD dwFlagsAndAttributes); * * Need to write a small program that calls CreateFile("CONIN$", ...); * to test this theory. * * Results: * None * * Side Effects: * Save the return value in an array of known console handles * with their statuses. * *---------------------------------------------------------------------- */ static void OnOpenConsoleW(ExpThreadInfo *threadInfo, DWORD returnValue) { WCHAR name[256]; PVOID ptr; ptr = (PVOID) threadInfo->args[0]; ReadSubprocessStringW(ptr, name, 256); if (wcsicmp(name, L"CONIN$") == 0) { /* * Add to our list of known console handles */ } else if (wcsicmp(name, L"CONOUT$") == 0) { /* * Add to our list of known console handles */ } printf("OpenConsoleW(0x%08x, 0x%08x, 0x%08x, 0x%08x) ==> 0x%x\n", threadInfo->args[0], threadInfo->args[1], threadInfo->args[2], threadInfo->args[3], returnValue); #if 0 printf("OpenConsoleW(name=%S)\n", name); #endif } /* *---------------------------------------------------------------------- * * OnWriteConsoleA -- * * This function gets called when an WriteConsoleA breakpoint * is hit. * * Results: * None * * Side Effects: * Prints some output. * * Notes: * XXX: If this is using a handle to a known console handle, * then redirect the output to expect. * *---------------------------------------------------------------------- */ static void OnWriteConsoleA(ExpThreadInfo *threadInfo, DWORD returnValue) { CHAR name[256]; PVOID ptr; DWORD n; PCHAR p; ptr = (PVOID) threadInfo->args[1]; n = threadInfo->args[2]; if (n > 256) { if (n > 32768) n = 32768; p = malloc(n * sizeof(CHAR)); } else { p = name; } ReadSubprocessMemory(ptr, p, n * sizeof(CHAR)); p[n] = 0; printf("WriteConsoleA(0x%08x, 0x%08x, 0x%08x, 0x%08x) ==> 0x%x\n", threadInfo->args[0], threadInfo->args[1], threadInfo->args[2], threadInfo->args[3], returnValue); printf("WriteConsoleA(buf=%s)\n", p); if (p != name) { free(name); } } /* *---------------------------------------------------------------------- * * OnWriteConsoleW -- * * This function gets called when an WriteConsoleW breakpoint * is hit. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ static void OnWriteConsoleW(ExpThreadInfo *threadInfo, DWORD returnValue) { WCHAR name[256]; PVOID ptr; DWORD n; PWCHAR p; ptr = (PVOID) threadInfo->args[1]; n = threadInfo->args[2]; if (n > 256) { if (n > 32768) n = 32768; p = malloc(n * sizeof(WCHAR)); } else { p = name; } ReadSubprocessMemory(ptr, p, n * sizeof(WCHAR)); p[n] = 0; printf("WriteConsoleW(0x%08x, 0x%08x, 0x%08x, 0x%08x) ==> 0x%x\n", threadInfo->args[0], threadInfo->args[1], threadInfo->args[2], threadInfo->args[3], returnValue); printf("WriteConsoleW(buf=%S)\n", p); if (p != name) { free(name); } } /* *---------------------------------------------------------------------- * * OnSetConsoleMode -- * * This function gets called when a SetConsoleMode breakpoint * is hit. * * Results: * None * * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ static void OnSetConsoleMode(ExpThreadInfo *threadInfo, DWORD returnValue) { printf("SetConsoleMode(0x%08x, 0x%08x) ==> 0x%x\n", threadInfo->args[0], threadInfo->args[1], returnValue); } /* *---------------------------------------------------------------------- * * OnGetStdHandle -- * * This function gets called when a GetStdHandle breakpoint * is hit. * * Results: * None * * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ static void OnGetStdHandle(ExpThreadInfo *threadInfo, DWORD returnValue) { printf("GetStdHandle(0x%08x) ==> 0x%x\n", threadInfo->args[0], returnValue); } /* *---------------------------------------------------------------------- * * ReadSubprocessStringW -- * * Read a wide character string from the subprocess * * Results: * The length of the string in wide characters. * *---------------------------------------------------------------------- */ static int ReadSubprocessStringW(PVOID base, PWCHAR buf, int buflen) { PWCHAR ip, op; int i; ip = base; op = buf; i = 0; while (i < buflen-1) { if (! ReadSubprocessMemory(ip, op, sizeof(WCHAR))) { break; } if (*op == 0) break; op++; ip++; i++; } *op = 0; return i; } /* *---------------------------------------------------------------------- * * ReadSubprocessStringA -- * * Read an ANSI character string from the subprocess * * Results: * The length of the string in characters. * *---------------------------------------------------------------------- */ static int ReadSubprocessStringA(PVOID base, PCHAR buf, int buflen) { PCHAR ip, op; int i; ip = base; op = buf; i = 0; while (i < buflen-1) { if (! ReadSubprocessMemory(ip, op, sizeof(CHAR))) { break; } if (*op == 0) break; op++; ip++; i++; } *op = 0; return i; } /* *---------------------------------------------------------------------- * * ReadSubprocessMemory -- * * Reads memory from the subprocess. Takes care of all the * issues with page protection. * * Results: * FALSE if unsuccessful, TRUE if successful. * *---------------------------------------------------------------------- */ static BOOL ReadSubprocessMemory(LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret = TRUE; /* if not committed memory abort */ if (!VirtualQueryEx(HProcess, addr, &mbi, sizeof(mbi)) || mbi.State != MEM_COMMIT) { return FALSE; } /* if guarded memory, change protection temporarily */ if (!(mbi.Protect & PAGE_READONLY) && !(mbi.Protect & PAGE_READWRITE)) { VirtualProtectEx(HProcess, addr, len, PAGE_READONLY, &oldProtection); } if (!ReadProcessMemory(HProcess, addr, buf, len, NULL)) { ret = FALSE; } /* reset protection if changed */ if (oldProtection) { VirtualProtectEx(HProcess, addr, len, oldProtection, &oldProtection); } return ret; } /* *---------------------------------------------------------------------- * * WriteSubprocessMemory -- * * Writes memory from the subprocess. Takes care of all the * issues with page protection. * * Results: * 0 if unsuccessful, 1 if successful. * *---------------------------------------------------------------------- */ static BOOL WriteSubprocessMemory(LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret = TRUE; DWORD err; /* if not committed memory abort */ if (!VirtualQueryEx(HProcess, addr, &mbi, sizeof(mbi)) || mbi.State != MEM_COMMIT) { ret = FALSE; assert(ret != FALSE); return ret; } /* if guarded memory, change protection temporarily */ if (!(mbi.Protect & PAGE_READWRITE)) { if (!VirtualProtectEx(HProcess, addr, len, PAGE_READWRITE, &oldProtection)) { err = GetLastError(); } } if (!WriteProcessMemory(HProcess, addr, buf, len, NULL)) { ret = FALSE; err = GetLastError(); } /* reset protection if changed */ if (oldProtection) { VirtualProtectEx(HProcess, addr, len, oldProtection, &oldProtection); } if (ret == FALSE) { assert(ret != FALSE); } return ret; } /* *---------------------------------------------------------------------- * * AllocProcessMemory -- * * Allocates memory in the subprocess. Makes the memory readable, * writable, and executable. Allocation is done by calling * CreateRemoteThread(), making it unsuitable for use on Windows 95. * The alternative is to use some special injection code to load * a DLL that then calls AllocMemory() and stores the pointer * somewhere where we can get at it. * * Results: * A pointer that is valid in the other process * *---------------------------------------------------------------------- */ static PVOID AllocProcessMemory(HANDLE hProcess, DWORD numBytes) { HANDLE hThread; DWORD threadId; CONTEXT context; MEMORY_BASIC_INFORMATION mbi; PVOID pMem; DWORD oldProtection; hThread = CreateRemoteThread(HProcess, NULL, numBytes, (LPTHREAD_START_ROUTINE) NULL, 0, CREATE_SUSPENDED, &threadId); context.ContextFlags = CONTEXT_CONTROL; GetThreadContext(hThread, &context); /* * Address of top of stack is in stack pointer register */ VirtualQueryEx(hProcess, (PDWORD) context.Esp - 1, &mbi, sizeof(mbi)); pMem = (PVOID) mbi.BaseAddress; VirtualProtectEx(hProcess, pMem, numBytes, PAGE_EXECUTE_READWRITE, &oldProtection); return pMem; } |
Added win/expWinCommand.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 | /* ---------------------------------------------------------------------------- * expWinCommand.c -- * * Implements Windows specific parts required by expCommand.c. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinCommand.c,v 1.1.2.1.2.10 2002/02/10 12:03:30 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #endif #ifdef _DEBUG #include "MsvcDbgControl.h" static void *dbgtoken; #endif /* * Arbitrary, but this is the port we are going to use for communicating * with the slave driver. */ #define SLAVE_PORT 9877 static void ExpSockAcceptProc _ANSI_ARGS_((ClientData callbackData, Tcl_Channel chan, char *address, int port)); /* *---------------------------------------------------------------------- * * exp_f_new_platform -- * * Platform specific initialization of exp_f structure * * Results: * TRUE if successful, FALSE if unsuccessful. * * Side Effects: * None * *---------------------------------------------------------------------- */ int exp_f_new_platform(f) struct exp_f *f; { if (EXP_NOPID != f->pid) { f->tclPid = (Tcl_Pid) OpenProcess(PROCESS_ALL_ACCESS, FALSE, f->pid); TclWinAddProcess((HANDLE) f->tclPid, f->pid); } else { f->tclPid = (Tcl_Pid) INVALID_HANDLE_VALUE; } /* WIN32 only fields */ f->over.hEvent = NULL; return TRUE; } /* *---------------------------------------------------------------------- * * exp_f_free_platform -- * * Frees any platform specific pieces of the exp_f structure. * * Results: * None * *---------------------------------------------------------------------- */ void exp_f_free_platform(f) struct exp_f *f; { if (f->tclPid != (Tcl_Pid) INVALID_HANDLE_VALUE) { __try { CloseHandle((HANDLE) f->tclPid); } __except (1) {}; } if (f->over.hEvent) { CloseHandle(f->over.hEvent); f->over.hEvent = NULL; } } void exp_close_on_exec(fd) int fd; { /* This is here for place keeping purposes */ } /* *---------------------------------------------------------------------- * * exp_getpidproc -- * * Return the process id for this process * * Results: * A process id * *---------------------------------------------------------------------- */ int exp_getpidproc() { return GetCurrentProcessId(); } #define EXP_PIPE_BASENAME "\\\\.\\pipe\\ExpectPipe" /* *---------------------------------------------------------------------- * * Exp_SpawnCmd -- * * Creates a new expect process id. It normally does this * by creating a new process, but it may choose to open a * Tcl file id. * * Results: * A standard Tcl result * * Side Effects: * * NT Notes: * This whole thing is complicated immensely by NT's lack of * flexibility when dealing with console processes. For one, * a console process cannot have simultaneous access to more * than once console. There is no way to call DuplicateHandle() * on a console handle so a single executable could control * multiple consoles. This leaves one option: execute slave * controllers who allocate their own consoles and then control. * the actual slave. The normal expect process communicates * with these slave drivers over pipes. There is still one * remaining problem: consoles pop up on the screen. When * creating the subprocesses, force them to allocate new * consoles, but tell them to hide the consoles. This should * make everyone happy. For debugging, leave the consoles * visible as this shows us that something is happening. Another * alternative is this: create another desktop or * possibly another windows station/desktop combination, but * never make the desktop the active desktop. However, use the * desktop for running the slave driver in, and then the slave * console will show up in the hidden desktop. We can control * anything this way without annoying the user with all kinds * of stuff popping up. *---------------------------------------------------------------------- */ /* arguments are passed verbatim to execvp() */ /*ARGSUSED*/ int Exp_SpawnCmd(ClientData clientData,Tcl_Interp *interp,int argc,char **argv) { HANDLE hSlaveDrv = INVALID_HANDLE_VALUE; /* Handle to communicate with slave driver */ Tcl_Pid slaveDrvPid; /* Process id of the slave */ BOOL bRet; DWORD dwRet; DWORD count; int echo = TRUE; char **a; char *argv0 = argv[0]; char slaveName[50]; /* Used to set 'spawn_out(slave,name)' */ static int slaveId = 1; /* Start at one because console0 is expect's */ UCHAR buf[8]; /* enough space for child status info */ WCHAR execPath[MAX_PATH]; /* needed for unicode space. */ Tcl_DString slavePath; Tcl_DString slaveDrvPath; struct exp_f *f; HANDLE hEvent = NULL; OVERLAPPED over; DWORD globalPid; Tcl_Channel channel = NULL; Tcl_Channel channel2 = NULL; Tcl_Channel spawnChan = NULL; TclFile masterRFile; TclFile masterWFile; char *openarg = NULL; int leaveopen = 0; CONST char *val; int hide; int debug; char **nargv = NULL; int i, j; int usePipes = 0; int useSocket = 0; char pipeName[100]; static int pipeNameId = 0; char sockPort[10]; static int sockPortInc = 0; /* * Need to create a structure with hEvent, overlapped, etc * for each pipe we handle */ argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-nottyinit")) { exp_error(interp, "%s -nottyinit is unsupported on NT", argv0); return TCL_ERROR; } else if (streq(*argv,"-nottycopy")) { exp_error(interp, "%s -nottycopy is unsupported on NT", argv0); return TCL_ERROR; } else if (streq(*argv,"-noecho")) { echo = FALSE; } else if (streq(*argv,"-console")) { exp_error(interp, "%s -console is unsupported on NT", argv0); return TCL_ERROR; } else if (streq(*argv,"-pty")) { exp_error(interp, "%s -pty is unsupported on NT", argv0); return TCL_ERROR; } else if (streq(*argv,"-open")) { /* * This allows us to treat an open file id as an * expect process id. We should be eventually be able * to support this under NT. */ if (argc < 2) { exp_error(interp,"usage: %s -open file-identifier", argv0); return TCL_ERROR; } openarg = argv[1]; argc--; argv++; } else if (streq(*argv,"-leaveopen")) { /* * This leaves the file id open when the process id * gets closed. We should be able to eventually support * this under NT. */ if (argc < 2) { exp_error(interp,"usage: %s -leaveopen file-identifier", argv0); return TCL_ERROR; } openarg = argv[1]; leaveopen = TRUE; argc--; argv++; } else if (streq(*argv,"-ignore")) { if (argc < 2) { exp_error(interp,"usage: %s -ignore signal", argv0); return TCL_ERROR; } argc--; argv++; exp_error(interp, "%s -ignore is unsupported on NT", argv0); return TCL_ERROR; } else if (streq(*argv,"-pipes")) { usePipes = 1; } else if (streq(*argv,"-socket")) { useSocket = 1; } else break; } if (openarg) { if (argc != 0) { exp_error(interp,"usage: -[leave]open [fileXX]"); return TCL_ERROR; } if (echo) exp_log(0,"%s [open ...]\r\n",argv0); return ExpSpawnOpen(interp, openarg, leaveopen); } if (!openarg && (argc == 0)) { exp_error(interp,"usage: %s [spawn-args] program [program-args]", argv0); return(TCL_ERROR); } Tcl_ReapDetachedProcs(); if (echo) { exp_log(0,"%s ",argv0); for (a = argv;*a;a++) { exp_log(0,"%s ",*a); } exp_nflog("\r\n",0); } /* console0 would be the parent process console */ sprintf(slaveName, "console%d", slaveId++); Tcl_SetVar2(interp,EXP_SPAWN_OUT,"slave,name",slaveName,0); /* * Time to create our subprocess. slavedrv.exe is ALWAYS in the same * directory alongside the extension dll. */ Tcl_DStringInit(&slaveDrvPath); (*expWinProcs->getModuleFileNameProc)(expDllInstance, (LPTSTR) execPath, MAX_PATH); val = Tcl_WinTCharToUtf((LPTSTR)execPath, -1, &slaveDrvPath); for (i = Tcl_DStringLength(&slaveDrvPath) - 1; i > 0; i--) { if (*(val+i) == '\\') { Tcl_DStringSetLength(&slaveDrvPath, i+1); Tcl_DStringAppend(&slaveDrvPath, "slavedrv.exe", 12); break; } } Tcl_DStringInit(&slavePath); dwRet = ExpWinApplicationType(argv[0], &slavePath); if (dwRet == EXP_APPL_NONE) { errno = ENOENT; exp_error(interp, "couldn't execute \"%s\": %s", argv[0],Tcl_PosixError(interp)); return TCL_ERROR; } /* * The whole point of this is that named pipes don't exist on Win95, * so we have the sockets as a backup communications protocol. The user * can specify that they get sockets at all times if they want. */ if (useSocket == 0) { sprintf(pipeName, "%s%08x%08x", EXP_PIPE_BASENAME, GetCurrentProcessId(), pipeNameId++); hSlaveDrv = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 8192, 8192, 20000, NULL); } /* * If we cannot create the named pipe (or if we have been told to use * sockets for communications at this level), try opening a socket. */ if (hSlaveDrv == INVALID_HANDLE_VALUE) { channel2 = NULL; for (i = 0; i < 50 && channel2 == NULL; i++) { channel2 = Tcl_OpenTcpServer(interp, SLAVE_PORT + sockPortInc, NULL, ExpSockAcceptProc, (ClientData) &channel); sprintf(sockPort, "%d", SLAVE_PORT + sockPortInc); sockPortInc++; } useSocket = 1; } if (channel2 == NULL && hSlaveDrv == INVALID_HANDLE_VALUE ) { exp_debuglog("CreateNamedPipe failed: error=0x%08x\r\n", GetLastError()); exp_debuglog("socket failed: error=0x%08x\r\n", GetLastError()); TclWinConvertError(GetLastError()); exp_error(interp, "unable to create either named pipe or socket: %s", Tcl_PosixError(interp)); goto end; } hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hEvent == NULL) { exp_debuglog("CreateEvent failed: error=0x%08x\r\n", GetLastError()); TclWinConvertError(GetLastError()); exp_error(interp, "unable to create event: %s", Tcl_PosixError(interp)); goto end; } val = exp_get_var(interp, "exp_nt_debug"); if (val) { if (! Tcl_GetBoolean(interp, val, &debug) == TCL_OK) { Tcl_ResetResult(interp); debug = 1; } } else { debug = 0; } nargv = (char **) ckalloc(sizeof(char *) * (argc+4)); nargv[0] = Tcl_DStringValue(&slaveDrvPath); if (!useSocket) { nargv[1] = pipeName; } else { nargv[1] = sockPort; } nargv[2] = usePipes ? "1" : "0"; nargv[3] = debug ? "1" : "0"; j = 4; nargv[j++] = Tcl_DStringValue(&slavePath); for (i = 1; i < argc; i++, j++) { nargv[j] = argv[i]; } argc = j; #ifdef _DEBUG /* * When the Expect extension is running in a debugger, * print the commandline to the debugger's output window. * This is a feature of the OS. * * >>>>[ And don't leave this stuff in the retail build! ]<<<< */ if (IsDebuggerPresent()) { Tcl_DString cmdLine; OutputDebugString("spawndrv.exe args: "); Tcl_DStringInit(&cmdLine); /* This quotes the strings properly. */ BuildCommandLine(nargv[0], argc, nargv, &cmdLine); (*expWinProcs->outputDebugStringProc)((LPCTSTR)Tcl_DStringValue(&cmdLine)); OutputDebugString("\n"); # ifdef _MSC_VER /* * Launch a new instance of MSVC++ with the right project file, if one * does not already exist. And tell MSVC++ to run it in the debuger. */ globalPid = MsvcDbg_Launch( "D:\\expect_wslive\\expect_win32_take2\\win\\slavedrv.dsp", &cmdLine, &dbgtoken); # else # error "Need Debugger control for this IDE" # endif } else { #endif hide = !debug; dwRet = ExpWinCreateProcess(argc, nargv, NULL, NULL, NULL, TRUE, hide, FALSE, FALSE, &slaveDrvPid, &globalPid); if (dwRet != 0) { TclWinConvertError(dwRet); exp_error(interp, "couldn't execute \"%s\": %s", argv[0],Tcl_PosixError(interp)); goto end; } /* * Until we use the process handle for something, close it */ CloseHandle((HANDLE) slaveDrvPid); #ifdef _DEBUG } #endif /* * Wait for connection with the slave driver */ if (!useSocket) { ZeroMemory(&over, sizeof(over)); over.hEvent = hEvent; bRet = ConnectNamedPipe(hSlaveDrv, &over); if (bRet == FALSE) { dwRet = GetLastError(); if (dwRet == ERROR_PIPE_CONNECTED) { ; } else if (dwRet == ERROR_IO_PENDING) { dwRet = WaitForSingleObject(hEvent, 10000 /* XXX 30000*/); if (dwRet != WAIT_OBJECT_0) { TclWinConvertError(dwRet); exp_error(interp, "\"%s\" did not connect to server pipe: %s", Tcl_DStringValue(&slaveDrvPath), Tcl_PosixError(interp)); goto end; } bRet = GetOverlappedResult(hSlaveDrv, &over, &count, FALSE); if (bRet == FALSE) { TclWinConvertError(GetLastError()); exp_error(interp, "\"%s\" did not connect to server pipe: %s", Tcl_DStringValue(&slaveDrvPath), Tcl_PosixError(interp)); goto end; } } else { exp_error(interp, "\"%s\" did not connect to server pipe: %s", Tcl_DStringValue(&slaveDrvPath), Tcl_PosixError(interp)); goto end; } } } else { while (channel == NULL) { Tcl_DoOneEvent(TCL_FILE_EVENTS); } /* * At this point, 'channel' should point to a valid channel that * we can use for I/O. * We aren't interested in listening for more connections, so we * can close that channel now. */ Tcl_Close(interp, channel2); } /* * wait for slave driver to initialize before allowing user to send to it */ exp_debuglog("parent: waiting for sync bytes\r\n"); if (!useSocket) { ResetEvent(hEvent); bRet = ReadFile(hSlaveDrv, buf, 8, &count, &over); if (bRet == FALSE) { dwRet = GetLastError(); if (dwRet == ERROR_IO_PENDING) { dwRet = WaitForSingleObject(hEvent, 50000); /* 50 seconds */ if (dwRet != WAIT_OBJECT_0) { TclWinConvertError(dwRet); exp_error(interp, "\"%s\" did not synchronize with master: %s", Tcl_DStringValue(&slaveDrvPath), Tcl_PosixError(interp)); goto end; } bRet = GetOverlappedResult(hSlaveDrv, &over, &count, FALSE); if (bRet == FALSE) { TclWinConvertError(GetLastError()); exp_error(interp, "\"%s\" did not synchronize with master: %s", Tcl_DStringValue(&slaveDrvPath), Tcl_PosixError(interp)); goto end; } } } } else { /* * We are reading data from the socket channel right away, so * we need to set the mode to binary now. If we are using * named pipes on NT, the channel doesn't exist yet, and we * would instead read directly from the pipe. */ Tcl_SetChannelOption(interp, channel, "-translation", "binary"); count = Tcl_Read(channel, buf, 8); if( count != 8 ) { exp_error(interp, "Synchronized with wrong number of bytes %d", count); goto end; } } dwRet = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); if (dwRet != 0) { TclWinConvertError(dwRet); exp_error(interp, "couldn't execute \"%s\": %s", argv[0],Tcl_PosixError(interp)); goto end; } globalPid = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24); if (!useSocket) { HANDLE dupe; masterRFile = tclWinMakeFileProc(hSlaveDrv); /* * We need to make a duplicate, because the handles are closed * seperately by the core. */ DuplicateHandle(GetCurrentProcess(), hSlaveDrv, GetCurrentProcess(), &dupe, 0, FALSE, DUPLICATE_SAME_ACCESS); masterWFile = tclWinMakeFileProc(dupe); channel = TclpCreateCommandChannel(masterRFile, masterWFile, NULL, 0, NULL); } if (channel == NULL) { goto end; } Tcl_SetChannelOption(interp, channel, "-blocking", "0"); Tcl_SetChannelOption(interp, channel, "-buffering", "none"); Tcl_SetChannelOption(interp, channel, "-translation", "binary"); spawnChan = ExpCreateSpawnChannel(interp, channel); f = exp_f_new(interp, spawnChan, NULL, globalPid); f->over.hEvent = hEvent; f->channel = spawnChan; f->Master = channel; exp_debuglog("parent: now unsynchronized from child\r\n"); /* tell user id of new process */ Tcl_SetVar(interp, EXP_SPAWN_ID_VARNAME, Tcl_GetChannelName(spawnChan), 0); Tcl_RegisterChannel(interp, spawnChan); sprintf(interp->result,"%d",(int) globalPid); exp_debuglog("spawn: returns {%s}\r\n",Tcl_GetStringResult(interp)); ckfree((char *) nargv); return(TCL_OK); end: Tcl_DStringFree(&slavePath); if (hSlaveDrv != NULL) CloseHandle(hSlaveDrv); if (hEvent != NULL) CloseHandle(hEvent); if (nargv != NULL) ckfree((char *) nargv); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * Exp_KillCmd -- * * Implements the 'kill' and 'exp_kill' commands. There were * not in the Unix version of expect, but since there is no * kill command on NT (well, at least not by default), this * gives us a way to kill a slave. The argument is the signal * number to send to the subprocess. On NT, this is interpreted * interpret a bit differently than on Unix. For a signal of 2, * a CTRL-C is sent to the subprocess. For a signal of 3, a * CTRL-BREAK is sent to the subprocess. All other signals cause * the subprocess to be directly terminated. * * Results: * A standard TCL result * * Side Effects: * A process may be killed * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int Exp_KillCmd(ClientData clientData,Tcl_Interp *interp,int argc,char **argv) { struct exp_f *f; char *chanId = NULL; char *argv0 = argv[0]; int signal = 9; char buf[2]; int msg; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) { exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } chanId = *argv; } else break; } if (argc > 0) { if (Tcl_GetInt(interp, argv[0], &signal) != TCL_OK) { return TCL_ERROR; } } if (chanId == NULL) { f = exp_update_master(interp,0,0); } else { f = exp_chan2f(interp, chanId, 1, 0, argv0); } if (f == NULL) { return(TCL_ERROR); } if (f->Master == NULL) { Tcl_AppendResult(interp, "cannot kill ", f->spawnId, ": not a spawned process", NULL); return TCL_ERROR; } switch (signal) { case 2: /* Send Ctrl-C */ msg = EXP_KILL_CTRL_C; break; case 3: /* Send Ctrl-Break */ msg = EXP_KILL_CTRL_BREAK; break; default: /* Terminate subprocess with prejudice */ msg = EXP_KILL_TERMINATE; break; } buf[0] = EXP_SLAVE_KILL; buf[1] = msg; /* * The Master holds the direct line of communication to * the slave driver. We don't want to go through the toplevel * channel because that assumes that all writes are data while * this is really a command. */ Tcl_Write(f->Master, buf, 2); return TCL_OK; } /* *---------------------------------------------------------------------- * * ExpSockAcceptProc -- * * For doing socket communication with slave driver. This * routine is called when the slave driver connects up to us. * * Results: * None *---------------------------------------------------------------------- */ static void ExpSockAcceptProc(callbackData, chan, address, port) ClientData callbackData; Tcl_Channel chan; char *address; int port; { Tcl_Channel * ptr; /* * We do a couple of things here. First we save the pointer to * the actual channel that we use for read/write, and secondly we set * the event that is used for synchronization. */ ptr = (Tcl_Channel *) callbackData; *ptr = chan; return; } |
Added win/expWinConsoleDebugger.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 | /* ---------------------------------------------------------------------------- * expWinConsoleDebugger.cpp -- * * Console debugger core implimentation. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinConsoleDebugger.cpp,v 1.1.2.13 2002/03/15 07:51:56 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <stddef.h> #include <assert.h> #include "expWinConsoleDebugger.hpp" #ifdef _MSC_VER # pragma comment (lib, "imagehlp.lib") #endif // Constructor. ConsoleDebugger::ConsoleDebugger (int _argc, char * const *_argv, CMclQueue<Message *> &_mQ) : argc(_argc), argv(_argv), ProcessList(0L), CursorKnown(FALSE), ShowExceptionBacktraces(FALSE), SymbolPath(0L), mQ(_mQ) { // Until further notice, assume this. // ConsoleSize.X = 80; ConsoleSize.Y = 25; // Until further notice, assume this, too. // CursorPosition.X = 0; CursorPosition.Y = 0; // Set all our breakpoint info. We have to do this the long way, here in // the constructor, because we need to have the this pointer already // set because we refer to ourselves by needing the address to member // functions. // BreakArrayKernel32[0].funcName = "Beep"; BreakArrayKernel32[0].nargs = 2; BreakArrayKernel32[0].breakProc = OnBeep; BreakArrayKernel32[0].dwFlags = BREAK_OUT|BREAK_IN; BreakArrayKernel32[1].funcName = "FillConsoleOutputCharacterA"; BreakArrayKernel32[1].nargs = 5; BreakArrayKernel32[1].breakProc = OnFillConsoleOutputCharacter; BreakArrayKernel32[1].dwFlags = BREAK_OUT; BreakArrayKernel32[2].funcName = "FillConsoleOutputCharacterW"; BreakArrayKernel32[2].nargs = 5; BreakArrayKernel32[2].breakProc = OnFillConsoleOutputCharacter; BreakArrayKernel32[2].dwFlags = BREAK_OUT; BreakArrayKernel32[3].funcName = "GetStdHandle"; BreakArrayKernel32[3].nargs = 1; BreakArrayKernel32[3].breakProc = OnGetStdHandle; BreakArrayKernel32[3].dwFlags = BREAK_OUT; BreakArrayKernel32[4].funcName = "OpenConsoleW"; BreakArrayKernel32[4].nargs = 4; BreakArrayKernel32[4].breakProc = OnOpenConsoleW; BreakArrayKernel32[4].dwFlags = BREAK_OUT; BreakArrayKernel32[5].funcName = "ReadConsoleInputA"; BreakArrayKernel32[5].nargs = 4; BreakArrayKernel32[5].breakProc = OnReadConsoleInput; BreakArrayKernel32[5].dwFlags = BREAK_OUT; BreakArrayKernel32[6].funcName = "ReadConsoleInputW"; BreakArrayKernel32[6].nargs = 4; BreakArrayKernel32[6].breakProc = OnReadConsoleInput; BreakArrayKernel32[6].dwFlags = BREAK_OUT; BreakArrayKernel32[7].funcName = "ScrollConsoleScreenBufferA"; BreakArrayKernel32[7].nargs = 5; BreakArrayKernel32[7].breakProc = OnScrollConsoleScreenBuffer; BreakArrayKernel32[7].dwFlags = BREAK_OUT; BreakArrayKernel32[8].funcName = "ScrollConsoleScreenBufferW"; BreakArrayKernel32[8].nargs = 5; BreakArrayKernel32[8].breakProc = OnScrollConsoleScreenBuffer; BreakArrayKernel32[8].dwFlags = BREAK_OUT; BreakArrayKernel32[9].funcName = "SetConsoleMode"; BreakArrayKernel32[9].nargs = 2; BreakArrayKernel32[9].breakProc = OnSetConsoleMode; BreakArrayKernel32[9].dwFlags = BREAK_OUT; BreakArrayKernel32[10].funcName = "SetConsoleActiveScreenBuffer"; BreakArrayKernel32[10].nargs = 1; BreakArrayKernel32[10].breakProc = OnSetConsoleActiveScreenBuffer; BreakArrayKernel32[10].dwFlags = BREAK_OUT; BreakArrayKernel32[11].funcName = "SetConsoleCursorPosition"; BreakArrayKernel32[11].nargs = 2; BreakArrayKernel32[11].breakProc = OnSetConsoleCursorPosition; BreakArrayKernel32[11].dwFlags = BREAK_OUT; BreakArrayKernel32[12].funcName = "SetConsoleWindowInfo"; BreakArrayKernel32[12].nargs = 2; BreakArrayKernel32[12].breakProc = OnSetConsoleWindowInfo; BreakArrayKernel32[12].dwFlags = BREAK_OUT; BreakArrayKernel32[13].funcName = "WriteConsoleA"; BreakArrayKernel32[13].nargs = 5; BreakArrayKernel32[13].breakProc = OnWriteConsoleA; BreakArrayKernel32[13].dwFlags = BREAK_OUT; BreakArrayKernel32[14].funcName = "WriteConsoleW"; BreakArrayKernel32[14].nargs = 5; BreakArrayKernel32[14].breakProc = OnWriteConsoleW; BreakArrayKernel32[14].dwFlags = BREAK_OUT; BreakArrayKernel32[15].funcName = "WriteConsoleOutputA"; BreakArrayKernel32[15].nargs = 5; BreakArrayKernel32[15].breakProc = OnWriteConsoleOutputA; BreakArrayKernel32[15].dwFlags = BREAK_OUT; BreakArrayKernel32[16].funcName = "WriteConsoleOutputW"; BreakArrayKernel32[16].nargs = 5; BreakArrayKernel32[16].breakProc = OnWriteConsoleOutputW; BreakArrayKernel32[16].dwFlags = BREAK_OUT; BreakArrayKernel32[17].funcName = "WriteConsoleOutputCharacterA"; BreakArrayKernel32[17].nargs = 5; BreakArrayKernel32[17].breakProc = OnWriteConsoleOutputCharacterA; BreakArrayKernel32[17].dwFlags = BREAK_OUT; BreakArrayKernel32[18].funcName = "WriteConsoleOutputCharacterW"; BreakArrayKernel32[18].nargs = 5; BreakArrayKernel32[18].breakProc = OnWriteConsoleOutputCharacterW; BreakArrayKernel32[18].dwFlags = BREAK_OUT; BreakArrayKernel32[19].funcName = 0L; BreakArrayKernel32[19].nargs = 0; BreakArrayKernel32[19].breakProc = 0L; BreakArrayKernel32[19].dwFlags = 0; BreakArrayUser32[0].funcName = "IsWindowVisible"; BreakArrayUser32[0].nargs = 1; BreakArrayUser32[0].breakProc = OnIsWindowVisible; BreakArrayUser32[0].dwFlags = BREAK_OUT; BreakArrayUser32[1].funcName = 0L; BreakArrayUser32[1].nargs = 0; BreakArrayUser32[1].breakProc = 0L; BreakArrayUser32[1].dwFlags = 0; BreakPoints[0].dllName = "kernel32.dll"; BreakPoints[0].breakInfo = BreakArrayKernel32; BreakPoints[1].dllName = "user32.dll"; BreakPoints[1].breakInfo = BreakArrayUser32; BreakPoints[2].dllName = 0L; BreakPoints[2].breakInfo = 0L; hMasterConsole = CreateFile("CONOUT$", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0L, OPEN_EXISTING, 0, 0L); } ConsoleDebugger::~ConsoleDebugger() { if (SymbolPath) delete [] SymbolPath; } unsigned ConsoleDebugger::ThreadHandlerProc(void) { Process *proc; DWORD ok; STARTUPINFO si; PROCESS_INFORMATION pi; char *cmdline; ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.wShowWindow = SW_SHOWDEFAULT; cmdline = ArgMaker::BuildCommandLine(argc, argv); // Make sure the master does not ignore Ctrl-C SetConsoleCtrlHandler(0L, FALSE); ok = CreateProcess ( 0L, // Module name (not needed). cmdline, // Command line. 0L, // Process handle will not be inheritable. 0L, // Thread handle will not be inheritable. FALSE, // No handle inheritance. DEBUG_PROCESS|CREATE_NEW_CONSOLE|CREATE_DEFAULT_ERROR_MODE, // Creation flags. 0L, // Use parent's environment block. 0L, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi); // Pointer to PROCESS_INFORMATION structure. delete [] cmdline; if (!ok) { //arg->lastError = GetLastError(); } WaitForInputIdle(pi.hProcess, 5000); CloseHandle(pi.hThread); // Make sure we now ignore Ctrl-C SetConsoleCtrlHandler(0L, TRUE); proc = ProcessNew(); //CloseHandle(pi.hProcess); proc->hProcess = pi.hProcess; proc->pid = pi.dwProcessId; CommonDebugger(); return 0; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::ProcessNew -- * * Allocates a new structure for debugging a process and * initializes it. * * Results: * A new structure * * Side Effects: * Memory is allocated, an event is created. * *---------------------------------------------------------------------- */ ConsoleDebugger::Process * ConsoleDebugger::ProcessNew(void) { Process *proc; proc = new Process; proc->threadList = 0L; proc->threadCount = 0; proc->brkptList = 0L; proc->lastBrkpt = 0L; proc->offset = 0; proc->nBreakCount = 0; proc->consoleHandlesMax = 0; proc->isConsoleApp = FALSE; proc->isShell = FALSE; proc->hProcess = 0L; proc->pSubprocessMemory = 0; proc->pSubprocessBuffer = 0; proc->pMemoryCacheBase = 0; proc->exeModule = 0L; proc->nextPtr = ProcessList; ProcessList = proc; return proc; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::ProcessFree -- * * Frees all allocated memory for a process and closes any * open handles * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::ProcessFree(Process *proc) { ThreadInfo *tcurr, *tnext; Breakpoint *bcurr, *bnext; Process *pcurr, *pprev; for (tcurr = proc->threadList; tcurr != 0L; tcurr = tnext) { tnext = tcurr->nextPtr; proc->threadCount--; CloseHandle(tcurr->hThread); delete tcurr; } for (bcurr = proc->brkptList; bcurr != 0L; bcurr = bnext) { bnext = bcurr->nextPtr; delete bcurr; } for (pprev = 0L, pcurr = ProcessList; pcurr != 0L; pcurr = pcurr->nextPtr) { if (pcurr == proc) { if (pprev == 0L) { ProcessList = pcurr->nextPtr; } else { pprev->nextPtr = pcurr->nextPtr; } break; } } CloseHandle(proc->hProcess); delete proc; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::CommonDebugger -- * * This is the function that is the debugger for all slave processes * * Results: * None. This thread exits with ExitThread() when the subprocess dies. * * Side Effects: * Adds the process to the things being waited for by * WaitForMultipleObjects * *---------------------------------------------------------------------- */ void ConsoleDebugger::CommonDebugger() { DEBUG_EVENT debEvent; // debugging event info. DWORD dwContinueStatus; // exception continuation. DWORD err; Process *proc; DWORD n, i; n = GetEnvironmentVariable("Path", 0L, 0); n += GetEnvironmentVariable("_NT_SYMBOL_PATH", 0L, 0) + 1; n += GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", 0L, 0) + 1; n += GetEnvironmentVariable("SystemRoot", 0L, 0) + 1; SymbolPath = new char [n]; i = GetEnvironmentVariable("Path", SymbolPath, n); SymbolPath[i++] = ';'; i += GetEnvironmentVariable("_NT_SYMBOL_PATH", &SymbolPath[i], n-i); SymbolPath[i++] = ';'; i += GetEnvironmentVariable("_NT_ALT_SYMBOL_PATH", &SymbolPath[i], n-i); SymbolPath[i++] = ';'; i += GetEnvironmentVariable("SystemRoot", &SymbolPath[i], n-i); for(;;) { dwContinueStatus = DBG_CONTINUE; // Wait for a debugging event to occur. The second parameter // indicates that the function does not return until // a debugging event occurs. // if (WaitForDebugEvent(&debEvent, INFINITE) == FALSE) { err = GetLastError(); *((char *) 0L) = 0; // cause an exception. } // Find the process that is responsible for this event. // for (proc = ProcessList; proc; proc = proc->nextPtr) { if (proc->pid == debEvent.dwProcessId) { break; } } if (!proc && debEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) { char buf[50]; wsprintf(buf, "%d/%d (%d)", debEvent.dwProcessId, debEvent.dwThreadId, debEvent.dwDebugEventCode); EXP_LOG1(MSG_DT_UNEXPECTEDDBGEVENT, buf); if (debEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) { char buf[50]; wsprintf(buf, "0x%08x", debEvent.u.Exception.ExceptionRecord.ExceptionCode); EXP_LOG1(MSG_DT_EXCEPTIONDBGEVENT, buf); dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; } goto skip; } // Process the debugging event code. // switch (debEvent.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: // Process the exception code. When handling // exceptions, remember to set the continuation // status parameter (dwContinueStatus). This value // is used by the ContinueDebugEvent function. // switch (debEvent.u.Exception.ExceptionRecord.ExceptionCode) { case EXCEPTION_BREAKPOINT: { if (proc->nBreakCount < 1000) { proc->nBreakCount++; } if (proc->nBreakCount == 1) { OnXFirstBreakpoint(proc, &debEvent); } else if (proc->nBreakCount == 2) { OnXSecondBreakpoint(proc, &debEvent); } else { OnXBreakpoint(proc, &debEvent); } break; } case EXCEPTION_SINGLE_STEP: OnXSingleStep(proc, &debEvent); break; case DBG_CONTROL_C: dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; break; case DBG_CONTROL_BREAK: dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; break; case EXCEPTION_DATATYPE_MISALIGNMENT: case EXCEPTION_ACCESS_VIOLATION: default: // An exception was hit and it was not handled by the program. // Now it is time to get a backtrace. if (! debEvent.u.Exception.dwFirstChance) { OnXSecondChanceException(proc, &debEvent); } dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; } break; case CREATE_THREAD_DEBUG_EVENT: OnXCreateThread(proc, &debEvent); break; case CREATE_PROCESS_DEBUG_EVENT: OnXCreateProcess(proc, &debEvent); break; case EXIT_THREAD_DEBUG_EVENT: OnXDeleteThread(proc, &debEvent); break; case EXIT_PROCESS_DEBUG_EVENT: // XXX: This is really screwed up, but we get breakpoints // for processes that are already dead. So we cannot remove // and cleanup a process until some later (How much later?) // point. This really, really sucks.... // #if 0 /* This gets closed in WaitQueueThread */ CloseHandle(proc->hProcess); #endif err = debEvent.u.ExitProcess.dwExitCode; ProcessFree(proc); if (ProcessList == 0L) { // When the last process exits, we exit. NotifyDone(); return; } break; case LOAD_DLL_DEBUG_EVENT: OnXLoadDll(proc, &debEvent); break; case UNLOAD_DLL_DEBUG_EVENT: OnXUnloadDll(proc, &debEvent); break; case OUTPUT_DEBUG_STRING_EVENT: // Display the output debugging string. break; } skip: // Resume executing the thread that reported the debugging event. ContinueDebugEvent(debEvent.dwProcessId, debEvent.dwThreadId, dwContinueStatus); } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXFirstBreakpoint -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_BREAKPOINT, and it is the * first one to occur in the program. This happens when the * process finally gets loaded into memory and is about to * start. * * Results: * None * *---------------------------------------------------------------------- */ static CONTEXT FirstContext; static UCHAR FirstPage[PAGESIZE]; static HANDLE FirstThread; #include <pshpack1.h> typedef struct _InjectCode { UCHAR instPush1; DWORD argMemProtect; UCHAR instPush2; DWORD argMemType; UCHAR instPush3; DWORD argMemSize; UCHAR instPush4; DWORD argMemAddr; UCHAR instCall; DWORD argCallAddr; DWORD instIntr; } InjectCode; #include <poppack.h> void ConsoleDebugger::OnXFirstBreakpoint(Process *proc, LPDEBUG_EVENT pDebEvent) { DWORD base; ThreadInfo *tinfo; for (tinfo = proc->threadList; tinfo != 0L; tinfo = tinfo->nextPtr) { if (pDebEvent->dwThreadId == tinfo->dwThreadId) { break; } } // Set up the memory that will serve as the place for our // intercepted function return points. { InjectCode code; DWORD addr; FirstThread = tinfo->hThread; FirstContext.ContextFlags = CONTEXT_FULL; GetThreadContext(FirstThread, &FirstContext); if (proc->funcTable.Find("VirtualAlloc", reinterpret_cast<PVOID *>(&addr)) != TCL_OK) { proc->nBreakCount++; // Don't stop at second breakpoint EXP_LOG0(MSG_DT_NOVIRT); return; } code.instPush1 = 0x68; code.argMemProtect = PAGE_EXECUTE_READWRITE; code.instPush2 = 0x68; code.argMemType = MEM_COMMIT; code.instPush3 = 0x68; code.argMemSize = 2048; code.instPush4 = 0x68; code.argMemAddr = 0; code.instCall = 0xe8; code.argCallAddr = addr - FirstContext.Eip - offsetof(InjectCode, instCall) - 5; code.instIntr = 0xCC; base = FirstContext.Eip; if (!ReadSubprocessMemory(proc, (PVOID) base, FirstPage, sizeof(InjectCode))) { EXP_LOG0(MSG_DT_CANTREADSPMEM); } if (!WriteSubprocessMemory(proc, (PVOID) base, &code, sizeof(InjectCode))) { EXP_LOG0(MSG_DT_CANTWRITESPMEM); } } return; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXSecondBreakpoint -- * * This routine is called when the second breakpoint is hit. * The second breakpoint is at the end of our call to GlobalAlloc(). * Save the returned pointer from GlobalAlloc, then restore the * first page of memory and put everything back the way it was. * Finally, we can start. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXSecondBreakpoint(Process *proc, LPDEBUG_EVENT pDebEvent) { CONTEXT context; BYTE retbuf[2048]; DWORD base; LPEXCEPTION_DEBUG_INFO exceptInfo; BreakInfo *info; int i; exceptInfo = &pDebEvent->u.Exception; context.ContextFlags = CONTEXT_FULL; GetThreadContext(FirstThread, &context); proc->pSubprocessMemory = context.Eax; memset(retbuf, 0xcc, sizeof(retbuf)); // All breakpoints WriteSubprocessMemory(proc, (PVOID) proc->pSubprocessMemory, retbuf, sizeof(retbuf)); base = FirstContext.Eip; if (!WriteSubprocessMemory(proc, (PVOID) base, FirstPage, sizeof(InjectCode))) { EXP_LOG0(MSG_DT_CANTWRITESPMEM); } SetThreadContext(FirstThread, &FirstContext); // Set all breakpoints // for (i = 0; BreakPoints[i].dllName; i++) { for (info = BreakPoints[i].breakInfo; info->funcName; info++) { SetBreakpoint(proc, info); } } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXSingleStep -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_SINGLE_STEP. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXSingleStep(Process *proc, LPDEBUG_EVENT pDebEvent) { BYTE code; // Now, we need to restore the breakpoint that we had removed. // code = 0xcc; WriteSubprocessMemory(proc, proc->lastBrkpt->codePtr, &code, sizeof(BYTE)); } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXSecondChanceException -- * * Handle a second chance exception * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXSecondChanceException(Process *proc, LPDEBUG_EVENT pDebEvent) { BOOL b; STACKFRAME frame; CONTEXT context; ThreadInfo *tinfo; Module *modPtr; DWORD displacement; BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512]; PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer; char *s; if (!ShowExceptionBacktraces) { return; } for (tinfo = proc->threadList; tinfo != 0L; tinfo = tinfo->nextPtr) { if (pDebEvent->dwThreadId == tinfo->dwThreadId) { break; } } assert(tinfo != 0L); context.ContextFlags = CONTEXT_FULL; GetThreadContext(tinfo->hThread, &context); // XXX: From what I can tell, SymInitialize is broken on Windows NT 4.0 // if you try to have it iterate the modules in a process. It always // returns an object mismatch error. Instead, initialize without iterating // the modules. Contrary to what MSDN documentation says, // Microsoft debuggers do not exclusively use the imagehlp API. In // fact, the only thing VC 5.0 uses is the StackWalk function. // Windbg uses a few more functions, but it doesn't use SymInitialize. // We will then do the hard work of finding all the // modules and doing the right thing. // if (! SymInitialize(proc->hProcess, SymbolPath, FALSE)){ fprintf(stderr, "Unable to get backtrace (Debug 1): 0x%08x\n", GetLastError()); return; } #ifdef _M_IX86 memset(&frame, 0, sizeof(frame)); frame.AddrPC.Mode = AddrModeFlat; frame.AddrPC.Segment = 0; frame.AddrPC.Offset = context.Eip; frame.AddrReturn.Mode = AddrModeFlat; frame.AddrReturn.Segment = 0; frame.AddrReturn.Offset = context.Ebp; // I think this is correct frame.AddrFrame.Mode = AddrModeFlat; frame.AddrFrame.Segment = 0; frame.AddrFrame.Offset = context.Ebp; frame.AddrStack.Mode = AddrModeFlat; frame.AddrStack.Segment = 0; frame.AddrStack.Offset = context.Esp; frame.FuncTableEntry = 0L; frame.Params[0] = context.Eax; frame.Params[1] = context.Ecx; frame.Params[2] = context.Edx; frame.Params[3] = context.Ebx; frame.Far = FALSE; frame.Virtual = FALSE; frame.Reserved[0] = 0; frame.Reserved[1] = 0; frame.Reserved[2] = 0; /* frame.KdHelp.* is not set */ // Iterate through the loaded modules and load symbols for each one. // proc->moduleTable.Top(&modPtr); do { if (! modPtr->loaded) { modPtr->dbgInfo = MapDebugInformation(modPtr->hFile, 0L, SymbolPath, (DWORD)modPtr->baseAddr); SymLoadModule(proc->hProcess, modPtr->hFile, 0L, 0L, (DWORD) modPtr->baseAddr, 0); modPtr->loaded = TRUE; } } while (proc->moduleTable.Next(&modPtr) != TCL_ERROR); if (proc->exeModule && proc->exeModule->dbgInfo && proc->exeModule->dbgInfo->ImageFileName) { s = proc->exeModule->dbgInfo->ImageFileName; } else { s = ""; } // fprintf(stderr, "Backtrace for %s\n", s); // fprintf(stderr, "-------------------------------------\n"); // EXP_LOG("Backtrace for %s", s); while (1) { pSymbol->SizeOfStruct = sizeof(symbolBuffer); pSymbol->MaxNameLength = 512; b = StackWalk(IMAGE_FILE_MACHINE_I386, proc->hProcess, tinfo->hThread, &frame, &context, 0L, SymFunctionTableAccess, SymGetModuleBase, 0L); if (b == FALSE || frame.AddrPC.Offset == 0) { break; } if (SymGetSymFromAddr(proc->hProcess, frame.AddrPC.Offset, &displacement, pSymbol) ) { DWORD base; char buf[1024]; base = SymGetModuleBase(proc->hProcess, frame.AddrPC.Offset); proc->moduleTable.Find(reinterpret_cast<PVOID>(base), &modPtr); if (modPtr->dbgInfo && modPtr->dbgInfo->ImageFileName) { s = modPtr->dbgInfo->ImageFileName; } else { s = ""; } // fprintf(stderr, "%.20s %08x\t%s+%X\n", s, frame.AddrPC.Offset, // pSymbol->Name, displacement); sprintf(buf, "%.20s %08x\t%s+%X", s, frame.AddrPC.Offset, pSymbol->Name, displacement); // EXP_LOG("%s", buf); } else { // fprintf(stderr, "%08x\n", frame.AddrPC.Offset); // EXP_LOG("%08x\t", frame.AddrPC.Offset); } } #else # error "Unsupported architecture" #endif } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXCreateThread -- * * This routine is called when a CREATE_THREAD_DEBUG_EVENT * occurs. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXCreateThread(Process *proc, LPDEBUG_EVENT pDebEvent) { // As needed, examine or change the thread's registers // with the GetThreadContext and SetThreadContext functions; // and suspend and resume thread execution with the // SuspendThread and ResumeThread functions. // ThreadInfo *threadInfo; threadInfo = new ThreadInfo; threadInfo->dwThreadId = pDebEvent->dwThreadId; threadInfo->hThread = pDebEvent->u.CreateThread.hThread; proc->threadCount++; threadInfo->nextPtr = proc->threadList; proc->threadList = threadInfo; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXDeleteThread -- * * This routine is called when a CREATE_THREAD_DEBUG_EVENT * occurs. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXDeleteThread(Process *proc, LPDEBUG_EVENT pDebEvent) { // As needed, examine or change the thread's registers // with the GetThreadContext and SetThreadContext functions; // and suspend and resume thread execution with the // SuspendThread and ResumeThread functions. // ThreadInfo *threadInfo; ThreadInfo *prev; prev = 0L; for (threadInfo = proc->threadList; threadInfo; prev = threadInfo, threadInfo = threadInfo->nextPtr) { if (threadInfo->dwThreadId == pDebEvent->dwThreadId) { if (prev == 0L) { proc->threadList = threadInfo->nextPtr; } else { prev->nextPtr = threadInfo->nextPtr; } proc->threadCount--; CloseHandle(threadInfo->hThread); delete threadInfo; break; } } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXCreateProcess -- * * This routine is called when a CREATE_PROCESS_DEBUG_EVENT * occurs. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXCreateProcess(Process *proc, LPDEBUG_EVENT pDebEvent) { ThreadInfo *threadInfo; CREATE_PROCESS_DEBUG_INFO *info = &pDebEvent->u.CreateProcessInfo; int known; if (proc == 0L) { proc = ProcessNew(); // proc->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!DuplicateHandle(GetCurrentProcess(), info->hProcess, GetCurrentProcess(), &proc->hProcess, PROCESS_ALL_ACCESS, FALSE, 0)) { fprintf(stderr, "Unable to duplicate handle\n"); } proc->pid = pDebEvent->dwProcessId; // ExpAddToWaitQueue(proc->hProcess); } known = LoadedModule(proc, info->hFile, info->lpImageName, info->fUnicode, info->lpBaseOfImage, info->dwDebugInfoFileOffset); // As needed, examine or change the registers of the // process's initial thread with the GetThreadContext and // SetThreadContext functions; read from and write to the // process's virtual memory with the ReadProcessMemory and // WriteProcessMemory functions; and suspend and resume // thread execution with the SuspendThread and ResumeThread // functions. // threadInfo = new ThreadInfo; threadInfo->dwThreadId = pDebEvent->dwThreadId; threadInfo->hThread = info->hThread; threadInfo->nextPtr = proc->threadList; proc->threadCount++; proc->threadList = threadInfo; } /* *---------------------------------------------------------------------- * * OnXLoadDll -- * * This routine is called when a LOAD_DLL_DEBUG_EVENT is seen * * Results: * None * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXLoadDll(Process *proc, LPDEBUG_EVENT pDebEvent) { WORD w; DWORD dw; DWORD ImageHdrOffset; PIMAGE_FILE_HEADER pfh; /* File header image in subprocess memory */ PIMAGE_SECTION_HEADER psh; PIMAGE_OPTIONAL_HEADER poh; IMAGE_DATA_DIRECTORY dataDir; PIMAGE_EXPORT_DIRECTORY ped; IMAGE_EXPORT_DIRECTORY exportDir; DWORD n; DWORD base; CHAR funcName[256]; CHAR dllname[256]; PVOID ptr, namePtr, funcPtr; DWORD p; LPLOAD_DLL_DEBUG_INFO info = &pDebEvent->u.LoadDll; BOOL bFound; int unknown = !LoadedModule(proc, info->hFile, info->lpImageName, info->fUnicode, info->lpBaseOfDll, info->dwDebugInfoFileOffset); base = (DWORD) info->lpBaseOfDll; // Check for the DOS signature // ReadSubprocessMemory(proc, info->lpBaseOfDll, &w, sizeof(WORD)); if (w != IMAGE_DOS_SIGNATURE) return; // Skip over the DOS signature and check the PE signature // p = base; p += 15 * sizeof(DWORD); ptr = (PVOID) p; ReadSubprocessMemory(proc, (PVOID) p, &ImageHdrOffset, sizeof(DWORD)); p = base; p += ImageHdrOffset; ReadSubprocessMemory(proc, (PVOID) p, &dw, sizeof(DWORD)); if (dw != IMAGE_NT_SIGNATURE) { return; } ImageHdrOffset += sizeof(DWORD); p += sizeof(DWORD); pfh = (PIMAGE_FILE_HEADER) p; ptr = &pfh->SizeOfOptionalHeader; ReadSubprocessMemory(proc, ptr, &w, sizeof(WORD)); // We want to find the exports section. It can be found in the // data directory that is part of the IMAGE_OPTIONAL_HEADER // if (!w) return; p += sizeof(IMAGE_FILE_HEADER); poh = (PIMAGE_OPTIONAL_HEADER) p; // Find the number of entries in the data directory // ptr = &poh->NumberOfRvaAndSizes; ReadSubprocessMemory(proc, ptr, &dw, sizeof(DWORD)); if (dw == 0) return; // Read the export data directory // ptr = &poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; ReadSubprocessMemory(proc, ptr, &dataDir, sizeof(IMAGE_DATA_DIRECTORY)); // This points us to the exports section // ptr = (PVOID) (base + dataDir.VirtualAddress); ped = (PIMAGE_EXPORT_DIRECTORY) ptr; ReadSubprocessMemory(proc, ptr, &exportDir, sizeof(IMAGE_EXPORT_DIRECTORY)); // See if this is a DLL we are interested in // ptr = &ped->Name; ReadSubprocessMemory(proc, ptr, &dw, sizeof(DWORD)); ptr = (PVOID) (base + dw); ReadSubprocessStringA(proc, ptr, dllname, sizeof(dllname)); bFound = FALSE; for (n = 0; BreakPoints[n].dllName; n++) { if (stricmp(dllname, BreakPoints[n].dllName) == 0) { bFound = TRUE; break; } } if (!bFound) { return; } ptr = (PVOID) (base + (DWORD) exportDir.AddressOfNames); for (n = 0; n < exportDir.NumberOfNames; n++) { ReadSubprocessMemory(proc, ptr, &dw, sizeof(DWORD)); namePtr = (PVOID) (base + dw); // Now, we should hopefully have a pointer to the name of the // function, so lets get it. // ReadSubprocessStringA(proc, namePtr, funcName, sizeof(funcName)); // Keep a list of all function names in a hash table // funcPtr = (PVOID) (base + n*sizeof(DWORD) + (DWORD) exportDir.AddressOfFunctions); ReadSubprocessMemory(proc, funcPtr, &dw, sizeof(DWORD)); funcPtr = (PVOID) (base + dw); proc->funcTable.Add(funcName, funcPtr); ptr = (PVOID) (sizeof(DWORD) + (ULONG) ptr); } // The IMAGE_SECTION_HEADER comes after the IMAGE_OPTIONAL_HEADER // (if the IMAGE_OPTIONAL_HEADER exists) // p += w; psh = (PIMAGE_SECTION_HEADER) p; } /* *---------------------------------------------------------------------- * * OnXUnloadDll -- * * This routine is called when a UNLOAD_DLL_DEBUG_EVENT is seen * * Results: * None * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXUnloadDll(Process *proc, LPDEBUG_EVENT pDebEvent) { Module *modPtr; if (proc->moduleTable.Find(pDebEvent->u.UnloadDll.lpBaseOfDll, &modPtr) != TCL_ERROR) { if (modPtr->hFile) { CloseHandle(modPtr->hFile); } if (modPtr->modName) { free(modPtr->modName); } if (modPtr->dbgInfo) { UnmapDebugInformation(modPtr->dbgInfo); } delete modPtr; proc->moduleTable.Delete(pDebEvent->u.UnloadDll.lpBaseOfDll); } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::SetBreakpoint -- * * Inserts a single breakpoint * * Results: * TRUE if successful, FALSE if unsuccessful. * *---------------------------------------------------------------------- */ BOOL ConsoleDebugger::SetBreakpoint(Process *proc, BreakInfo *info) { PVOID funcPtr; if (proc->funcTable.Find((void *)info->funcName, &funcPtr) == TCL_ERROR) { // EXP_LOG("Unable to set breakpoint at %s", info->funcName); return FALSE; } // Set a breakpoint at the function start in the subprocess and // save the original code at the function start. // SetBreakpointAtAddr(proc, info, funcPtr); return TRUE; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::SetBreakpointAtAddr -- * * Inserts a single breakpoint at the given address * * Results: * TRUE if successful, FALSE if unsuccessful. * *---------------------------------------------------------------------- */ ConsoleDebugger::Breakpoint * ConsoleDebugger::SetBreakpointAtAddr(Process *proc, BreakInfo *info, PVOID funcPtr) { Breakpoint *bpt; BYTE code; bpt = new Breakpoint; bpt->returning = FALSE; bpt->codePtr = funcPtr; bpt->codeReturnPtr = (PVOID) (proc->offset + (DWORD) proc->pSubprocessMemory); bpt->origRetAddr = 0; bpt->breakInfo = info; bpt->threadInfo = 0L; proc->offset += 2; bpt->nextPtr = proc->brkptList; proc->brkptList = bpt; ReadSubprocessMemory(proc, funcPtr, &bpt->code, sizeof(BYTE)); #ifdef _M_IX86 // Breakpoint opcode on i386 code = 0xcc; #else # error "need breakpoint opcode for this hardware" #endif WriteSubprocessMemory(proc, funcPtr, &code, sizeof(BYTE)); return bpt; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::ReadSubprocessMemory -- * * Reads memory from the subprocess. Takes care of all the * issues with page protection. * * Results: * FALSE if unsuccessful, TRUE if successful. * * Notes: * The efficient memory reading routine is disabled here * because it doesn't quite work right. I don't see the * problem in the code, but there must be something there * since the test suite fails when run with this code * enabled. When it works, it should be much faster than * the current safe but slow implementation. * *---------------------------------------------------------------------- */ #if 0 BOOL ConsoleDebugger::ReadSubprocessMemory(ExpProcess *proc, LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret = TRUE; DWORD offset; DWORD base, curr, end, n; HANDLE hProcess; PBYTE bufpos = buf; hProcess = proc->hProcess; end = len + (DWORD) addr; for (curr = (DWORD) addr; curr < end; ) { base = curr & (~PAGEMASK); offset = curr & PAGEMASK; if (offset + len > PAGESIZE) { n = PAGESIZE - offset; } else { n = len; } if (proc->pMemoryCacheBase != (curr & PAGEMASK)) { /* if not committed memory abort */ if (!VirtualQueryEx(hProcess, (LPVOID) base, &mbi, sizeof(mbi)) || (mbi.State != MEM_COMMIT)) { return FALSE; } /* if guarded memory, change protection temporarily */ if (!(mbi.Protect & PAGE_READONLY) && !(mbi.Protect & PAGE_READWRITE)) { VirtualProtectEx(hProcess, (LPVOID) base, PAGESIZE, PAGE_READONLY, &oldProtection); } if (!ReadProcessMemory(hProcess, (LPVOID) base, proc->pMemoryCache, PAGESIZE, 0L)) { ret = FALSE; } /* reset protection if changed */ if (oldProtection) { VirtualProtectEx(hProcess, (LPVOID) base, PAGESIZE, oldProtection, &oldProtection); } if (ret == FALSE) { return FALSE; } proc->pMemoryCacheBase = base; } memcpy(bufpos, &proc->pMemoryCache[offset], n); bufpos += n; curr += n; } return ret; } #else BOOL ConsoleDebugger::ReadSubprocessMemory(Process *proc, LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret; LONG error; // if not committed memory abort if (!VirtualQueryEx(proc->hProcess, addr, &mbi, sizeof(mbi)) || mbi.State != MEM_COMMIT) { return FALSE; } // if guarded memory, change protection temporarily if (!(mbi.Protect & PAGE_READONLY) && !(mbi.Protect & PAGE_READWRITE)) { VirtualProtectEx(proc->hProcess, addr, len, PAGE_READONLY, &oldProtection); } ret = ReadProcessMemory(proc->hProcess, addr, buf, len, 0L); if (ret == FALSE) { error = GetLastError(); } // reset protection if changed if (oldProtection) { VirtualProtectEx(proc->hProcess, addr, len, oldProtection, &oldProtection); SetLastError(error); } return ret; } #endif /* XXX */ /* *---------------------------------------------------------------------- * * ConsoleDebugger::WriteSubprocessMemory -- * * Writes memory from the subprocess. Takes care of all the * issues with page protection. * * Results: * 0 if unsuccessful, 1 if successful. * *---------------------------------------------------------------------- */ BOOL ConsoleDebugger::WriteSubprocessMemory(Process *proc, LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret = TRUE; DWORD err; HANDLE hProcess; hProcess = proc->hProcess; // Flush the read cache. proc->pMemoryCacheBase = 0; // if not committed memory abort if (!VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi)) || mbi.State != MEM_COMMIT) { ret = FALSE; // assert(ret != FALSE); return ret; } // if guarded memory, change protection temporarily. if (!(mbi.Protect & PAGE_READWRITE)) { if (!VirtualProtectEx(hProcess, addr, len, PAGE_READWRITE, &oldProtection)) { err = GetLastError(); } } if (!WriteProcessMemory(hProcess, addr, buf, len, 0L)) { ret = FALSE; err = GetLastError(); } // reset protection if changed if (oldProtection) { VirtualProtectEx(hProcess, addr, len, oldProtection, &oldProtection); } return ret; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnXBreakpoint -- * * This routine is called when a EXCEPTION_DEBUG_EVENT with * an exception code of EXCEPTION_BREAKPOINT. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnXBreakpoint(Process *proc, LPDEBUG_EVENT pDebEvent) { LPEXCEPTION_DEBUG_INFO exceptInfo; CONTEXT context; ThreadInfo *tinfo; Breakpoint *pbrkpt, *brkpt; PDWORD pdw; DWORD i; DWORD dw; for (tinfo = proc->threadList; tinfo != 0L; tinfo = tinfo->nextPtr) { if (pDebEvent->dwThreadId == tinfo->dwThreadId) { break; } } assert(tinfo != 0L); exceptInfo = &pDebEvent->u.Exception; pbrkpt = 0L; for (brkpt = proc->brkptList; brkpt != 0L; pbrkpt = brkpt, brkpt = brkpt->nextPtr) { if (brkpt->codePtr == exceptInfo->ExceptionRecord.ExceptionAddress) { if (brkpt->threadInfo == 0L) { break; } if (brkpt->threadInfo == tinfo) { break; } } } context.ContextFlags = CONTEXT_FULL; GetThreadContext(tinfo->hThread, &context); if (! brkpt->returning) { Breakpoint *bpt; // Get the arguments to the function and store them in the thread // specific data structure. for (pdw = tinfo->args, i=0; i < brkpt->breakInfo->nargs; i++, pdw++) { ReadSubprocessMemory(proc, (PVOID) (context.Esp+(4*(i+1))), pdw, sizeof(DWORD)); } tinfo->nargs = brkpt->breakInfo->nargs; tinfo->context = &context; if (brkpt->breakInfo->dwFlags & BREAK_IN) { ((this)->*(brkpt->breakInfo->breakProc))(proc, tinfo, brkpt, &context.Eax, BREAK_IN); } // Only set a return breakpoint if something is interested // in the return value if (brkpt->breakInfo->dwFlags & BREAK_OUT) { bpt = new Breakpoint; ReadSubprocessMemory(proc, (PVOID) context.Esp, &bpt->origRetAddr, sizeof(DWORD)); dw = (DWORD) brkpt->codeReturnPtr; WriteSubprocessMemory(proc, (PVOID) context.Esp, &dw, sizeof(DWORD)); bpt->codePtr = brkpt->codeReturnPtr; bpt->returning = TRUE; bpt->codeReturnPtr = 0L; // Doesn't matter bpt->breakInfo = brkpt->breakInfo; bpt->threadInfo = tinfo; bpt->nextPtr = proc->brkptList; proc->brkptList = bpt; } // Now, we need to restore the original code for this breakpoint. // Put the program counter back, then do a single-step and put // the breakpoint back again. // WriteSubprocessMemory(proc, brkpt->codePtr, &brkpt->code, sizeof(BYTE)); context.EFlags |= SINGLE_STEP_BIT; context.Eip--; proc->lastBrkpt = brkpt; } else { // Make the callback with the params and the return value if (brkpt->breakInfo->dwFlags & BREAK_OUT) { ((this)->*(brkpt->breakInfo->breakProc))(proc, tinfo, brkpt, &context.Eax, BREAK_OUT); } context.Eip = brkpt->origRetAddr; if (pbrkpt == 0L) { proc->brkptList = brkpt->nextPtr; } else { pbrkpt->nextPtr = brkpt->nextPtr; } delete brkpt; } SetThreadContext(tinfo->hThread, &context); } /* *---------------------------------------------------------------------- * * ReadSubprocessStringA -- * * Read a character string from the subprocess * * Results: * The length of the string * *---------------------------------------------------------------------- */ int ConsoleDebugger::ReadSubprocessStringA(Process *proc, PVOID base, PCHAR buf, int buflen) { CHAR *ip, *op; int i; ip = static_cast<CHAR *>(base); op = buf; i = 0; while (i < buflen-1) { if (! ReadSubprocessMemory(proc, ip, op, sizeof(CHAR))) { break; } if (*op == 0) break; op++; ip++; i++; } *op = 0; return i; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::ReadSubprocessStringW -- * * Read a character string from the subprocess * * Results: * The length of the string * *---------------------------------------------------------------------- */ int ConsoleDebugger::ReadSubprocessStringW(Process *proc, PVOID base, PWCHAR buf, int buflen) { WCHAR *ip, *op; int i; ip = static_cast<WCHAR *>(base); op = buf; i = 0; while (i < buflen-1) { if (! ReadSubprocessMemory(proc, ip, op, sizeof(WCHAR))) { break; } if (*op == 0) break; op++; ip++; i++; } *op = 0; return i; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::LoadedModule -- * * A module with the specifed name was loaded. Add it to our * list of loaded modules and print any debugging information * if debugging is enabled. * * Results: * If the module is known, return TRUE. Otherwise, return FALSE * *---------------------------------------------------------------------- */ int ConsoleDebugger::LoadedModule(Process *proc, HANDLE hFile, LPVOID modname, int isUnicode, LPVOID baseAddr, DWORD debugOffset) { int known = 1; PVOID ptr; char mbstr[512]; char *s = 0L; Module *modPtr; if (modname) { // This modname is a pointer to the name of the // DLL in the process space of the subprocess // if (ReadSubprocessMemory(proc, modname, &ptr, sizeof(PVOID)) && ptr) { if (isUnicode) { WCHAR name[512]; ReadSubprocessStringW(proc, ptr, name, 512); wcstombs(mbstr, name, sizeof(mbstr)); } else { ReadSubprocessStringA(proc, ptr, mbstr, sizeof(mbstr)); } s = strdup(mbstr); } else { known = 0; } } modPtr = new Module; modPtr->loaded = FALSE; modPtr->hFile = hFile; modPtr->baseAddr = baseAddr; modPtr->modName = s; modPtr->dbgInfo = 0L; if (proc->exeModule == 0L) { proc->exeModule = modPtr; } proc->moduleTable.Add(baseAddr, modPtr); return known; } void ConsoleDebugger::WriteMaster(CHAR *buf, DWORD len) { Message *msg; msg = new Message; msg->bytes = (BYTE *) _strdup(buf); msg->length = len; msg->type = Message::TYPE_NORMAL; mQ.Put(msg); } void ConsoleDebugger::NotifyDone() { Message *msg; msg = new Message; msg->type = Message::TYPE_SLAVEDONE; mQ.Put(msg); } |
Added win/expWinConsoleDebugger.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | /* ---------------------------------------------------------------------------- * expWinConsoleDebugger.hpp -- * * Console debugger class declared here. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinConsoleDebugger.hpp,v 1.1.2.16 2002/03/15 07:51:56 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef INC_expWinConsoleDebugger_hpp__ #define INC_expWinConsoleDebugger_hpp__ #include "expWinSlave.hpp" #include "TclHash.hpp" // for the hash table template. #include <imagehlp.h> #ifdef _M_IX86 // 4096 is for ix86 only # define PAGESIZE 0x1000 // This only works on ix86 # define SINGLE_STEP_BIT 0x100; #else # error "need platform page size" #endif #define PAGEMASK (PAGESIZE-1) // This is our debugger. We run it in a thread. // class ConsoleDebugger : public CMclThreadHandler, ArgMaker { public: ConsoleDebugger(int argc, char * const *argv, CMclQueue<Message *> &_mQ); ~ConsoleDebugger(); private: virtual unsigned ThreadHandlerProc(void); // forward reference. class Process; class Breakpoint; class CreateProcessInfo { friend class ConsoleDebugger; TCHAR appName[8192]; TCHAR cmdLine[8192]; SECURITY_ATTRIBUTES procAttrs; SECURITY_ATTRIBUTES threadAttrs; BOOL bInheritHandles; DWORD dwCreationFlags; LPVOID lpEnvironment; TCHAR currDir[8192]; STARTUPINFO si; PROCESS_INFORMATION pi; PVOID piPtr; // Pointer to PROCESS_INFORMATION in slave. DWORD flags; }; class CreateProcessThreadArgs { friend class ConsoleDebugger; CreateProcessInfo *cp; Process *proc; }; class ThreadInfo { friend class ConsoleDebugger; HANDLE hThread; DWORD dwThreadId; DWORD nargs; DWORD args[16]; // Space for saving 16 args. We need this // space while we are waiting for the return // value for the function. LPCONTEXT context; // Current context. CreateProcessInfo *createProcess; // Create process pointer. ThreadInfo *nextPtr; // Linked list. }; class BreakInfo { friend class ConsoleDebugger; const char *funcName; // Name of function to intercept. DWORD nargs; // Number of arguments. void (ConsoleDebugger::*breakProc)(Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); // Function to call when the breakpoint is hit. # define BREAK_IN 1 // Call handler on the way in. # define BREAK_OUT 2 // Call handler on the way out. DWORD dwFlags; // Bits for direction to call handler in. }; class DllBreakpoints { friend class ConsoleDebugger; const char *dllName; BreakInfo *breakInfo; }; class Breakpoint { friend class ConsoleDebugger; BOOL returning; // Is this a returning breakpoint? BYTE code; // Original code. PVOID codePtr; // Address of original code. PVOID codeReturnPtr; // Address of return breakpoint. DWORD origRetAddr; // Original return address. BreakInfo *breakInfo; // Information about the breakpoint. ThreadInfo *threadInfo; // If this breakpoint is for a specific thread. Breakpoint *nextPtr; // Linked list. }; class Module { friend class ConsoleDebugger; BOOL loaded; HANDLE hFile; LPVOID baseAddr; PCHAR modName; PIMAGE_DEBUG_INFORMATION dbgInfo; }; typedef Tcl::Hash<PVOID,TCL_STRING_KEYS> STRING2PTR; typedef Tcl::Hash<Module *,TCL_ONE_WORD_KEYS> PTR2MODULE; // There is one of these instances for each subprocess that we are // controlling. // class Process { friend class ConsoleDebugger; ThreadInfo *threadList; // List of threads in the subprocess. Breakpoint *brkptList; // List of breakpoints in the subprocess. Breakpoint *lastBrkpt; // Last breakpoint hit. DWORD offset; // Breakpoint offset in allocated mem. DWORD nBreakCount; // Number of breakpoints hit. DWORD consoleHandles[100];// A list of input console handles. DWORD consoleHandlesMax; BOOL isConsoleApp; // Is this a console app? BOOL isShell; // Is this some sort of console shell? HANDLE hProcess; // handle to subprocess. DWORD pid; // Global process id. DWORD threadCount; // Number of threads in process. DWORD pSubprocessMemory; // Pointer to allocated memory in subprocess. DWORD pSubprocessBuffer; // Pointer to buffer memory in subprocess. DWORD pMemoryCacheBase; // Base address of memory cache. BYTE pMemoryCache[PAGESIZE];// Subprocess memory cache. STRING2PTR funcTable; // Function table name to address mapping. PTR2MODULE moduleTable; // Win32 modules that have been loaded. Module *exeModule; // Executable module info. Process *nextPtr; // Linked list. }; // Direct debug event handlers. // void OnXFirstBreakpoint (Process *, LPDEBUG_EVENT); void OnXSecondBreakpoint (Process *, LPDEBUG_EVENT); void OnXBreakpoint (Process *, LPDEBUG_EVENT); void OnXCreateProcess (Process *, LPDEBUG_EVENT); void OnXCreateThread (Process *, LPDEBUG_EVENT); void OnXDeleteThread (Process *, LPDEBUG_EVENT); void OnXLoadDll (Process *, LPDEBUG_EVENT); void OnXUnloadDll (Process *, LPDEBUG_EVENT); void OnXSecondChanceException (Process *, LPDEBUG_EVENT); void OnXSingleStep (Process *, LPDEBUG_EVENT); // Our breakpoint handlers (indirect). Called from OnXBreakpoint(). // void OnBeep (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnFillConsoleOutputCharacter (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnGetStdHandle (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnIsWindowVisible (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnOpenConsoleW (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnReadConsoleInput (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnSetConsoleActiveScreenBuffer (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnSetConsoleCursorPosition (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnSetConsoleMode (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnSetConsoleWindowInfo (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnScrollConsoleScreenBuffer (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleA (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleW (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleOutputA (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleOutputW (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleOutputCharacterA (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); void OnWriteConsoleOutputCharacterW (Process *, ThreadInfo *, Breakpoint *, PDWORD, DWORD); // Internal utilities // Process *ProcessNew (); void ProcessFree (Process *); void CommonDebugger (); BOOL SetBreakpoint (Process *, BreakInfo *); Breakpoint *SetBreakpointAtAddr (Process *, BreakInfo *, PVOID); int LoadedModule (Process *, HANDLE, LPVOID, int, LPVOID, DWORD); BOOL ReadSubprocessMemory (Process *, LPVOID, LPVOID, DWORD); BOOL WriteSubprocessMemory (Process *, LPVOID, LPVOID, DWORD); int ReadSubprocessStringA (Process *, PVOID, PCHAR, int); int ReadSubprocessStringW (Process *, PVOID, PWCHAR, int); void CreateVtSequence (Process *, COORD, DWORD); // send info back to the parent void WriteMaster (CHAR *, DWORD); // announce we are done. void NotifyDone (); // The arrays of functions where we set breakpoints // BreakInfo BreakArrayKernel32[20]; BreakInfo BreakArrayUser32[2]; DllBreakpoints BreakPoints[3]; // private vars // Process *ProcessList; // Top of linked list of Process instances. HANDLE hMasterConsole; // Master console handle (us). DWORD MasterConsoleInputMode;// Current flags for the master console. COORD ConsoleSize; // Size of the console in the slave. COORD CursorPosition; // Coordinates of the cursor in the slave. BOOL CursorKnown; // Do we know where the slave's cursor is? char *SymbolPath; // Storage for setting OS kernel symbols path. BOOL ShowExceptionBacktraces;// print exception info from debuggee? int argc; // Debugee process commandline count char * const * argv; // Debugee process commandline args // Thread-safe message queue used for communication back to the parent. CMclQueue<Message *> &mQ; }; #endif // INC_expWinConsoleDebugger_hpp__ |
Added win/expWinConsoleDebuggerBreakPoints.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 | /* ---------------------------------------------------------------------------- * expWinConsoleDebuggerBreakPoints.cpp -- * * Breakpoints for the ConsoleDebugger class are in here. These define * the behavior of what to do when a breakpoint happens in the slave * we are intercepting. From here, we transfer the stream .... (TBF) * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinConsoleDebuggerBreakPoints.cpp,v 1.1.2.9 2002/03/13 03:52:57 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinConsoleDebugger.hpp" // NOTE: black magic abounds... be warry young padwon... /* *---------------------------------------------------------------------- * * ConsoleDebugger::CreateVtSequence -- * * When moving the cursor to a new location, this will create * the appropriate VT100 type sequence to get the cursor there. * * Results: * None * * Side Effects: * Characters are written to the pipe going to Expect * *---------------------------------------------------------------------- */ void ConsoleDebugger::CreateVtSequence(Process *proc, COORD newPos, DWORD n) { COORD oldPos; CHAR buf[2048]; DWORD count; if (n == 0) { return; } oldPos = CursorPosition; if (CursorKnown && (newPos.Y > oldPos.Y) && (newPos.X == 0)) { buf[0] = '\r'; memset(&buf[1], '\n', newPos.Y - oldPos.Y); count = 1 + newPos.Y - oldPos.Y; } else { // VT100 sequence wsprintfA(buf, "\033[%d;%dH", newPos.Y+1, newPos.X+1); count = strlen(buf); } newPos.X += (SHORT) (n % ConsoleSize.X); newPos.Y += (SHORT) (n / ConsoleSize.X); CursorPosition = newPos; WriteMaster(buf, count); } /* *----------------------------------------------------------------------------- * * ConsoleDebugger::OnBeep -- * * This routine gets called when Beep is called. At least in sshd, * we don't want a beep to show up on the local console. Instead, * direct it back to the master with a ASCII 7. * * Results: * None * * Notes: * XXX: Setting the duration to 0 doesn't seem to make the local * beep go away. It seems we need to stop the call at this point * (or point it to some other call with the same number of arguments) * *----------------------------------------------------------------------------- */ void ConsoleDebugger::OnBeep(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[2] = {0,0}; if (direction == BREAK_IN) { // Modify the arguments so a beep doesn't sound in the slave. threadInfo->args[1] = 0; } else if (direction == BREAK_OUT) { if (*returnValue == 0) { buf[0] = 7; // ASCII beep WriteMaster(buf, 1); } } } /* *----------------------------------------------------------------------------- * * ConsoleDebugger::OnFillConsoleOutputCharacter -- * * This function gets called when an FillConsoleOutputCharacterA * or FillConsoleOutputCharacterW breakpoint is hit. * * Results: * None * * Side Effects: * Prints some output. * *----------------------------------------------------------------------------- */ void ConsoleDebugger::OnFillConsoleOutputCharacter(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[4096]; int bufpos; UCHAR c; PVOID ptr; DWORD i; DWORD len; COORD coord; DWORD lines, preCols, postCols; BOOL eol, bol; // Needs clearing to end, beginning of line CONSOLE_SCREEN_BUFFER_INFO info; if (*returnValue == 0) { return; } c = (UCHAR) threadInfo->args[1]; len = threadInfo->args[2]; coord = *((PCOORD) &(threadInfo->args[3])); ptr = (PVOID) threadInfo->args[4]; if (ptr) { ReadSubprocessMemory(proc, ptr, &len, sizeof(DWORD)); } preCols = 0; bufpos = 0; eol = bol = FALSE; if (coord.X) { preCols = ConsoleSize.X - coord.X; if (len <= preCols) { preCols = len; len = 0; if (len == preCols) { eol = TRUE; } } else { eol = TRUE; len -= preCols; } } else if (len < (DWORD) ConsoleSize.X) { bol = TRUE; preCols = len; len = 0; } lines = len / ConsoleSize.X; postCols = len % ConsoleSize.X; if (preCols) { if (bol) { // Beginning of line to before end of line if (c == ' ') { wsprintfA(&buf[bufpos], "\033[%d;%dH\033[1K", coord.Y+1, preCols+coord.X); bufpos += strlen(&buf[bufpos]); } else { wsprintfA(&buf[bufpos], "\033[%d;%dH", coord.Y+1, coord.X+1); bufpos += strlen(&buf[bufpos]); memset(&buf[bufpos], c, preCols); bufpos += preCols; } } else { // After beginning of line to end of line wsprintfA(&buf[bufpos], "\033[%d;%dH", coord.Y+1, coord.X+1); bufpos += strlen(&buf[bufpos]); if (eol && c == ' ') { wsprintfA(&buf[bufpos], "\033[K"); bufpos += strlen(&buf[bufpos]); } else { memset(&buf[bufpos], c, preCols); bufpos += preCols; } } coord.X = 0; coord.Y++; } if (lines) { if ((c == ' ') && ((lines + coord.Y) >= (DWORD) ConsoleSize.Y)) { // Clear to end of screen wsprintfA(&buf[bufpos], "\033[%d;%dH\033[J", coord.Y+1, coord.X+1); bufpos += strlen(&buf[bufpos]); } else if ((c == ' ') && (coord.Y == 0) && (lines > 0)) { // Clear to top of screen wsprintfA(&buf[bufpos], "\033[%d;%dH\033[1J", lines, 1); bufpos += strlen(&buf[bufpos]); } else { for (i = 0; i < lines; i++) { wsprintfA(&buf[bufpos], "\033[%d;%dH", coord.Y+i+1, coord.X+1); bufpos += strlen(&buf[bufpos]); if (c == ' ') { wsprintfA(&buf[bufpos], "\033[2K"); bufpos += strlen(&buf[bufpos]); } else { memset(&buf[bufpos], c, ConsoleSize.X); bufpos += ConsoleSize.X; } } } coord.Y += (SHORT) lines; } if (postCols) { if (c == ' ') { // Clear to beginning of line wsprintfA(&buf[bufpos], "\033[%d;%dH\033[1K", coord.Y+1, postCols+coord.X); bufpos += strlen(&buf[bufpos]); } else { wsprintfA(&buf[bufpos], "\033[%d;%dH", coord.X+1, coord.Y+1); bufpos += strlen(&buf[bufpos]); memset(&buf[bufpos], c, postCols); bufpos += postCols; } } if (GetConsoleScreenBufferInfo(hMasterConsole, &info) == FALSE) { char errbuf[200]; wsprintfA(errbuf, "handle=0x%08x", hMasterConsole); EXP_LOG2(MSG_DT_SCREENBUF, errbuf, ExpSyslogGetSysMsg(GetLastError())); } else { CursorPosition = info.dwCursorPosition; wsprintfA(&buf[bufpos], "\033[%d;%dH", CursorPosition.Y+1, CursorPosition.X+1); bufpos += strlen(&buf[bufpos]); CursorKnown = TRUE; } WriteMaster(buf, bufpos); } /* *----------------------------------------------------------------------------- * * ConsoleDebugger::OnGetStdHandle -- * * This function gets called when a GetStdHandle breakpoint * is hit. * * Results: * None * * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *----------------------------------------------------------------------------- */ void ConsoleDebugger::OnGetStdHandle(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { DWORD i; BOOL found; if (*returnValue == (DWORD) INVALID_HANDLE_VALUE) { return; } if (threadInfo->args[0] != STD_INPUT_HANDLE) { return; } for (found = FALSE, i = 0; i < proc->consoleHandlesMax; i++) { if (proc->consoleHandles[i] == *returnValue) { found = TRUE; break; } } if (! found) { if (proc->consoleHandlesMax > 100) { proc->consoleHandlesMax = 100; } proc->consoleHandles[proc->consoleHandlesMax++] = *returnValue; } return; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnOpenConsoleW -- * * This function gets called when an OpenConsoleW breakpoint * is hit. There is one big problem with this function--it * isn't documented. However, we only really care about the * return value which is a console handle. I think this is * what this function declaration should be: * * HANDLE OpenConsoleW(LPWSTR lpFileName, * DWORD dwDesiredAccess, * DWORD dwShareMode, * LPSECURITY_ATTRIBUTES lpSecurityAttributes); * * So why do we intercept an undocumented function while we * could just intercept CreateFileW and CreateFileA? Well, * those functions are going to get called alot more than this * one, so limiting the number of intercepted functions * improves performance since fewer breakpoints will be hit. * * Results: * None * * Side Effects: * Save the return value in an array of known console handles * with their statuses. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnOpenConsoleW(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR name[256]; PVOID ptr; if (*returnValue == (DWORD) INVALID_HANDLE_VALUE) { return; } // Save any console input handle. No SetConsoleMode() calls will // succeed unless they are really attached to a console input buffer. // ptr = (PVOID) threadInfo->args[0]; ReadSubprocessStringW(proc, ptr, name, 256); if (wcsicmp(name, L"CONIN$") == 0) { if (proc->consoleHandlesMax > 100) { proc->consoleHandlesMax = 100; } proc->consoleHandles[proc->consoleHandlesMax++] = *returnValue; } return; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnReadConsoleInput -- * * This function gets called when a ReadConsoleInput breakpoint * is hit. * * Results: * None * * Notes: * If this is ever used for real, there need to be ASCII * and UNICODE versions. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnReadConsoleInput(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnScrollConsoleScreenBuffer -- * * This funtions gets called when a ScrollConsoleScreenBuffer * breakpoint is hit. * * Results: * None * * Side Effects: * Generate some VT100 sequences to insert lines * * Notes: * XXX: Ideally, we should check if the screen buffer is the one that * is currently being displayed. However, that means we have to * track CONOUT$ handles, so we don't do it for now. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnScrollConsoleScreenBuffer(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[100]; DWORD count = 0; SMALL_RECT scroll, clip, *pClip; COORD dest; CHAR_INFO fill; CHAR c; PVOID ptr; if (*returnValue == FALSE) { return; } ptr = (PVOID) threadInfo->args[1]; ReadSubprocessMemory(proc, ptr, &scroll, sizeof(SMALL_RECT)); ptr = (PVOID) threadInfo->args[2]; pClip = 0L; if (ptr) { pClip = &clip; ReadSubprocessMemory(proc, ptr, &clip, sizeof(SMALL_RECT)); } dest = *((PCOORD) &threadInfo->args[3]); ptr = (PVOID) threadInfo->args[4]; ReadSubprocessMemory(proc, ptr, &fill, sizeof(CHAR_INFO)); c = fill.Char.AsciiChar; // Check for a full line scroll if (c == ' ' && scroll.Left == dest.X && scroll.Left == 0 && scroll.Right >= ConsoleSize.X-1) { if (dest.Y < scroll.Top) { wsprintfA(&buf[count], "\033[%d;%dr\033[%d;%dH\033[%dM", dest.Y+1,scroll.Bottom+1,dest.Y+1,1, scroll.Top - dest.Y); } else { wsprintfA(&buf[count], "\033[%d;%dr\033[%d;%dH\033[%dL", scroll.Top+1,dest.Y+1+(scroll.Bottom - scroll.Top), scroll.Top+1,1, dest.Y - scroll.Top); } count = strlen(&buf[count]); wsprintf(&buf[count], "\033[%d;%dr", 1, ConsoleSize.Y); count += strlen(&buf[count]); WriteMaster(buf, count); } else { // RefreshScreen(&proc->overlapped); } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnSetConsoleMode -- * * This function gets called when a SetConsoleMode breakpoint * is hit. * * Results: * None * * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnSetConsoleMode(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { DWORD i; BOOL found; // The console mode seems to get set even if the return value is FALSE if (*returnValue == FALSE) { return; } for (found = FALSE, i = 0; i < proc->consoleHandlesMax; i++) { if (threadInfo->args[0] == proc->consoleHandles[i]) { found = TRUE; break; } } if (found) { MasterConsoleInputMode = threadInfo->args[1]; } } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnSetConsoleActiveScreenBuffer -- * * This function gets called when a SetConsoleActiveScreenBuffer * breakpoint is hit. * * Results: * None * * Side Effects: * We reread the entire console and send it to the master. * Updates the current console cursor position * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnSetConsoleActiveScreenBuffer(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { if (*returnValue == FALSE) { return; } // RefreshScreen(&proc->overlapped); } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnSetConsoleCursorPosition -- * * This function gets called when a SetConsoleCursorPosition breakpoint * is hit. * * Results: * None * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnSetConsoleCursorPosition(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[50]; DWORD count; if (*returnValue == FALSE) { return; } CursorPosition = *((PCOORD) &threadInfo->args[1]); wsprintfA(buf, "\033[%d;%dH", CursorPosition.Y+1, CursorPosition.X+1); count = strlen(buf); WriteMaster(buf, count); } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnSetConsoleWindowInfo -- * * This function gets called when a SetConsoleWindowInfo breakpoint * is hit. * * Results: * None * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnSetConsoleWindowInfo(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleA -- * * This function gets called when an WriteConsoleA breakpoint * is hit. The data is also redirected to expect since expect * normally couldn't see any output going through this interface. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleA(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[1024]; PVOID ptr; DWORD n; PCHAR p; if (*returnValue == 0) { return; } // Get number of bytes written ptr = (PVOID) threadInfo->args[3]; if (ptr == 0L) { n = threadInfo->args[2]; } else { ReadSubprocessMemory(proc, ptr, &n, sizeof(DWORD)); } if (n > 1024) { p = new CHAR [n]; } else { p = buf; } ptr = (PVOID) threadInfo->args[1]; ReadSubprocessMemory(proc, ptr, p, n * sizeof(CHAR)); // ResetEvent(proc->overlapped.hEvent); WriteMaster(p, n); if (p != buf) { delete [] p; } CursorKnown = FALSE; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleW -- * * This function gets called when an WriteConsoleW breakpoint * is hit. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleW(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { static WCHAR buf[1024]; static CHAR ansi[2048]; PVOID ptr; DWORD n; PWCHAR p; PCHAR a; int asize; int w; if (*returnValue == 0) { return; } ptr = (PVOID) threadInfo->args[1]; n = threadInfo->args[2]; if (n > 1024) { p = new WCHAR [n]; asize = n * 2 * sizeof(CHAR); a = new CHAR [n * 2]; } else { p = buf; a = ansi; asize = sizeof(ansi); } ReadSubprocessMemory(proc, ptr, p, n * sizeof(WCHAR)); // ResetEvent(proc->overlapped.hEvent); // Convert to ASCII and write the intercepted data to the pipe. // w = WideCharToMultiByte(CP_ACP, 0, p, n, a, asize, 0L, 0L); WriteMaster(a, w); if (p != buf) { delete [] p, a; } CursorKnown = FALSE; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleOutputA -- * * This function gets called when an WriteConsoleOutputA breakpoint * is hit. The data is also redirected to expect since expect * normally couldn't see any output going through this interface. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleOutputA(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[1024]; PVOID ptr; DWORD n; CHAR *p, *end; int maxbuf; COORD bufferSize; COORD bufferCoord; COORD curr; SMALL_RECT writeRegion; CHAR_INFO *charBuf, *pcb; SHORT x, y; if (*returnValue == 0) { return; } bufferSize = *((PCOORD) &threadInfo->args[2]); bufferCoord = *((PCOORD) &threadInfo->args[3]); ptr = (PVOID) threadInfo->args[4]; // Get the rectangle written if (ptr == 0L) return; ReadSubprocessMemory(proc, ptr, &writeRegion,sizeof(SMALL_RECT)); ptr = (PVOID) threadInfo->args[1]; // Get character array if (ptr == 0L) return; n = bufferSize.X * bufferSize.Y * sizeof(CHAR_INFO); charBuf = new CHAR_INFO [n]; #if 0 wsprintfA((char *) charBuf, "writeRegion: (%d,%d) to (%d,%d) bufferCoord: (%d,%d) bufferSize: (%d,%d)", writeRegion.Left, writeRegion.Top, writeRegion.Right, writeRegion.Bottom, bufferCoord.X, bufferCoord.Y, bufferSize.X, bufferSize.Y); ExpSyslog("Debug 0: %s", charBuf); #endif ReadSubprocessMemory(proc, ptr, charBuf, n); pcb = charBuf; for (y = 0; y <= writeRegion.Bottom - writeRegion.Top; y++) { pcb = charBuf; pcb += (y + bufferCoord.Y) * bufferSize.X; pcb += bufferCoord.X; p = buf; maxbuf = sizeof(buf); end = buf + maxbuf; for (x = 0; x <= writeRegion.Right - writeRegion.Left; x++, pcb++) { *p++ = pcb->Char.AsciiChar; if (p == end) { // ResetEvent(proc->overlapped.hEvent); WriteMaster(buf, maxbuf); p = buf; } } curr.X = writeRegion.Left; curr.Y = writeRegion.Top + y; n = writeRegion.Right - writeRegion.Left; CreateVtSequence(proc, curr, n); // ResetEvent(proc->overlapped.hEvent); maxbuf = p - buf; WriteMaster(buf, maxbuf); buf[maxbuf] = 0; } delete [] charBuf; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleOutputW -- * * This function gets called when an WriteConsoleOutputW breakpoint * is hit. The data is also redirected to expect since expect * normally couldn't see any output going through this interface. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleOutputW(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR buf[1024]; PVOID ptr; DWORD n; WCHAR *p, *end; int maxbuf; COORD bufferSize; COORD bufferCoord; COORD curr; SMALL_RECT writeRegion; CHAR_INFO *charBuf, *pcb; SHORT x, y; if (*returnValue == 0) { return; } bufferSize = *((PCOORD) &threadInfo->args[2]); bufferCoord = *((PCOORD) &threadInfo->args[3]); ptr = (PVOID) threadInfo->args[4]; // Get the rectangle written if (ptr == 0L) return; ReadSubprocessMemory(proc, ptr, &writeRegion,sizeof(SMALL_RECT)); ptr = (PVOID) threadInfo->args[1]; // Get character array if (ptr == 0L) return; n = bufferSize.X * bufferSize.Y * sizeof(CHAR_INFO); charBuf = new CHAR_INFO [n]; #if 0 wsprintfA((char *) charBuf, "writeRegion: (%d,%d) to (%d,%d) bufferCoord: (%d,%d) bufferSize: (%d,%d)", writeRegion.Left, writeRegion.Top, writeRegion.Right, writeRegion.Bottom, bufferCoord.X, bufferCoord.Y, bufferSize.X, bufferSize.Y); ExpSyslog("Debug 0: %s", charBuf); #endif ReadSubprocessMemory(proc, ptr, charBuf, n); pcb = charBuf; for (y = 0; y <= writeRegion.Bottom - writeRegion.Top; y++) { pcb = charBuf; pcb += (y + bufferCoord.Y) * bufferSize.X; pcb += bufferCoord.X; p = buf; maxbuf = sizeof(buf); end = buf + maxbuf; for (x = 0; x <= writeRegion.Right - writeRegion.Left; x++, pcb++) { *p++ = (CHAR) (pcb->Char.UnicodeChar & 0xff); if (p == end) { // ResetEvent(proc->overlapped.hEvent); WriteMaster((char *)buf, maxbuf); p = buf; } } curr.X = writeRegion.Left; curr.Y = writeRegion.Top + y; n = writeRegion.Right - writeRegion.Left; CreateVtSequence(proc, curr, n); // ResetEvent(proc->overlapped.hEvent); maxbuf = p - buf; WriteMaster((char *)buf, maxbuf); buf[maxbuf] = 0; } delete [] charBuf; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleOutputCharacterA -- * * This function gets called when an WriteConsoleOutputCharacterA breakpoint * is hit. The data is also redirected to expect since expect * normally couldn't see any output going through this interface. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleOutputCharacterA(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { static CHAR buf[1024]; PVOID ptr; DWORD n; PCHAR p; if (*returnValue == 0) { return; } // Get number of bytes written ptr = (PVOID) threadInfo->args[4]; if (ptr == 0L) { n = threadInfo->args[2]; } else { ReadSubprocessMemory(proc, ptr, &n, sizeof(DWORD)); } CreateVtSequence(proc, *((PCOORD) &threadInfo->args[3]), n); if (n > 1024) { p = new CHAR [n]; } else { p = buf; } ptr = (PVOID) threadInfo->args[1]; ReadSubprocessMemory(proc, ptr, p, n * sizeof(CHAR)); // ResetEvent(proc->overlapped.hEvent); WriteMaster(p, n); if (p != buf) { delete [] p; } CursorKnown = FALSE; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnWriteConsoleOutputCharacterW -- * * This function gets called when an WriteConsoleOutputCharacterW * breakpoint is hit. * * Results: * None * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnWriteConsoleOutputCharacterW(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { static WCHAR buf[1024]; static CHAR ansi[2048]; PVOID ptr; DWORD n; PWCHAR p; PCHAR a; int asize; int w; if (*returnValue == 0) { return; } // Get number of bytes written ptr = (PVOID) threadInfo->args[4]; if (ptr == 0L) { n = threadInfo->args[2]; } else { ReadSubprocessMemory(proc, ptr, &n, sizeof(DWORD)); } CreateVtSequence(proc, *((PCOORD) &threadInfo->args[3]), n); if (n > 1024) { p = new WCHAR [n]; asize = n * 2 * sizeof(CHAR); a = new CHAR [n * 2]; } else { p = buf; a = ansi; asize = sizeof(ansi); } ptr = (PVOID) threadInfo->args[1]; ReadSubprocessMemory(proc, ptr, p, n * sizeof(WCHAR)); // ResetEvent(proc->overlapped.hEvent); // Convert to ASCI and Write the intercepted data to the pipe. w = WideCharToMultiByte(CP_ACP, 0, p, n, a, asize, 0L, 0L); WriteMaster(a, w); if (p != buf) { delete [] p, a; } CursorKnown = FALSE; } /* *---------------------------------------------------------------------- * * ConsoleDebugger::OnIsWindowVisible -- * * This routine gets called when IsWindowVisible is called. * The MKS Korn shell uses this as an indication of a window * that can be seen by the user. If the window can't be seen, * it pops up a graphical error notification. We really, really * don't want those damn things popping up, so this helps avoid * it. And there really doesn't seem to be any good reason to * return FALSE given that nobody is ever going to see anything. * * Results: * None * *---------------------------------------------------------------------- */ void ConsoleDebugger::OnIsWindowVisible(Process *proc, ThreadInfo *threadInfo, Breakpoint *brkpt, PDWORD returnValue, DWORD direction) { *returnValue = TRUE; } |
Added win/expWinDynloadTclStubs.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | /* ---------------------------------------------------------------------------- * expWinDynloadTclStubs.cpp -- * * Grabs and loads tclXX.dll from the EXP_TCLDLL environment variable. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.sf.net/ * http://expect.nist.gov/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinDynloadTclStubs.cpp,v 1.1.2.1 2002/03/12 18:41:38 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "tcl.h" // We need at least the Tcl_Obj interface that was started in 8.0 #if TCL_MAJOR_VERSION < 8 # error "we need Tcl 8.0 or greater to build this" // Check for Stubs compatibility when asked for it. #elif defined(USE_TCL_STUBS) && TCL_MAJOR_VERSION == 8 && \ (TCL_MINOR_VERSION == 0 || \ (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL != TCL_FINAL_RELEASE)) # error "Stubs interface doesn't work in 8.0 and alpha/beta 8.1; only 8.1.0+" #endif #ifdef _MSC_VER // Only do this when MSVC++ is compiling us. # ifdef USE_TCL_STUBS // Mark this .obj as needing tcl's Stubs library. # pragma comment(lib, "tclstub" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # if !defined(_MT) || !defined(_DLL) || defined(_DEBUG) // This fixes a bug with how the Stubs library was compiled. // The requirement for msvcrt.lib from tclstubXX.lib should // be removed. # pragma comment(linker, "-nodefaultlib:msvcrt.lib") # endif # else // Mark this .obj needing the import library # pragma comment(lib, "tcl" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # endif #endif #include "slavedrvmc.h" #include <windows.h> #include "expWinUtils.hpp" static HMODULE hTclMod; void DynloadTclStubs (void) { TCHAR TclDLLPath[MAX_PATH+1]; typedef Tcl_Interp *(*LPFN_createInterpProc) (); LPFN_createInterpProc createInterpProc; Tcl_Interp *interp; char appname[MAX_PATH+1]; if (GetEnvironmentVariable("EXP_TCLDLL", TclDLLPath, MAX_PATH)) { /* Load it */ if (!(hTclMod = LoadLibrary(TclDLLPath))) { EXP_LOG1(MSG_STUBS_TCLDLLCANTFIND, TclDLLPath); } /* LoadLibrary() loaded the module correctly. * Get the location of Tcl_CreateInterp. */ if ((createInterpProc = (LPFN_createInterpProc) GetProcAddress(hTclMod, "Tcl_CreateInterp")) == 0L) { EXP_LOG1(MSG_STUBS_NOCREATEINTERP, TclDLLPath); } interp = createInterpProc(); if (Tcl_InitStubs(interp, "8.1", 0) == 0L) { EXP_LOG1(MSG_STUBS_INITSTUBS, interp->result); } /* Discover the calling application. */ GetModuleFileName(0L, appname, MAX_PATH); Tcl_FindExecutable(appname); /* we're done initializing the core, and now don't need this * interp anymore. */ Tcl_DeleteInterp(interp); } else { /* envar not found */ EXP_LOG0(MSG_STUBS_ENVARNOTSET); } } void ShutdownTcl (void) { Tcl_Finalize(); FreeLibrary(hTclMod); } |
Added win/expWinInit.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /* ---------------------------------------------------------------------------- * expWinInit.c -- * * Win OS specific inits. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinInit.c,v 1.1.4.3 2002/02/11 09:56:00 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" static ExpWinProcs asciiProcs = { 0, (HANDLE (WINAPI *)(LPCTSTR, DWORD, DWORD, SECURITY_ATTRIBUTES *, DWORD, DWORD, HANDLE)) CreateFileA, (BOOL (WINAPI *)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION)) CreateProcessA, (DWORD (WINAPI *)(LPCTSTR)) GetFileAttributesA, (DWORD (WINAPI *)(LPCTSTR, LPTSTR, DWORD)) GetShortPathNameA, (DWORD (WINAPI *)(LPCTSTR, LPCTSTR, LPCTSTR, DWORD, LPTSTR, LPTSTR *)) SearchPathA, (VOID (WINAPI *)(LPCTSTR)) OutputDebugStringA, (DWORD (WINAPI *)(HMODULE, LPTSTR, DWORD)) GetModuleFileNameA, (BOOL (WINAPI *)(LPCTSTR, LPCTSTR)) SetEnvironmentVariableA, (BOOL (WINAPI *)(LPCTSTR, LPTSTR, DWORD)) GetEnvironmentVariableA, (LONG (WINAPI *)(HKEY, LPCTSTR, DWORD, DWORD, CONST BYTE *, DWORD)) RegSetValueExA }; static ExpWinProcs unicodeProcs = { 1, (HANDLE (WINAPI *)(LPCTSTR, DWORD, DWORD, SECURITY_ATTRIBUTES *, DWORD, DWORD, HANDLE)) CreateFileW, (BOOL (WINAPI *)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION)) CreateProcessW, (DWORD (WINAPI *)(LPCTSTR)) GetFileAttributesW, (DWORD (WINAPI *)(LPCTSTR, LPTSTR, DWORD)) GetShortPathNameW, (DWORD (WINAPI *)(LPCTSTR, LPCTSTR, LPCTSTR, DWORD, LPTSTR, LPTSTR *)) SearchPathW, (VOID (WINAPI *)(LPCTSTR)) OutputDebugStringW, (DWORD (WINAPI *)(HMODULE, LPTSTR, DWORD)) GetModuleFileNameW, (BOOL (WINAPI *)(LPCTSTR, LPCTSTR)) SetEnvironmentVariableW, (BOOL (WINAPI *)(LPCTSTR, LPTSTR, DWORD)) GetEnvironmentVariableW, (LONG (WINAPI *)(HKEY, LPCTSTR, DWORD, DWORD, CONST BYTE *, DWORD)) RegSetValueExW }; ExpWinProcs *expWinProcs = &asciiProcs; tclWinMakeFileProcType tclWinMakeFileProc; /* *---------------------------------------------------------------------- * ExpWinInit -- * * Switches to the correct native API at run-time. Works in * tandem with Tcl_WinUtfToTchar(). * * Returns: * nothing. * *---------------------------------------------------------------------- */ void ExpWinInit(void) { if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { expWinProcs = &unicodeProcs; } /* need TclWinMakeFile() from the outside... los bastards! */ tclWinMakeFileProc = (tclWinMakeFileProcType) GetProcAddress(TclWinGetTclInstance(), "TclWinMakeFile"); #ifdef STATIC_BUILD /* this may not be correct, but closer than not */ expDllInstance = TclWinGetTclInstance(); #endif } |
Added win/expWinInt.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /* ---------------------------------------------------------------------------- * expWinInt.h -- * * Declarations of Windows-specific shared variables and procedures. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinInt.h,v 1.1.4.5 2002/03/09 01:17:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPWININT #define _EXPWININT #ifndef _EXPINT # ifndef _EXP /* Ask windows.h to be agressive about the HANDLE type. */ # define STRICT /* make sure we get the Win95 API */ # define WINVER 0x0400 # ifdef _DEBUG /* Make sure we add the WinNT API for IsDebuggerPresent(). */ # define _WIN32_WINNT 0x0400 # endif # endif # include "expInt.h" #endif #ifndef _EXPPORT # include "expPort.h" #endif #undef TCL_STORAGE_CLASS #if defined(BUILD_slavedriver) # define TCL_STORAGE_CLASS # include "expWinSlave.hpp" # ifdef _DEBUG # include "MsvcDbgControl.h" # endif # include "slavedrvmc.h" #elif defined(BUILD_exp) # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_EXP_STUBS # define TCL_STORAGE_CLASS # else # define TCL_STORAGE_CLASS DLLIMPORT # endif #endif #define EXP_SLAVE_CREATE 'c' #define EXP_SLAVE_KEY 'k' #define EXP_SLAVE_MOUSE 'm' #define EXP_SLAVE_WRITE 'w' #define EXP_SLAVE_KILL 'x' /* * Define the types of attempts to use to kill the subprocess */ #define EXP_KILL_TERMINATE 0x1 #define EXP_KILL_CTRL_C 0x2 #define EXP_KILL_CTRL_BREAK 0x4 //#define EXP_LOG(format, args) \ // ExpSyslog("Expect SlaveDriver (%s: %d): " format, __FILE__, __LINE__, args) /* * Errors and logging */ #define EXP_LOG0(errCode) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, 0) #define EXP_LOG1(errCode, arg1) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, arg1, 0) #define EXP_LOG2(errCode, arg1, arg2) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, arg1, arg2, 0) /* * The following defines identify the various types of applications that * run under windows. There is special case code for the various types. */ #define EXP_APPL_NONE 0 #define EXP_APPL_BATCH 1 #define EXP_APPL_DOS16 2 #define EXP_APPL_OS2 3 #define EXP_APPL_OS2DRV 4 #define EXP_APPL_WIN16 5 #define EXP_APPL_WIN16DRV 6 #define EXP_APPL_WIN32CUI 7 #define EXP_APPL_WIN32GUI 8 #define EXP_APPL_WIN32DLL 9 #define EXP_APPL_WIN32DRV 10 #define EXP_APPL_WIN64CUI 11 #define EXP_APPL_WIN64GUI 12 #define EXP_APPL_WIN64DLL 13 #define EXP_APPL_WIN64DRV 14 extern HMODULE expDllInstance; typedef struct { int useWide; HANDLE (WINAPI *createFileProc)(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); BOOL (WINAPI *createProcessProc)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD (WINAPI *getFileAttributesProc)(LPCTSTR); DWORD (WINAPI *getShortPathNameProc)(LPCTSTR, LPTSTR, DWORD); DWORD (WINAPI *searchPathProc)(LPCTSTR, LPCTSTR, LPCTSTR, DWORD, LPTSTR, LPTSTR *); VOID (WINAPI *outputDebugStringProc)(LPCTSTR); DWORD (WINAPI *getModuleFileNameProc)(HMODULE, LPTSTR, DWORD); BOOL (WINAPI *setEnvironmentVariableProc)(LPCTSTR, LPCTSTR); BOOL (WINAPI *getEnvironmentVariableProc)(LPCTSTR, LPTSTR, DWORD); LONG (WINAPI *regSetValueExProc)(HKEY, LPCTSTR, DWORD, DWORD, CONST BYTE *, DWORD); } ExpWinProcs; extern TCL_CPP ExpWinProcs *expWinProcs; #include "expIntPlatDecls.h" #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _EXPWININT */ |
Added win/expWinLog.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | /* ---------------------------------------------------------------------------- * expWinLog.c -- * * This file logs to the NT system log. Use the Event Viewer to * see these logs. This was predominately used to debug the * slavedrv.exe process. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinLog.c,v 1.1.2.1.2.2 2002/02/10 12:03:30 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" static char sysMsgSpace[1024]; /* local protos */ static TCHAR *Exp95Log (DWORD errCode, char *errData[], int cnt); #define GETSEVERITY(code) (UCHAR)((code >> 30) & 0x3) #define GETFACILITY(code) (WORD)((code >> 16) & 0x0FFF) #define GETCODE(code) (WORD)(code & 0xFFFF) /* *---------------------------------------------------------------------- * * ExpWinSyslog -- * * Logs error messages to the system application event log. * It is normally called through the macro EXP_LOG() when * errors occur in the slave driver process, but it can be * used elsewhere. * * Results: * None * *---------------------------------------------------------------------- */ void ExpWinSyslog TCL_VARARGS_DEF(DWORD,arg1) { DWORD errCode; va_list args; char *errData[10]; int cnt = 0; TCHAR *errMsg; static char codeBuf[33]; DWORD dwWritten; char *file; int line; static char fileInfo[MAX_PATH]; /* Get the error code */ errCode = TCL_VARARGS_START(DWORD,arg1,args); /* Get the file info */ file = va_arg(args, char *); line = va_arg(args, int); wsprintfA(fileInfo, "%s(%d)", file, line); errData[cnt++] = fileInfo; /* Set the textual severity */ switch(GETSEVERITY(errCode)) { case STATUS_SEVERITY_WARNING: errData[cnt++] = "Warning"; break; case STATUS_SEVERITY_SUCCESS: errData[cnt++] = "Success"; break; case STATUS_SEVERITY_INFORMATIONAL: errData[cnt++] = "Info"; break; case STATUS_SEVERITY_FATAL: errData[cnt++] = "Fatal"; break; } /* Set the textual Facility */ switch(GETFACILITY(errCode)) { case FACILITY_WINSOCK: errData[cnt++] = "Winsock IPC"; break; case FACILITY_SYSTEM: errData[cnt++] = "System"; break; case FACILITY_STUBS: errData[cnt++] = "Stubs"; break; case FACILITY_NAMEDPIPE: errData[cnt++] = "NamedPipe IPC"; break; case FACILITY_MSPROTO: errData[cnt++] = "Master/Slave Protocol"; break; case FACILITY_MAILBOX: errData[cnt++] = "MailBoxing IPC"; break; case FACILITY_IO: errData[cnt++] = "I/O general"; break; case FACILITY_DBGTRAP: errData[cnt++] = "Debug/Trap"; break; } /* Set the textual Code */ errData[cnt++] = codeBuf; wsprintfA(codeBuf, "0x%04X", GETCODE(errCode)); /* set everyone else */ while ((errData[cnt] = va_arg(args, char *)) != NULL) cnt++; va_end(args); /* format this error according to the message catalog contained in the exe. */ errMsg = Exp95Log(errCode, errData, cnt); OutputDebugString(errMsg); /* If running under NT, also save this error in the event log. */ /* TODO: add platform test */ // ExpNTLog(errCode, errData, cnt); if (GETSEVERITY(errCode) & STATUS_SEVERITY_FATAL) { /* I could have used printf() and fflush(), but chose the direct * route instead */ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), errMsg, _tcslen(errMsg), &dwWritten, NULL); /* Stop the world, I want to get off. */ //DebugBreak(); Sleep(5000); ExitProcess(255); } LocalFree(errMsg); } char *ExpSyslogGetSysMsg (DWORD id) { int chars; chars = wsprintfA(sysMsgSpace, "[%d] ", id); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, id, 0, (LPVOID) &sysMsgSpace[chars], (1024-chars), 0); return sysMsgSpace; } TCHAR *Exp95Log(DWORD errCode, char *errData[], int cnt) { TCHAR *msg; FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY, GetModuleHandle(NULL), errCode, 0, (LPVOID) &msg, 0, errData); return msg; } |
Added win/expWinMessage.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* ---------------------------------------------------------------------------- * expWinMessage.cpp -- * * Defines the Message class. This is what is passed over the * thread-safe event queue. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinMessage.cpp,v 1.1.2.4 2002/03/15 07:41:45 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinMessage.hpp" Message::Message() : bytes(0L), length(0), type(TYPE_BLANK) { } Message::Message(Message &other) { type = other.type; bytes = other.bytes; length = other.length; } |
Added win/expWinMessage.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* ---------------------------------------------------------------------------- * expWinMessage.hpp -- * * Declare the Message class. This is what is passed over the thread-safe * event queue. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinMessage.hpp,v 1.1.2.4 2002/03/15 07:41:45 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef INC_expWinMessage_hpp__ #define INC_expWinMessage_hpp__ #include <stddef.h> // for size_t class Message { public: Message(); Message(Message &); enum Mode {TYPE_BLANK, TYPE_NORMAL, TYPE_ERROR, TYPE_INSTREAM, TYPE_FUNCTION, TYPE_SLAVEDONE}; Mode type; size_t length; unsigned char *bytes; }; #endif |
Added win/expWinPort.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | /* ---------------------------------------------------------------------------- * expWinPort.h -- * * This header file handles porting issues that occur because of * differences between Windows and Unix. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinPort.h,v 1.1.2.1.2.4 2002/02/11 09:56:00 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPWINPORT #define _EXPWINPORT #ifndef _EXPINT # include "expInt.h" #endif #define HAVE_SV_TIMEZONE 1 #define EXP_SLAVE_CREATE 'c' #define EXP_SLAVE_KEY 'k' #define EXP_SLAVE_MOUSE 'm' #define EXP_SLAVE_WRITE 'w' #define EXP_SLAVE_KILL 'x' /* * Define the types of attempts to use to kill the subprocess */ #define EXP_KILL_TERMINATE 0x1 #define EXP_KILL_CTRL_C 0x2 #define EXP_KILL_CTRL_BREAK 0x4 /* * Errors and logging */ #define EXP_LOG(format, args) \ ExpSyslog("Expect SlaveDriver (%s: %d): " format, __FILE__, __LINE__, args) /* * The following defines identify the various types of applications that * run under windows. There is special case code for the various types. */ #define EXP_APPL_NONE 0 #define EXP_APPL_BATCH 1 #define EXP_APPL_DOS16 2 #define EXP_APPL_OS2 3 #define EXP_APPL_OS2DRV 4 #define EXP_APPL_WIN16 5 #define EXP_APPL_WIN16DRV 6 #define EXP_APPL_WIN32CUI 7 #define EXP_APPL_WIN32GUI 8 #define EXP_APPL_WIN32DLL 9 #define EXP_APPL_WIN32DRV 10 #define EXP_APPL_WIN64CUI 11 #define EXP_APPL_WIN64GUI 12 #define EXP_APPL_WIN64DLL 13 #define EXP_APPL_WIN64DRV 14 #undef TCL_STORAGE_CLASS #if defined(BUILD_slavedriver) # define TCL_STORAGE_CLASS #elif defined(BUILD_exp) # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_EXP_STUBS # define TCL_STORAGE_CLASS # else # define TCL_STORAGE_CLASS DLLIMPORT # endif #endif typedef TclFile (__cdecl *tclWinMakeFileProcType)(HANDLE handle); extern tclWinMakeFileProcType tclWinMakeFileProc; #include "expPlatDecls.h" /*#include "expIntPlatDecls.h"*/ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _EXPWINPORT */ |
Added win/expWinProcess.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 | /* ---------------------------------------------------------------------------- * expWinProcess.c -- * * This file contains utility procedures. It primarily handled * processes for Expect. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinProcess.c,v 1.1.2.1.2.7 2002/03/08 23:31:18 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" /* * This list is used to map from pids to process handles. */ typedef struct ProcInfo { HANDLE hProcess; DWORD dwProcessId; struct ProcInfo *nextPtr; } ProcInfo; static ProcInfo *procList = NULL; #define IsGUI(a) (a == EXP_APPL_WIN16 || a == EXP_APPL_WIN32GUI || \ a == EXP_APPL_WIN64GUI) #define IsCUI(a) (a == EXP_APPL_BATCH || a == EXP_APPL_DOS16 || \ a == EXP_APPL_OS2 || a == EXP_APPL_WIN32CUI || \ a == EXP_APPL_WIN64CUI) /* *---------------------------------------------------------------------- * * HasConsole -- * * Determines whether the current application is attached to a * console. * * Results: * Returns TRUE if this application has a console, else FALSE. * * Side effects: * None. * *---------------------------------------------------------------------- */ static BOOL HasConsole() { HANDLE handle = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); return TRUE; } else { return FALSE; } } /* *-------------------------------------------------------------------- * * ExpWinApplicationType -- * * Search for the specified program and identify if it refers to a DOS, * Windows 3.X, or Win32 program. Used to determine how to invoke * a program, or if it can even be invoked. * * It is possible to almost positively identify DOS and Windows * applications that contain the appropriate magic numbers. However, * DOS .com files do not seem to contain a magic number; if the program * name ends with .com and could not be identified as a Windows .com * file, it will be assumed to be a DOS application, even if it was * just random data. If the program name does not end with .com, no * such assumption is made. * * The Win32 procedure GetBinaryType incorrectly identifies any * junk file that ends with .exe as a dos executable and some * executables that don't end with .exe as not executable. Plus it * doesn't exist under win95, so I won't feel bad about reimplementing * functionality. * * Results: * The return value is one of EXP_APPL_DOS, EXP_APPL_WIN3X, or EXP_APPL_WIN32 * if the filename referred to the corresponding application type. * If the file name could not be found or did not refer to any known * application type, EXP_APPL_NONE is returned and the caller can use * GetLastError() to find out what went wrong. * * Side effects: * None. * *---------------------------------------------------------------------- */ DWORD ExpWinApplicationType( const char *originalName, /* Name of the application to find. (in UTF-8) */ Tcl_DString *fullName) /* Buffer space filled with complete path to * application. (in UTF-8) */ { int applType, i, nameLen, nativeNameLen; HANDLE hFile; TCHAR *rest; char *ext; DWORD attr, read; IMAGE_DOS_HEADER p236; /* p236, DOS (old-style) executable-file header */ union { BYTE buf[200]; IMAGE_NT_HEADERS pe; IMAGE_OS2_HEADER ne; IMAGE_VXD_HEADER le; } header; Tcl_DString nameBuf, nativeNameBuff, ds; CONST TCHAR *nativeName; WCHAR nativeShortPath[MAX_PATH]; /* needed for unicode space */ static char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; int offset64; /* Look for the program as an external program. First try the name * as it is, then try adding .com, .exe, and .bat, in that order, to * the name, looking for an executable. * * Using the raw SearchPath() procedure doesn't do quite what is * necessary. If the name of the executable already contains a '.' * character, it will not try appending the specified extension when * searching (in other words, SearchPath will not find the program * "a.b.exe" if the arguments specified "a.b" and ".exe"). * So, first look for the file as it is named. Then manually append * the extensions, looking for a match. */ applType = EXP_APPL_NONE; Tcl_DStringInit(&nameBuf); Tcl_DStringInit(&nativeNameBuff); Tcl_DStringAppend(&nameBuf, originalName, -1); Tcl_DStringAppend(fullName, originalName, -1); nameLen = Tcl_DStringLength(&nameBuf); for (i = 0; i < (sizeof(extensions) / sizeof(extensions[0])); i++) { Tcl_DStringSetLength(&nameBuf, nameLen); Tcl_DStringAppend(&nameBuf, extensions[i], -1); nativeName = Tcl_WinUtfToTChar(Tcl_DStringValue(&nameBuf), Tcl_DStringLength(&nameBuf), &ds); /* Just get the size of the buffer needed, when found. */ nativeNameLen = (*expWinProcs->searchPathProc)(NULL, nativeName, NULL, 0, NULL, &rest); if (nativeNameLen == 0) { /* not found. */ Tcl_DStringFree(&ds); continue; } /* Set the buffer needed. */ Tcl_DStringSetLength(&nativeNameBuff, (expWinProcs->useWide ? nativeNameLen*2 : nativeNameLen)); (*expWinProcs->searchPathProc)(NULL, nativeName, NULL, Tcl_DStringLength(&nativeNameBuff), (TCHAR *) Tcl_DStringValue(&nativeNameBuff), &rest); Tcl_DStringFree(&ds); /* * Ignore matches on directories, keep falling through * when identified as something else. */ attr = (*expWinProcs->getFileAttributesProc)( (TCHAR *) Tcl_DStringValue(&nativeNameBuff)); if ((attr == -1) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { continue; } Tcl_WinTCharToUtf((TCHAR *) Tcl_DStringValue(&nativeNameBuff), -1, fullName); ext = strrchr(Tcl_DStringValue(fullName), '.'); if ((ext != NULL) && (stricmp(ext, ".bat") == 0 || stricmp(ext, ".cmd") == 0)) { applType = EXP_APPL_BATCH; break; } hFile = (*expWinProcs->createFileProc)( (TCHAR *) Tcl_DStringValue(&nativeNameBuff), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { applType = EXP_APPL_NONE; break; } p236.e_magic = 0; ReadFile(hFile, &p236, sizeof(IMAGE_DOS_HEADER), &read, NULL); if (p236.e_magic != IMAGE_DOS_SIGNATURE) { /* * Doesn't have the magic number for relocatable executables. If * filename ends with .com, assume it's a DOS application anyhow. * Note that we didn't make this assumption at first, because some * supposed .com files are really 32-bit executables with all the * magic numbers and everything. */ /* * Additional notes from Ralf Brown's interupt list: * * The COM files are raw binary executables and are a leftover * from the old CP/M machines with 64K RAM. A COM program can * only have a size of less than one segment (64K), including code * and static data since no fixups for segment relocation or * anything else is included. One method to check for a COM file * is to check if the first byte in the file could be a valid jump * or call opcode, but this is a very weak test since a COM file * is not required to start with a jump or a call. In principle, * a COM file is just loaded at offset 100h in the segment and * then executed. * * OFFSET Count TYPE Description * 0000h 1 byte ID=0E9h * ID=0EBh */ CloseHandle(hFile); if ((ext != NULL) && (strcmp(ext, ".com") == 0)) { applType = EXP_APPL_DOS16; break; } SetLastError(ERROR_INVALID_EXE_SIGNATURE); applType = EXP_APPL_NONE; break; } if (p236.e_lfarlc < 0x40 || p236.e_lfanew == 0 /* reserved */) { /* * Old-style header only. Can't be more than a DOS16 executable. */ CloseHandle(hFile); applType = EXP_APPL_DOS16; break; } /* * The LONG at p236.e_lfanew points to the real exe header only * when p236.e_lfarlc is set to 40h (or greater). */ if (SetFilePointer(hFile, p236.e_lfanew, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { /* Bogus PE header pointer. */ CloseHandle(hFile); SetLastError(ERROR_BAD_EXE_FORMAT); applType = EXP_APPL_NONE; break; } ReadFile(hFile, header.buf, 200, &read, NULL); CloseHandle(hFile); /* * Check the sigs against the following list: * 'PE\0\0' Win32 (Windows NT and Win32s) portable executable based * on Unix COFF. * 'NE' Windows or OS/2 1.x segmented ("new") executable. * 'LE' Windows virtual device driver (VxD) linear executable. * 'LX' Variant of LE used in OS/2 2.x * 'W3' Windows WIN386.EXE file; a collection of LE files * (protected mode windows). * 'W4' Variant of above. */ if (header.pe.Signature == IMAGE_NT_SIGNATURE) { if (!(header.pe.FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) { /* Not an executable. */ SetLastError(ERROR_BAD_EXE_FORMAT); applType = EXP_APPL_NONE; break; } if (header.pe.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { /* Win32 executable */ offset64 = 0; } else if (header.pe.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { /* Win64 executable */ offset64 = 4; } else { /* Unknown magic number */ SetLastError(ERROR_INVALID_MODULETYPE); applType = EXP_APPL_NONE; break; } if (header.pe.FileHeader.Characteristics & IMAGE_FILE_DLL) { /* * DLLs are executable, but indirectly. We shouldn't return * APPL_NONE or the subsystem that its said to run under * as it's not the complete truth, so return a new type and * let the user decide what to do. */ applType = EXP_APPL_WIN32DLL + offset64; break; } switch (header.pe.OptionalHeader.Subsystem) { case IMAGE_SUBSYSTEM_WINDOWS_CUI: case IMAGE_SUBSYSTEM_OS2_CUI: case IMAGE_SUBSYSTEM_POSIX_CUI: /* Runs in the CUI subsystem */ applType = EXP_APPL_WIN32CUI + offset64; break; case IMAGE_SUBSYSTEM_WINDOWS_GUI: case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: /* Runs in the GUI subsystem */ applType = EXP_APPL_WIN32GUI + offset64; break; case IMAGE_SUBSYSTEM_UNKNOWN: case IMAGE_SUBSYSTEM_NATIVE: case IMAGE_SUBSYSTEM_NATIVE_WINDOWS: /* Special Driver */ applType = EXP_APPL_WIN32DRV + offset64; break; } #define IMAGE_NE_FLAG_DRIVER 0x8000 #define IMAGE_NE_EXETYP_OS2 0x1 #define IMAGE_NE_EXETYP_WIN 0x2 #define IMAGE_NE_EXETYP_DOS4X 0x3 #define IMAGE_NE_EXETYP_WIN386 0x4 } else if (header.ne.ne_magic == IMAGE_OS2_SIGNATURE) { switch (header.ne.ne_exetyp) { case IMAGE_NE_EXETYP_OS2: /* Microsoft/IBM OS/2 1.x */ if (header.ne.ne_flags & IMAGE_NE_FLAG_DRIVER) { applType = EXP_APPL_OS2DRV; } else { applType = EXP_APPL_OS2; } break; case IMAGE_NE_EXETYP_WIN: /* Microsoft Windows */ case IMAGE_NE_EXETYP_WIN386: /* Same, but Protected mode */ if (header.ne.ne_flags & IMAGE_NE_FLAG_DRIVER) { applType = EXP_APPL_WIN16DRV; } else { applType = EXP_APPL_WIN16; } break; case IMAGE_NE_EXETYP_DOS4X: /* Microsoft MS-DOS 4.x */ applType = EXP_APPL_DOS16; break; default: /* Unidentified */ SetLastError(ERROR_INVALID_MODULETYPE); applType = EXP_APPL_NONE; } } else if ( header.le.e32_magic == IMAGE_OS2_SIGNATURE_LE /* 'LE' */ || header.le.e32_magic == 0x584C /* 'LX' */ || header.le.e32_magic == 0x3357 /* 'W3' */ || header.le.e32_magic == 0x3457 /* 'W4' */ ){ /* Virtual device drivers are not executables, per se. */ applType = EXP_APPL_WIN16DRV; } else { /* The loader will barf anyway, so barf now. */ SetLastError(ERROR_INVALID_EXE_SIGNATURE); applType = EXP_APPL_NONE; } break; } if (applType == EXP_APPL_DOS16 || applType == EXP_APPL_WIN16 || applType == EXP_APPL_WIN16DRV || applType == EXP_APPL_OS2 || applType == EXP_APPL_OS2DRV) { /* * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able * to correctly parse its own command line to separate off the * application name from the arguments. */ (*expWinProcs->getShortPathNameProc)( (TCHAR *) Tcl_DStringValue(&nativeNameBuff), (TCHAR *) nativeShortPath, MAX_PATH); Tcl_WinTCharToUtf((TCHAR *) nativeShortPath, -1, fullName); } Tcl_DStringFree(&nativeNameBuff); Tcl_DStringFree(&nameBuf); return applType; } /* *---------------------------------------------------------------------- * * BuildCommandLine -- * * The command line arguments are stored in linePtr separated * by spaces, in a form that CreateProcess() understands. Special * characters in individual arguments from argv[] must be quoted * when being stored in cmdLine. * * Results: * None. * * Side effects: * None. * * Comment: COPY OF NON_PUBLIC CORE FUNCTION WITH CHANGES! * *---------------------------------------------------------------------- */ void BuildCommandLine( CONST char *executable, /* Full path of executable (including * extension). Replacement for argv[0]. */ int argc, /* Number of arguments. */ char *const *argv, /* Argument strings (in UTF-8). */ Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the * command line (TCHAR). */ { CONST char *arg, *start, *special; int quote, i; Tcl_DString ds; Tcl_DStringInit(&ds); /* * Prime the path. */ Tcl_DStringAppend(&ds, Tcl_DStringValue(linePtr), -1); for (i = 0; i < argc; i++) { if (i == 0) { arg = executable; } else { arg = argv[i]; Tcl_DStringAppend(&ds, " ", 1); } quote = 0; if (arg[0] == '\0') { quote = 1; } else { for (start = arg; *start != '\0'; start++) { if (isspace(*start)) { /* INTL: ISO space. */ quote = 1; break; } } } if (quote) { Tcl_DStringAppend(&ds, "\"", 1); } start = arg; for (special = arg; ; ) { if ((*special == '\\') && (special[1] == '\\' || special[1] == '"')) { Tcl_DStringAppend(&ds, start, special - start); start = special; while (1) { special++; if (*special == '"') { /* * N backslashes followed a quote -> insert * N * 2 + 1 backslashes then a quote. */ Tcl_DStringAppend(&ds, start, special - start); break; } if (*special != '\\') { break; } } Tcl_DStringAppend(&ds, start, special - start); start = special; } if (*special == '"') { Tcl_DStringAppend(&ds, start, special - start); Tcl_DStringAppend(&ds, "\\\"", 2); start = special + 1; } if (*special == '\0') { break; } special++; } Tcl_DStringAppend(&ds, start, special - start); if (quote) { Tcl_DStringAppend(&ds, "\"", 1); } } Tcl_DStringFree(linePtr); Tcl_WinUtfToTChar(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds), linePtr); Tcl_DStringFree(&ds); } /* *---------------------------------------------------------------------- * * Exp_WaitPid -- * * Emulates the waitpid system call. * * Results: * Returns 0 if the process is still alive, -1 on an error, or * the pid on a clean close. * * Side effects: * Unless WNOHANG is set and the wait times out, the process * information record will be deleted and the process handle * will be closed. * *---------------------------------------------------------------------- */ Tcl_Pid Exp_WaitPid(pid, statPtr, options) Tcl_Pid pid; int *statPtr; int options; { ProcInfo *infoPtr, **prevPtrPtr; int flags; Tcl_Pid result; DWORD ret; if (options & WNOHANG) { flags = 0; } else { flags = INFINITE; } if (pid == 0) { *statPtr = 0; return 0; } /* * Find the process on the process list. */ prevPtrPtr = &procList; for (infoPtr = procList; infoPtr != NULL; prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { if (infoPtr->hProcess == (HANDLE) pid) { break; } } if (infoPtr == NULL) { return 0; } ret = WaitForSingleObject(infoPtr->hProcess, flags); if (ret == WAIT_TIMEOUT) { *statPtr = 0; if (options & WNOHANG) { return 0; } else { result = 0; } } else if (ret != WAIT_FAILED) { GetExitCodeProcess(infoPtr->hProcess, (DWORD*)statPtr); *statPtr = ((*statPtr << 8) & 0xff00); result = pid; } else { errno = ECHILD; result = (Tcl_Pid) -1; } /* * Remove the process from the process list and close the process handle. */ CloseHandle(infoPtr->hProcess); *prevPtrPtr = infoPtr->nextPtr; ckfree((char*)infoPtr); return result; } /* *---------------------------------------------------------------------- * * Exp_KillProcess -- * * Kills the subprocess * * Results: * Nothing * * Side effects: * The subprocess is killed. * *---------------------------------------------------------------------- */ void Exp_KillProcess(pid) Tcl_Pid pid; { TerminateProcess((HANDLE) pid, 0xFFFF); } /* *---------------------------------------------------------------------- * * ExpCreateProcess -- * * Create a child process that has the specified files as its * standard input, output, and error. The child process is set * to run properly under only Windows NT right now, and runs with * the same environment variables as the creating process. * * The complete Windows search path is searched to find the specified * executable. If an executable by the given name is not found, * automatically tries appending ".com", ".exe", ".bat", and ".cmd" to * the executable name. * * Results: * 0 on success, an error value otherwise. * * Side effects: * A process is created. * *---------------------------------------------------------------------- */ DWORD ExpWinCreateProcess( int argc, /* Number of arguments in following array. */ char *const *argv, /* Array of argument strings. argv[0] * contains the name of the executable * converted to native format (using the * Tcl_TranslateFileName call). Additional * arguments have not been converted. */ HANDLE inputHandle, /* If non-NULL, gives the file to use as * input for the child process. If inputHandle * is NULL, the child will receive no standard * input. */ HANDLE outputHandle, /* If non-NULL, gives the file that * receives output from the child process. If * outputHandle is NULL, output from the child * will be discarded. */ HANDLE errorHandle, /* If non-NULL, gives the file that * receives errors from the child process. If * errorFile file is not writeable or is NULL, * errors from the child will be discarded. * errorFile may be the same as outputFile. */ int allocConsole, /* Should a console be allocated */ int hideConsole, /* Hide or display the created console */ int debug, /* Is this process going to be debugged? */ int newProcessGroup, /* Create a new process group */ HANDLE *processPtr, /* If this procedure is successful, pidPtr * is filled with the process handle of the child * process. */ PDWORD globalPidPtr) /* Globally unique pid */ { DWORD applType; int createFlags, i; Tcl_DString cmdLine; STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; SECURITY_ATTRIBUTES secAtts; HANDLE hProcess, h; Tcl_DString execPath; LONG result; char tclpipBuf[MAX_PATH]; /* buffer used for finding tclpipXX.dll */ result = 0; Tcl_DStringInit(&execPath); Tcl_DStringInit(&cmdLine); ZeroMemory(&startInfo, sizeof(startInfo)); startInfo.cb = sizeof(startInfo); startInfo.hStdInput = INVALID_HANDLE_VALUE; startInfo.hStdOutput = INVALID_HANDLE_VALUE; startInfo.hStdError = INVALID_HANDLE_VALUE; applType = ExpWinApplicationType(argv[0], &execPath); if (applType == EXP_APPL_NONE) { /* Can't execute what doesn't exist */ result = GetLastError(); goto end; } else if (!IsCUI(applType)) { /* * Not a valid application to use if it isn't character mode. * We need it to run inside a console. */ result = ERROR_BAD_EXE_FORMAT; goto end; } hProcess = GetCurrentProcess(); secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); secAtts.lpSecurityDescriptor = NULL; secAtts.bInheritHandle = TRUE; /* * STARTF_USESTDHANDLES must be used to pass handles to child process. * Using SetStdHandle() and/or dup2() only works when a console mode * parent process is spawning an attached console mode child process. */ if (inputHandle || outputHandle || errorHandle) { startInfo.dwFlags = STARTF_USESTDHANDLES; if (! inputHandle) { inputHandle = GetStdHandle(STD_INPUT_HANDLE); } if (! outputHandle) { outputHandle = GetStdHandle(STD_OUTPUT_HANDLE); } if (! errorHandle) { errorHandle = GetStdHandle(STD_ERROR_HANDLE); } } /* * Duplicate all the handles which will be passed off as stdin, stdout * and stderr of the child process. The duplicate handles are set to * be inheritable, so the child process can use them. */ if (inputHandle == NULL || inputHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, stdin should return immediate EOF. * Under Windows95, some applications (both 16 and 32 bit!) * cannot read from the NUL device; they read from console * instead. */ if (CreatePipe(&startInfo.hStdInput, &h, &secAtts, 0) != FALSE) { CloseHandle(h); } } else { DuplicateHandle(hProcess, inputHandle, hProcess, &startInfo.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS); if (startInfo.hStdInput == INVALID_HANDLE_VALUE) { // EXP_LOG("couldn't duplicate input handle: 0x%x", GetLastError()); result = GetLastError(); goto end; } } if (outputHandle == NULL || outputHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, output should be sent to an infinitely * deep sink. Under Windows 95, some 16 bit applications cannot * have stdout redirected to NUL; they send their output to * the console instead. Some applications, like "more" or "dir /p", * when outputting multiple pages to the console, also then try and * read from the console to go the next page. */ if ((TclWinGetPlatformId() == VER_PLATFORM_WIN32_WINDOWS) && (applType == EXP_APPL_DOS16)) { if (CreatePipe(&h, &startInfo.hStdOutput, &secAtts, 0) != FALSE) { CloseHandle(h); } } else { startInfo.hStdOutput = CreateFileA("NUL:", GENERIC_WRITE, 0, &secAtts, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } } else { DuplicateHandle(hProcess, outputHandle, hProcess, &startInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS); if (startInfo.hStdOutput == INVALID_HANDLE_VALUE) { // EXP_LOG("couldn't duplicate output handle: 0x%x", GetLastError()); result = GetLastError(); goto end; } } if (errorHandle == NULL || errorHandle == INVALID_HANDLE_VALUE) { /* * If handle was not set, errors should be sent to an infinitely * deep sink. */ startInfo.hStdError = CreateFileA("NUL:", GENERIC_WRITE, 0, &secAtts, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { DuplicateHandle(hProcess, errorHandle, hProcess, &startInfo.hStdError, 0, TRUE, DUPLICATE_SAME_ACCESS); if (startInfo.hStdError == INVALID_HANDLE_VALUE) { // EXP_LOG("couldn't duplicate error handle: 0x%x", GetLastError()); result = GetLastError(); goto end; } } /* * If we do not have a console window, then we must run DOS and * WIN32 console mode applications as detached processes. This tells * the loader that the child application should not inherit the * console, and that it should not create a new console window for * the child application. The child application should get its stdio * from the redirection handles provided by this application, and run * in the background. * * If we are starting a GUI process, they don't automatically get a * console, so it doesn't matter if they are started detached. */ if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { if (!allocConsole && HasConsole()) { createFlags = 0; } else if (applType == EXP_APPL_DOS16 || applType == EXP_APPL_OS2 || allocConsole) { /* * Under NT, 16-bit DOS applications will not run unless they * can be attached to a console. If we are running without a * console, run the 16-bit program as an normal process inside * of a hidden console application, and then run that hidden * console as a detached process. */ if (hideConsole) { startInfo.wShowWindow = SW_HIDE; } else { /* For debugging, show the sub process console */ startInfo.wShowWindow = SW_SHOW; } startInfo.dwFlags |= STARTF_USESHOWWINDOW; createFlags = CREATE_NEW_CONSOLE; Tcl_DStringAppend(&cmdLine, "cmd.exe /c ", -1); } else { createFlags = DETACHED_PROCESS; } } else { if (!allocConsole && HasConsole()) { createFlags = 0; } else if (allocConsole) { createFlags = CREATE_NEW_CONSOLE; } else { createFlags = DETACHED_PROCESS; } if (applType == EXP_APPL_DOS16) { /* * Under Windows 95, 16-bit DOS applications do not work well * with pipes: * * 1. EOF on a pipe between a detached 16-bit DOS application * and another application is not seen at the other * end of the pipe, so the listening process blocks forever on * reads. This inablity to detect EOF happens when either a * 16-bit app or the 32-bit app is the listener. * * 2. If a 16-bit DOS application (detached or not) blocks when * writing to a pipe, it will never wake up again, and it * eventually brings the whole system down around it. * * The 16-bit application is run as a normal process inside * of a hidden helper console app, and this helper may be run * as a detached process. If any of the stdio handles is * a pipe, the helper application accumulates information * into temp files and forwards it to or from the DOS * application as appropriate. This means that DOS apps * must receive EOF from a stdin pipe before they will actually * begin, and must finish generating stdout or stderr before * the data will be sent to the next stage of the pipe. * * The helper app should be located in the same directory as * the tcl dll. */ if (createFlags != 0) { if (hideConsole) { startInfo.wShowWindow = SW_HIDE; } else { /* For debugging, show the sub process console */ startInfo.wShowWindow = SW_SHOW; } startInfo.dwFlags |= STARTF_USESHOWWINDOW; createFlags = CREATE_NEW_CONSOLE; } /* * Retrieve the location of the tcl DLL and replace the last * file part with the name of the pipe helper. This allows * it to be called by fullpath and doesn't require that it be * found in the system search path. */ GetModuleFileName(TclWinGetTclInstance(), tclpipBuf, MAX_PATH); Tcl_DStringAppend(&cmdLine, tclpipBuf, -1); for (i = Tcl_DStringLength(&cmdLine) - 1; i > 0; i--) { if (*(tclpipBuf+i) == '\\') { Tcl_DStringSetLength(&cmdLine, i+1); Tcl_DStringAppend(&cmdLine, "tclpip" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll ", -1); break; } } } } if (debug) { createFlags |= DEBUG_PROCESS; } if (newProcessGroup) { createFlags |= CREATE_NEW_PROCESS_GROUP; } /* * cmdLine gets the full command line used to invoke the executable, * including the name of the executable itself. The command line * arguments in argv[] are stored in cmdLine separated by spaces. * Special characters in individual arguments from argv[] must be * quoted when being stored in cmdLine. * * When calling any application, bear in mind that arguments that * specify a path name are not converted. If an argument contains * forward slashes as path separators, it may or may not be * recognized as a path name, depending on the program. In general, * most applications accept forward slashes only as option * delimiters and backslashes only as paths. * * Additionally, when calling a 16-bit dos or windows application, * all path names must use the short, cryptic, path format (e.g., * using ab~1.def instead of "a b.default"). */ BuildCommandLine(Tcl_DStringValue(&execPath), argc, argv, &cmdLine); if ((*expWinProcs->createProcessProc)(NULL, (TCHAR *) Tcl_DStringValue(&cmdLine), NULL, NULL, TRUE, (DWORD) createFlags, NULL, NULL, &startInfo, &procInfo) == 0) { // EXP_LOG("couldn't CreateProcess(): 0x%x", (result = GetLastError())); goto end; } /* * This wait is used to force the OS to give some time to the character-mode * process. */ if (applType == EXP_APPL_DOS16) { WaitForSingleObject(procInfo.hProcess, 50); } /* * "When an application spawns a process repeatedly, a new thread * instance will be created for each process but the previous * instances may not be cleaned up. This results in a significant * virtual memory loss each time the process is spawned. If there * is a WaitForInputIdle() call between CreateProcess() and * CloseHandle(), the problem does not occur." PSS ID Number: Q124121 */ WaitForInputIdle(procInfo.hProcess, 5000); CloseHandle(procInfo.hThread); *globalPidPtr = procInfo.dwProcessId; *processPtr = procInfo.hProcess; if (procInfo.hProcess != 0) { ProcInfo *procPtr = (ProcInfo *) ckalloc(sizeof(ProcInfo)); procPtr->hProcess = procInfo.hProcess; procPtr->dwProcessId = procInfo.dwProcessId; procPtr->nextPtr = procList; procList = procPtr; } end: Tcl_DStringFree(&cmdLine); Tcl_DStringFree(&execPath); if (startInfo.hStdInput != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdInput); } if (startInfo.hStdOutput != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdOutput); } if (startInfo.hStdError != INVALID_HANDLE_VALUE) { CloseHandle(startInfo.hStdError); } return result; } |
Added win/expWinSlave.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | /* * expWinSlave.h * * Useful definitions used by the slave driver but not useful * for anybody else. * * Copyright (c) 1997 by Mitel, Inc. * Copyright (c) 1997 by Gordon Chaffee ([email protected]) * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ typedef struct ExpSlaveDebugArg { HANDLE hMaster; /* Output handle */ HANDLE hConsole; /* Console handle to use */ HANDLE process; /* Handle to subprocess */ DWORD globalPid; /* Program identifier of slave */ HANDLE thread; /* Handle of debugger thread */ HANDLE event; /* Gets set when the process has been created */ DWORD result; /* Result of process being started */ DWORD lastError; /* GetLastError for result */ int passThrough; /* Pass through mode? */ int useSocket; /* Communicate to master through socket */ /* Args for ExpCreateProcess */ int argc; /* Number of args to start slave program */ char **argv; /* Argument list of slave program */ HANDLE slaveStdin; /* stdin for slave program */ HANDLE slaveStdout; /* stdout for slave program */ HANDLE slaveStderr; /* stderr for slave program */ } ExpSlaveDebugArg; typedef struct _EXP_KEY { WORD wVirtualKeyCode; WORD wVirtualScanCode; DWORD dwControlKeyState; } EXP_KEY; #define EXP_KEY_CONTROL 0 #define EXP_KEY_SHIFT 1 #define EXP_KEY_LSHIFT 1 #define EXP_KEY_RSHIFT 2 #define EXP_KEY_ALT 3 /* For ExpVtFunctionToKeyArray. Ordering must match ExpFunctionToKeyArray[] */ #define EXP_KEY_UP 0 #define EXP_KEY_DOWN 1 #define EXP_KEY_RIGHT 2 #define EXP_KEY_LEFT 3 #define EXP_KEY_END 4 #define EXP_KEY_HOME 5 #define EXP_KEY_PAGEUP 6 #define EXP_KEY_PAGEDOWN 7 #define EXP_KEY_INSERT 8 #define EXP_KEY_DELETE 9 #define EXP_KEY_SELECT 10 #define EXP_KEY_F1 11 #define EXP_KEY_F2 12 #define EXP_KEY_F3 13 #define EXP_KEY_F4 14 #define EXP_KEY_F5 15 #define EXP_KEY_F6 16 #define EXP_KEY_F7 17 #define EXP_KEY_F8 18 #define EXP_KEY_F9 19 #define EXP_KEY_F10 20 #define EXP_KEY_F11 21 #define EXP_KEY_F12 22 #define EXP_KEY_F13 23 #define EXP_KEY_F14 24 #define EXP_KEY_F15 25 #define EXP_KEY_F16 26 #define EXP_KEY_F17 27 #define EXP_KEY_F18 28 #define EXP_KEY_F19 29 #define EXP_KEY_F20 30 #define EXP_WIN_RESIZE 31 extern EXP_KEY ExpModifierKeyArray[]; extern EXP_KEY ExpAsciiToKeyArray[]; extern EXP_KEY ExpFunctionToKeyArray[]; extern DWORD ExpConsoleInputMode; extern HANDLE ExpConsoleOut; extern int ExpDebug; extern void ExpAddToWaitQueue(HANDLE handle); extern void ExpKillProcessList(); extern DWORD WINAPI ExpSlaveDebugThread(LPVOID arg); extern DWORD WINAPI ExpGetExecutablePathA(PSTR pathInOut); extern DWORD WINAPI ExpGetExecutablePathW(PWSTR pathInOut); extern BOOL ExpWriteMaster(int useSocket, HANDLE hFile, LPCVOID buf, DWORD n, LPOVERLAPPED over); extern BOOL ExpReadMaster(int useSocket, HANDLE hFile, void *buf, DWORD n, PDWORD pCount, LPOVERLAPPED over, PDWORD pError); extern void ExpNewConsoleSequences(int useSocket, HANDLE hMaster, LPOVERLAPPED over); extern void ExpProcessFreeByHandle(HANDLE hProcess); extern void ExpSetConsoleSize(HANDLE hConsoleInW, HANDLE hConsoleOut, int w, int h, int useSocket, HANDLE hMaster, LPOVERLAPPED over); |
Added win/expWinSlave.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* ---------------------------------------------------------------------------- * expWinSlave.hpp -- * * Useful definitions used by the slave driver application but not * useful for anybody else. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSlave.hpp,v 1.1.4.9 2002/03/12 21:07:00 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef INC_expWinSlave_hpp__ #define INC_expWinSlave_hpp__ #include <windows.h> void DynloadTclStubs (void); void ShutdownTcl (void); #include "Mcl/include/CMcl.h" #include "slavedrvmc.h" #include "expWinUtils.hpp" #include "expWinMessage.hpp" #include "expWinSpawnClient.hpp" #include "expWinSlaveTrap.hpp" #endif // INC_expWinSlave_hpp__ |
Added win/expWinSlaveMain.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | /* ---------------------------------------------------------------------------- * expWinSlaveMain.cpp -- * * Program entry for the Win32 slave driver helper application. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSlaveMain.cpp,v 1.1.4.16 2002/03/15 07:41:45 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinSlave.hpp" // local protos static SpawnClientTransport *SpawnOpenClientTransport(const char *, CMclQueue<Message *> &); static SlaveTrap *SlaveOpenTrap(const char *, int, char * const *, CMclQueue<Message *> &); static int DoEvents(SpawnClientTransport *, SlaveTrap *, CMclQueue<Message *> &, CMclEvent &); static char *OurGetCmdLine(); // Turns on/off special debugger hooks used in development. // #ifndef IDE_LATCHED # define IDE_LATCHED 0 #endif int main (void) { int argc; // Number of command-line arguments. char **argv; // Values of command-line arguments. SpawnClientTransport *transport;// class pointer of transport client. SlaveTrap *slaveCtrl; // trap method class pointer. CMclQueue<Message *> messageQ; // Our message Queue we hand off to everyone. CMclEvent Shutdown; // global shutdown for the event queue. int code; // exitcode. CHAR *cmdLine; // commandline to use. // We need a few Tcl APIs in here. Load it now. // DynloadTclStubs(); // Get our commandline. MSVC++ doesn't like to debug spawned processes // without a bit of help. So help it out. // cmdLine = OurGetCmdLine(); // Use our custom commandline parser to overcome bugs in the default // crt library as well as allowing us to hook at GetCommandLine(). // SetArgv(cmdLine, &argc, &argv); if (argc < 4) { EXP_LOG0(MSG_IO_ARGSWRONG); } // Open the client side of our IPC transport that connects us back // to the parent (ie. the Expect extension). // transport = SpawnOpenClientTransport(argv[1], messageQ); // Start the process to be intercepted within the trap method requested // on the commandline (ie. run telnet in a debugger and trap OS calls). // slaveCtrl = SlaveOpenTrap(argv[2], argc-3, &argv[3], messageQ); // Process messages. // code = DoEvents(transport, slaveCtrl, messageQ, Shutdown); // Close up. // ShutdownTcl(); return code; } /* *---------------------------------------------------------------------- * SpawnOpenTransport -- * * The factory method for creating the client IPC transport from * the name asked of it. * * Returns: * a polymorphed SpawnClientTransport pointer or die. * *---------------------------------------------------------------------- */ SpawnClientTransport * SpawnOpenClientTransport(const char *method, CMclQueue<Message *> &mQ) { if (!strcmp(method, "stdio")) { return new SpawnStdioClient(method, mQ); } else EXP_LOG1(MSG_IO_TRANSPRTARGSBAD, method); // not reached. return 0L; } /* *---------------------------------------------------------------------- * SlaveOpenTrap -- * * The factory method for creating the trap class instance. * * Returns: * a polymorphed SpawnTrap pointer or die. * *---------------------------------------------------------------------- */ SlaveTrap * SlaveOpenTrap(const char *method, int argc, char * const argv[], CMclQueue<Message *> &mQ) { if (!strcmp(method, "dbg")) { return new SlaveTrapDbg(argc, argv, mQ); } else EXP_LOG1(MSG_IO_TRAPARGSBAD, method); // not reached. return 0L; } /* *---------------------------------------------------------------------- * DoEvents -- * * Process all events for the slavedrv application. We are the * master. The slave is the process we are trapping. * * Returns: * an exit code. * *---------------------------------------------------------------------- */ int DoEvents(SpawnClientTransport *transport, SlaveTrap *slaveCtrl, CMclQueue<Message *> &mQ, CMclEvent &sd) { Message *msg; while (mQ.Get(msg, INFINITE)) { switch (msg->type) { case Message::TYPE_NORMAL: case Message::TYPE_ERROR: // Send stuff back to the parent. // transport->Write(msg); break; case Message::TYPE_INSTREAM: // Send stuff to the slave. // slaveCtrl->Write(msg); break; case Message::TYPE_FUNCTION: // Internal mode switching and info gathering. // break; case Message::TYPE_SLAVEDONE: //delete slaveCtrl; Sleep(500); // bad hack, please ignore for now. return 0; } } //delete transport, slaveCtrl; return 0; } /* *---------------------------------------------------------------------- * OurGetCmdLine -- * * Handles the logic for how to retrieve the commandline. * * Returns: * the commandline in a single string. * *---------------------------------------------------------------------- */ char * OurGetCmdLine() { #if defined(_DEBUG) && IDE_LATCHED if (IsDebuggerPresent()) { # ifdef _MSC_VER CHAR * MsvcDbg_GetCommandLine(); return MsvcDbg_GetCommandLine(); # else # error "Need Debugger control for this IDE" # endif } else { #endif return GetCommandLine(); #if defined(_DEBUG) && IDE_LATCHED } #endif } #if defined(_DEBUG) && defined(_MSC_VER) && IDE_LATCHED CHAR * MsvcDbg_GetCommandLine(void) { HKEY root; HANDLE event1; CHAR pidChar[33], *buf; DWORD type = REG_SZ, size = 0; int pid; // <- this is read by the parent's debugger. pid = GetCurrentProcessId(); event1 = CreateEvent(0L, FALSE, FALSE, "SpawnStartup"); SetEvent(event1); CloseHandle(event1); // >>>> IMPORTANT! <<<< // Set a soft break on the next line for this to work. // It is essential that the app stops here during startup // and syncs to the parent properly. __asm nop; // >>>> END IMPORTANT! <<<< itoa(pid, pidChar, 10); RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Tomasoft\\MsDevDbgCtrl", 0, KEY_ALL_ACCESS, &root); RegQueryValueEx(root, pidChar, 0, &type, 0L, &size); buf = (CHAR *) HeapAlloc(GetProcessHeap(), 0, size); RegQueryValueEx(root, pidChar, 0, &type, (LPBYTE) buf, &size); RegDeleteValue(root, pidChar); RegCloseKey(root); return buf; } #endif // _DEBUG && _MSC_VER && IDE_LATCHED |
Added win/expWinSlaveTrap.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ---------------------------------------------------------------------------- * expWinSlaveTrap.hpp -- * * Declares the SlaveTrap classes. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSlaveTrap.hpp,v 1.1.2.1 2002/03/12 07:09:36 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef INC_expWinSlaveTrap_hpp__ #define INC_expWinSlaveTrap_hpp__ #include "expWinMessage.hpp" #include "Mcl/include/CMcl.h" class SlaveTrap { public: virtual void Write(Message *) = 0; }; class SlaveTrapDbg : public SlaveTrap { public: SlaveTrapDbg(int argc, char * const argv[], CMclQueue<Message *> &_mQ); virtual void Write(Message *); private: CMclQueue<Message *> &mQ; CMclThreadAutoPtr debuggerThread; }; #endif |
Added win/expWinSlaveTrapDbg.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ---------------------------------------------------------------------------- * expWinSlaveTrapDbg.cpp -- * * The slave driver acts as a debugger for the slave program. It * does this so that we can determine echoing behavior of the * subprocess. This isn't perfect as the subprocess can change * echoing behavior while our keystrokes are lying in its console * input buffer, but it is much better than nothing. The debugger * thread sets up breakpoints on the OS functions we want to intercept, * and it writes data that is written directly to the console of * the master over a method of IPC. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSlaveTrapDbg.cpp,v 1.1.4.9 2002/03/13 03:52:57 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinSlave.hpp" #include "expWinConsoleDebugger.hpp" SlaveTrapDbg::SlaveTrapDbg(int argc, char * const argv[], CMclQueue<Message *> &_mQ) : mQ(_mQ) { debuggerThread = new CMclThread(new ConsoleDebugger(argc, argv, _mQ)); } void SlaveTrapDbg::Write(Message *msg) { // inject it from here.. how? delete [] msg->bytes; } |
Added win/expWinSpawnChan.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /* ---------------------------------------------------------------------------- * expWinSpawnChan.c -- * * Implements the Windows specific portion of the exp_spawn * channel id. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" /* *---------------------------------------------------------------------- * * ExpPlatformSpawnOutput -- * * Write routine for exp_spawn channel * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpPlatformSpawnOutput(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; CONST char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { ExpSpawnState *ssPtr = (ExpSpawnState *) instanceData; Tcl_Channel channelPtr = ssPtr->channelPtr; unsigned char lenbuf[5]; int n; if (ssPtr->toWrite == 0) { lenbuf[0] = EXP_SLAVE_WRITE; lenbuf[1] = toWrite & 0xff; lenbuf[2] = (toWrite & 0xff00) >> 8; lenbuf[3] = (toWrite & 0xff0000) >> 16; lenbuf[4] = (toWrite & 0xff000000) >> 24; n = Tcl_WriteRaw(channelPtr, lenbuf, 5); if (n < 0) { return n; } if (n != 5) { return 0; } ssPtr->toWrite = toWrite; } n = Tcl_WriteRaw(channelPtr, bufPtr, toWrite); if (n > 0) { ssPtr->toWrite -= n; } return n; } |
Added win/expWinSpawnClient.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /* ---------------------------------------------------------------------------- * expWinSpawnClient.hpp -- * * Declares the SpawnClient classes. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnClient.hpp,v 1.1.2.2 2002/03/12 21:34:16 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinMessage.hpp" #include "Mcl/include/CMcl.h" class SpawnClientTransport { public: virtual void Write(Message *) = 0; }; class SpawnMailboxClient : public SpawnClientTransport { public: SpawnMailboxClient(const char *name, CMclQueue<Message *> &_mQ); virtual void Write(Message *); private: CMclMailbox *MasterToExpect; CMclMailbox *MasterFromExpect; CMclQueue<Message *> &mQ; }; class ReadPipe : public CMclThreadHandler { public: ReadPipe(CMclQueue<Message *> &_mQ); private: virtual unsigned ThreadHandlerProc(void); CMclQueue<Message *> &mQ; HANDLE hStdIn; }; class SpawnStdioClient : public SpawnClientTransport { public: SpawnStdioClient(const char *name, CMclQueue<Message *> &_mQ); ~SpawnStdioClient(); virtual void Write(Message *); private: CMclQueue<Message *> &mQ; HANDLE hStdOut; HANDLE hStdErr; ReadPipe *reader; CMclThreadAutoPtr readThread; }; |
Added win/expWinSpawnStdioClient.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /* ---------------------------------------------------------------------------- * expWinSpawnStdioClient.cpp -- * * Simple standard IO as our IPC mechanism. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnStdioClient.cpp,v 1.1.2.1 2002/03/12 21:33:26 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinSpawnClient.hpp" SpawnStdioClient::SpawnStdioClient(const char *name, CMclQueue<Message *> &_mQ) : mQ(_mQ) { hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); hStdErr = GetStdHandle(STD_ERROR_HANDLE); reader = new ReadPipe(_mQ); readThread = new CMclThread(reader); } SpawnStdioClient::~SpawnStdioClient() { DWORD dwExit; readThread->GetExitCode(&dwExit); if (dwExit == STILL_ACTIVE) { // by cute convention, terminate threads with a 666. // readThread->Terminate(666); } delete reader; } void SpawnStdioClient::Write(Message *what) { DWORD dwWritten; HANDLE where; switch (what->type) { case Message::TYPE_NORMAL: where = hStdOut; case Message::TYPE_ERROR: where = hStdErr; } WriteFile(where, what->bytes, what->length, &dwWritten, 0L); } ReadPipe::ReadPipe(CMclQueue<Message *> &_mQ) : mQ(_mQ) { hStdIn = GetStdHandle(STD_INPUT_HANDLE); } #define READ_BUFFER_SIZE 128 unsigned ReadPipe::ThreadHandlerProc(void) { BOOL ok; DWORD dwRead; Message *msg; BYTE *readBuf; again: readBuf = new BYTE [READ_BUFFER_SIZE]; ok = ReadFile(hStdIn, readBuf, READ_BUFFER_SIZE, &dwRead, 0L); if (!ok || dwRead == 0) { CloseHandle(hStdIn); // <- should this be here? delete [] readBuf; goto done; } msg = new Message; msg->bytes = readBuf; msg->length = dwRead; msg->type = Message::TYPE_INSTREAM; mQ.Put(msg); goto again; done: return 0; } |
Added win/expWinTest.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include "TclAdapter.hpp" #include "expWinUtils.hpp" class Test1 : protected Tcl::Adapter<Test1>, ArgMaker { public: Test1(Tcl_Interp *_interp) : Tcl::Adapter<Test1>(_interp) { NewTclCmd(interp, "test_buildcmdline", TestCmdLineCmd); NewTclCmd(interp, "test_passthru", TestPassThruCmd); }; virtual void DoCleanup () { // The adapter base class is telling us we are about to go away and it is // safe to use the interp pointer to do any needed cleanup. }; ~Test1() { // can't use interp pointer in here. }; private: // Test the ArgMaker::BuildCommandLine() function. // int TestCmdLineCmd (int objc, struct Tcl_Obj * CONST objv[]) { char **argv = new char * [objc-1]; int i; char *line; for (i = objc-1; i > 0; i--) argv[i-1] = Tcl_GetString(objv[i]); line = BuildCommandLine(objc-1, argv); Tcl_SetObjResult(interp, Tcl_NewStringObj(line, -1)); delete [] line; return TCL_OK; } // Test the full pass-thru // int TestPassThruCmd (int objc, struct Tcl_Obj * CONST objv[]) { char **argvIn = new char * [objc-1]; int i, argc; char *line, **argv; Tcl_Obj **oobjv; // Take the array and turn it into a string. for (i = objc-1; i > 0; i--) argvIn[i-1] = Tcl_GetString(objv[i]); line = BuildCommandLine(objc-1, argvIn); // Now take the string and turn it back into an array. SetArgv(line, &argc, &argv); delete [] line; oobjv = new Tcl_Obj * [argc]; for (i = 0; i < argc; i++) oobjv[i] = Tcl_NewStringObj(argv[i], -1); Tcl_SetObjResult(interp, Tcl_NewListObj(argc, oobjv)); return TCL_OK; } }; // tell the EXTERN macro we want to declare functions for export. #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT EXTERN int Slavedrv_test_Init (Tcl_Interp *interp) { #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == 0L) { return TCL_ERROR; } #endif new Test1(interp); Tcl_PkgProvide(interp, "exptest", "1.0"); return TCL_OK; } |
Added win/expWinTrap.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* * expWinTrap.c -- * * Expect's trap command. Not implemented under Windows. * Only same placeholder functions exist. * * Copyright (c) 1997 by Mitel Corporation * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include "exp_port.h" #include "tcl.h" #include "exp_prog.h" #include "exp_command.h" #include "exp_log.h" int exp_nostack_dump = FALSE; /* TRUE if user has requested unrolling of */ /* stack with no trace */ void exp_init_trap() { } /*ARGSUSED*/ int Exp_TrapCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { Tcl_AppendResult(interp, argv[0], ": not implemented", (char *) NULL); return TCL_ERROR; } static struct exp_cmd_data cmd_data[] = { {"trap", Exp_TrapCmd, (ClientData)EXP_SPAWN_ID_BAD, 0}, {0}}; void exp_init_trap_cmds(interp) Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); } void exp_rearm_sigchld(interp) Tcl_Interp *interp; { } |
Added win/expWinTty.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | /* ---------------------------------------------------------------------------- * expWinTty.c -- * * Implements some tty related functions. Handles interaction with * the console * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" struct exp_f *exp_dev_tty = NULL; char *exp_dev_tty_id = "exp_tty"; int exp_stdin_is_tty; int exp_stdout_is_tty; static int consoleInitialized = FALSE; static DWORD originalConsoleOutMode; static DWORD originalConsoleInMode; static DWORD consoleOutMode; static DWORD consoleInMode; static HANDLE hConsoleOut; static HANDLE hConsoleIn; int exp_israw() { if (! consoleInitialized) { return 0; } return !(consoleOutMode & ENABLE_PROCESSED_OUTPUT); } int exp_isecho() { if (! consoleInitialized) { return 1; } return consoleInMode & ENABLE_ECHO_INPUT; } /* *---------------------------------------------------------------------- * * exp_tty_raw -- * * Set the tty status. If 1, set to raw. Otherwise, set * to normal. * * Results: * None * * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void exp_tty_raw(set) int set; { if (! consoleInitialized) { return; } if (set == 1) { consoleOutMode &= ~ENABLE_PROCESSED_OUTPUT; } else { consoleOutMode |= ENABLE_PROCESSED_OUTPUT; } SetConsoleMode(hConsoleOut, consoleOutMode); } /* *---------------------------------------------------------------------- * * exp_tty_echo -- * * Set the tty status. If 1, set to echo. Otherwise, set * to no echo. * * Results: * None * * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void exp_tty_echo(set) int set; { if (! consoleInitialized) { return; } if (set == 1) { consoleInMode |= ENABLE_ECHO_INPUT; } else { consoleInMode &= ~ENABLE_ECHO_INPUT; } SetConsoleMode(hConsoleIn, consoleInMode); } /* *---------------------------------------------------------------------- * * exp_cook -- * * take strings with newlines and insert carriage-returns. * This allows user to write send_user strings without always * putting in \r. If len == 0, use strlen to compute it * NB: if terminal is not in raw mode, nothing is done. * * Results: * The same string if in raw mode, the modified string otherwise * *---------------------------------------------------------------------- */ char * exp_cook(s,len) CONST char *s; int *len; /* current and new length of s */ { static unsigned int destlen = 0; static char *dest = 0; char *d; /* ptr into dest */ unsigned int need; if (s == 0) return("<null>"); /* worst case is every character takes 2 to represent */ need = 1 + 2*(len?*len:strlen(s)); if (need > destlen) { if (dest) ckfree(dest); dest = ckalloc(need); destlen = need; } for (d = dest;*s;s++) { if (*s == '\n') { *d++ = '\r'; *d++ = '\n'; } else { *d++ = *s; } } *d = '\0'; if (len) *len = d-dest; return(dest); } void exp_init_stdio() { exp_stdin_is_tty = isatty(0); exp_stdout_is_tty = isatty(1); setbuf(stdout,(char *)0); /* unbuffer stdout */ } /* *---------------------------------------------------------------------- * * exp_tty_break -- * * Send a BREAK to the controlled subprocess * * Results: * XXX: None, so we can't propagate an error back up * *---------------------------------------------------------------------- */ /*ARGSUSED*/ void exp_tty_break(interp,f) Tcl_Interp *interp; struct exp_f *f; { #ifdef POSIX tcsendbreak(fd,0); #endif Tcl_AppendResult(interp, "exp_tty_break not implemented", NULL); } /* *---------------------------------------------------------------------- * * Exp_SttyCmd -- * * Implements the 'stty' and 'exp_stty' command. * * Results: * A standard Tcl result * * Side Effects: * Can change the characteristics of the console * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int Exp_SttyCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { #if 1 /* redirection symbol is not counted as a stty arg in terms */ /* of recognition. */ int saw_unknown_stty_arg = FALSE; int saw_known_stty_arg = FALSE; int no_args = TRUE; int rc = TCL_OK; int cooked = FALSE; int was_raw, was_echo; char **argv0 = argv; for (argv=argv0+1;*argv;argv++) { if (argv[0][0] == '<') { Tcl_AppendResult(interp, argv0, ": redirection not supported on Windows NT", NULL); return TCL_ERROR; } } was_raw = exp_israw(); was_echo = exp_isecho(); for (argv=argv0+1;*argv;argv++) { if (streq(*argv,"raw") || streq(*argv,"-cooked")) { exp_tty_raw(1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"-raw") || streq(*argv,"cooked")) { cooked = TRUE; exp_tty_raw(-1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"echo")) { exp_tty_echo(1); saw_known_stty_arg = TRUE; no_args = FALSE; } else if (streq(*argv,"-echo")) { exp_tty_echo(-1); saw_known_stty_arg = TRUE; no_args = FALSE; #ifdef XXX /* This can be implemented, but it isn't right now */ } else if (streq(*argv,"rows")) { if (*(argv+1)) { exp_win_rows_set(*(argv+1)); argv++; no_args = FALSE; } else { exp_win_rows_get(interp->result); return TCL_OK; } } else if (streq(*argv,"columns")) { if (*(argv+1)) { exp_win_columns_set(*(argv+1)); argv++; no_args = FALSE; } else { exp_win_columns_get(interp->result); return TCL_OK; } #endif } else { saw_unknown_stty_arg = TRUE; } } /* if no result, make a crude one */ if (interp->result[0] == '\0') { sprintf(interp->result,"%sraw %secho", (was_raw?"":"-"), (was_echo?"":"-")); } return rc; #else Tcl_AppendResult(interp, argv[0], ": not implemented", NULL); return TCL_ERROR; #endif } /*ARGSUSED*/ static int Exp_SystemCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { Tcl_AppendResult(interp, argv[0], ": not implemented", NULL); return TCL_ERROR; } static struct exp_cmd_data cmd_data[] = { {"stty", 0, Exp_SttyCmd, 0, 0}, {"system", 0, Exp_SystemCmd, 0, 0}, {0} }; /* *---------------------------------------------------------------------- * * exp_init_tty_cmds -- * * Adds tty related commands to the interpreter * * Results: * A standard TCL result * * Side Effects: * Commands are added to the interpreter. * *---------------------------------------------------------------------- */ int exp_init_tty_cmds(interp) struct Tcl_Interp *interp; { exp_create_commands(interp,cmd_data); return TRUE; } /* *---------------------------------------------------------------------- * * exp_init_pty -- * * This is where the console device is initialized. We wrap * it in a channel (if it is available). * * Results: * None at the moment. * * Side Effects: * A channel name is set and an exp_f structure is created. * * Notes: * XXX: GetCurrentProcessId() might not be the appropriate thing * as exp_getpid was previously used. We might want to have * a separate console input channel. * *---------------------------------------------------------------------- */ void exp_init_pty(interp) Tcl_Interp *interp; { HANDLE hOut, hIn; Tcl_Channel channel, inChannel, outChannel; struct exp_f *f; CONST char *inId, *outId; int mode; DWORD dw; hOut = GetStdHandle(STD_OUTPUT_HANDLE); if (GetConsoleMode(hOut, &dw) == FALSE) { hOut = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hOut == INVALID_HANDLE_VALUE) { return; } outChannel = Tcl_MakeFileChannel(hOut, TCL_WRITABLE); f = exp_f_new(interp, outChannel, NULL, GetCurrentProcessId()); f->channel = outChannel; Tcl_RegisterChannel(interp, outChannel); } else { outChannel = Tcl_GetChannel(interp, "stdout", &mode); } hIn = GetStdHandle(STD_INPUT_HANDLE); if (GetConsoleMode(hIn, &dw) == FALSE) { hIn = CreateFile("CONIN$", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hIn == INVALID_HANDLE_VALUE) { if (hOut != GetStdHandle(STD_OUTPUT_HANDLE)) { CloseHandle(hOut); return; } } inChannel = Tcl_MakeFileChannel(hIn, TCL_READABLE); f = exp_f_new(interp, inChannel, NULL, GetCurrentProcessId()); f->channel = inChannel; Tcl_RegisterChannel(interp, inChannel); } else { inChannel = Tcl_GetChannel(interp, "stdin", &mode); } inId = Tcl_GetChannelName(inChannel); outId = Tcl_GetChannelName(outChannel); /* * Create an alias channel */ channel = ExpCreatePairChannel(interp, inId, outId, "exp_tty"); Tcl_SetChannelOption(interp, channel, "-buffering", "none"); Tcl_SetChannelOption(interp, channel, "-translation", "binary"); exp_dev_tty = exp_f_new(interp, channel, NULL, EXP_NOPID); Tcl_RegisterChannel(interp, channel); /* * Get the original console modes */ if (GetConsoleMode(hOut, &originalConsoleOutMode) == FALSE) { return; } consoleOutMode = originalConsoleOutMode; hConsoleOut = hOut; if (GetConsoleMode(hIn, &originalConsoleInMode) == FALSE) { return; } consoleInMode = originalConsoleInMode; hConsoleIn = hIn; consoleInitialized = TRUE; } /* *---------------------------------------------------------------------- * * exp_pty_exit -- * * Routine to set the terminal mode back to normal on exit. * * Results: * None * * Side Effects: * Console mode is set to what is was when we entered Expect. * *---------------------------------------------------------------------- */ void exp_pty_exit() { SetConsoleMode(hConsoleIn, originalConsoleInMode); SetConsoleMode(hConsoleOut, originalConsoleOutMode); } /* *---------------------------------------------------------------------- * * exp_init_tty -- * * Placeholder routine in library * *---------------------------------------------------------------------- */ void exp_init_tty(interp) Tcl_Interp *interp; { } |
Added win/expWinTty.h.
> > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /* * expWinTty.h -- * * tty support definitions for Windows * * Copyright (c) 1997 by Mitel Corporation * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #ifndef __EXP_UNIX_TTY_H__ #define __EXP_UNIX_TTY_H__ #include <io.h> #include <process.h> extern int exp_stdin_is_tty; extern int exp_stdout_is_tty; extern void exp_tty_break(); #endif /* __EXP_UNIX_TTY_H__ */ |
Added win/expWinUtils.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | /* ---------------------------------------------------------------------------- * expWinUtils.cpp -- * * Misc stuff. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinUtils.cpp,v 1.1.2.5 2002/03/12 07:59:14 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinUtils.hpp" #include "slavedrvmc.h" #include <ctype.h> #include <string.h> /* *---------------------------------------------------------------------- * * ArgMaker::BuildCommandLine -- * * Takes an array form and turns it into a single string according * to the rules of quoting needed for windows. * * Results: * The new string. * * Side Effects: * Memory is allocated. * *---------------------------------------------------------------------- */ char * ArgMaker::BuildCommandLine( int argc, // Number of arguments. char *const *argv) // Argument strings (in ascii). { const char *arg, *start, *special; char *out; int quote, i, need; // Guess how large we are. for (i = need = 0; i < argc; i++) { need += strlen(argv[i]) + 10; } out = new char [need]; *out = '\0'; for (i = 0; i < argc; i++) { arg = argv[i]; if (i != 0) { strcat(out, " "); } quote = 0; if (arg[0] == '\0') { quote = 1; } else { for (start = arg; *start != '\0'; start++) { if (isspace(*start) || *start == '"' ) { quote = 1; break; } } } if (quote) { strcat(out, "\""); } start = arg; for (special = arg; ; ) { if (*special == '"' && quote) { strncat(out, start, special - start); // replace a single double quote with 2 double quotes. strcat(out, "\"\""); start = special + 1; } if (*special == '\0') { break; } special++; } strncat(out, start, special - start); if (quote) { strcat(out, "\""); } } return out; } /* *------------------------------------------------------------------------- * * SetArgv -- * * Parse the Windows command line string into argc/argv. Done here * because we don't trust the builtin argument parser in crt0. * Windows applications are responsible for breaking their command * line into arguments. * * 2N backslashes + quote -> N backslashes + begin quoted string * 2N + 1 backslashes + quote -> literal * N backslashes + non-quote -> literal * quote + quote in a quoted string -> single quote * quote + quote not in quoted string -> empty string * quote -> begin quoted string * * Results: * Fills argcPtr with the number of arguments and argvPtr with the * array of arguments. * * Side effects: * Memory allocated. * *-------------------------------------------------------------------------- */ void SetArgv( const char *cmdLine,// commandline string. int *argcPtr, // Filled with number of argument strings. char ***argvPtr) // Filled with argument strings in UTF (alloc'd with new). { char *arg, *argSpace; char **argv; const char *p; int inquote, copy, slashes; size_t size, argc; // Precompute an overly pessimistic guess at the number of arguments // in the command line by counting non-space spans. // size = 2; for (p = cmdLine; *p != '\0'; p++) { if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ size++; while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ p++; } if (*p == '\0') { break; } } } argSpace = new char [(size * sizeof(char *)) + strlen(cmdLine) + 1]; argv = (char **) argSpace; argSpace += size * sizeof(char *); size--; p = cmdLine; for (argc = 0; argc < size; argc++) { argv[argc] = arg = argSpace; while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ p++; } if (*p == '\0') { break; } inquote = 0; slashes = 0; while (1) { copy = 1; while (*p == '\\') { slashes++; p++; } if (*p == '"') { if ((slashes & 1) == 0) { copy = 0; if ((inquote) && (p[1] == '"')) { p++; copy = 1; } else { inquote = !inquote; } } slashes >>= 1; } while (slashes) { *arg = '\\'; arg++; slashes--; } if ((*p == '\0') || (!inquote && ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ break; } if (copy != 0) { *arg = *p; arg++; } p++; } *arg = '\0'; argSpace = arg + 1; } argv[argc] = 0L; *argcPtr = argc; *argvPtr = argv; } static char sysMsgSpace[1024]; /* local protos */ static TCHAR *Exp95Log (DWORD errCode, char *errData[], int cnt); #define GETSEVERITY(code) (UCHAR)((code >> 30) & 0x3) #define GETFACILITY(code) (WORD)((code >> 16) & 0x0FFF) #define GETCODE(code) (WORD)(code & 0xFFFF) /* *---------------------------------------------------------------------- * * ExpWinSyslog -- * * Logs error messages to the system application event log. * It is normally called through the macro EXP_LOG() when * errors occur in the slave driver process, but it can be * used elsewhere. * * Results: * None * *---------------------------------------------------------------------- */ void ExpWinSyslog (DWORD errCode, ...) { va_list args; char *errData[10]; int cnt = 0; char *errMsg; static char codeBuf[33]; DWORD dwWritten; char *file; int line; static char fileInfo[MAX_PATH]; va_start(args,errCode); /* Get the file info */ file = va_arg(args, char *); line = va_arg(args, int); wsprintfA(fileInfo, "%s(%d)", file, line); errData[cnt++] = fileInfo; /* Set the textual severity */ switch(GETSEVERITY(errCode)) { case STATUS_SEVERITY_WARNING: errData[cnt++] = "Warning"; break; case STATUS_SEVERITY_SUCCESS: errData[cnt++] = "Success"; break; case STATUS_SEVERITY_INFORMATIONAL: errData[cnt++] = "Info"; break; case STATUS_SEVERITY_FATAL: errData[cnt++] = "Fatal"; break; } /* Set the textual Facility */ switch(GETFACILITY(errCode)) { case FACILITY_WINSOCK: errData[cnt++] = "Winsock IPC"; break; case FACILITY_SYSTEM: errData[cnt++] = "System"; break; case FACILITY_STUBS: errData[cnt++] = "Stubs"; break; case FACILITY_NAMEDPIPE: errData[cnt++] = "NamedPipe IPC"; break; case FACILITY_MSPROTO: errData[cnt++] = "Master/Slave Protocol"; break; case FACILITY_MAILBOX: errData[cnt++] = "MailBoxing IPC"; break; case FACILITY_IO: errData[cnt++] = "I/O general"; break; case FACILITY_DBGTRAP: errData[cnt++] = "Debug/Trap"; break; } /* Set the textual Code */ errData[cnt++] = codeBuf; wsprintfA(codeBuf, "0x%04X", GETCODE(errCode)); /* set everyone else */ while ((errData[cnt] = va_arg(args, char *)) != NULL) cnt++; va_end(args); /* format this error according to the message catalog contained in the exe. */ errMsg = Exp95Log(errCode, errData, cnt); OutputDebugString(errMsg); if (GETSEVERITY(errCode) & STATUS_SEVERITY_FATAL) { /* I could have used printf() and fflush(), but chose the direct * route instead */ WriteFile(GetStdHandle(STD_ERROR_HANDLE), errMsg, strlen(errMsg), &dwWritten, NULL); /* Stop the world, I want to get off. */ //DebugBreak(); Sleep(5000); ExitProcess(255); } LocalFree(errMsg); } char *ExpSyslogGetSysMsg (DWORD id) { int chars; chars = wsprintf(sysMsgSpace, "[%d] ", id); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, id, 0, &sysMsgSpace[chars], (1024-chars), 0); return sysMsgSpace; } char *Exp95Log(DWORD errCode, char *errData[], int cnt) { char *msg; FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY, GetModuleHandle(NULL), errCode, 0, (char *) &msg, 0, errData); return msg; } |
Added win/expWinUtils.hpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // This was pulled from ConsoleDebugger to enable a test suite // to use this in isolation. // #ifndef INC_expWinUtils_hpp__ #define INC_expWinUtils_hpp__ #include <windows.h> // Errors and logging #define EXP_LOG0(errCode) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, 0) #define EXP_LOG1(errCode, arg1) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, arg1, 0) #define EXP_LOG2(errCode, arg1, arg2) ExpWinSyslog(errCode, __FILE__, (int)__LINE__, arg1, arg2, 0) void ExpWinSyslog (DWORD errCode, ...); char *ExpSyslogGetSysMsg (DWORD id); class ArgMaker { public: char *BuildCommandLine (int, char * const *); }; void SetArgv (const char *cmdLine, int *argcPtr, char ***argvPtr); #endif |
Added win/expect.dsp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | # Microsoft Developer Studio Project File - Name="expect" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=expect - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "expect.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "expect.mak" CFG="expect - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "expect - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "expect - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "expect - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release\expect" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPECT_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "..\generic" /I "d:\tcl_workspace\tcl_head\generic" /D "NDEBUG" /D "WIN32" /D "BUILD_exp" /D TCL_THREADS=1 /D "USE_TCL_STUBS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /i "..\generic" /i "d:\tcl_workspace\tcl_head\generic" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 advapi32.lib user32.lib /nologo /dll /machine:I386 /out:"Release/expect60.dll" /libpath:"d:\tcl_workspace\tcl_head\win\Release" !ELSEIF "$(CFG)" == "expect - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug\expect" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPECT_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /GB /MDd /W3 /Gm /GX /ZI /Od /I "." /I "..\generic" /I "d:\tcl_workspace\tcl_head\generic" /D "_DEBUG" /D "WIN32" /D "BUILD_exp" /D TCL_THREADS=1 /D "USE_TCL_STUBS" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /i "..\generic" /i "d:\tcl_workspace\tcl_head\generic" /d "DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 advapi32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"Debug/expect60d.dll" /pdbtype:sept /libpath:"d:\tcl_workspace\tcl_head\win\Debug" !ENDIF # Begin Target # Name "expect - Win32 Release" # Name "expect - Win32 Debug" # Begin Group "generic" # PROP Default_Filter "" # Begin Group "headers" # PROP Default_Filter "" # Begin Source File SOURCE=..\generic\exp.h # End Source File # Begin Source File SOURCE=..\generic\expDecls.h # End Source File # Begin Source File SOURCE=..\generic\expInt.h # End Source File # Begin Source File SOURCE=..\generic\expIntDecls.h # End Source File # Begin Source File SOURCE=..\generic\expIntPlatDecls.h # End Source File # Begin Source File SOURCE=..\generic\expPlatDecls.h # End Source File # End Group # Begin Source File SOURCE=..\generic\exp.decls !IF "$(CFG)" == "expect - Win32 Release" # Begin Custom Build - Rebuilding the Stubs table... InputDir=\expect_wslive\expect_win32_take2\generic InputPath=..\generic\exp.decls BuildCmds= \ c:\progra~1\tcl\bin\tclsh84 d:/tcl_workspace/tcl_head/tools/genStubs.tcl $(InputDir) $(InputPath) "$(InputDir)\expDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expPlatDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expIntDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expIntPlatDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expStubInit.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "expect - Win32 Debug" # Begin Custom Build - Rebuilding the Stubs table... InputDir=\expect_wslive\expect_win32_take2\generic InputPath=..\generic\exp.decls BuildCmds= \ c:\progra~1\tcl\bin\tclsh84 d:/tcl_workspace/tcl_head/tools/genStubs.tcl $(InputDir) $(InputPath) "$(InputDir)\expDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expPlatDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expIntDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expIntPlatDecls.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(InputDir)\expStubInit.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\generic\exp_closetcl.c # End Source File # Begin Source File SOURCE=..\generic\exp_event.c # End Source File # Begin Source File SOURCE=..\generic\exp_glob.c # End Source File # Begin Source File SOURCE=..\generic\exp_inter.c # End Source File # Begin Source File SOURCE=..\generic\exp_log.c # End Source File # Begin Source File SOURCE=..\generic\exp_main_sub.c # End Source File # Begin Source File SOURCE=..\generic\exp_printify.c # End Source File # Begin Source File SOURCE=..\generic\exp_strf.c # End Source File # Begin Source File SOURCE=..\generic\expChan.c # End Source File # Begin Source File SOURCE=..\generic\expCommand.c # End Source File # Begin Source File SOURCE=..\generic\expect.c # End Source File # Begin Source File SOURCE=..\generic\expSpawnChan.c # End Source File # Begin Source File SOURCE=..\generic\expStubInit.c # End Source File # Begin Source File SOURCE=..\generic\expTrap.c # End Source File # Begin Source File SOURCE=..\generic\getopt.c # End Source File # End Group # Begin Group "win" # PROP Default_Filter "" # Begin Group "winheaders" # PROP Default_Filter "" # Begin Source File SOURCE=.\expWinInt.h # End Source File # Begin Source File SOURCE=.\expWinPort.h # End Source File # Begin Source File SOURCE=.\MsvcDbgControl.h # End Source File # End Group # Begin Source File SOURCE=.\expect.rc !IF "$(CFG)" == "expect - Win32 Release" !ELSEIF "$(CFG)" == "expect - Win32 Debug" # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 !ENDIF # End Source File # Begin Source File SOURCE=.\expWinCommand.c # End Source File # Begin Source File SOURCE=.\expWinInit.c # End Source File # Begin Source File SOURCE=.\expWinLog.c # End Source File # Begin Source File SOURCE=.\expWinProcess.c # End Source File # Begin Source File SOURCE=.\expWinSpawnChan.c # End Source File # Begin Source File SOURCE=.\expWinTty.c # End Source File # Begin Source File SOURCE=.\MsvcDbgControl.cpp !IF "$(CFG)" == "expect - Win32 Release" # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "expect - Win32 Debug" !ENDIF # End Source File # Begin Source File SOURCE=.\winDllMain.c # End Source File # End Group # End Target # End Project |
Added win/expect.dsw.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "expect"=.\expect.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### |
Added win/expect.rc.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* ---------------------------------------------------------------------------- * expect.rc -- * * Version Resource Script. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.4.4 2002/02/10 10:17:04 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <winver.h> #include <winnt.h> #define RESOURCE_INCLUDED /* needed for tcl.h, only */ #include "exp.h" #ifdef DEBUG #define SUFFIX_DEBUG "d" #else #define SUFFIX_DEBUG "" #endif #define SUFFIX SUFFIX_DEBUG LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT VS_VERSION_INFO VERSIONINFO FILEVERSION EXP_MAJOR_VERSION,EXP_MINOR_VERSION,EXP_RELEASE_LEVEL,EXP_RELEASE_SERIAL PRODUCTVERSION EXP_MAJOR_VERSION,EXP_MINOR_VERSION,EXP_RELEASE_LEVEL,EXP_RELEASE_SERIAL FILEFLAGSMASK 0x3fL #if defined(DEBUG) FILEFLAGS VS_FF_DEBUG #elif EXP_RELEASE_LEVEL != TCL_FINAL_RELEASE FILEFLAGS VS_FF_PRERELEASE #else FILEFLAGS 0x0L #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ BEGIN VALUE "FileDescription", "Expect DLL\0" VALUE "OriginalFilename", "expect" STRINGIFY(EXP_MAJOR_VERSION) STRINGIFY(EXP_MINOR_VERSION) SUFFIX ".dll\0" VALUE "CompanyName", "Teleindustrie, LLC\0" VALUE "FileVersion", EXP_PATCH_LEVEL VALUE "LegalCopyright", "Copyright \251 Teleindustrie, LLC 2002\0" VALUE "ProductName", "Expect " EXP_VERSION " for Win32\0" VALUE "ProductVersion", EXP_PATCH_LEVEL VALUE "Comments", "Expect was written for Unix by Don Libes at NIST. This is the Win32 port.\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END |
Added win/pkgIndex.tcl.
> | 1 | package ifneeded expect 5.21 [list tclPkgSetup $dir expect 5.21 {{expect52.dll load {exp_close exp_continue exp_exit exp_getpid exp_inter_return exp_internal exp_interpreter exp_kill exp_log_file exp_log_user exp_match_max exp_open exp_parity exp_pid exp_remove_nulls exp_send exp_send_error exp_send_log exp_send_spawn exp_send_tty exp_send_user exp_sleep exp_spawn exp_strace exp_stty exp_system exp_tcl_close exp_tcl_continue exp_tcl_exit exp_timestamp exp_trap exp_version exp_wait expect expect_after expect_background expect_before expect_tty expect_user expect_version getpid inter_return interpreter kill log_file log_user match_max parity prompt1 prompt2 remove_nulls send_error send_log send_spawn send_tty send_user sleep spawn strace stty system timestamp trap wait}}}] |
Added win/slavedrv.dsp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | # Microsoft Developer Studio Project File - Name="slavedrv" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=slavedrv - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "slavedrv.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "slavedrv.mak" CFG="slavedrv - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "slavedrv - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "slavedrv - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "slavedrv - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "slavedrv___Win32_Release" # PROP BASE Intermediate_Dir "slavedrv___Win32_Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release\slavedrv" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I "..\generic" /I "d:\tcl_workspace\tcl_head\generic" /I "d:\tcl_workspace\tcl_head\win" /I "$(IntDir)" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "USE_TCL_STUBS" /D IDE_LATCHED=0 /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /i "..\generic" /i "d:\tcl_workspace\tcl_head\generic" /i "$(IntDir)" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /libpath:"d:\tcl_workspace\tcl_head\win\Release" /opt:nowin98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "slavedrv - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "slavedrv___Win32_Debug" # PROP BASE Intermediate_Dir "slavedrv___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug\slavedrv" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /GB /MDd /W3 /Gm /GX /ZI /Od /I "." /I "..\generic" /I "d:\tcl_workspace\tcl_head\generic" /I "d:\tcl_workspace\tcl_head\win" /I "$(IntDir)" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "USE_TCL_STUBS" /D "BUILD_slavedriver" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /i "..\generic" /i "d:\tcl_workspace\tcl_head\generic" /i "$(IntDir)" /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"d:\tcl_workspace\tcl_head\win\Release" !ENDIF # Begin Target # Name "slavedrv - Win32 Release" # Name "slavedrv - Win32 Debug" # Begin Group "winheaders" # PROP Default_Filter "h" # Begin Source File SOURCE=.\expWinSlave.hpp # End Source File # End Group # Begin Source File SOURCE=.\expWinConsoleDebugger.cpp # End Source File # Begin Source File SOURCE=.\expWinConsoleDebugger.hpp # End Source File # Begin Source File SOURCE=.\expWinConsoleDebuggerBreakPoints.cpp # End Source File # Begin Source File SOURCE=.\expWinDynloadTclStubs.cpp # End Source File # Begin Source File SOURCE=.\expWinMessage.cpp # End Source File # Begin Source File SOURCE=.\expWinMessage.hpp # End Source File # Begin Source File SOURCE=.\expWinSlaveMain.cpp # End Source File # Begin Source File SOURCE=.\expWinSlaveTrap.hpp # End Source File # Begin Source File SOURCE=.\expWinSlaveTrapDbg.cpp # End Source File # Begin Source File SOURCE=.\expWinSpawnClient.hpp # End Source File # Begin Source File SOURCE=.\expWinSpawnStdioClient.cpp # End Source File # Begin Source File SOURCE=.\expWinUtils.cpp # End Source File # Begin Source File SOURCE=.\expWinUtils.hpp # End Source File # Begin Source File SOURCE=.\slavedrv.rc !IF "$(CFG)" == "slavedrv - Win32 Release" !ELSEIF "$(CFG)" == "slavedrv - Win32 Debug" # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 !ENDIF # End Source File # Begin Source File SOURCE=.\slavedrvmc.mc !IF "$(CFG)" == "slavedrv - Win32 Release" # Begin Custom Build - Compiling message catalog... IntDir=.\Release\slavedrv InputPath=.\slavedrvmc.mc BuildCmds= \ mc -w -h "$(IntDir)" -r "$(IntDir)" $(InputPath) "$(IntDir)\slavedrvmc.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\slavedrvmc.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\MSG00409.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "slavedrv - Win32 Debug" # Begin Custom Build - Compiling message catalog... IntDir=.\Debug\slavedrv InputPath=.\slavedrvmc.mc BuildCmds= \ mc -w -h "$(IntDir)" -r "$(IntDir)" $(InputPath) "$(IntDir)\slavedrvmc.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\slavedrvmc.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\MSG00409.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\TclHash.hpp # End Source File # End Target # End Project |
Added win/slavedrv.dsw.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "Mcl"=.\Mcl\Mcl.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "slavedrv"=.\slavedrv.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name Mcl End Project Dependency }}} ############################################################################### Project: "slavedrv_test"=.\slavedrv_test.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### |
Added win/slavedrv.rc.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* ---------------------------------------------------------------------------- * slavedrv.rc -- * * Resource script for use with the resource compiler. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: slavedrv.rc,v 1.1.2.1 2002/03/09 01:42:25 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <winver.h> VS_VERSION_INFO VERSIONINFO FILEVERSION 6,0,0,0 PRODUCTVERSION 6,0,0,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #if defined(_DEBUG) FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif FILEOS VOS__WINDOWS32 /* open to all */ FILETYPE VFT_DLL FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ BEGIN VALUE "FileDescription", "Spawn Driver helper application for overseeing Win32 consoles.\0" VALUE "OriginalFilename", "spawndrv.exe\0" VALUE "CompanyName", "Telindustrie, LLC\0" VALUE "FileVersion", "6.0a0" "\0" VALUE "LegalCopyright", "Copyright \251 Telindustrie, LLC 2002\0" VALUE "ProductName", "Expect " "6.0" " for Win32\0" VALUE "ProductVersion", "6.0a0" "\0" VALUE "Comments", "Expect was written for Unix by Don Libes at NIST.\r\n" "Gordon Chaffee ported it to WinNT for Mitel Corporation in 1997.\r\n" "David Gravereaux merged Gordon's port back into the official sources for Telindustrie LLC in Oct. 2001.\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END // Include the Message Table that lists the error codes and textual replies. // This is output from the message compiler and found in the temp build directory. #include "slavedrvmc.rc" |
Added win/slavedrv_test.dsp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | # Microsoft Developer Studio Project File - Name="slavedrv_test" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=slavedrv_test - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "slavedrv_test.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "slavedrv_test.mak" CFG="slavedrv_test - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "slavedrv_test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "slavedrv_test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "slavedrv_test - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "slavedrv_test___Win32_Release" # PROP BASE Intermediate_Dir "slavedrv_test___Win32_Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release\slavedrv_test" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SLAVEDRV_TEST_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 !ELSEIF "$(CFG)" == "slavedrv_test - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "slavedrv_test___Win32_Debug" # PROP BASE Intermediate_Dir "slavedrv_test___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug\slavedrv_test" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SLAVEDRV_TEST_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "d:\tcl_workspace\tcl_head\generic" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "USE_TCL_STUBS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"d:\tcl_workspace\tcl_head\win\Release" !ENDIF # Begin Target # Name "slavedrv_test - Win32 Release" # Name "slavedrv_test - Win32 Debug" # Begin Source File SOURCE=.\expWinTest.cpp # End Source File # Begin Source File SOURCE=.\expWinUtils.cpp # End Source File # Begin Source File SOURCE=.\expWinUtils.hpp # End Source File # Begin Source File SOURCE=.\TclAdapter.hpp # End Source File # End Target # End Project |
Added win/slavedrvmc.mc.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | ;/* ---------------------------------------------------------------------------- ; * spawndrvmc.mc -- ; * ; * This file contains the message catalog for use with Win32 error ; * reporting through ReportEvent() and FormatMessage(). ; * ---------------------------------------------------------------------------- ; * ; * Written by: Don Libes, [email protected], NIST, 12/3/90 ; * ; * Design and implementation of this program was paid for by U.S. tax ; * dollars. Therefore it is public domain. However, the author and NIST ; * would appreciate credit if this program or parts of it are used. ; * ; * Copyright (c) 1997 Mitel Corporation ; * work by Gordon Chaffee <[email protected]> for the WinNT port. ; * ; * Copyright (c) 2001-2002 Telindustrie, LLC ; * work by David Gravereaux <[email protected]> for any Win32 OS. ; * ; * ---------------------------------------------------------------------------- ; * URLs: http://expect.nist.gov/ ; * http://expect.sf.net/ ; * http://bmrc.berkeley.edu/people/chaffee/expectnt.html ; * ---------------------------------------------------------------------------- ; * RCS: @(#) $Id: slavedrvmc.mc,v 1.1.2.1 2002/03/09 01:42:00 davygrvy Exp $ ; * ---------------------------------------------------------------------------- ; */ MessageIdTypedef = DWORD OutputBase = 16 SeverityNames = ( Success=0x0:STATUS_SEVERITY_SUCCESS Informational=0x1:STATUS_SEVERITY_INFORMATIONAL Warning=0x2:STATUS_SEVERITY_WARNING Fatal=0x3:STATUS_SEVERITY_FATAL ) FacilityNames = ( Catagories=0x0 System=0x0:FACILITY_SYSTEM Stubs=0x1:FACILITY_STUBS Io=0x2:FACILITY_IO Mailbox=0x3:FACILITY_MAILBOX NamedPipe=0x4:FACILITY_NAMEDPIPE WinSock=0x5:FACILITY_WINSOCK DbgTrap=0x6:FACILITY_DBGTRAP MasterSlave_Protocol=0x7:FACILITY_MSPROTO ) LanguageNames=(English=0x409:MSG00409) MessageId=0x1 Severity=Success Facility=Catagories Language=English Stubs . MessageId=0x2 Severity=Success Facility=Catagories Language=English General I/O . MessageId=0x3 Severity=Success Facility=Catagories Language=English MailBoxing IPC . MessageId=0x4 Severity=Success Facility=Catagories Language=English NamedPipe IPC . MessageId=0x5 Severity=Success Facility=Catagories Language=English WinSock IPC . MessageId=0x6 Severity=Success Facility=Catagories Language=English Console API traps . MessageId=0x7 Severity=Success Facility=Catagories Language=English Master/Slave protocol . MessageId=0x1 Severity=Error Facility=System SymbolicName=MSG_BYPASS Language=English %1 . MessageId=0x1 Severity=Error Facility=Io SymbolicName=MSG_IO_ARGSWRONG Language=English %1 : %2 (%3,%4): No commandline arguements to slavedrv.exe. No work to do. . MessageId=0x2 Severity=Warning Facility=Io SymbolicName=MSG_IO_BADSHUTDOWN Language=English %1 : %2 (%3,%4): Unclean shutdown: %5 . MessageId=0x2 Severity=Error Facility=Io SymbolicName=MSG_IO_UNEXPECTED Language=English %1 : %2 (%3,%4): Unexpected error: %5 . MessageId=0x3 Severity=Fatal Facility=Io SymbolicName=MSG_IO_TRANSPRTARGSBAD Language=English %1 : %2 (%3,%4): Transport protocol bad: %5 . MessageId=0x4 Severity=Fatal Facility=Io SymbolicName=MSG_IO_TRAPARGSBAD Language=English %1 : %2 (%3,%4): Trap method bad: %5 . MessageId=0x0 Severity=Error Facility=Mailbox SymbolicName=MSG_MB_CANTOPENCLIENT1 Language=English %1 : %2 (%3,%4): Can't open client-side IPC mailbox for named mailbox "%5". . MessageId=0x1 Severity=Error Facility=Mailbox SymbolicName=MSG_MB_CANTOPENCLIENT2 Language=English %1 : %2 (%3,%4): Can't open client-side IPC mailbox for named mailbox "%5". Got system error %6 . MessageId=0x1 Severity=Fatal Facility=Stubs SymbolicName=MSG_STUBS_TCLDLLCANTFIND Language=English %1 : %2 (%3,%4): Tcl is not available. The Tcl Dll as specified in the environment variable EXP_TCLDLL as "%5" could not be loaded by LoadLibrary(). Check that EXP_TCLDLL has the correct filename and is the fullpath. ex: "C:\Program Files\Tcl\bin\tcl84.dll" . MessageId=0x2 Severity=Fatal Facility=Stubs SymbolicName=MSG_STUBS_NOCREATEINTERP Language=English %1 : %2 (%3,%4): Tcl API function, Tcl_CreateInterp(), not found in "%5". . MessageId=0x3 Severity=Fatal Facility=Stubs SymbolicName=MSG_STUBS_ENVARNOTSET Language=English %1 : %2 (%3,%4): EXP_TCLDLL was not found in the environment. It is required for slavedrv.exe to know where the Tcl DLL is to use its services. The channel driver in the Expect extension should be setting this before launching spawndrv.exe. This executable was not intended to be used outside of the Expect extension. . MessageId=0x4 Severity=Fatal Facility=Stubs SymbolicName=MSG_STUBS_INITSTUBS Language=English %1 : %2 (%3,%4): Tcl_InitStubs() failed with "%5". . MessageId=0x1 Severity=Warning Facility=MasterSlave_Protocol SymbolicName=MSG_MS_SLAVENOWRITABLE Language=English %1 : %2 (%3,%4): Unable to write to slave: %5 . MessageId=0x2 Severity=Error Facility=MasterSlave_Protocol SymbolicName=MSG_MS_BADSTATE Language=English %1 : %2 (%3,%4): Unexpected state . MessageId=0x1 Severity=Error Facility=NamedPipe SymbolicName=MSG_NP_CANTOPEN Language=English %1 : %2 (%3,%4): Can't open argv[1], "%5", for read/write. CreateFile() returned: %6 . MessageId=0x2 Severity=Error Facility=NamedPipe SymbolicName=MSG_NP_BADTYPE Language=English %1 : %2 (%3,%4): NamedPipe specified as, "%5", was found not to be a pipe filetype. . MessageId=0x1 Severity=Error Facility=WinSock SymbolicName=MSG_WS_CANTSTART Language=English %1 : %2 (%3,%4): WinSock system was unable to start. slavedrv.exe requested version %5. WSAStartup() returned: %6 . MessageId=0x2 Severity=Error Facility=WinSock SymbolicName=MSG_WS_CANTCREATEMASTERSOCK Language=English %1 : %2 (%3,%4): Master socket was unable to be created. WSASocket() returned: %6 . MessageId=0x3 Severity=Error Facility=WinSock SymbolicName=MSG_WS_CANTCONNECTMASTERSOCK Language=English %1 : %2 (%3,%4): Can't connect to local loopback on port %5. connect() returned: %6 . MessageId=0x4 Severity=Error Facility=WinSock SymbolicName=MSG_WS_PORTOUTOFRANGE Language=English %1 : %2 (%3,%4): Local loopback port out-of-range at "%5". Must be greater than zero and less than 65536. . MessageId=0x1 Severity=Error Facility=DbgTrap SymbolicName=MSG_DT_CANTGETCONSOLEHANDLE Language=English %1 : %2 (%3,%4): Can't open the console handle. CreateFile("%5") returned: %6 . MessageId=0x2 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_UNEXPECTEDDBGEVENT Language=English %1 : %2 (%3,%4): Unexpected debug event for %5 . MessageId=0x3 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_EXCEPTIONDBGEVENT Language=English %1 : %2 (%3,%4): Exception code is %5 . MessageId=0x4 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_NOVIRT Language=English %1 : %2 (%3,%4): Unable to find entry for VirtualAlloc . MessageId=0x5 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_CANTREADSPMEM Language=English %1 : %2 (%3,%4): Error reading from subprocess memory . MessageId=0x6 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_CANTWRITESPMEM Language=English %1 : %2 (%3,%4): Error writing to subprocess memory . MessageId=0x7 Severity=Warning Facility=DbgTrap SymbolicName=MSG_DT_SCREENBUF Language=English %1 : %2 (%3,%4): Call to GetConsoleScreenBufferInfo() failed with %5, %6 . |
Added win/tests/all.
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # This file contains a top-level script to run all of the Tcl # tests. Execute it by invoking "source all" when running tclTest # in this directory. # # SCCS: @(#) all 1.8 97/08/01 11:07:14 #package require expect load expect52.dll if {$tcl_platform(os) == "Win32s"} { set files [glob *.tes] } else { set files [glob *.test] } foreach i [lsort $files] { if [string match l.*.test $i] { # This is an SCCS lock file; ignore it. continue } puts stdout $i if [catch {source $i} msg] { puts $msg } } |
Added win/tests/basic.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | # Commands covered: test basic expect functionality # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/basic.test,v 1.8 1998/08/28 22:29:51 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} if {0} { test basic-1.0 {basic tests} { if [catch { set spawn_id exp_user send -null } msg] {set msg} else {set ok 1} } {1} test basic-1.1 {basic tests} { if [catch { spawn ftp set id1 $spawn_id spawn ftp set id2 $spawn_id close -i $id1 close -i $id2 wait -i $id2 wait -i $id1 } msg] {set msg} else {set ok 1} } {1} test basic-1.2 {test of any_spawn_id} { set timeout -1 spawn ftp set id1 $spawn_id spawn ftp set id2 $spawn_id set ok 0 expect { -i "$id1" crap1 {} -i "$any_spawn_id" "ftp> " {set ok 1} } close -i $id1 close -i $id2 wait -i $id1 wait -i $id2 set ok } {1} test basic-1.3 {test of spawn -open} { if [catch { set f [open "defs"] spawn -open $f set id1 $spawn_id close -i $id1 catch {close $f} errmsg if {! [regexp "can not find channel *" $errmsg]} { error "spawn -open not working properly" } } msg] {set msg} else {set ok 1} } {1} test basic-1.4 {test of spawn -leaveopen} { if [catch { set f [open "defs"] spawn -leaveopen $f set id1 $spawn_id spawn -leaveopen $f set id2 $spawn_id close -i $id1 close $f } msg] {set msg} else {set ok 1} } {1} test basic-1.5 {test of expect eof} { if [catch { spawn ipconfig.exe expect { "crap" {puts crap; error "unexpected crap"} timeout {puts timeout; error "unexpected timeout"} eof {set ok 1} } # No close since we saw an eof wait } msg] {set msg} else {set ok 1} } {1} test basic-1.6 {test of expect timeout} { if [catch { set timeout 3 spawn ftp.exe expect { "crap" {error "unexpected crap"} eof {error "unexpected eof"} timeout {set ok 1} } close wait } msg] {set msg} else {set ok 1} } {1} test basic-1.7 {test of spawn -pipes} { if [catch { set timeout 3 spawn -pipes ftp.exe expect { "ftp> " {set ok 1} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } close wait } msg] {set msg} else {set ok 1} } {1} test basic-1.8 {test of spawn -pipes} { # exp_internal -f dbg.log 1 if [catch { set timeout 3 spawn -pipes testa2.exe expect { -re "^Msg1 to stderr\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg1 to stderr" } timeout {error "unexpected timeout: looking for Msg1 to stderr" } eof {error "unexpected eof: looking for Msg1 to stderr" } } expect { -re "^Msg1 to stdout\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg1 to stdout" } timeout {error "unexpected timeout: looking for Msg1 to stdout" } eof {error "unexpected eof: looking for Msg1 to stdout" } } expect { -re "^Msg2 to stdout\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg2 to stdout" } timeout {error "unexpected timeout: looking for Msg2 to stdout" } eof {error "unexpected eof: looking for Msg2 to stdout" } } expect { -re "^Msg2 to stderr\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg2 to stderr" } timeout {error "unexpected timeout: looking for Msg2 to stderr" } eof {error "unexpected eof: looking for Msg2 to stderr" } } expect { -re "^Msg3 to stderr\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg3 to stderr" } timeout {error "unexpected timeout: looking for Msg3 to stderr" } eof {error "unexpected eof: looking for Msg3 to stderr" } } expect { -re "^Msg3 to stdout\r\n" {set ok 1} default {error "unexpected bad match: looking for Msg3 to stdout" } timeout {error "unexpected timeout: looking for Msg3 to stdout" } eof {error "unexpected eof: looking for Msg3 to stdout" } } expect { eof {set ok 1} timeout {error "unexpected timeout: looking for eof" } } wait } msg] {set msg} else {set ok 1} } {1} test basic-1.9 {test send_user} { if [catch { send_user "" } msg] {set msg} else {set ok 1} } {1} test basic-1.10 {send -i} { if [catch { spawn ftp set id1 $spawn_id spawn ftp set id2 $spawn_id send -i $id1 "nothing\r" send -i $id2 "something\r" close -i $id1 close -i $id2 wait -i $id2 wait -i $id1 } msg] {set msg} else {set ok 1} } {1} } test basic-1.11 {test of spawn -socket} { if [catch { set timeout 3 spawn -socket ftp.exe expect { "ftp> " {set ok 1} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} |
Added win/tests/cmd.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | # Commands covered: Subprocess' offspring handling # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/cmd.test,v 1.1 1997/09/05 05:30:39 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} test cmd-1.1 {tests of spawned processes' offspring} { if [catch { set timeout 10 spawn cmd.exe expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } {1} test cmd-1.2 {tests of multiple descendents} { if [catch { set timeout 10 spawn cmd.exe expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "net\r" expect { "VIEW " {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "net\r" expect { "VIEW " {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } {1} test cmd-1.3 {tests of multiple descendents} { if [catch { set timeout 10 spawn cmd.exe expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "cmd\r" expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "cmd\r" expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "exit\r" expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "exit\r" expect { "tests>" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "exit\r" expect { eof {} "tests>" {error "unexpected prompt"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } {1} |
Added win/tests/crash.tcl.
> > > > | 1 2 3 4 | set exp_nt_debug 1 spawn ../testcrash.exe set x 1 vwait x |
Added win/tests/crash.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # Commands covered: test traceback facility # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/crash.test,v 1.2 1998/09/17 21:21:48 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} # Expected output: #Backtrace for testcrash.exe #------------------------------------- #testcrash.exe 00401013 crash+13 #testcrash.exe 0040103e subroutine4+17 #testcrash.exe 00401062 subroutine3+17 #testcrash.exe 00401086 subroutine2+17 #testcrash.exe 004010aa subroutine1+17 #testcrash.exe 004010c9 main+12 #testcrash.exe 00401dfc mainCRTStartup+FC #kernel32.dbg 77f1afc1 GetProcessPriorityBoost+117 # Note: this test will fail if testcrash.exe was not compiled with # debugging enabled. # XXX: This test is not yet correct or working. test crash-1.0 {subprocess crash tests} { if [catch { # spawn tclsh80.exe crash.tcl spawn ../testcrash.exe if {0} { expect { "Backtrace for" {} {set ok 1} timeout {error "Unexpected timeout 1"} eof {error "Unexpected eof 1"} } expect { " crash" {} {set ok 1} timeout {error "Unexpected timeout 2"} eof {error "Unexpected eof 2"} } expect { " subroutine4" {} {set ok 1} timeout {error "Unexpected timeout 3"} eof {error "Unexpected eof 3"} } expect { " subroutine3" {} {set ok 1} timeout {error "Unexpected timeout 4"} eof {error "Unexpected eof 4"} } expect { " subroutine2" {} {set ok 1} timeout {error "Unexpected timeout 5"} eof {error "Unexpected eof 5"} } expect { " subroutine1" {} {set ok 1} timeout {error "Unexpected timeout 6"} eof {error "Unexpected eof 6"} } } catch { kill } catch { close } catch { wait } } msg] {set msg} else {set ok 1} } {1} |
Added win/tests/defs.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | # This file contains support code for the Tcl test suite. It is # normally sourced by the individual files in the test suite before # they run their tests. This improved approach to testing was designed # and initially implemented by Mary Ann May-Pumphrey of Sun Microsystems. # # Copyright (c) 1990-1994 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # SCCS: @(#) defs 1.60 97/08/13 18:10:19 log_user 0 if ![info exists exp_nt_debug] { set exp_nt_debug 1 } if ![info exists VERBOSE] { set VERBOSE 0 } if ![info exists TESTS] { set TESTS {} } # If tests are being run as root, issue a warning message and set a # variable to prevent some tests from running at all. set user {} if {$tcl_platform(platform) == "unix"} { catch {set user [exec whoami]} if {$user == ""} { catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user} } if {$user == ""} {set user root} if {$user == "root"} { puts stdout "Warning: you're executing as root. I'll have to" puts stdout "skip some of the tests, since they'll fail as root." set testConfig(root) 1 } } # Some of the tests don't work on some system configurations due to # differences in word length, file system configuration, etc. In order # to prevent false alarms, these tests are generally only run in the # master development directory for Tcl. The presence of a file # "doAllTests" in this directory is used to indicate that the non-portable # tests should be run. # If there is no "memory" command (because memory debugging isn't # enabled), generate a dummy command that does nothing. if {[info commands memory] == ""} { proc memory args {} } # Check configuration information that will determine which tests # to run. To do this, create an array testConfig. Each element # has a 0 or 1 value, and the following elements are defined: # unixOnly - 1 means this is a UNIX platform, so it's OK # to run tests that only work under UNIX. # macOnly - 1 means this is a Mac platform, so it's OK # to run tests that only work on Macs. # pcOnly - 1 means this is a PC platform, so it's OK to # run tests that only work on PCs. # unixOrPc - 1 means this is a UNIX or PC platform. # macOrPc - 1 means this is a Mac or PC platform. # macOrUnix - 1 means this is a Mac or UNIX platform. # nonPortable - 1 means this the tests are being running in # the master Tcl/Tk development environment; # Some tests are inherently non-portable because # they depend on things like word length, file system # configuration, window manager, etc. These tests # are only run in the main Tcl development directory # where the configuration is well known. The presence # of the file "doAllTests" in this directory indicates # that it is safe to run non-portable tests. # knownBug - The test is known to fail and the bug is not yet # fixed. The test will be run only if the file # "doBuggyTests" exists (intended for Tcl dev. group # internal use only). # tempNotPc - The inverse of pcOnly. This flag is used to # temporarily disable a test. # tempNotMac - The inverse of macOnly. This flag is used to # temporarily disable a test. # nonBlockFiles - 1 means this platform supports setting files into # nonblocking mode. # asyncPipeClose- 1 means this platform supports async flush and # async close on a pipe. # unixExecs - 1 means this machine has commands such as 'cat', # 'echo' etc available. # notIfCompiled - 1 means this that it is safe to run tests that # might fail if the bytecode compiler is used. This # element is set 1 if the file "doAllTests" exists in # this directory. Normally, this element is 0 so that # tests that fail with the bytecode compiler are # skipped. As of 11/2/96 these are the history tests # since they depend on accurate source location # information. catch {unset testConfig} if {$tcl_platform(platform) == "unix"} { set testConfig(unixOnly) 1 set testConfig(tempNotPc) 1 set testConfig(tempNotMac) 1 } else { set testConfig(unixOnly) 0 } if {$tcl_platform(platform) == "macintosh"} { set testConfig(tempNotPc) 1 set testConfig(macOnly) 1 } else { set testConfig(macOnly) 0 } if {$tcl_platform(platform) == "windows"} { set testConfig(tempNotMac) 1 set testConfig(pcOnly) 1 } else { set testConfig(pcOnly) 0 } set testConfig(unixOrPc) [expr $testConfig(unixOnly) || $testConfig(pcOnly)] set testConfig(macOrPc) [expr $testConfig(macOnly) || $testConfig(pcOnly)] set testConfig(macOrUnix) [expr $testConfig(macOnly) || $testConfig(unixOnly)] set testConfig(nonPortable) [expr [file exists doAllTests] || [file exists doAllTe]] set testConfig(knownBug) [expr [file exists doBuggyTests] || [file exists doBuggyT]] set testConfig(notIfCompiled) [file exists doAllCompilerTests] set testConfig(unix) $testConfig(unixOnly) set testConfig(mac) $testConfig(macOnly) set testConfig(pc) $testConfig(pcOnly) set testConfig(nt) [expr {$tcl_platform(os) == "Windows NT"}] set testConfig(95) [expr {$tcl_platform(os) == "Windows 95"}] set testConfig(win32s) [expr {$tcl_platform(os) == "Win32s"}] # The following config switches are used to mark tests that crash on # certain platforms, so that they can be reactivated again when the # underlying problem is fixed. set testConfig(pcCrash) $testConfig(macOrUnix) set testConfig(macCrash) $testConfig(unixOrPc) set testConfig(unixCrash) $testConfig(macOrPc) if {[catch {set f [open defs r]}]} { set testConfig(nonBlockFiles) 1 } else { if {[expr [catch {fconfigure $f -blocking off}]] == 0} { set testConfig(nonBlockFiles) 1 } else { set testConfig(nonBlockFiles) 0 } close $f } trace variable testConfig r safeFetch proc safeFetch {n1 n2 op} { global testConfig if {($n2 != {}) && ([info exists testConfig($n2)] == 0)} { set testConfig($n2) 0 } } # Test for SCO Unix - cannot run async flushing tests because a potential # problem with select is apparently interfering. (Mark Diekhans). if {$tcl_platform(platform) == "unix"} { if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} { set testConfig(asyncPipeClose) 0 } else { set testConfig(asyncPipeClose) 1 } } else { set testConfig(asyncPipeClose) 1 } # Test to see if execed commands such as cat, echo, rm and so forth are # present on this machine. set testConfig(unixExecs) 1 if {$tcl_platform(platform) == "macintosh"} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && ($tcl_platform(platform) == "windows")} { if {[catch {exec cat defs}] == 1} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && ([catch {exec echo hello}] == 1)} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && \ ([catch {exec sh -c echo hello}] == 1)} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && ([catch {exec wc defs}] == 1)} { set testConfig(unixExecs) 0 } if {$testConfig(unixExecs) == 1} { exec echo hello > removeMe if {[catch {exec rm removeMe}] == 1} { set testConfig(unixExecs) 0 } } if {($testConfig(unixExecs) == 1) && ([catch {exec sleep 1}] == 1)} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && \ ([catch {exec fgrep unixExecs defs}] == 1)} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && ([catch {exec ps}] == 1)} { set testConfig(unixExecs) 0 } if {($testConfig(unixExecs) == 1) && \ ([catch {exec echo abc > removeMe}] == 0) && \ ([catch {exec chmod 644 removeMe}] == 1) && \ ([catch {exec rm removeMe}] == 0)} { set testConfig(unixExecs) 0 } else { catch {exec rm -f removeMe} } if {($testConfig(unixExecs) == 1) && \ ([catch {exec mkdir removeMe}] == 1)} { set testConfig(unixExecs) 0 } else { catch {exec rm -r removeMe} } if {$testConfig(unixExecs) == 0} { puts stdout "Warning: Unix-style executables are not available, so" puts stdout "some tests will be skipped." } } proc print_verbose {name description constraints script code answer} { puts stdout "\n" if {[string length $constraints]} { puts stdout "==== $name $description\t--- ($constraints) ---" } else { puts stdout "==== $name $description" } puts stdout "==== Contents of test case:" puts stdout "$script" if {$code != 0} { if {$code == 1} { puts stdout "==== Test generated error:" puts stdout $answer } elseif {$code == 2} { puts stdout "==== Test generated return exception; result was:" puts stdout $answer } elseif {$code == 3} { puts stdout "==== Test generated break exception" } elseif {$code == 4} { puts stdout "==== Test generated continue exception" } else { puts stdout "==== Test generated exception $code; message was:" puts stdout $answer } } else { puts stdout "==== Result was:" puts stdout "$answer" } } # test -- # This procedure runs a test and prints an error message if the # test fails. If VERBOSE has been set, it also prints a message # even if the test succeeds. The test will be skipped if it # doesn't match the TESTS variable, or if one of the elements # of "constraints" turns out not to be true. # # Arguments: # name - Name of test, in the form foo-1.2. # description - Short textual description of the test, to # help humans understand what it does. # constraints - A list of one or more keywords, each of # which must be the name of an element in # the array "testConfig". If any of these # elements is zero, the test is skipped. # This argument may be omitted. # script - Script to run to carry out the test. It must # return a result that can be checked for # correctness. # answer - Expected result from script. proc test {name description script answer args} { global VERBOSE TESTS testConfig if {[string compare $TESTS ""] != 0} then { set ok 0 foreach test $TESTS { if [string match $test $name] then { set ok 1 break } } if !$ok then return } set i [llength $args] if {$i == 0} { set constraints {} } elseif {$i == 1} { # "constraints" argument exists; shuffle arguments down, then # make sure that the constraints are satisfied. set constraints $script set script $answer set answer [lindex $args 0] set doTest 0 if {[string match {*[$\[]*} $constraints] != 0} { # full expression, e.g. {$foo > [info tclversion]} catch {set doTest [uplevel #0 expr [list $constraints]]} msg } elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} { # something like {a || b} should be turned into # $testConfig(a) || $testConfig(b). regsub -all {[.a-zA-Z0-9]+} $constraints {$testConfig(&)} c catch {set doTest [eval expr $c]} } else { # just simple constraints such as {unixOnly fonts}. set doTest 1 foreach constraint $constraints { if {![info exists testConfig($constraint)] || !$testConfig($constraint)} { set doTest 0 break } } } if {$doTest == 0} { if $VERBOSE then { puts stdout "++++ $name SKIPPED: $constraints" } return } } else { error "wrong # args: must be \"test name description ?constraints? script answer\"" } memory tag $name set code [catch {uplevel $script} result] if {$code != 0} { print_verbose $name $description $constraints $script \ $code $result } elseif {[string compare $result $answer] == 0} then { if $VERBOSE then { if {$VERBOSE > 0} { print_verbose $name $description $constraints $script \ $code $result } if {$VERBOSE != -2} { puts stdout "++++ $name PASSED" } } } else { print_verbose $name $description $constraints $script \ $code $result puts stdout "---- Result should have been:" puts stdout "$answer" puts stdout "---- $name FAILED" } } proc dotests {file args} { global TESTS set savedTests $TESTS set TESTS $args source $file set TESTS $savedTests } proc normalizeMsg {msg} { regsub "\n$" [string tolower $msg] "" msg regsub -all "\n\n" $msg "\n" msg regsub -all "\n\}" $msg "\}" msg return $msg } proc makeFile {contents name} { set fd [open $name w] fconfigure $fd -translation lf if {[string index $contents [expr [string length $contents] - 1]] == "\n"} { puts -nonewline $fd $contents } else { puts $fd $contents } close $fd } proc removeFile {name} { file delete $name } proc makeDirectory {name} { file mkdir $name } proc removeDirectory {name} { file delete -force $name } proc viewFile {name} { global tcl_platform testConfig if {($tcl_platform(platform) == "macintosh") || \ ($testConfig(unixExecs) == 0)} { set f [open $name] set data [read -nonewline $f] close $f return $data } else { exec cat $name } } # Locate tcltest executable set tcltest [info nameofexecutable] if {$tcltest == "{}"} { set tcltest {} puts "Unable to find tcltest executable, multiple process tests will fail." } if {$tcl_platform(os) != "Win32s"} { # Don't even try running another copy of tcltest under win32s, or you # get an error dialog about multiple instances. catch { file delete -force tmp set f [open tmp w] puts $f { exit } close $f set f [open "|[list $tcltest tmp]" r] close $f set testConfig(stdio) 1 } } #if {($tcl_platform(platform) == "windows") && ($testConfig(stdio) == 0)} { # puts "(will skip tests that redirect stdio of exec'd 32-bit applications)" #} catch {socket} msg set testConfig(socket) [expr {$msg != "sockets are not available on this system"}] if {$testConfig(socket) == 0} { puts "(will skip tests that use sockets)" } |
Added win/tests/emacs.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | # Commands covered: testing interaction with console based version of emacs # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/emacs.test,v 1.2 1998/08/28 23:14:32 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} test emacs-1.1 {emacs tests} { set ok 1 if [catch { spawn emacs -nw expect { "latest version" {} eof {error "unexpected eof: did not see latest version"} timeout {error "unexpected timeout: did not see latest version"} } # C-x C-f send "\030\006" expect { "tests" {} eof {error "unexpected eof: did not see tests"} timeout {error "unexpected timeout: did not see tests"} } # C-g send "\007" expect { "Quit" {} eof {error "unexpected eof: did not see Quit"} timeout {error "unexpected timeout: did not see Quit"} } # C-x C-c send "\030\003" } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} # exp_internal -f dbg.log 1 test emacs-1.2 {emacs tests} { set ok 1 if [catch { spawn emacs -nw send "\021"; send -null for {set i 1} {$i <= 26} {incr i} { set s [format "%03o" $i] send "\021$s" } expect { {\^@\^A\^B\^C\^D\^E\^F\^G\^H} {} eof {error "unexpected timeout: did not see ^@^A^B^C^D^E^F^G^H"} timeout {set saw [expect *]; error "unexpected eof: did not see ^@^A^B^C^D^E^F^G^H but saw $saw"} } expect { {\^K\^L\^M\^N\^O\^P\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z} {} eof {error "unexpected eof: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} timeout {error "unexpected timeout: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} } } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} test emacs-1.3 {emacs tests} { set ok 1 if [catch { spawn -socket emacs -nw send "\021"; send -null for {set i 1} {$i <= 26} {incr i} { set s [format "%03o" $i] send "\021$s" } expect { {\^@\^A\^B\^C\^D\^E\^F\^G\^H} {} eof {error "unexpected timeout: did not see ^@^A^B^C^D^E^F^G^H"} timeout {set saw [expect *]; error "unexpected eof: did not see ^@^A^B^C^D^E^F^G^H but saw $saw"} } expect { {\^K\^L\^M\^N\^O\^P\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z} {} eof {error "unexpected eof: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} timeout {error "unexpected timeout: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} } close wait } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} # Emacs seems to mess up our echo stty -echo stty echo |
Added win/tests/etest.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | #package require expect load expect52.dll Expect # For now, have consoles visible set exp_nt_debug 1 proc testchars {} { send "aAbBcCdDeEfFgG\r" send "1234567890\r" send "ls !@#\$%^&*()\r" send "ls abcdefghijklmnopqrstuvwxyz\r" send "ls ABCDEFGHIJKLMNOPQRSTUVWXYZ\r" send "ls ~\`!1@2#3\$4%5^6&7*8(9)0_-+=|\\\r" set z [format "%c" 26] send "ls $z\r" send "\[\{\]\};:\'\",<.>/?\r" } # The next bit of code doesn't seem to work in a procedure.. # Probably need to be setting some value globally. proc zeego {} { # set timeout -1 # set timeout 10000 global spawn_id spawn ftp puts "spawn_id=$spawn_id" expect "ftp> " send "open zeego\r" expect "(none)):" send "test\r" expect "Password:" send "testPasswd\r" expect "logged in." # The following line is wrong on purpose # expect "logged in>" expect "ftp> " send "ls\r" expect "ftp> " } # The next bit of code doesn't seem to work in a procedure.. # Probably need to be setting some value globally. proc pipe-zeego {} { # set timeout -1 # set timeout 10000 global spawn_id spawn -pipes ftp puts "spawn_id=$spawn_id" expect "ftp> " send "open zeego\r" expect "(none)):" send "test\r" expect "Password:" send "testPasswd\r" expect "logged in." # The following line is wrong on purpose # expect "logged in>" expect "ftp> " send "ls\r" expect "ftp> " } proc socket-zeego {} { # set timeout -1 # set timeout 10000 global spawn_id spawn -socket ftp puts "spawn_id=$spawn_id" expect "ftp> " send "open zeego\r" expect "(none)):" send "test\r" expect "Password:" send "testPasswd\r" expect "logged in." # The following line is wrong on purpose # expect "logged in>" expect "ftp> " send "ls\r" expect "ftp> " } proc testany {} { global id1 id2 any_spawn_id set timeout -1 spawn ftp set id1 $spawn_id spawn ftp set id2 $spawn_id # -i "$id2" crap2 expect { -i "$id1" crap1 {puts "crap1"} -i "$any_spawn_id" "ftp> " {puts "found ftp>"} } } proc test-open {} { global id1 id2 f set f [open "d:/mksnt/mksnt/ls.exe"] spawn -open $f set id1 $spawn_id spawn -open $f set id2 $spawn_id } proc test-telnet {} { set timeout 1000000 global id1 spawn telnet expect "telnet>" send "open zeego\r" expect "login:" send "test\r" expect "Password:" send "testPasswd\r" expect "zeego:" send "ls\r" expect "zeego:" set id1 $spawn_id } proc traptest {} { global trapcount set trapcount 0 proc trapped {} { global trapcount incr trapcount if {$trapcount == 5} { send_user "bye bye" exit } } trap { puts "Caught SIGINT" trapped } SIGINT # Ctrl-Break on Windows NT trap { puts "Caught SIGQUIT" trapped } SIGQUIT trap { puts "Caught SIGTERM" trapped } SIGTERM trap { puts "Caught SIGABRT" trapped } SIGABRT global x set x 1 vwait x } proc testkill2 {} { global spawn_id set exp_nt_debug 1 spawn ftp puts "spawn_id=$spawn_id" puts "Trying to kill ftp with a Ctrl-C" kill 2 puts "spawn_id=$spawn_id" } proc testkill3 {} { global spawn_id set exp_nt_debug 1 spawn ftp puts "spawn_id=$spawn_id" puts "Trying to kill ftp with a Ctrl-Break" kill 3 puts "spawn_id=$spawn_id" } proc subslave {} { global spawn_id spawn cmd /c d:\\mksnt\\mksnt\\ls.exe } # Bogus commands run under cmd are causing problems right now proc subslave1 {} { global spawn_id spawn cmd /c ls } # XXX: I think there is a bug when spawn_id is not set as global. # That needs to be tested. proc cmdtest1 {} { global spawn_id spawn cmd expect crap } proc cmdtest2 {} { global spawn_id exp_internal -f dbg.log 1 spawn cmd send "ls\r" # The last part of this goes into a busy wait. Find out why. after 6000 expect crap # This second ls illustrates a problem. Not all of the data is # collected. This seems to be a problem in Tcl core. PipeInputProc # returns all the data, but when it goes through the translation code, # it doesn't all come out in a timely fashion. send "ls\r" after 6000 expect crap } proc cmdtest3 {} { global spawn_id exp_internal -f dbg.log 1 spawn cmd # Run ls and wait until it should have completed send "ls\r" after 6000 set ok 0 expect { -re crap {} timeout { set ok 1 } } expect * puts "Saw: $expect_out(buffer)" # This second ls illustrates a problem. Not all of the data is # collected. This seems to be a problem in Tcl core. PipeInputProc # returns all the data, but when it goes through the translation code, # it doesn't all come out in a timely fashion. send "ls\r" after 6000 set ok 0 expect { -re crap {} timeout { set ok 1 } } expect * puts "Saw: $expect_out(buffer)" } proc cmdtest4 {} { spawn cmd expect crap } proc usertest1 {} { set timeout 1000 puts "Please enter a string" expect_user -re "(.*)\n" puts "You entered: $expect_out(buffer)" } # Compare the execution speed between the first zeego run and the # second zeego run. There are lots of callbacks to ExpPairReadable # going on. proc busytest1 {} { global spawn_id zeego close wait puts "" puts "" usertest1 zeego close wait } proc getpass {} { set oldmode [stty -echo -raw] set timeout -1 send_user "Password: " expect_user -re "(.*)\n" send_user "\n" puts "Your password was: $expect_out(1,string)\n" eval stty $oldmode } proc eoftest {} { spawn cmd.exe /c echo yes set timeout -1 expect { eof {send_user "Saw eof"} } } proc nettest {} { spawn net.exe expect VIEW } proc calctest {} { exec echo hello | testcalc.exe } proc serialtest {} { # exp_internal -f dbg.log 0 set exp_nt_debug 1 global serid serfile global spawn_id; set f [open com1: w+] set setfile $f fconfigure $f -blocking 0 -buffering none -translation binary if [catch { set timeout 3 spawn -open $f set serid $spawn_id puts "Serial id: $serid" send -i $serid "test\r" puts "*********** Debug A ***********" expect { "Password" {send "testPasswd\r"} eof {error "Premature EOF 0"} timeout {puts "Timeout 0"} } puts "*********** Debug B ***********" expect { "zeego:" {} eof {error "Premature EOF 1"} timeout {puts "Timeout 1"} } set timeout 60 send "\\ls\r" puts "*********** Debug C ***********" expect { "zeego:" {} eof {error "Premature EOF 2"} timeout {puts "Timeout 2"} } send "cd /usr/bin\r" puts "*********** Debug D ***********" expect { "zeego:" {} eof {error "Premature EOF 3"} } send "\\ls -l\r" puts "*********** Debug E ***********" expect { "zeego:" {} eof {error "Premature EOF 4"} } } msg] { close $serid put "Error: $msg" } } proc modemtest {} { exp_internal -f dbg.log 1 set timeout 10000 set exp_nt_debug 1 global serid; global spawn_id; set f [open com2: w+] fconfigure $f -blocking 0 -buffering none -translation binary if [catch { spawn -open $f set serid $spawn_id send "AT\r" expect { timeout {error "Timeout 1"} "OK" {} } send "AT\r" expect { timeout {error "Timeout 1"} "OK" {} } } msg] { close $serid puts "Error: $msg" } } proc consoletest {} { global x fileevent stdin readable {gets stdin line; puts "Read: $line"} set x 1 vwait x } proc crashtest {} { set exp_nt_debug 1 spawn testcrash.exe } proc emacstest {opt} { set exp_nt_debug 1 eval "spawn $opt emacs -nw" send "\021"; send -null for {set i 1} {$i <= 26} {incr i} { set s [format "%03o" $i] send "\021$s" } expect { {\^@\^A\^B\^C\^D\^E\^F\^G\^H} {} eof {error "unexpected eof: did not see ^@^A^B^C^D^E^F^G^H"} timeout {set saw [expect *]; error "unexpected timeout: did not see ^@^A^B^C^D^E^F^G^H but saw $saw"} } expect { {\^K\^L\^M\^N\^O\^P\^Q\^R\^S\^T\^U\^V\^W\^X\^Y\^Z} {} eof {error "unexpected eof: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} timeout {error "unexpected timeout: did not see ^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z"} } send "testing 1 2 3 4 5" } proc emacs1 {} { emacstest -socket } proc emacs2 {} { emacstest {} } proc k95 {} { set timeout 30 global spawn_id exp_internal -f dbg.log 0 log_user 0 spawn k95beta.exe expect { "K-95" {set ok 1} eof {error "Unexpected eof"} timeout {error "Unexpected timeout: did not see k-95"} } send "telnet zeego\r" expect { "perspecta" {set ok 1} eof {error "Unexpected eof"} timeout {error "Unexpected timeout: did not see perspecta"} } } proc k95loop {} { set timeout 30000 global spawn_id while {1} { catch {exec rm -f dbg.log} exp_internal -f dbg.log 0 log_user 0 spawn k95beta.exe expect { "K-95" {set ok 1} eof {error "Unexpected eof"} timeout {error "Unexpected timeout: did not see k-95"} } send "telnet zeego\r" expect { "perspecta" {set ok 1} eof {error "Unexpected eof"} timeout {error "Unexpected timeout: did not see perspecta"} } close wait } } #zeego #spawn d:/mksnt/mksnt/ls.exe #spawn testcat #testany #test-open |
Added win/tests/ftp.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | # Commands covered: spawn, expect interacting with ftp # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/ftp.test,v 1.1 1997/09/05 05:30:39 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} # Basic ftp tests. test ftp-1.1 {basic ftp tests} { if [catch { set timeout 100 spawn ftp expect { "ftp> " {} eof {error "unable to spawn ftp"} timeout {error "no response seen from ftp"} } send "open tsx-11.mit.edu\r" expect { "(none)): " {} eof {error "unexpected eof"} timeout {error "timeout connecting to tsx-11.mit.edu"} } send "ftp\r" expect { "Password:" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "[email protected]\r" expect { "ftp> " {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } {1} |
Added win/tests/modemtest.exp.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # modemtest.exp # # Expect script to test modem with redirected handles. To be used # in conjunction with testmodem.exe load expect52.dll Expect send -i exp_tty "Modemtest 1\n" set timeout 10 send "AT\r" send -i exp_tty "Send AT\n" expect { "OK" {send -i exp_tty "Saw OK\n"} timeout {send -i exp_tty "Timed out waiting for OK\n"} } |
Added win/tests/pipe.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # Commands covered: Pipeline test for a previous race condition # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/pipe.test,v 1.2 1997/09/09 19:24:57 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} test pipe-1.1 {tests of pipes} { if [catch { for {set i 0} {$i < 20} {incr i} { set x [exec echo hello | testcalc.exe] if {$x == "calc: Unknown command: hello\ncalc: "} { set ok 1 } else { error "unexpected output from pipe: |$x|" } } } msg] {} else {set msg 1} set msg } {1} |
Added win/tests/script.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # Commands covered: shell script handling. # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/script.test,v 1.2 1997/09/09 19:24:58 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} # Basic scripting tests. test script-1.1 {basic shell script tests} { catch { set msg [exec testtcl] } msg if [regexp "This is Tcl 8.0" $msg] { set ok 1 } else { set msg } } {1} test script-1.2 {basic shell script tests} { catch { set msg [exec test.pl] } msg set msg } {This is perl. You will be assimilated.} test script-1.3 {basic shell script tests} { if [catch { spawn test.pl expect { "This is perl. You will be assimilated" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {set msg} else {set ok 1} } {1} |
Added win/tests/suite.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | load expect52.dll Expect proc zeego1 {} { global spawn_id global timeout spawn ftp puts "spawn_id=$spawn_id" expect "ftp> " send "open zeego\r" expect "(none)):" send "test\r" expect "for test." send "testPasswd\r" expect "logged in." # The following line is wrong on purpose # expect "logged in>" expect "ftp> " send "ls\r" expect "ftp> " } proc zeego2 {} { global timeout set timeout -1 zeego1 } proc zeego3 {} { global timeout set timeout 10000 zeego1 } proc closetest {} { global spawn_id puts "closetest 1" set f [open "|d:/mksnt/mksnt/ls.exe"] if {! [catch {close -i $f} msg]} { puts "close -i $f should have failed" } close puts "closetest 2" set f [open "|d:/mksnt/mksnt/ls.exe"] close $f puts "closetest 3" spawn ftp close -i $spawn_id puts "closetest 4" spawn ftp close $spawn_id puts "closetest 5" spawn ftp close puts "closetest 6" close -i stderr puts "closetest 7" close -i stdout puts "closetest 8" close -i stdin } proc test1 {} { for {set i 0} {$i < 5} {incr i} { global spawn_id zeego1 set id1 $spawn_id zeego2 set id2 $spawn_id zeego3 set id3 $spawn_id close close $id1 close -i $id2 } } closetest |
Added win/tests/telnet.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # Commands covered: spawn, expect interacting with BSD telnet port # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/telnet.test,v 1.2 1999/01/06 10:24:33 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} # Basic telnet tests. test telnet-1.1 {basic BSD telnet tests} { if [catch { set timeout 100 spawn telnet expect { "telnet> " {} eof {error "unable to spawn telnet"} timeout {error "no response seen from telnet"} } send "open quimby.cs.berkeley.edu\r" expect { "login: " {} eof {error "unexpected eof"} timeout {error "timeout connecting to odie.cs.berkeley.edu"} } send "bogus\r" expect { "Password:" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "none\r" expect { "Login incorrect" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } {1} |
Added win/tests/test.pl.
> > > | 1 2 3 | #! perl print "This is perl. You will be assimilated.\n"; |
Added win/tests/test_suite.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | proc runtest {version body answer} { global interactive if {$interactive} { puts -nonewline stdout "Run test $version? " gets stdin yn if {[string range $yn 0 1] == "n"} { return } } if [catch {set result [eval $body]} error] { global errorInfo puts " - expectnt test $version failed: $error $errorInfo" } elseif {[string compare $result $answer] != 0} { puts " - expectnt test $version failed" puts " Result was:" puts " --------------------------------------------------" puts " $result" puts " Result should have been:" puts " --------------------------------------------------" puts " $answer" puts "" } else { puts " + expectnt test $version succeeded" } } # XXX: Create a procedure to recursively delete a directory. #for {set run 1} {$run <= $runs} {incr run} { # puts "" # puts "Iteration #$run of $runs" #} # Tests using cmd runtest 1.0 { file spawn cmd send "dir\r" } |
Added win/tests/testa2.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Testcase a2 * * This testcase may depend on the behavior of a particular * C library. MSVCRT seems to buffer stderr, if it isn't * attached to a console. */ #include <windows.h> #include <stdio.h> main() { fprintf(stderr,"Msg1 to stderr\n"); fflush(stderr); fprintf(stdout,"Msg1 to stdout\n"); fflush(stdout); fprintf(stderr,"Msg2 to stderr\n"); fprintf(stdout,"Msg2 to stdout\n"); fflush(stdout); setbuf(stderr, 0); fprintf(stderr,"Msg3 to stderr\n"); fprintf(stdout,"Msg3 to stdout\n"); fflush(stdout); return 0; } |
Added win/tests/testcalc.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #include <ctype.h> #include <string.h> #include <stdio.h> #include "testcalc.h" extern int atoi(char *); static int words(); int split(line,words,nword) char *line; char **words; int nword; /* number of elements in words */ { int i; while(isspace(*line)) line++; if(*line == '\0') return(0); for(i = 0;i < nword;i++) { words[i] = line; while(*line != '\0' && !isspace(*line)) line++; if(*line == '\0') break; *line++ = '\0'; while(isspace(*line)) line++; } return(i); } int main() { char line[SIZE]; int nword; char *words[NWORD]; int val=65; while(printf("calc: "), fflush(stdout), fgets(line,SIZE,stdin) != NULL) { val++; if((nword = split(line,words,NWORD)) == 0) continue; if(strcmp(words[0],"add") == 0) { if(nword != 3) { printf("Usage: add #1 #2\n"); } else { printf("%d",atoi(words[1]) + atoi(words[2])); } } else if(strcmp(words[0],"multiply") == 0) { if(nword != 3) { printf("Usage: multiply #1 #2\n"); } else { int i1 = atoi(words[1]); printf("%d",i1*atoi(words[2])); } } else if(strcmp(words[0],"quit") == 0) { break; } else if(strcmp(words[0],"version") == 0) { printf("Version: %s",VERSION); } else { printf("Unknown command: %s",words[0]); } printf("\n"); } return(0); } |
Added win/tests/testcalc.h.
> > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* calc.h. Generated automatically by configure. */ /* * Check for headers */ #ifndef __CALC_H__ #define __CALC_H__ /* #undef HAVE_STDLIB_H */ /* * Check for functions */ #define HAVE_STRCMP 1 #define NWORD 10 #define SIZE 100 #define VERSION "1.0 Beta" #endif /* __CALC_H__ */ |
Added win/tests/testcat.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /* * The standard libraries startup code really seems to be messed up * when dealing with consoles. Depending on which version of the * standard library and which shell starts the program, behavior is * different. If I link it with msvcrt40d.dll and start it from * cmd.exe, it doesn't echo anything. If I link it with msvcrt.dll * and start it form cmd.exe, it does echo. If started from the Korn * shell, it never echos anything. If I can get it to work when linked * with msvcrt.dll, it will crash when linked with msvcrt40d.dll */ #include <windows.h> #include <stdio.h> extern void mainCRTStartup(); void main(int argc, char **argv) { size_t n = 0; char buffer[4096]; char *p; static int initialized = 0; if (! initialized) { printf("Initializing\n"); initialized = 1; FreeConsole(); AllocConsole(); mainCRTStartup(); printf("Initialized\n"); } #if 0 HANDLE in = GetStdHandle(STD_INPUT_HANDLE); HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); DWORD count; WriteFile(out, "WriteFile: Entering main\n", sizeof("Entering main\n"), &count, NULL); #endif printf("printf: Entering main\n"); fflush(stdout); do { p = fgets(buffer, sizeof(buffer)-1, stdin); if (p) { fputs(p, stdout); } } while (p); } void specialCRTStartup(void) { #if 0 HANDLE h = NULL, h1 = NULL, h2 = NULL, h3 = NULL; /* * Sleep for 30 seconds before allowing the normal initialization to * take place */ /* Sleep(30000); */ #if 1 h1 = GetStdHandle(STD_INPUT_HANDLE); if (h1 != INVALID_HANDLE_VALUE) { CloseHandle(h1); } h2 = GetStdHandle(STD_OUTPUT_HANDLE); if (h2 != INVALID_HANDLE_VALUE && h2 != h1) { CloseHandle(h2); } h3 = GetStdHandle(STD_ERROR_HANDLE); if (h3 != INVALID_HANDLE_VALUE && h3 != h2 && h3 != h1) { CloseHandle(h3); } #endif FreeConsole(); AllocConsole(); #if 0 h = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); SetConsoleActiveScreenBuffer(h); #endif #if 1 h = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); SetStdHandle(STD_INPUT_HANDLE, h); h = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); SetStdHandle(STD_OUTPUT_HANDLE, h); SetStdHandle(STD_ERROR_HANDLE, h); #endif #if 0 SetStdHandle(STD_INPUT_HANDLE, h); SetStdHandle(STD_OUTPUT_HANDLE, h); SetStdHandle(STD_ERROR_HANDLE, h); #endif #endif mainCRTStartup(); } |
Added win/tests/testcat.mak.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | # Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 !IF "$(CFG)" == "" CFG=testcat - Win32 Debug !MESSAGE No configuration specified. Defaulting to testcat - Win32 Debug. !ENDIF !IF "$(CFG)" != "testcat - Win32 Release" && "$(CFG)" !=\ "testcat - Win32 Debug" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE on this makefile !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "testcat.mak" CFG="testcat - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "testcat - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "testcat - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF ################################################################################ # Begin Project # PROP Target_Last_Scanned "testcat - Win32 Debug" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "testcat - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" OUTDIR=.\Release INTDIR=.\Release ALL : "$(OUTDIR)\testcat.exe" CLEAN : -@erase "$(INTDIR)\testcat.obj" -@erase "$(OUTDIR)\testcat.exe" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c # ADD CPP /nologo /MDd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c CPP_PROJ=/nologo /MDd /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)/testcat.pch" /YX /Fo"$(INTDIR)/" /c CPP_OBJS=.\Release/ CPP_SBRS=.\. # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo BSC32_FLAGS=/nologo /o"$(OUTDIR)/testcat.bsc" BSC32_SBRS= \ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"specialCRTStartup" /subsystem:console /machine:I386 LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ odbccp32.lib /nologo /entry:"specialCRTStartup" /subsystem:console\ /incremental:no /pdb:"$(OUTDIR)/testcat.pdb" /machine:I386\ /out:"$(OUTDIR)/testcat.exe" LINK32_OBJS= \ "$(INTDIR)\testcat.obj" "$(OUTDIR)\testcat.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << !ELSEIF "$(CFG)" == "testcat - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" OUTDIR=.\Debug INTDIR=.\Debug ALL : "$(OUTDIR)\testcat.exe" CLEAN : -@erase "$(INTDIR)\testcat.obj" -@erase "$(INTDIR)\vc40.idb" -@erase "$(INTDIR)\vc40.pdb" -@erase "$(OUTDIR)\testcat.exe" -@erase "$(OUTDIR)\testcat.ilk" -@erase "$(OUTDIR)\testcat.pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c # ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)/testcat.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c CPP_OBJS=.\Debug/ CPP_SBRS=.\. # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo BSC32_FLAGS=/nologo /o"$(OUTDIR)/testcat.bsc" BSC32_SBRS= \ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"specialCRTStartup" /subsystem:console /debug /machine:I386 LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ odbccp32.lib /nologo /entry:"specialCRTStartup" /subsystem:console\ /incremental:yes /pdb:"$(OUTDIR)/testcat.pdb" /debug /machine:I386\ /out:"$(OUTDIR)/testcat.exe" LINK32_OBJS= \ "$(INTDIR)\testcat.obj" "$(OUTDIR)\testcat.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << !ENDIF .c{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .cpp{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .cxx{$(CPP_OBJS)}.obj: $(CPP) $(CPP_PROJ) $< .c{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< .cpp{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< .cxx{$(CPP_SBRS)}.sbr: $(CPP) $(CPP_PROJ) $< ################################################################################ # Begin Target # Name "testcat - Win32 Release" # Name "testcat - Win32 Debug" !IF "$(CFG)" == "testcat - Win32 Release" !ELSEIF "$(CFG)" == "testcat - Win32 Debug" !ENDIF ################################################################################ # Begin Source File SOURCE=.\testcat.c "$(INTDIR)\testcat.obj" : $(SOURCE) "$(INTDIR)" # End Source File # End Target # End Project ################################################################################ |
Added win/tests/testconsout.c.
> > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <windows.h> #include <stdio.h> #include <stdlib.h> void specialCRTStartup() { HANDLE console; COORD coord; DWORD n; #define ESTR "String at x=1, y=2\n\nAfter two \\n's. Lots of additonal characters and stuff. Want to see what happens when we wrap" console = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); coord.X = 1; coord.Y = 5; WriteConsoleOutputCharacterA(console, ESTR, lstrlenA(ESTR), coord, &n); // Sleep(20000); } |
Added win/tests/testcrash.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* * testcrash.c * * This program is used to check stack tracebacks with Expect. * It purposely crashes with several frames on the stack. */ #include <stdio.h> int crash(int a, int b) { char *p = NULL; /* Crash occurs here */ *p = 0; return a*b; } int subroutine4(int a, int b) { return crash(a+1, b+2); } int subroutine3(int a, int b) { return subroutine4(a+1,b+2); } int subroutine2(int a, int b) { return subroutine3(a+1,b+2); } int subroutine1(int a, int b) { return subroutine2(a+1,b+2); } int main(int argc, char **argv) { return subroutine1(100,200); return 0; } |
Added win/tests/testmodem.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /* * testmodem.c * * Test of Expect's handling of redirected serial handles. * * Usage: testmodem comfile scriptname */ #include <windows.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { char *nativeName, *scriptName; HANDLE handle; DWORD accessMode, flags; COMMTIMEOUTS cto; DCB dcb; SECURITY_ATTRIBUTES sa; STARTUPINFO si; PROCESS_INFORMATION pi; BOOL b; char buffer[4096]; if (argc >= 2) { nativeName = argv[1]; } else { nativeName = "com2:"; } if (argc >= 3) { scriptName = argv[2]; } else { scriptName = "tests\\modemtest.exp"; } printf("Debug 1\n"); flags = GetFileAttributes(nativeName); if (flags == 0xFFFFFFFF) { flags = 0; } accessMode = (GENERIC_READ | GENERIC_WRITE); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; handle = CreateFile(nativeName, accessMode, 0, &sa, OPEN_EXISTING, flags | FILE_FLAG_OVERLAPPED, NULL); if (handle == INVALID_HANDLE_VALUE) { fprintf(stderr, "Unable to open %s, exiting...\n", nativeName); exit(1); } printf("Debug 2\n"); /* * FileInit the com port. */ SetCommMask(handle, EV_RXCHAR); SetupComm(handle, 4096, 4096); PurgeComm(handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); cto.ReadIntervalTimeout = MAXDWORD; cto.ReadTotalTimeoutMultiplier = 0; cto.ReadTotalTimeoutConstant = 0; cto.WriteTotalTimeoutMultiplier = 0; cto.WriteTotalTimeoutConstant = 0; SetCommTimeouts(handle, &cto); GetCommState(handle, &dcb); SetCommState(handle, &dcb); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = handle; si.hStdInput = handle; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); printf("Debug 3\n"); sprintf(buffer, "tclsh80.exe %s", scriptName); printf("Debug 4: Command Line=%s\n", buffer); b = CreateProcess(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); printf("Debug 5\n"); if (b == FALSE) { fprintf(stderr, "Unable to create process tclsh80.exe: error=%08x\n", GetLastError()); exit(1); } printf("Debug 6\n"); return 0; } |
Added win/tests/testsig.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <windows.h> #include <stdio.h> #include <signal.h> static BOOL WINAPI ctrlc(DWORD sig) { static char strc[] = "Received Ctrl-C\n"; static char strbrk[] = "Received Ctrl-Break\n"; DWORD written; if (sig == CTRL_C_EVENT) { WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strc, sizeof(strc), &written, NULL); // signal(SIGINT, SIG_DFL); // signal(SIGINT, ctrlc); return TRUE; } WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strbrk, sizeof(strbrk), &written, NULL); ExitProcess(1); return FALSE; } static void ctrlbreak(int sig) { printf("Received Ctrl-Break\n"); signal(SIGINT, ctrlbreak); } void main() { char buffer[1024]; SetConsoleCtrlHandler(ctrlc, TRUE); while (1) { gets(buffer); printf("|\n"); } Sleep(1000000); } |
Added win/tests/testtcl.
> > > | 1 2 3 | #! tclsh80 puts "This is Tcl 8.0" |
Added win/tests/testwprog.c.
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <windows.h> #include <stdio.h> int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpComdLine, int nCmdShow) { BOOL bRet; FILE *fp; Sleep(5000); bRet = AllocConsole(); fp = fopen("d:\\temp\\testwprog.log", "w+"); if (fp) { fprintf(fp, "Result from AllocConsole() was %s\n", bRet ? "TRUE" : "FALSE"); if (!bRet) { fprintf(fp, "Error was %d (0x%08x)\n", GetLastError(), GetLastError()); } } fclose(fp); return 0; } |
Added win/tests/testwstation.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | /* * testwstation.c * * Tests creation of a new Windows station and desktop. * */ #include <windows.h> #include <stdio.h> #include <string.h> int main(int argc, char **argv) { HWINSTA hStation; HDESK hDesk; BOOL bRet; UCHAR buf[1024]; DWORD need; STARTUPINFO si; PROCESS_INFORMATION pi; DWORD exitStatus; /* * Create a Windows station with all access attributes but ExitWindows */ hStation = CreateWindowStation(NULL, 0, WINSTA_ACCESSCLIPBOARD|WINSTA_ACCESSGLOBALATOMS| WINSTA_CREATEDESKTOP|WINSTA_ENUMDESKTOPS| WINSTA_ENUMERATE|WINSTA_READATTRIBUTES| WINSTA_READSCREEN|WINSTA_WRITEATTRIBUTES, NULL); if (hStation == NULL) { fprintf(stderr, "Unable to create new window station\n"); exit(1); } bRet = SetProcessWindowStation(hStation); if (!bRet) { fprintf(stderr, "Unable to get access to the new Windows station\n"); exit(1); } bRet = GetUserObjectInformation(hStation, UOI_NAME, buf, sizeof(buf), &need); if (!bRet) { fprintf(stderr, "Unable to find window station name\n"); exit(1); } printf("New window station: %s\n", buf); strcpy(buf, "ExpectDesktop"); hDesk = CreateDesktop(buf, NULL, NULL, 0, DESKTOP_CREATEMENU| // Required to create a menu on the desktop. DESKTOP_CREATEWINDOW| // Required to create a window on the desktop. DESKTOP_ENUMERATE| // Required for the desktop to be enumerated. DESKTOP_HOOKCONTROL| // Required to establish any of the window hooks. DESKTOP_JOURNALPLAYBACK|// Required to perform journal playback on the desktop. DESKTOP_JOURNALRECORD| // Required to perform journal recording on the desktop. DESKTOP_READOBJECTS| // Required to read objects on the desktop. DESKTOP_WRITEOBJECTS, // Required to write objects on the desktop. NULL); if (hDesk == NULL) { fprintf(stderr, "Unable to create new desktop\n"); exit(1); } si.cb = sizeof(si); si.lpReserved = NULL; si.lpDesktop = buf; si.lpTitle = NULL; si.dwFlags = 0; si.cbReserved2 = 0; si.lpReserved2 = NULL; #if 0 bRet = CreateProcess(NULL, "tclsh80.exe testwstation.tcl", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); if (!bRet) { fprintf(stderr, "Unable to create new subprocess\n"); exit(1); } #else bRet = CreateProcess(NULL, "testwprog.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (!bRet) { fprintf(stderr, "Unable to create new subprocess\n"); exit(1); } #endif /* * Wait for the subprocess to exit */ WaitForSingleObject(pi.hProcess, INFINITE); bRet = GetExitCodeProcess(pi.hProcess, &exitStatus); if (!bRet) { fprintf(stderr, "Unable to get exit code of subprocess\n"); exit(1); } printf("Subprocess has exited with status 0x%08x\n", exitStatus); /* * XXX: Have the subprocess create some file that we can than check the * results on if it succeeded */ return 0; } |
Added win/tests/testwstation.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | catch {file delete testwstation.debug} set f [open testwstation.debug w] puts $f starting close $f proc telnet-test {} { exp_internal -f testwstation.log 1 if [catch { set timeout 100 spawn telnet expect { "telnet> " {} eof {error "unable to spawn telnet"} timeout {error "no response seen from telnet"} } send "open odie.cs.berkeley.edu\r" expect { "login: " {} eof {error "unexpected eof"} timeout {error "timeout connecting to odie.cs.berkeley.edu"} } send "bogus\r" expect { "Password:" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } send "none\r" expect { "Login incorrect" {} eof {error "unexpected eof"} timeout {error "unexpected timeout"} } } msg] {} else {set msg 1} catch {close} catch {wait} set msg } telnet-test |
Added win/tests/trap.tcl.
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # # trap.tcl # # Used in conjunction with trap.test. This script traps # SIGINT and SIGQUIT # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/trap.tcl,v 1.1 1997/11/13 12:16:36 chaffee Exp $ trap { puts "Caught SIGINT" } SIGINT trap { puts "Caught SIGQUIT" } SIGQUIT set x 1 vwait x |
Added win/tests/trap.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # Commands covered: trap, kill # # This file contains a collection of tests for one or more of the Expect # command capabilities. Sourcing this file into Tcl runs the tests and # generates output for errors. No output means no errors were found. # # Copyright (c) 1997 Mitel, Inc. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/trap.test,v 1.2 1998/08/28 22:29:52 chaffee Exp $ if {[string compare test [info procs test]] == 1} then {source defs} catch {unset a} catch {unset x} # Basic trap tests. set timeout 10 test trap-1.1 {trap SIGQUIT} { if [catch { global ok set ok 0 spawn expect.exe trap.tcl # Wait for process to get started after 3000 kill 3 expect { "Caught SIGQUIT" {} timeout {error "Expect did not catch first SIGQUIT"} eof {error "Expect did not catch first SIGQUIT"} } kill 3 expect { "Caught SIGQUIT" {} timeout {error "Expect did not catch second SIGQUIT"} eof {error "Expect did not catch second SIGQUIT"} } kill 9 expect { eof {set ok 1} } } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} # There is a problem with DBG_CONTROL_EVENT not properly propagating # through the debugger. This seems to be an NT 4.0 problem, but it # may exist in other version of Windows NT. This test will fail. test trap-1.2 {trap SIGINT} { if [catch { global ok 0 spawn expect.exe trap.tcl # Wait for process to get started after 3000 kill 2 expect { "Caught SIGINT" {} timeout {error "Expect did not catch first SIGINT. This is a problem with Windows NT 4.0."} eof {error "Expect did not catch first SIGINT"} } kill 2 expect { "Caught SIGINT" {} timeout {error "Expect did not catch second SIGINT"} eof {error "Expect did not catch second SIGINT"} } kill 9 expect { eof {set ok 1} } } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} test trap-1.3 {trap SIGQUIT with spawned telnet} { if [catch { global ok set ok 0 spawn expect.exe trap2.tcl # Wait for the spawned telnet in trap2.tcl to get connected after 10000 kill 3 expect { "Caught SIGQUIT" {} timeout {error "Expect did not catch first SIGQUIT"} eof {error "Expect did not catch first SIGQUIT"} } # Make sure the telnet has closed after 5000 set ok 1 } msg] {} else {set msg $ok} catch {close} catch {wait} set msg } {1} |
Added win/tests/trap2.tcl.
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # # trap2.tcl # # Used in conjunction with trap.test. This script traps # SIGINT and SIGQUIT. # # RCS: $Header: /disk/3/CVSROOT/Mitel/expect/win/tests/trap2.tcl,v 1.2 1999/01/06 10:24:49 chaffee Exp $ set exp_nt_debug 1 spawn telnet quimby.cs.berkeley.edu trap { puts "Caught SIGINT" } SIGINT trap { puts "Caught SIGQUIT" close } SIGQUIT set x 1 vwait x |
Added win/winDllMain.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | /* ---------------------------------------------------------------------------- * winDllMain.h -- * * entry-point for windows. * * ---------------------------------------------------------------------------- * * Written by: Don Libes, [email protected], NIST, 12/3/90 * * Design and implementation of this program was paid for by U.S. tax * dollars. Therefore it is public domain. However, the author and NIST * would appreciate credit if this program or parts of it are used. * * Copyright (c) 1997 Mitel Corporation * work by Gordon Chaffee <[email protected]> for the WinNT port. * * Copyright (c) 2001-2002 Telindustrie, LLC * work by David Gravereaux <[email protected]> for any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: winDllMain.c,v 1.1.2.4 2002/02/10 12:03:30 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "tcl.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> #ifdef _MSC_VER /* Only do this when MSVC++ is compiling us. */ # ifdef USE_TCL_STUBS # pragma comment (lib, "tclstub" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # if !defined(_MT) || !defined(_DLL) || defined(_DEBUG) /* This fixes a bug with how the Stubs library was compiled. * The requirement for msvcrt.lib from tclstubXX.lib must * be removed. This bug has been fixed since 8.4a3, I beleive. */ # pragma comment(linker, "-nodefaultlib:msvcrt.lib") # endif # else # ifdef _DEBUG # pragma comment (lib, "tcl" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) "d.lib") # else # pragma comment (lib, "tcl" \ STRINGIFY(JOIN(TCL_MAJOR_VERSION,TCL_MINOR_VERSION)) ".lib") # endif # endif #endif /* public global */ HMODULE expDllInstance = NULL; #ifndef STATIC_BUILD BOOL WINAPI DllMain (HINSTANCE hInst, ULONG ulReason, LPVOID lpReserved) { switch (ulReason) { case DLL_PROCESS_ATTACH: expDllInstance = hInst; } return TRUE; } #endif |