Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch telco-tec-win32-branch Excluding Merge-Ins
This is equivalent to a diff from be6c4ae2c3 to 8dfbe8bed5
2001-11-22
| ||
08:50 | A working set of code against Tcl8.4! check-in: 4bac78b859 user: davygrvy tags: trunk, win32-jump-point-1 | |
2001-11-18
| ||
21:53 | updated last update date. Leaf check-in: 8dfbe8bed5 user: davygrvy tags: trunk, telco-tec-win32-branch | |
21:51 | no message check-in: 3f0ca7e189 user: davygrvy tags: trunk, telco-tec-win32-branch | |
2001-09-13
| ||
23:00 | the catalog of my changes in this branch check-in: 6f871d0b9e user: davygrvy tags: trunk, telco-tec-win32-branch | |
03:43 | a notice of nothing. check-in: be6c4ae2c3 user: davygrvy tags: trunk, win32-jump-point-1 | |
03:33 | moved from root check-in: e629beeecd user: davygrvy tags: trunk, win32-jump-point-1 | |
Changes to .gitignore.
︙ | ︙ | |||
22 23 24 25 26 27 28 | *.so *.exe *.Z *.elc *.ln core # CVS default ignores end | > > > | 22 23 24 25 26 27 28 29 30 31 | *.so *.exe *.Z *.elc *.ln core # CVS default ignores end *.ncb *.opt *.plg |
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 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 | 2001-11-07 davygrvy * win/.cvsignore: * win/Mcl/.cvsignore: a few more globs added. * expect.dsw: * win/buildfiles.dsp(removed): * win/expect.dsp(removed): * win/genStubs.dsp(removed): * win/slavedrv.dsp: Changed to an IDE project rather than a makefile project. The makefiles will be disappearing. * generic/exp.decls: * generic/exp.h: * generic/expDecls.h: * generic/expInt.h: * generic/expIntDecls.h: * generic/expIntPlatDecls.h: * generic/expPlatDecls.h: * generic/expStubInit.c: Massive restructuring done to the header files. Closely emulates the core. * 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: "Mcl" multithreading C++ class library added * win/dllEntryPoint.c: * win/expSlaveDrvMain.c: * win/expWin.h: * win/expWinCommand.c: * win/expWinDynloadTclStubs.c: * win/expWinInit.c: * win/expWinInt.h: * win/expWinLog.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSlaveKey.c: * win/expWinSpawnChan.c: * win/makefile.vc32: * win/spawndrv.rc: * win/spawndrvmc.mc: Numerous changes * win/slavedrv.dsp: small unicode changes. * win/expWinMailboxCli.cpp: * win/expWinMailboxSrv.cpp: Small test beginnings of the IPC channel driver with client for spawndrv.exe 2001-10-30 davygrvy * win/dllEntryPoint.c: (new) not neccessarily needed, but being explict is a good thing. * win/makefile.vc32: * win/mkfiles.mif: * win/mkvc32.mif: added a 'clean' target. 2001-10-29 davygrvy * win/expect.dsp: folder change * generic/exp.h: needed an <eol> at the end of the file for the resource compiler. * win/makefile.vc32: added the 'genstubs' target * generic/exp.decls: * generic/exp.h: * generic/expDecls.h: * generic/expInt.h: * generic/expIntDecls.h: * generic/expIntPlatDecls.h: * generic/expStubInit.c: * win/expWinPort.h: expStubInit.c now hooked in. Nothing inside exp.decl except some test code to buzz the lines. * generic/exp_printify.h (removed): not needed. * win/slavedrv.dsp: fixed the release build to actually do a release build. * generic/expPlatIntDecls.h (removed): Whoops. should be IntPlat, not PlatInt. * generic/expIntPlatDecls.h: * generic/expPlatIntDecls.h: improper naming convention. Should be PlatInt not IntPlat * generic/exp_printify.c: This should be part of exp_clib.c, but not yet. * generic/exp_strf.c: was moved to compat/ * generic/exp.decls: * generic/expDecls.h: * generic/expInt.h: * generic/expIntPlatDecls.h: * generic/expStubInit.c: Stubs play. * win/expect.rc: * win/spawndrv.rc: set use the newer exp.h * mkconfig.mif: had to put the !error directive back in place. 2001-10-28 davygrvy * generic/exp.h: * generic/expDecls.h: * generic/expInt.h: * generic/expIntDecls.h: * generic/exp_command.h: * generic/exp_event.h: reworking the header files for a more core style and structure. * generic/exp.decls: (new) Stubs table * expect.dsw: * win/genStubs.dsp: (new) IDE file for rebuilding the Stubs table. * win/expWinLog.c: removed the check to when not to call DebugBreak(). Always call it. * generic/expCommand.c: * generic/expCommand.c: * generic/exp_event.c: large amount of edits to make it work (again). Needs to be checked against the snap29 mods. * generic/exp_main_sub.c: no more custom shells * generic/expDecls.h: * generic/expPlatDecls.h: * generic/expStubInit.c: Stubs has begun * win/buildfiles.dsp: * win/expect.dsp: * win/makefile.vc32: * win/mkfiles.mif: build instruction changes * makefile.win: extension target changed from 'release' to 'expect' 2001-10-26 davygrvy * unix/expUnixSpawnChan.c: a "merge" of the older Gordon port to 5.32.2's * win/expWinLog.c: * win/expWinProcess.c: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/spawndrvmc.mc: adding more calls to ExpSyslog() where needed. * win/expWin.h: * win/expWinDynloadTclStubs.c: * win/expWinLog.c: * win/expWinProcess.c: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * 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: * win/expect.dsp: a couple more IDE project files for MsDev 2001-10-22 davygrvy * win/msjexhnd.cpp: * win/msjexhnd.h: simple formatting changes. * win/makefile.vc32: Needed to include the temp directory in the include path so spawndrvmc.h is picked-up. * win/expWinSlaveDbg.c: removed #include "tclInt.h". tclPort.h brings it in anyways. * win/slavedrv.dsp: MSVC++ v6 project file. Calls the makefile anyways.. Just a shortcut when working in the IDE so the debugger knows what is what and who is who and everyone can co-exist all peacefully. * expect.dsw: MSVC++ v6 workspace file for the IDE. * .cvsignore: * win/.cvsignore: globs to ignore by CVS. 2001-10-14 davygrvy * win/expect.rc: * 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: * 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. 2001-10-11 davygrvy * win/expWin.h: * win/expWinDynloadTclStubs.c: * win/expWinProcess.c: * win/expWinSlaveDrv.c: * win/mkfiles.mif: Added Stubs dynloading stuff. slavedrv.exe appears to be working thus far, * win/expWinProcess.c: Added ExpInitWinProcessAPI() to setup the ascii/unicode proc switching. * win/expWinProcess.c: l'il bugfix * win/expWin.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinProcess.c: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSpawnChan.c: * win/expWinTty.c: * win/expect.rc: * win/makefile.vc32: * win/makefile.vc32: * win/mkfiles.mif: * win/mkvc32.mif: * win/mkvc32.mif: slavedrv.exe is building.. need to add Stubs startup code. * win/expWinProcess.c: updated ExpCreateProcess() to match 8.4 imp. I wish I could use the core for this function, but can't as the changes are deep. * win/expWinProcess.c: Ack! bigger bugfix repaired. Had some doubleup during some edits for comparisons and forget to delete the old half. 2001-10-05 davygrvy * generic/exp_main_exp.c: * generic/exp_main_tk.c: motion toward a pure extension. No custom shells. * generic/expSpawnChan.c: Mostly adapted to the ExpState structure... * generic/exp_regexp.c: * generic/exp_regexp.h: won't be used anymore in favor of the core RE engine. * generic/expChannel.c: pertinent code moved to expSpawnChan.c instead. * generic/exp_memmove.c: moved to the compat/ directory 2001-10-04 davygrvy * win/expectlib.rc: There will be no more expectLib 2001-10-03 davygrvy * exp_tty_in.h: Top-level source files removed. 2001-10-02 davygrvy * win/panic.c: * win/tclHash.c: not needed. We'll be using the core for this. NO COPIES! * win/Dbg_cf.h: not needed here. * generic/expect.c: * generic/expect.h: fixed numerous warnings and errors. code is from 5.32.2 * Dbg.c: * 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_win.c: * exp_win.h: * expect.c: * expect.h: * expect_comm.h: * expect_tcl.h: * pty_sgttyb.c: * pty_termios.c: * pty_unicos.c: * tcldbg.h: Top-level source files removed. * generic/Dbg.c: * generic/Dbg.h: * generic/tcldbg.h: Brought in 5.32.2 and fixed compiler warnings about inappropriate casts. 2001-09-28 davygrvy * win/mkfiles.mif: Common list of target object files for all make implimentations. * makefile.win: Added list of expected (pun intended) targets that will be used. * win/mkprepvc32.mif: * win/mkvc32.mif: Moved the makefile prep work to a seperate file. * mkconfig.mif: Added more config info the build system will need. 2001-09-26 davygrvy * win/expAlloc.c: * win/expDString.c: already found in the core. NO COPIES ALLOWED! * makefile.win: * mkconfig.mif: * win/makefile.vc32: * win/mkbc32.mif: * win/mkmgw32.mif: * win/mkvc32.mif: * win/mkwc32.mif: New top-root makefile under windows. 2001-09-13 davygrvy * generic/Dbg.c: * generic/Dbg.h: * generic/expChan.c: * generic/expChannel.c: * generic/expCommand.c: * generic/expSpawnChan.c: * generic/expTrap.c: * generic/exp_clib.c: * generic/exp_closetcl.c: * generic/exp_command.h: * generic/exp_event.c: * generic/exp_event.h: * generic/exp_glob.c: * generic/exp_int.h: * generic/exp_inter.c: * generic/exp_log.c: * generic/exp_log.h: * generic/exp_main_exp.c: * generic/exp_main_sub.c: * generic/exp_main_tk.c: * generic/exp_memmove.c: * generic/exp_noevent.c: * generic/exp_port.h: * generic/exp_printify.c: * generic/exp_printify.h: * generic/exp_prog.h: * generic/exp_regexp.c: * generic/exp_regexp.h: * generic/exp_rename.h: * generic/exp_strf.c: * generic/exp_tstamp.h: * generic/exp_tty.h: * generic/exp_version.h: * generic/exp_win.c: * generic/exp_win.h: * generic/expect.c: * generic/expect.h: * generic/expect_comm.h: * generic/expect_tcl.h: * generic/getopt.c: * generic/getopt.h: * unix/DbgMkfl.in: * unix/Dbg_cf.h.in: * unix/Dbgconfig.in: * unix/Makefile.in: * unix/aclocal.m4: * unix/config.guess: * unix/config.sub: * unix/configure: * unix/configure.in: * unix/expUnixCommand.c: * unix/expUnixPort.h: * unix/expUnixSpawnChan.c: * unix/expUnixTty.c: * unix/expUnixTty.h: * unix/exp_clib_orig.c: * unix/exp_command.c: * unix/exp_console.c: * unix/exp_poll.c: * unix/exp_pty.c: * unix/exp_pty.h: * unix/exp_select.c: * unix/exp_simple.c: * unix/exp_trap.c: * unix/exp_tty_comm.c: * unix/exp_tty_in.h: * unix/expect_cf.h.in: * unix/fixcat: * unix/fixline1: * unix/install-sh: * unix/pkgIndex.in: * unix/pty_sgttyb.c: * unix/pty_termios.c: * unix/pty_unicos.c: * unix/vgrindefs: * win/Dbg_cf.h: * win/debugger.c: * win/etest.tcl: * win/expAlloc.c: * win/expDString.c: * win/expWin.h: * win/expWinCLib.c: * win/expWinCommand.c: * win/expWinLog.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSlaveKey.c: * win/expWinSpawnChan.c: * win/expWinTrap.c: * win/expWinTty.c: * win/expWinTty.h: * win/expect.rc: * win/expectlib.rc: * win/makefile: * win/msjexhnd.cpp: * win/msjexhnd.h: * win/panic.c: * win/pkgIndex.tcl: * win/tclHash.c: * 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/all: * win/tests/basic.test: * win/tests/cmd.test: * win/tests/crash.tcl: * win/tests/crash.test: * win/tests/defs: * win/tests/emacs.test: * win/tests/ftp.test: * win/tests/modemtest.exp: * win/tests/pipe.test: * win/tests/script.test: * win/tests/suite.tcl: * win/tests/telnet.test: * win/tests/test.pl: * win/tests/test_suite.tcl: * win/tests/testtcl: * win/tests/trap.tcl: * win/tests/trap.test: * win/tests/trap2.tcl: * win/testsig.c: * win/testwprog.c: * win/testwstation.c: * win/testwstation.tcl: snap29 "import" * exp_clib.c: <eol> mishandling repaired * mac/README.mac.txt: a notice of nothing. * exp_clib.c: umm.. fixed bad fix... ignore last mistake ;) * compat/exp_memmove.c: * compat/exp_select.c: * compat/exp_strf.c: * doc/expect.man: * doc/expectk.man: * doc/libexpect.man: * exp_memmove.c: * exp_select.c: * exp_strf.c: * expect.man: * expectk.man: * libexpect.man: moved from root 2000-01-06 wart * exp_printify.c: * exp_printify.h: Merge of expect5-31-branch to mainline 1999-09-01 jenn * tests/all: * tests/defs: Removed all and defs, added all.tcl. 1999-08-31 jenn * tests/all: * tests/defs: * 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-15 stanton * exp_printify.c: * exp_printify.h: regenerated configure script removed exp_printify files changed Dbg.c to use new regexp interfaces 1999-06-14 don * exp_printify.h: made stuff compile * exp_printify.c: fixed Log/Diag and ExpectCmd 1999-06-11 stanton * exp_printify.c: modified expect command to use new regexp interfaces, made various I18N changes 1998-10-14 cvsadmin * exp_printify.c: * exp_printify.h: * tests/all: * tests/defs: Import of Expect v. 5.28.1 2001-10-14 davygrvy * win/expect.rc: * 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: * 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. 2001-10-11 davygrvy * win/expWin.h: * win/expWinDynloadTclStubs.c: * win/expWinProcess.c: * win/expWinSlaveDrv.c: * win/mkfiles.mif: Added Stubs dynloading stuff. slavedrv.exe appears to be working thus far, * win/expWinProcess.c: Added ExpInitWinProcessAPI() to setup the ascii/unicode proc switching. * win/expWinProcess.c: l'il bugfix * win/expWin.h: * win/expWin.h: * win/expWinCommand.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinProcess.c: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSpawnChan.c: * win/expWinTty.c: * win/expect.rc: * win/makefile.vc32: * win/makefile.vc32: * win/mkfiles.mif: * win/mkvc32.mif: * win/mkvc32.mif: slavedrv.exe is building.. need to add Stubs startup code. * win/expWinProcess.c: updated ExpCreateProcess() to match 8.4 imp. I wish I could use the core for this function, but can't as the changes are deep. * win/expWinProcess.c: Ack! bigger bugfix repaired. Had some doubleup during some edits for comparisons and forget to delete the old half. 2001-10-05 davygrvy * generic/exp_main_exp.c: * generic/exp_main_tk.c: motion toward a pure extension. No custom shells. * generic/expSpawnChan.c: Mostly adapted to the ExpState structure... * generic/exp_regexp.c: * generic/exp_regexp.h: won't be used anymore in favor of the core RE engine. * generic/expChannel.c: pertinent code moved to expSpawnChan.c instead. * generic/exp_memmove.c: moved to the compat/ directory 2001-10-04 davygrvy * win/expectlib.rc: There will be no more expectLib 2001-10-03 davygrvy * exp_tty_in.h: Top-level source files removed. 2001-10-02 davygrvy * win/panic.c: * win/tclHash.c: not needed. We'll be using the core for this. NO COPIES! * win/Dbg_cf.h: not needed here. * generic/expect.c: * generic/expect.h: fixed numerous warnings and errors. code is from 5.32.2 * Dbg.c: * 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_win.c: * exp_win.h: * expect.c: * expect.h: * expect_comm.h: * expect_tcl.h: * pty_sgttyb.c: * pty_termios.c: * pty_unicos.c: * tcldbg.h: Top-level source files removed. * generic/Dbg.c: * generic/Dbg.h: * generic/tcldbg.h: Brought in 5.32.2 and fixed compiler warnings about inappropriate casts. 2001-09-28 davygrvy * win/mkfiles.mif: Common list of target object files for all make implimentations. * makefile.win: Added list of expected (pun intended) targets that will be used. * win/mkprepvc32.mif: * win/mkvc32.mif: Moved the makefile prep work to a seperate file. * mkconfig.mif: Added more config info the build system will need. 2001-09-26 davygrvy * win/expAlloc.c: * win/expDString.c: already found in the core. NO COPIES ALLOWED! * makefile.win: * mkconfig.mif: * win/makefile.vc32: * win/mkbc32.mif: * win/mkmgw32.mif: * win/mkvc32.mif: * win/mkwc32.mif: New top-root makefile under windows. 2001-09-12 David Gravereaux <[email protected]> * makefile.win: * mkconfig.mif: * win/mkvc32.mif: * win/makefile.vc32: 2001-09-13 David Gravereaux <[email protected]> * generic/Dbg.c: * generic/Dbg.h: * generic/expChan.c: * generic/expChannel.c: * generic/expCommand.c: * generic/expSpawnChan.c: * generic/expTrap.c: * generic/exp_clib.c: * generic/exp_closetcl.c: * generic/exp_command.h: * generic/exp_event.c: * generic/exp_event.h: * generic/exp_glob.c: * generic/exp_int.h: * generic/exp_inter.c: * generic/exp_log.c: * generic/exp_log.h: * generic/exp_main_exp.c: * generic/exp_main_sub.c: * generic/exp_main_tk.c: * generic/exp_memmove.c: * generic/exp_noevent.c: * generic/exp_port.h: * generic/exp_printify.c: * generic/exp_printify.h: * generic/exp_prog.h: * generic/exp_regexp.c: * generic/exp_regexp.h: * generic/exp_rename.h: * generic/exp_strf.c: * generic/exp_tstamp.h: * generic/exp_tty.h: * generic/exp_version.h: * generic/exp_win.c: * generic/exp_win.h: * generic/expect.c: * generic/expect.h: * generic/expect_comm.h: * generic/expect_tcl.h: * generic/getopt.c: * generic/getopt.h: * unix/DbgMkfl.in: * unix/Dbg_cf.h.in: * unix/Dbgconfig.in: * unix/Makefile.in: * unix/aclocal.m4: * unix/config.guess: * unix/config.sub: * unix/configure: * unix/configure.in: * unix/expUnixCommand.c: * unix/expUnixPort.h: * unix/expUnixSpawnChan.c: * unix/expUnixTty.c: * unix/expUnixTty.h: * unix/exp_clib_orig.c: * unix/exp_command.c: * unix/exp_console.c: * unix/exp_poll.c: * unix/exp_pty.c: * unix/exp_pty.h: * unix/exp_select.c: * unix/exp_simple.c: * unix/exp_trap.c: * unix/exp_tty_comm.c: * unix/exp_tty_in.h: * unix/expect_cf.h.in: * unix/fixcat: * unix/fixline1: * unix/install-sh: * unix/pkgIndex.in: * unix/pty_sgttyb.c: * unix/pty_termios.c: * unix/pty_unicos.c: * unix/vgrindefs: * win/Dbg_cf.h: * win/debugger.c: * win/etest.tcl: * win/expAlloc.c: * win/expDString.c: * win/expWin.h: * win/expWinCLib.c: * win/expWinCommand.c: * win/expWinLog.c: * win/expWinPort.h: * win/expWinProcess.c: * win/expWinSlave.h: * win/expWinSlaveDbg.c: * win/expWinSlaveDrv.c: * win/expWinSlaveKey.c: * win/expWinSpawnChan.c: * win/expWinTrap.c: * win/expWinTty.c: * win/expWinTty.h: * win/expect.rc: * win/expectlib.rc: * win/makefile: * win/msjexhnd.cpp: * win/msjexhnd.h: * win/panic.c: * win/pkgIndex.tcl: * win/tclHash.c: * 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/all: * win/tests/basic.test: * win/tests/cmd.test: * win/tests/crash.tcl: * win/tests/crash.test: * win/tests/defs: * win/tests/emacs.test: * win/tests/ftp.test: * win/tests/modemtest.exp: * win/tests/pipe.test: * win/tests/script.test: * win/tests/suite.tcl: * win/tests/telnet.test: * win/tests/test.pl: * win/tests/test_suite.tcl: * win/tests/testtcl: * win/tests/trap.tcl: * win/tests/trap.test: * win/tests/trap2.tcl: * win/testsig.c: * win/testwprog.c: * win/testwstation.c: * win/testwstation.tcl: snap29 "import" * exp_clib.c: <eol> mishandling repaired * mac/README.mac.txt: a notice of nothing. * exp_clib.c: umm.. fixed bad fix... ignore last mistake ;) * compat/exp_memmove.c (new): * compat/exp_select.c (new): * compat/exp_strf.c (new): * doc/expect.man (new): * doc/expectk.man (new): * doc/libexpect.man (new): * exp_memmove.c (deleted): * exp_select.c (deleted): * exp_strf.c (deleted): * expect.man (deleted): * expectk.man (deleted): * libexpect.man (deleted): moved from root 2001-09-12 David Gravereaux <[email protected]> * Created the 'telco-tec-win32-branch' from the HEAD. * `Imported`, as it were, Gordon Chaffe's snap29. The root directory is still 5.32.2, and the sub directories for generic, win, and unix are Gordon's 5.21-snap29. * Moved the 5.32.2 .man scripts into doc/ * Plans include full `Stubs compliance` for both importing Tcl's and exporting itself. expectlib is to be discarded as the direction problem with it needing core function COPIES is a maintenence nightmare. When one will want the C library, it will be housed in the extension itself, the outside interface will not mention Tcl, but the inside usage will require the Tcl library. This backward reverse loading issue is identical in the pattern the TclPlugin has, and similar to TclBlend as well. |
Deleted Dbg.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added README.win32.txt.
> > | 1 2 | Nothing here yet. This will be an addition to the main README specific to Windows. |
Deleted expTcl.c.
Deleted expTcl.h.
Deleted exp_chan.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
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_noevent.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted exp_poll.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
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_simple.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.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added 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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "Mcl"=.\win\Mcl\Mcl.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "slavedrv"=.\win\slavedrv.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name Mcl End Project Dependency }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### |
Deleted expect.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect_comm.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted expect_tcl.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to generic/Dbg.c.
1 2 3 4 5 6 7 8 9 10 11 12 | /* 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> | > > | | < < < < < < < < < < < < < < < < < | < | < < < < < < > > > > > > > > > > | 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 | /* 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: Dbg.c,v 5.31 2001/08/02 00:30:14 hobbs Exp $ */ #include <stdio.h> #include "tcldbgcf.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 "tcldbg.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static int simple_interactor _ANSI_ARGS_((Tcl_Interp *interp, ClientData data)); static int zero _ANSI_ARGS_((Tcl_Interp *interp, char *funcname)); /* 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 void print _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); static Tcl_CmdProc cmdNext; static Tcl_CmdProc cmdSimple; static Tcl_CmdProc cmdWhere; static Tcl_CmdProc cmdBreak; static Tcl_CmdProc cmdDir; static Tcl_CmdProc cmdHelp; static Tcl_CmdTraceProc debugger_trap; static int debugger_active = FALSE; /* this is not externally documented anywhere as of yet */ char *Dbg_VarName = "dbg"; #define DEFAULT_COMPRESS 0 |
︙ | ︙ | |||
92 93 94 95 96 97 98 | 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 | | | > | < | | < < | 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 | 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 = step; /* 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; 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 * breakpoint_new() { struct breakpoint *b = (struct breakpoint *)ckalloc(sizeof(struct breakpoint)); if (break_base) break_base->previous = b; b->next = break_base; |
︙ | ︙ | |||
144 145 146 147 148 149 150 | static void breakpoint_print(interp,b) Tcl_Interp *interp; struct breakpoint *b; { | | | | | | | | | | | | | | | | | | | > > | | < < > | > > | > | < < < | | < < | | > > > > | > > > | > > > > | | > | | | | | | | | | | | | | | | | | | 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 | 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 |
︙ | ︙ | |||
311 312 313 314 315 316 317 | return result; } static char *printify(s) char *s; { | | | | | | > | | | | | | | | | < < < | | | | | | | | | | | | | | | | | > > | | | | | | | 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 | 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; |
︙ | ︙ | |||
387 388 389 390 391 392 393 | len = strlen(buf); space = buf_width - len; bufp = buf + len; argc--; argv++; arg_index = 1; while (argc && (space > 0)) { | | | < > < | | 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 | 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. */ if (proc && (arg_index > 1)) wrap = TRUE; else { (void) TclFindElement(interp,*argv, #if TCL_MAJOR_VERSION >= 8 -1, #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) { |
︙ | ︙ | |||
432 433 434 435 436 437 438 | /* 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 */ | | > > > > > > > > > > > > > > > > > > > > < > | < < < < < < < < < | < < | 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 | /* 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) == buf_width) { buf[buf_width-1] = buf[buf_width-2] = buf[buf_width-3] = '.'; } return(buf); } #if TCL_MAJOR_VERSION >= 8 static char * print_objv(interp,objc,objv) 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 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); print(interp,"%c%d: %s\n",ptr,curf->level, #if TCL_MAJOR_VERSION >= 8 print_objv(interp,curf->objc,curf->objv)); #else print_argv(interp,curf->argc,curf->argv)); #endif } } static void PrintStack(interp,curf,viewf,argc,argv,level) |
︙ | ︙ | |||
518 519 520 521 522 523 524 525 526 527 528 529 530 531 | 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; | > > > > > > > > > > > > > > > > > | 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 | if (goal == cf) { /* found, but since it's above us, fail */ return 1; } } return 0; } static char *cmd_print(cmdtype) enum debug_cmd cmdtype; { switch (cmdtype) { case none: return "cmd: none"; case step: return "cmd: step"; case next: return "cmd: next"; case ret: return "cmd: ret"; case cont: return "cmd: cont"; case up: return "cmd: up"; case down: return "cmd: down"; case where: return "cmd: where"; case Next: return "cmd: Next"; } return "cmd: Unknown"; } /* debugger's trace handler */ /*ARGSUSED*/ static void debugger_trap(clientData,interp,level,command,cmdProc,cmdClientData,argc,argv) ClientData clientData; /* not used */ Tcl_Interp *interp; |
︙ | ︙ | |||
583 584 585 586 587 588 589 | /* 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) { | | > > | | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | /* 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: |
︙ | ︙ | |||
698 699 700 701 702 703 704 705 706 707 708 709 710 711 | 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); } | > | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | 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); } |
︙ | ︙ | |||
743 744 745 746 747 748 749 | } static void breakpoint_destroy(b) struct breakpoint *b; { | | | | | | | | | | 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 | } 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; |
︙ | ︙ | |||
872 873 874 875 876 877 878 | } } b = breakpoint_new(); if (flageq("-regexp",argv[0],2)) { argc--; argv++; | | > | > > > > > | | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | } } 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]); |
︙ | ︙ | |||
909 910 911 912 913 914 915 | 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 */ | | | 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | 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)) { |
︙ | ︙ | |||
1131 1132 1133 1134 1135 1136 1137 | Tcl_Interp *interp; char *string; { return 0; } static int | | | | > > > > > > > > > > > > | > < < < < < < < < < < < < < < < < < < < < < < < < < | | 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 | Tcl_Interp *interp; char *string; { return 0; } static int simple_interactor(interp,data) Tcl_Interp *interp; ClientData data; { 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) { #if TCL_MAJOR_VERSION < 8 print(interp,"dbg%d.%d> ",iPtr->numLevels,iPtr->curEventNum+1); #else /* unncessarily tricky coding - if nextid isn't defined, maintain our own static version */ static int nextid = 0; char *nextidstr = Tcl_GetVar2(interp,"tcl::history","nextid",0); if (nextidstr) { sscanf(nextidstr,"%d",&nextid); } print(interp,"dbg%d.%d> ",iPtr->numLevels,nextid++); #endif } else { print(interp,"dbg+> "); } fflush(stdout); if (0 >= (rc = read(0,line,BUFSIZ))) { if (!newcmd) line[0] = 0; else exit(0); } else line[rc] = '\0'; (CONST char *) 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 */ |
︙ | ︙ | |||
1286 1287 1288 1289 1290 1291 1292 | 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); | > > > > > | | | > > > > | 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 | 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,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); /* initialize for next use */ debug_cmd = step; step_count = 1; } |
Changes to generic/Dbg.h.
︙ | ︙ | |||
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 | */ /* _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; | > > > > > > > > > > > > > > > | | | | | | | | | | | 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 | */ /* _DEBUG or _DBG is just too likely, use something more unique */ #ifndef _NIST_DBG #define _NIST_DBG #include "tcl.h" #ifndef TCL_NEWEXTERN # ifdef __cplusplus # define OLDEXTERN extern "C" TCL_STORAGE_CLASS # else # define OLDEXTERN extern TCL_STORAGE_CLASS # endif # undef EXTERN # define EXTERN(a) OLDEXTERN a #endif #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT 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; char * Dbg_VarName; char * Dbg_DefaultCmdName; /* trivial interface, creates a "debug" command in your interp */ EXTERN(int) Dbg_Init _ANSI_ARGS_((Tcl_Interp *)); void Dbg_On _ANSI_ARGS_((Tcl_Interp *interp, int immediate)); void Dbg_Off _ANSI_ARGS_((Tcl_Interp *interp)); char ** Dbg_ArgcArgv _ANSI_ARGS_((int argc,char *argv[], int copy)); int Dbg_Active _ANSI_ARGS_((Tcl_Interp *interp)); Dbg_InterStruct Dbg_Interactor _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_InterProc *interactor, ClientData data)); Dbg_IgnoreFuncsProc * Dbg_IgnoreFuncs _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_IgnoreFuncsProc *)); 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 | # 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 expStub.c files. # # RCS: @(#) $Id: exp.decls,v 1.1.2.4 2001/11/07 10:06:30 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[]) } ### From exp_printify.c declare 26 generic { char *exp_printify (char *s) } ## all below are NOT final -> declare 32 generic { void exp_parse_argv (Tcl_Interp *interp, int argc, char **argv) } declare 33 generic { int exp_interpreter (Tcl_Interp *interp, Tcl_Obj *eofObj) } declare 34 generic { int exp_interpret_cmdfile (Tcl_Interp *interp, Tcl_Channel file) } declare 35 generic { int exp_interpret_cmdfilename (Tcl_Interp *interp, char *filename) } declare 36 generic { void exp_interpret_rcfiles (Tcl_Interp *interp, int my_rc, int sys_rc) } declare 37 generic { char *exp_cook (char *s, int *len) } declare 38 generic { void expCloseOnExec (int fd) } declare 39 generic { int exp_getpidproc (void) } declare 40 generic { Tcl_Channel ExpCreateSpawnChannel (Tcl_Interp *interp, Tcl_Channel chan) } interface expPlat interface expInt interface expIntPlat #==================================================================================== # UNIX specific publics. #==================================================================================== # WIN32 specific privates. declare 0 win { DWORD ExpWinApplicationType (const char *originalName, char *fullPath) } declare 1 win { DWORD ExpWinCreateProcess (int argc, char **argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, Tcl_Pid *pidPtr, 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) } #==================================================================================== # MAC specific publics. ### You nutts!! can't do 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 220 221 | /* ---------------------------------------------------------------------------- * 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 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.2.5 2001/10/29 06:40:29 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 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 that's in Tcl. */ #ifndef TCL_EXTERN # undef DLLIMPORT # undef DLLEXPORT # if defined(__WIN32__) && (defined(_MSC_VER) || (defined(__GNUC__) && defined(__declspec))) # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # elif defined(__BORLANDC__) # define DLLIMPORT __import # define DLLEXPORT __export # else # define DLLIMPORT # define DLLEXPORT # endif /* * Make sure name mangling won't happen when the c++ language extensions * are used. */ # ifdef __cplusplus # define TCL_CPP "C" # else # define TCL_CPP # endif /* * Borland requires the attributes be placed after the return type. */ # ifdef __BORLANDC__ # 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 #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*/ /* from expect_tcl.h */ TCL_EXTERN(void) exp_parse_argv _ANSI_ARGS_((Tcl_Interp *,int argc,char **argv)); TCL_EXTERN(int) exp_interpreter _ANSI_ARGS_((Tcl_Interp *,Tcl_Obj *)); TCL_EXTERN(int) exp_interpret_cmdfile _ANSI_ARGS_((Tcl_Interp *,Tcl_Channel)); TCL_EXTERN(int) exp_interpret_cmdfilename _ANSI_ARGS_((Tcl_Interp *,char *)); TCL_EXTERN(void) exp_interpret_rcfiles _ANSI_ARGS_((Tcl_Interp *,int my_rc,int sys_rc)); TCL_EXTERN(char *) exp_cook _ANSI_ARGS_((char *s,int *len)); TCL_EXTERN(void) expCloseOnExec _ANSI_ARGS_((int)); /* app-specific exit handler */ //TCL_EXTERN(void) *exp_app_exit _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_exit_handlers _ANSI_ARGS_((ClientData)); TCL_EXTERN(void) exp_error _ANSI_ARGS_(TCL_VARARGS(Tcl_Interp *,interp)); TCL_EXTERN(int) exp_getpidproc _ANSI_ARGS_((void)); /* * 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 */ |
Deleted generic/expChannel.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to generic/expCommand.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | * 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. * */ | | | | < > | < < < < < < > < < > > < < < < > | > > > | > > > > > | | < | | > > > > > > > > | > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | | > > > > > > > > > > > > > > > | > | > > > > > > > > > > < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > | > | > | | | | | > > > > > > > > > > | > | > > > > | > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > < < | < < | < | | > | > > > | > | > > | > > > | | < < < < > > > | | | | < > | > > > > | > > | | | | | | | | | | | | | | | | | > > > > > > > > > > < | | > > > < > > > < < < | > > > > > | > > > > > | | < | < | | | > | | | | | | | > | > > > > > > | | | > > < | > > > > > > > > > > > > > > > > > > | > | < | > | > | | < < < | > > > > > > > > > > > > > > > > > | | | < < < < < | > | < < < < < < < < < < | < < < | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < < | < | < < < < < < | 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 | * 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 <math.h> /* for log/pow computation in send -h */ #include "expInt.h" /* * These constants refer to the UTF string that encodes a null character. */ #define NULL_STRING "\300\200" /* hex C080 */ #define NULL_LENGTH 2 /* * Found in either pty_sgtttyb.c, pty_termios.c, or pty_unicos.c */ extern int exp_getptymaster(); extern int exp_getptyslave(); int exp_forked = FALSE; /* whether we are child process */ /* the following are use to create 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 */ /* * 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; #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 */ typedef struct ThreadSpecificData { /* * List of all exp channels currently open. This is per thread and is * used to match up fd's to channels, which rarely occurs. */ ExpState *stdinout; ExpState *stderrX; /* grr....stderr is a macro */ ExpState *devtty; ExpState *any; /* for any_spawn_id */ Tcl_Channel *diagChannel; Tcl_DString diagDString; int diagEnabled; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; struct slow_arg { int size; double time; }; /* * Local prototypes for functions used only in this file and are not shared. */ static void exp_wait_zero _ANSI_ARGS_((WAIT_STATUS_TYPE *status)); static void expBusy _ANSI_ARGS_((ExpState *esPtr)); static int exact_write _ANSI_ARGS_((ExpState *esPtr,char *buffer,int rembytes)); static int human_write _ANSI_ARGS_((Tcl_Interp *interp, ExpState *esPtr, char *buffer, struct human_arg *arg)); static int get_slow_args _ANSI_ARGS_((Tcl_Interp *interp, struct slow_arg *x)); static void tcl_tracer _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int level, char *command, Tcl_CmdProc *cmdProc, ClientData cmdClientData, int argc, char *argv[])); /* *---------------------------------------------------------------------- * * init_traps -- * * Not sure what this does. * * Results: * None * * Side Effects: * No clue. * *---------------------------------------------------------------------- */ #ifdef FULLTRAPS static void init_traps(traps) RETSIGTYPE (*traps[])(); { int i; for (i=1;i<NSIG;i++) { traps[i] = SIG_ERR; } } #endif /* *---------------------------------------------------------------------- * * 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; char buffer[2000]; interp = TCL_VARARGS_START(Tcl_Interp *,arg1,args); fmt = va_arg(args,char *); vsprintf(buffer,fmt,args); Tcl_SetResult(interp,buffer,TCL_VOLATILE); va_end(args); } /* *---------------------------------------------------------------------- * * expStateCurrent -- * * If 0, may be immediately followed by return TCL_ERROR. * * Results: * current ExpState or 0 * *---------------------------------------------------------------------- */ struct ExpState * expStateCurrent(interp,opened,adjust,any) Tcl_Interp *interp; int opened; int adjust; int any; { static char *user_spawn_id = "exp0"; char *name = exp_get_var(interp,EXP_SPAWN_ID_VARNAME); if (!name) name = user_spawn_id; return expStateFromChannelName(interp,name,opened,adjust,any,EXP_SPAWN_ID_VARNAME); } /* *---------------------------------------------------------------------- * * expStateCheck -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ ExpState * expStateCheck(interp,esPtr,open,adjust,msg) Tcl_Interp *interp; ExpState *esPtr; int open; int adjust; char *msg; { if (open && !esPtr->open) { exp_error(interp,"%s: spawn id %s not open",msg,esPtr->name); return(0); } if (adjust) expAdjust(esPtr); return esPtr; } /* *---------------------------------------------------------------------- * * expStateFromChannelName -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ ExpState * expStateFromChannelName(interp,name,open,adjust,any,msg) Tcl_Interp *interp; char *name; int open; int adjust; char *msg; { ExpState *esPtr; Tcl_Channel channel; char *chanName; if (any) { if (0 == strcmp(name,EXP_SPAWN_ID_ANY_LIT)) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->any; } } channel = Tcl_GetChannel(interp,name,(int *)0); if (!channel) return(0); chanName = Tcl_GetChannelName(channel); if (!isExpChannelName(chanName)) { exp_error(interp,"%s: %s is not an expect channel - use spawn -open to convert",msg,chanName); return(0); } esPtr = (ExpState *)Tcl_GetChannelInstanceData(channel); return expStateCheck(interp,esPtr,open,adjust,msg); } /* *---------------------------------------------------------------------- * * exp_wait_zero -- * * Zero out the wait status field. * * Results: * None * *---------------------------------------------------------------------- */ 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_state_prep_for_invalidation -- * * called just before an ExpState entry is about to be invalidated. * * Results: * None * *---------------------------------------------------------------------- */ void exp_state_prep_for_invalidation(interp,esPtr) Tcl_Interp *interp; ExpState *esPtr; { exp_ecmd_remove_state_direct_and_indirect(interp,esPtr); exp_configure_count++; if (esPtr->fg_armed) { exp_event_disarm_fg(esPtr); } } /* *---------------------------------------------------------------------- * * exp_trap_on -- * * Add comment here. * * Results: * None * *---------------------------------------------------------------------- */ /*ARGSUSED*/ void exp_trap_on(master) int master; { #ifdef HAVE_PTYTRAP if (master == -1) return; exp_slave_control(master,1); #endif /* HAVE_PTYTRAP */ } /* *---------------------------------------------------------------------- * * exp_trap_off -- * * Add comment here. * * Results: * None * *---------------------------------------------------------------------- */ int exp_trap_off(name) char *name; { #ifdef HAVE_PTYTRAP ExpState *esPtr; int enable = 0; Tcl_HashEntry *entry = Tcl_FindHashEntry(&slaveNames,name); if (!entry) { expDiagLog("exp_trap_off: no entry found for %s\n",name); return -1; } esPtr = (ExpState *)Tcl_GetHashValue(entry); exp_slave_control(esPtr->fdin,0); return esPtr->fdin; #else return name[0]; /* pacify lint, use arg and return something */ #endif } /* *---------------------------------------------------------------------- * * expBusy -- * * Add comment here. Has OS depedancies. * * Results: * None * *---------------------------------------------------------------------- */ void expBusy(esPtr) ExpState *esPtr; { #ifndef __WIN32__ int x = open("/dev/null",0); if (x != esPtr->fdin) { fcntl(x,F_DUPFD,esPtr->fdin); close(x); } expCloseOnExec(esPtr->fdin); esPtr->fdBusy = TRUE; #else /* what goes here? */ #endif } /* *---------------------------------------------------------------------- * * exp_close -- * * Close a connection. * * Results: * None * * Side Effects: * A native file handle is closed * *---------------------------------------------------------------------- */ int exp_close(interp, esPtr) Tcl_Interp *interp; ExpState *esPtr; { if (0 == expStateCheck(interp,esPtr,1,0,"close")) return TCL_ERROR; esPtr->open = FALSE; /* * Ignore close errors from ptys. Ptys on some systems return errors for * no evident reason. Anyway, receiving an error upon pty-close doesn't * mean anything anyway as far as I know. */ close(esPtr->fdin); if (esPtr->fd_slave != EXP_NOFD) close(esPtr->fd_slave); if (esPtr->fdin != esPtr->fdout) close(esPtr->fdout); if (esPtr->channel_orig && !esPtr->leaveopen) { /* * Ignore close errors from Tcl channels. They indicate things * like broken pipelines, etc, which don't affect our * subsequent handling. */ Tcl_VarEval(interp,"close ",Tcl_GetChannelName(esPtr->channel_orig), (char *)0); } #ifdef HAVE_PTYTRAP if (esPtr->slave_name) { Tcl_HashEntry *entry; entry = Tcl_FindHashEntry(&slaveNames,esPtr->slave_name); Tcl_DeleteHashEntry(entry); ckfree(esPtr->slave_name); esPtr->slave_name = 0; } #endif exp_state_prep_for_invalidation(interp,esPtr); if (esPtr->user_waited) { if (esPtr->registered) { Tcl_UnregisterChannel(interp,esPtr->channel); /* at this point esPtr may have been freed so don't touch it any longer */ } } else { expBusy(esPtr); } return(TCL_OK); } /* *---------------------------------------------------------------------- * * expStateAnyIs -- * * report whether this ExpState represents special spawn_id_any * we need a separate function because spawn_id_any is thread-specific * and can't be seen outside this file. * * Results: * * *---------------------------------------------------------------------- */ int expStateAnyIs(esPtr) ExpState *esPtr; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return (esPtr == tsdPtr->any); } /* *---------------------------------------------------------------------- * * expDevttyIs -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ int expDevttyIs(esPtr) ExpState *esPtr; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return (esPtr == tsdPtr->devtty); } /* *---------------------------------------------------------------------- * * expStdinoutIs -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ int expStdinoutIs(esPtr) ExpState *esPtr; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return (tsdPtr->stdinout == esPtr); } /* *---------------------------------------------------------------------- * * expStdinoutGet -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ ExpState * expStdinoutGet() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->stdinout; } /* *---------------------------------------------------------------------- * * expDevttyGet -- * * Add comment here. * * Results: * * *---------------------------------------------------------------------- */ ExpState * expDevttyGet() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->devtty; } /* *---------------------------------------------------------------------- * * Exp_ExpPidCmd -- * |
︙ | ︙ | |||
455 456 457 458 459 460 461 | * Notes: * OS independent * *---------------------------------------------------------------------- */ /*ARGSUSED*/ | | < | | | | | | | | < < < | | | | | 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 | * Notes: * OS independent * *---------------------------------------------------------------------- */ /*ARGSUSED*/ int Exp_ExpPidCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { char *chanName = 0; ExpState *esPtr = 0; argc--; argv++; for (;argc>0;argc--,argv++) { if (streq(*argv,"-i")) { argc--; argv++; if (!*argv) goto usage; chanName = *argv; } else goto usage; } if (chanName) { if (!(esPtr = expStateFromChannelName(interp,chanName,0,0,0,"exp_pid"))) return TCL_ERROR; } else { if (!(esPtr = expStateCurrent(interp,0,0,0))) return TCL_ERROR; } sprintf(interp->result,"%d",esPtr->pid); return TCL_OK; usage: exp_error(interp,"usage: -i spawn_id"); return TCL_ERROR; } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
520 521 522 523 524 525 526 | static int Exp_GetpidDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | static int Exp_GetpidDeprecatedCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { expDiagLog("getpid is deprecated, use pid\r\n"); sprintf(interp->result,"%d",getpid()); return(TCL_OK); } /* *---------------------------------------------------------------------- * * Exp_SleepCmd -- * * Implements the 'sleep' (alias 'exp_sleep') command. * Can sleep for fractional seconds. |
︙ | ︙ | |||
596 597 598 599 600 601 602 | exp_error(interp,"must have one arg: seconds"); return TCL_ERROR; } return(exp_dsleep(interp,(double)atof(*argv))); } | > > > | > > > > > > > > > | > | > > > > > > | < | | | 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 | exp_error(interp,"must have one arg: seconds"); return TCL_ERROR; } return(exp_dsleep(interp,(double)atof(*argv))); } /* *---------------------------------------------------------------------- * * exact_write -- * * If this works, exact_write should disappear and function should * call Tcl_WriteChars directly. * * Notes: * OS independent * *---------------------------------------------------------------------- */ int exact_write(esPtr,buffer,rembytes) /* INTL */ ExpState *esPtr; char *buffer; int rembytes; { Tcl_WriteChars(esPtr->channel,buffer,rembytes); return(0); } /* *---------------------------------------------------------------------- * * 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 * *---------------------------------------------------------------------- */ 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); |
︙ | ︙ | |||
663 664 665 666 667 668 669 670 | * * Notes: * OS independent * *---------------------------------------------------------------------- */ static int | > | | | | | | | 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 | * * Notes: * OS independent * *---------------------------------------------------------------------- */ /* returns 0 for success, -1 for failure, pos. for Tcl return value */ static int slow_write(interp,esPtr,buffer,rembytes,arg) /* INTL */ Tcl_Interp *interp; ExpState *esPtr; char *buffer; int rembytes; struct slow_arg *arg; { int rc; while (rembytes > 0) { int len; len = (arg->size<rembytes?arg->size:rembytes); if (0 > Tcl_WriteChars(esPtr->channel,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; |
︙ | ︙ | |||
816 817 818 819 820 821 822 | { srand(exp_getpidproc()); } /* *---------------------------------------------------------------------- * | | < | | > < > > | | | > | | | < | | < | < | | | | < < < < < < < < < < < < < < < < < | | | | | > | | | | | > > | | | > | < < < < < < < < < < < < < | | | | < | | < | | | | < < < < < < < < < < < < < | | | | | | | | | < | | | | | | | | | | | | | | < < < < < < | < < < < < < < < < < < < < < < < | | | < < | < < < < < | > > > > > | | | < < < < < < < | | | | | | > | | < < < > | | > > | | | | < < | > | < < | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < > | | < | < < < | | < < < | < | | < | | | | < > > > > > | | < < < < < < | < < < < < < < | > | | | | | | | > < < < < < < < < < < < < < | | | | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < | < < | < < < < < < < < | | | < < < < < < < < < < | | | | > > | | | | | | | | | | > > > > > > | < < < | < | < < | | | | | > > > | | > | | | < | | < | < < | | < < | | > > > > | > > > > > | | > > > | < > > | | > | | | | < > | < | | > | | < < < < < < | < < < < < < < < < < | | < < < < | > | > > > > | < | < | | < | < < | > > | > | > > > > | > > > | > | | > > < | | < < < < < < < | < < | | < < | | | > < < | | | | | | | | | | | | > > | > | | | | | | < < | < | < < < < < < < < < < < < < < < < < < < < < < | < | < < < < | | < < | < < < < < < < < < < < < < | < | | < | | | > | | | > > > > | > > > > | | | < < | | < < | < | < | < < < < < < < < | < | | | < < < < < < < < > > < | < < < < < < < < < < | | < < | > | > | | | > > | | < < < < > > | | < < | | | < < < < < < < < < < < < < < < < < < < < | | | | < | | < < < < < < < < < < < < < | | | 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 | { srand(exp_getpidproc()); } /* *---------------------------------------------------------------------- * * human_write -- * * 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,esPtr,buffer,arg) /* INTL */ Tcl_Interp *interp; ExpState *esPtr; char *buffer; struct human_arg *arg; { char *sp; int size; float t; float alpha; int wc; int in_word = TRUE; Tcl_UniChar ch; expDiagLog("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 += size) { size = Tcl_UtfToUniChar(sp, &ch); /* use the end-of-word alpha at eow transitions */ if (in_word && (Tcl_UniCharIsPunct(ch) || Tcl_UniCharIsSpace(ch))) alpha = arg->alpha_eow; else alpha = arg->alpha; in_word = !(Tcl_UniCharIsPunct(ch) || Tcl_UniCharIsSpace(ch)); 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; /* skip sleep before writing first character */ if (sp != buffer) { wc = exp_dsleep(interp,(double)t); if (wc > 0) return wc; } wc = Tcl_WriteChars(esPtr->channel, sp, size); if (0 > wc) return(wc); } return(0); } struct exp_i *exp_i_pool = 0; struct exp_state_list *exp_state_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->state_list = 0; i->ecount = 0; i->next = 0; return i; } struct exp_state_list * exp_new_state(esPtr) ExpState *esPtr; { int n; struct exp_state_list *fd; if (!exp_state_list_pool) { /* none avail, generate some new ones */ exp_state_list_pool = fd = (struct exp_state_list *)ckalloc( EXP_FD_INIT_COUNT * sizeof(struct exp_state_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_state_list_pool; exp_state_list_pool = exp_state_list_pool->next; fd->esPtr = esPtr; /* fd->next is assumed to be changed by caller */ return fd; } void exp_free_state(fd_first) struct exp_state_list *fd_first; { struct exp_state_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_state_list_pool; exp_state_list_pool = fd_first; } /* free a single fd */ void exp_free_state_single(fd) struct exp_state_list *fd; { fd->next = exp_state_list_pool; exp_state_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_state(i->state_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 = (isExpChannelName(arg)?EXP_DIRECT:EXP_INDIRECT); #if OBSOLETE i->direct = (isdigit(arg[0]) || (arg[0] == '-'))?EXP_DIRECT:EXP_INDIRECT; #endif 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->state_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_state(i,esPtr) struct exp_i *i; ExpState *esPtr; { struct exp_state_list *new_state; new_state = exp_new_state(esPtr); new_state->next = i->state_list; i->state_list = new_state; } /* this routine assumes i->esPtr is meaningful */ static void exp_i_parse_states(interp,i) /* INTL */ Tcl_Interp *interp; struct exp_i *i; { struct ExpState *esPtr; char *p = i->value; int argc; char **argv; int j; if (Tcl_SplitList(NULL, p, &argc, &argv) != TCL_OK) goto error; for (j = 0; j < argc; j++) { esPtr = expStateFromChannelName(interp,argv[j],1,0,0,""); if (!esPtr) goto error; exp_i_add_state(i,esPtr); } ckfree((char*)argv); return; error: expDiagLogU("exp_i_parse_states: "); expDiagLogU(Tcl_GetStringResult(interp)); return; } /* 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 = ""; /* *really* big variable names could blow up expDiagLog! */ expDiagLog("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_state(i->state_list); i->state_list = 0; } else { /* no free, because this should only be called on */ /* "direct" i's once */ i->state_list = 0; } exp_i_parse_states(interp, i); return; } struct exp_i * exp_new_i_simple(esPtr,duration) ExpState *esPtr; 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_state(i,esPtr); return i; } /*ARGSUSED*/ static int Exp_SendLogCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { argv++; argc--; if (argc) { if (streq(*argv,"--")) { argc--; argv++; } } if (argc != 1) { exp_error(interp,"usage: send [args] string"); return TCL_ERROR; } expLogDiagU(*argv); 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*/ int Exp_SendObjCmd(clientData, interp, objc, objv) /* INTL */ ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr = 0; 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 = -1; /* length of string to send */ int zeros; /* count of how many ascii zeros to send */ char *chanName = 0; struct exp_state_list *state_list; struct exp_i *i; int j; static char *options[] = { "-i", "-h", "-s", "-null", "-0", "-raw", "-break", "--", (char *)0 }; enum options { SEND_SPAWNID, SEND_HUMAN, SEND_SLOW, SEND_NULL, SEND_ZERO, SEND_RAW, SEND_BREAK, SEND_LAST }; for (j = 1; j < objc; j++) { char *name; int index; name = Tcl_GetString(objv[j]); if (name[0] != '-') { break; } if (Tcl_GetIndexFromObj(interp, objv[j], options, "flag", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case SEND_SPAWNID: j++; chanName = Tcl_GetString(objv[j]); break; case SEND_LAST: j++; goto getString; case SEND_HUMAN: if (-1 == get_human_args(interp,&human_args)) return(TCL_ERROR); send_style = SEND_STYLE_HUMAN; break; case SEND_SLOW: if (-1 == get_slow_args(interp,&slow_args)) return(TCL_ERROR); send_style = SEND_STYLE_SLOW; break; case SEND_NULL: case SEND_ZERO: j++; if (j >= objc) { zeros = 1; } else if (Tcl_GetIntFromObj(interp, objv[j], &zeros) != TCL_OK) { return TCL_ERROR; } if (zeros < 1) return TCL_OK; send_style = SEND_STYLE_ZERO; string = "<zero(s)>"; break; case SEND_RAW: want_cooked = FALSE; break; case SEND_BREAK: send_style = SEND_STYLE_BREAK; string = "<break>"; break; } } if (send_style & SEND_STYLE_STRING_MASK) { if (j != objc-1) { exp_error(interp,"usage: send [args] string"); return TCL_ERROR; } getString: string = Tcl_GetStringFromObj(objv[j], &len); } else { len = strlen(string); } if (clientData == &sendCD_user) esPtr = tsdPtr->stdinout; else if (clientData == &sendCD_error) esPtr = tsdPtr->stderrX; else if (clientData == &sendCD_tty) esPtr = tsdPtr->devtty; else if (!chanName) { /* we 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 (!(esPtr = expStateCurrent(interp,0,0,0))) return(TCL_ERROR); } if (esPtr) { i = exp_new_i_simple(esPtr,EXP_TEMPORARY); } else { i = exp_new_i_complex(interp,chanName,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; expDiagLogU("send: sending \""); expDiagLogU(expPrintify(string)); expDiagLogU("\" to {"); /* if closing brace doesn't appear, that's because an error */ /* was encountered before we could send it */ } else { expLogDiagU(string); } for (state_list=i->state_list;state_list;state_list=state_list->next) { esPtr = state_list->esPtr; if (send_to_proc) { expDiagLog(" %s ",esPtr->name); } /* check validity of each - i.e., are they open */ if (0 == expStateCheck(interp,esPtr,1,0,"send")) { rc = TCL_ERROR; goto finish; } if (want_cooked) string = exp_cook(string,&len); switch (send_style) { case SEND_STYLE_PLAIN: rc = exact_write(esPtr,string,len); break; case SEND_STYLE_SLOW: rc = slow_write(interp,esPtr,string,len,&slow_args); break; case SEND_STYLE_HUMAN: rc = human_write(interp,esPtr,string,&human_args); break; case SEND_STYLE_ZERO: for (;zeros>0;zeros--) { rc = Tcl_WriteChars(esPtr->channel, NULL_STRING, NULL_LENGTH); } /* 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,esPtr->fdout); rc = 0; break; } if (rc != 0) { if (rc == -1) { exp_error(interp,"write(spawn_id=%d): %s",esPtr->fdout,Tcl_PosixError(interp)); rc = TCL_ERROR; } goto finish; } } if (send_to_proc) expDiagLogU("}\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 char resultbuf[1000]; char *chanName = 0; int leaveOpen = FALSE; int logAll = FALSE; int append = TRUE; char *filename = 0; argv++; argc--; for (;argc>0;argc--,argv++) { if (streq(*argv,"-open")) { if (!argv[1]) goto usage_error; chanName = argv[1]; argc--; argv++; } else if (streq(*argv,"-leaveopen")) { if (!argv[1]) goto usage_error; chanName = argv[1]; leaveOpen = TRUE; argc--; argv++; } else if (streq(*argv,"-a")) { logAll = TRUE; } else if (streq(*argv,"-info")) { resultbuf[0] = '\0'; if (expLogChannelGet()) { if (expLogAllGet()) strcat(resultbuf,"-a "); if (!expLogAppendGet()) strcat(resultbuf,"-noappend "); if (expLogFilenameGet()) { strcat(resultbuf,expLogFilenameGet()); } else { if (expLogLeaveOpenGet()) { strcat(resultbuf,"-leaveopen "); } strcat(resultbuf,Tcl_GetChannelName(expLogChannelGet())); } Tcl_SetResult(interp,resultbuf,TCL_STATIC); } 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 */ goto usage_error; } if (chanName && filename) { goto usage_error; } /* check if user merely wants to change logAll (-a) */ if (expLogChannelGet() && (chanName || filename)) { if (filename && (0 == strcmp(filename,expLogFilenameGet()))) { expLogAllSet(logAll); return TCL_OK; } else if (chanName && (0 == strcmp(filename,Tcl_GetChannelName(expLogChannelGet())))) { expLogAllSet(logAll); return TCL_OK; } else { exp_error(interp,"cannot start logging without first stopping logging"); return TCL_ERROR; } } if (filename) { if (TCL_ERROR == expLogChannelOpen(interp,filename,append)) { return TCL_ERROR; } } else if (chanName) { if (TCL_ERROR == expLogChannelSet(interp,chanName)) { return TCL_ERROR; } } else { expLogChannelClose(interp); if (logAll) { exp_error(interp,"cannot use -a without a file or channel"); return TCL_ERROR; } } expLogAllSet(logAll); expLogLeaveOpenSet(leaveOpen); return TCL_OK; usage_error: exp_error(interp,"usage: log_file [-info] [-noappend] [[-a] file] [-[leave]open [open ...]]"); return TCL_ERROR; } /*ARGSUSED*/ int Exp_LogUserCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int old_loguser = expLogUserGet(); if (argc == 0 || (argc == 2 && streq(argv[1],"-info"))) { /* do nothing */ } else if (argc == 2) { expLogUserSet(atoi(argv[1])); } else { exp_error(interp,"usage: [-info|1|0]"); } sprintf(interp->result,"%d",old_loguser); return(TCL_OK); } #ifdef TCL_DEBUGGER /*ARGSUSED*/ 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; |
︙ | ︙ | |||
1920 1921 1922 1923 1924 1925 1926 | } sprintf(interp->result,"%d",exp_tcl_debugger_was_available); return(TCL_OK); usage: exp_error(interp,"usage: [[-now] 1|0]"); return TCL_ERROR; } | | > | < < | | < < < > | < | > > | | < > | > < | < | < < < < > < < < | | | | < < | < | < < < < < < < < < < < < < < < | | | > > < < < < < < < < < < < < < < | | | | < > > | < < | < < | | | | | | | | | | | | | | > | | < < < < < < < < < | | < < | < < | < | < < < > < < < | | < | | | | | | | | | | | < | | | | | | > | 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 | } 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*/ int Exp_ExpInternalCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int newChannel = FALSE; Tcl_Channel oldChannel; static char resultbuf[1000]; if ((argc > 1) && streq(argv[1],"-info")) { resultbuf[0] = '\0'; oldChannel = expDiagChannelGet(); if (oldChannel) { sprintf(resultbuf,"-f %s ",expDiagFilename()); } strcat(resultbuf,expDiagToStderrGet()?"1":"0"); Tcl_SetResult(interp,resultbuf,TCL_STATIC); return TCL_OK; } argv++; argc--; while (argc) { if (!streq(*argv,"-f")) break; argc--;argv++; if (argc < 1) goto usage; expDiagChannelClose(interp); if (TCL_OK != expDiagChannelOpen(interp,argv[0])) { return TCL_ERROR; } newChannel = TRUE; argc--;argv++; } if (argc != 1) goto usage; /* if no -f given, close file */ if (!newChannel) { expDiagChannelClose(interp); } expDiagToStderrSet(atoi(*argv)); return(TCL_OK); usage: exp_error(interp,"usage: [-f file] 0|1"); return TCL_ERROR; } char *exp_onexit_action = 0; /*ARGSUSED*/ 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; } } Tcl_Exit(value); /*NOTREACHED*/ return TCL_OK; } /*ARGSUSED*/ static int Exp_CloseObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { int onexec_flag = FALSE; /* true if -onexec seen */ int close_onexec; int slave_flag = FALSE; ExpState *esPtr = 0; char *chanName = 0; int objc_orig = objc; Tcl_Obj *CONST *objv_orig = objv; objc--; objv++; for (;objc>0;objc--,objv++) { if (streq("-i",Tcl_GetString(*objv))) { objc--; objv++; if (objc == 0) { exp_error(interp,"usage: -i spawn_id"); return(TCL_ERROR); } chanName = Tcl_GetString(*objv); } else if (streq(Tcl_GetString(*objv),"-slave")) { slave_flag = TRUE; } else if (streq(Tcl_GetString(*objv),"-onexec")) { objc--; objv++; if (objc == 0) { exp_error(interp,"usage: -onexec 0|1"); return(TCL_ERROR); } onexec_flag = TRUE; close_onexec = atoi(Tcl_GetString(*objv)); } else break; } if (objc) { /* 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_CloseObjCmd(info.clientData,interp,objc_orig,objv_orig)); } if (chanName) { if (!(esPtr = expStateFromChannelName(interp,chanName,1,0,0,"close"))) return TCL_ERROR; } else { if (!(esPtr = expStateCurrent(interp,1,0,0))) return TCL_ERROR; } if (slave_flag) { if (esPtr->fd_slave != EXP_NOFD) { close(esPtr->fd_slave); esPtr->fd_slave = EXP_NOFD; exp_slave_control(esPtr->fdin,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 */ // fcntl(esPtr->fdin,F_SETFD,close_onexec); return TCL_OK; } return(exp_close(interp,esPtr)); } /*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 expErrorLog */ expErrorLog("%2d",level); for (i = 0;i<level;i++) expErrorLogU(" "); expErrorLogU(command); expErrorLogU("\r\n"); } /*ARGSUSED*/ static int Exp_StraceCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; |
︙ | ︙ | |||
2212 2213 2214 2215 2216 2217 2218 | } /* 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) | | < > > < > > | < | < < | < > > | > | > | < < < > > | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | < < < < | < > | < < < | < | | | | | < < | | | < < | | | | < | | | < | < | | < < | | | | < < < < < < < < | | | | > > < | | > | < < | < > | | | | < < | | > > > | | | | | < | | | > > | < < > | < < < < < < < < | < < < < < | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > > | > > > > > > | > | | | | | > > > > > | > > > > > | > > > | | | > > | > > > > | | > > > | > | > > | > > > | | | > | > | > > > | > > | > > > > > > | > > > > > > | | | > > > > | | < | > | > > > | > > > | > | > | > > > > > > > > > > > > > > > > > > > | > > > | > > | > | > > > | | > > > > > > > > > > > > > > | | | | > > > > > | | | | > > | > | > | > > > > | < | > > > > | > > > > | > > > > | > > > | > > | > | < > | | > > > | > | > > > > | | | | | < < < < < < < < < | < < < < < < < < | | < < < < < < < < < < < < < < < < < > > | | < | | | | > < < | > | | < < > | < < < < > | | < > > | > > > > > > > > > > > | | | | | | | | | | | > < | | < < > | < | > > | | | | | < > > > > | | | | | < | < | < | < | < | | | < | | | < | < | | < | | | | | | | | | < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 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 | } /* 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, NULL); 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; { char *chanName = 0; struct ExpState *esPtr; struct forked_proc *fp = 0; /* handle to a pure forked proc */ struct ExpState esTmp; /* temporary memory for either f or fp */ char spawn_id[20]; 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); } chanName = *argv; } else if (streq(*argv,"-nowait")) { nowait = TRUE; } } if (!chanName) { if (!(esPtr = expStateCurrent(interp,0,0,1))) return TCL_ERROR; } else { if (!(esPtr = expStateFromChannelName(interp,chanName,0,0,1,"wait"))) return TCL_ERROR; } if (!expStateAnyIs(esPtr)) { /* check if waited on already */ /* things opened by "open" or set with -nowait */ /* are marked sys_waited already */ if (!esPtr->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,(Tcl_Pid *)&esPtr->pid); exp_wait_zero(&esPtr->wait); } else { while (1) { if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(rc); } result = waitpid(esPtr->pid,&esPtr->wait,0); if (result == esPtr->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 */ strcpy(spawn_id,esPtr->name); } 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. */ int waited_on_forked_process = 0; esPtr = expWaitOnAny(); if (!esPtr) { /* 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; restart: result = waitpid(fp->pid,&fp->wait_status,WNOHANG); if (result == fp->pid) { waited_on_forked_process = 1; break; } if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart; else break; } } if (waited_on_forked_process) { /* * The literal spawn id in the return value from wait appears * as a -1 to indicate a forked process was waited on. */ strcpy(spawn_id,"-1"); } else { result = NO_CHILD; /* no children */ Tcl_ReapDetachedProcs(); } exp_rearm_sigchld(interp); } } /* sigh, wedge forked_proc into an ExpState structure so we don't * have to rewrite remaining code (too much) */ if (fp) { esPtr = &esTmp; esPtr->pid = fp->pid; esPtr->wait = fp->wait_status; } /* non-portable assumption that pid_t can be printed with %d */ if (result == -1) { sprintf(interp->result,"%d %s -1 %d POSIX %s %s", esPtr->pid,spawn_id,errno,Tcl_ErrnoId(),Tcl_ErrnoMsg(errno)); result = TCL_OK; } else if (result == NO_CHILD) { exp_error(interp,"no children"); return TCL_ERROR; } else { sprintf(interp->result,"%d %s 0 %d", esPtr->pid,spawn_id,WEXITSTATUS(esPtr->wait)); if (WIFSIGNALED(esPtr->wait)) { Tcl_AppendElement(interp,"CHILDKILLED"); Tcl_AppendElement(interp,Tcl_SignalId((int)(WTERMSIG(esPtr->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WTERMSIG(esPtr->wait)))); } else if (WIFSTOPPED(esPtr->wait)) { Tcl_AppendElement(interp,"CHILDSUSP"); Tcl_AppendElement(interp,Tcl_SignalId((int) (WSTOPSIG(esPtr->wait)))); Tcl_AppendElement(interp,Tcl_SignalMsg((int) (WSTOPSIG(esPtr->wait)))); } } if (fp) { fp->link_status = not_in_use; return ((result == -1)?TCL_ERROR:TCL_OK); } esPtr->sys_waited = TRUE; esPtr->user_waited = TRUE; /* if user has already called close, forget about this entry entirely */ if (!esPtr->open) { if (esPtr->registered) { Tcl_UnregisterChannel(interp,esPtr->channel); } } 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); expDiagLog("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; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* tell CenterLine 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 we're in a child that's about to be disconnected from the controlling tty, close and reopen 0, 1, and 2 but associated with /dev/null. This prevents send and expect_user doing special things if newly spawned processes accidentally get allocated 0, 1, and 2. */ if (isatty(0)) { ExpState *stdinout = tsdPtr->stdinout; if (stdinout->valid) { exp_close(interp,stdinout); if (stdinout->registered) { Tcl_UnregisterChannel(interp,stdinout->channel); } } open("/dev/null",0); open("/dev/null",1); /* tsdPtr->stdinout = expCreateChannel(interp,0,1,EXP_NOPID);*/ /* tsdPtr->stdinout->keepForever = 1;*/ } if (isatty(2)) { ExpState *devtty = tsdPtr->devtty; /* reopen stderr saves error checking in error/log routines. */ if (devtty->valid) { exp_close(interp,devtty); if (devtty->registered) { Tcl_UnregisterChannel(interp,devtty->channel); } } open("/dev/null",1); /* tsdPtr->devtty = expCreateChannel(interp,2,2,EXP_NOPID);*/ /* tsdPtr->devtty->keepForever = 1;*/ } 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); expSetpgrp(); #else expSetpgrp(); /*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 */ expSetpgrp(); /* 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++; expDiagLog("overlay: mapping fd %d to %d\r\n",oldfd,newfd); if (oldfd != newfd) (void) dup2(oldfd,newfd); else expDiagLog("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); execvp(command,argv); exp_error(interp,"execvp(%s): %s\r\n",argv[0],Tcl_PosixError(interp)); return(TCL_ERROR); } /*ARGSUSED*/ int Exp_InterpreterObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { Tcl_Obj *eofObj = 0; int i; int index; int rc; static char *options[] = { "-eof", (char *)0 }; enum options { FLAG_EOF }; for (i = 1; i < objc; i++) { if (Tcl_GetIndexFromObj(interp, objv[i], options, "flag", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case FLAG_EOF: i++; if (i >= objc) { Tcl_WrongNumArgs(interp, 1, objv,"-eof cmd"); return TCL_ERROR; } eofObj = objv[i]; Tcl_IncrRefCount(eofObj); break; } } /* errors and ok, are caught by exp_interpreter() and discarded */ /* to return TCL_OK, type "return" */ rc = exp_interpreter(interp,eofObj); if (eofObj) Tcl_DecrRefCount(eofObj); return rc; } /* 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_InterReturnObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; { /* 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_ReturnObjCmd(clientData,interp,objc,objv); 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; { ExpState *esPtr; char *chanName = 0; int newfd; int leaveopen = FALSE; Tcl_Channel channel; 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; } chanName = *argv; } else if (streq(*argv,"-leaveopen")) { leaveopen = TRUE; argc--; argv++; } else break; } if (!chanName) { if (!(esPtr = expStateCurrent(interp,1,0,0))) return TCL_ERROR; } else { if (!(esPtr = expStateFromChannelName(interp,chanName,1,0,0,"exp_open"))) return TCL_ERROR; } /* make a new copy of file descriptor */ if (-1 == (newfd = dup(esPtr->fdin))) { exp_error(interp,"dup: %s",Tcl_PosixError(interp)); return TCL_ERROR; } if (!leaveopen) { /* remove from Expect's memory in anticipation of passing to Tcl */ if (esPtr->pid != EXP_NOPID) { Tcl_DetachPids(1,(Tcl_Pid *)&esPtr->pid); esPtr->pid = EXP_NOPID; esPtr->sys_waited = esPtr->user_waited = TRUE; } exp_close(interp,esPtr); } /* * Tcl's MakeFileChannel only allows us to pass a single file descriptor * but that shouldn't be a problem in practice since all of the channels * that Expect generates only have one fd. Of course, this code won't * work if someone creates a pipeline, then passes it to spawn, and then * again to exp_open. For that to work, Tcl would need a new API. * Oh, and we're also being rather cavalier with the permissions here, * but they're likely to be right for the same reasons. */ channel = Tcl_MakeFileChannel((ClientData)newfd,TCL_READABLE|TCL_WRITABLE); Tcl_RegisterChannel(interp, channel); Tcl_AppendResult(interp, Tcl_GetChannelName(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 *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp); Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp); char cmdnamebuf[80]; for (;c->name;c++) { /* if already defined, don't redefine */ if ((c->flags & EXP_REDEFINE) || !(Tcl_FindHashEntry(&globalNsPtr->cmdTable,c->name) || Tcl_FindHashEntry(&currNsPtr->cmdTable,c->name))) { if (c->objproc) Tcl_CreateObjCommand(interp,c->name, c->objproc,c->data,exp_deleteObjProc); else 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); if (c->objproc) Tcl_CreateObjCommand(interp,cmdnamebuf,c->objproc,c->data, exp_deleteObjProc); else Tcl_CreateCommand(interp,cmdnamebuf,c->proc, c->data,exp_deleteProc); } } } static struct exp_cmd_data cmd_data[] = { {"close", Exp_CloseObjCmd, 0, 0, EXP_REDEFINE}, #ifdef TCL_DEBUGGER {"debug", exp_proc(Exp_DebugCmd), 0, 0}, #endif {"exp_internal",exp_proc(Exp_ExpInternalCmd), 0, 0}, {"disconnect", exp_proc(Exp_DisconnectCmd), 0, 0}, {"exit", exp_proc(Exp_ExitCmd), 0, EXP_REDEFINE}, {"exp_continue",exp_proc(Exp_ExpContinueCmd),0, 0}, {"fork", exp_proc(Exp_ForkCmd), 0, 0}, {"exp_pid", exp_proc(Exp_ExpPidCmd), 0, 0}, {"getpid", exp_proc(Exp_GetpidDeprecatedCmd),0, 0}, {"interpreter", Exp_InterpreterObjCmd, 0, 0, 0}, {"log_file", exp_proc(Exp_LogFileCmd), 0, 0}, {"log_user", exp_proc(Exp_LogUserCmd), 0, 0}, {"exp_open", exp_proc(Exp_OpenCmd), 0, 0}, {"overlay", exp_proc(Exp_OverlayCmd), 0, 0}, {"inter_return",Exp_InterReturnObjCmd, 0, 0, 0}, {"send", Exp_SendObjCmd, 0, (ClientData)&sendCD_proc,0}, {"send_error", Exp_SendObjCmd, 0, (ClientData)&sendCD_error,0}, {"send_log", exp_proc(Exp_SendLogCmd), 0, 0}, {"send_tty", Exp_SendObjCmd, 0, (ClientData)&sendCD_tty,0}, {"send_user", Exp_SendObjCmd, 0, (ClientData)&sendCD_user,0}, {"sleep", exp_proc(Exp_SleepCmd), 0, 0}, {"spawn", exp_proc(Exp_SpawnCmd), 0, 0}, {"strace", exp_proc(Exp_StraceCmd), 0, 0}, {"wait", exp_proc(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 */ } |
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 | /* * expDecls.h -- * * Declarations of functions in the platform independent public * Expect API. * * RCS: $Id: expDecls.h,v 1.1.2.5 2001/10/29 20:55:52 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)); /* 1 */ TCL_EXTERN(int) Expect_SafeInit _ANSI_ARGS_((Tcl_Interp * interp)); /* 2 */ TCL_EXTERN(int) Exp_CloseObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 3 */ TCL_EXTERN(int) Exp_ExpInternalCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 4 */ TCL_EXTERN(int) Exp_DisconnectCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 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[])); /* 7 */ TCL_EXTERN(int) Exp_ForkCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 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[])); /* 10 */ TCL_EXTERN(int) Exp_InterpreterObjCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 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[])); /* 14 */ TCL_EXTERN(int) Exp_OverlayCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 15 */ TCL_EXTERN(int) Exp_InterReturnObjCmd _ANSI_ARGS_(( ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 16 */ TCL_EXTERN(int) Exp_SendObjCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 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(char *) exp_printify _ANSI_ARGS_((char * s)); /* Slot 27 is reserved */ /* Slot 28 is reserved */ /* Slot 29 is reserved */ /* Slot 30 is reserved */ /* Slot 31 is reserved */ /* 32 */ TCL_EXTERN(void) exp_parse_argv _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 33 */ TCL_EXTERN(int) exp_interpreter _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * eofObj)); /* 34 */ TCL_EXTERN(int) exp_interpret_cmdfile _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel file)); /* 35 */ TCL_EXTERN(int) exp_interpret_cmdfilename _ANSI_ARGS_(( Tcl_Interp * interp, char * filename)); /* 36 */ TCL_EXTERN(void) exp_interpret_rcfiles _ANSI_ARGS_(( Tcl_Interp * interp, int my_rc, int sys_rc)); /* 37 */ TCL_EXTERN(char *) exp_cook _ANSI_ARGS_((char * s, int * len)); /* 38 */ TCL_EXTERN(void) expCloseOnExec _ANSI_ARGS_((int fd)); /* 39 */ TCL_EXTERN(int) exp_getpidproc _ANSI_ARGS_((void)); /* 40 */ TCL_EXTERN(Tcl_Channel) ExpCreateSpawnChannel _ANSI_ARGS_(( Tcl_Interp * interp, Tcl_Channel chan)); 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 */ int (*expect_SafeInit) _ANSI_ARGS_((Tcl_Interp * interp)); /* 1 */ int (*exp_CloseObjCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 2 */ int (*exp_ExpInternalCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 3 */ int (*exp_DisconnectCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 4 */ 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 */ int (*exp_ForkCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 7 */ 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 */ int (*exp_InterpreterObjCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 10 */ 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 */ int (*exp_OverlayCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int argc, char * argv[])); /* 14 */ int (*exp_InterReturnObjCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 15 */ int (*exp_SendObjCmd) _ANSI_ARGS_((ClientData clientData, Tcl_Interp * interp, int objc, struct Tcl_Obj * CONST objv[])); /* 16 */ 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 */ char * (*exp_printify) _ANSI_ARGS_((char * s)); /* 26 */ void *reserved27; void *reserved28; void *reserved29; void *reserved30; void *reserved31; void (*exp_parse_argv) _ANSI_ARGS_((Tcl_Interp * interp, int argc, char ** argv)); /* 32 */ int (*exp_interpreter) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * eofObj)); /* 33 */ int (*exp_interpret_cmdfile) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel file)); /* 34 */ int (*exp_interpret_cmdfilename) _ANSI_ARGS_((Tcl_Interp * interp, char * filename)); /* 35 */ void (*exp_interpret_rcfiles) _ANSI_ARGS_((Tcl_Interp * interp, int my_rc, int sys_rc)); /* 36 */ char * (*exp_cook) _ANSI_ARGS_((char * s, int * len)); /* 37 */ void (*expCloseOnExec) _ANSI_ARGS_((int fd)); /* 38 */ int (*exp_getpidproc) _ANSI_ARGS_((void)); /* 39 */ Tcl_Channel (*expCreateSpawnChannel) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Channel chan)); /* 40 */ } 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 #ifndef Expect_SafeInit #define Expect_SafeInit \ (expStubsPtr->expect_SafeInit) /* 1 */ #endif #ifndef Exp_CloseObjCmd #define Exp_CloseObjCmd \ (expStubsPtr->exp_CloseObjCmd) /* 2 */ #endif #ifndef Exp_ExpInternalCmd #define Exp_ExpInternalCmd \ (expStubsPtr->exp_ExpInternalCmd) /* 3 */ #endif #ifndef Exp_DisconnectCmd #define Exp_DisconnectCmd \ (expStubsPtr->exp_DisconnectCmd) /* 4 */ #endif #ifndef Exp_ExitCmd #define Exp_ExitCmd \ (expStubsPtr->exp_ExitCmd) /* 5 */ #endif #ifndef Exp_ExpContinueCmd #define Exp_ExpContinueCmd \ (expStubsPtr->exp_ExpContinueCmd) /* 6 */ #endif #ifndef Exp_ForkCmd #define Exp_ForkCmd \ (expStubsPtr->exp_ForkCmd) /* 7 */ #endif #ifndef Exp_ExpPidCmd #define Exp_ExpPidCmd \ (expStubsPtr->exp_ExpPidCmd) /* 8 */ #endif #ifndef Exp_GetpidDeprecatedCmd #define Exp_GetpidDeprecatedCmd \ (expStubsPtr->exp_GetpidDeprecatedCmd) /* 9 */ #endif #ifndef Exp_InterpreterObjCmd #define Exp_InterpreterObjCmd \ (expStubsPtr->exp_InterpreterObjCmd) /* 10 */ #endif #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 #ifndef Exp_OverlayCmd #define Exp_OverlayCmd \ (expStubsPtr->exp_OverlayCmd) /* 14 */ #endif #ifndef Exp_InterReturnObjCmd #define Exp_InterReturnObjCmd \ (expStubsPtr->exp_InterReturnObjCmd) /* 15 */ #endif #ifndef Exp_SendObjCmd #define Exp_SendObjCmd \ (expStubsPtr->exp_SendObjCmd) /* 16 */ #endif #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_printify #define exp_printify \ (expStubsPtr->exp_printify) /* 26 */ #endif /* Slot 27 is reserved */ /* Slot 28 is reserved */ /* Slot 29 is reserved */ /* Slot 30 is reserved */ /* Slot 31 is reserved */ #ifndef exp_parse_argv #define exp_parse_argv \ (expStubsPtr->exp_parse_argv) /* 32 */ #endif #ifndef exp_interpreter #define exp_interpreter \ (expStubsPtr->exp_interpreter) /* 33 */ #endif #ifndef exp_interpret_cmdfile #define exp_interpret_cmdfile \ (expStubsPtr->exp_interpret_cmdfile) /* 34 */ #endif #ifndef exp_interpret_cmdfilename #define exp_interpret_cmdfilename \ (expStubsPtr->exp_interpret_cmdfilename) /* 35 */ #endif #ifndef exp_interpret_rcfiles #define exp_interpret_rcfiles \ (expStubsPtr->exp_interpret_rcfiles) /* 36 */ #endif #ifndef exp_cook #define exp_cook \ (expStubsPtr->exp_cook) /* 37 */ #endif #ifndef expCloseOnExec #define expCloseOnExec \ (expStubsPtr->expCloseOnExec) /* 38 */ #endif #ifndef exp_getpidproc #define exp_getpidproc \ (expStubsPtr->exp_getpidproc) /* 39 */ #endif #ifndef ExpCreateSpawnChannel #define ExpCreateSpawnChannel \ (expStubsPtr->expCreateSpawnChannel) /* 40 */ #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 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 | /* ---------------------------------------------------------------------------- * 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 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.2.5 2001/10/29 06:40:29 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_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 /* * 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_CHANNELNAMELEN (16 + TCL_INTEGER_SPACE) #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')) #define EXP_SPAWN_ID_USER 0 #define EXP_SPAWN_ID_ANY_LIT "-1" #define EXP_SPAWN_ID_VARNAME "spawn_id" #define EXP_CHANNEL_PREFIX "exp" #define EXP_CHANNEL_PREFIX_LENGTH 3 #define isExpChannelName(name) \ (0 == strncmp(name,EXP_CHANNEL_PREFIX,EXP_CHANNEL_PREFIX_LENGTH)) #define exp_is_stdinfd(x) ((x) == 0) #define exp_is_devttyfd(x) ((x) == exp_dev_tty) #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 /* * This structure describes per-instance state of an Exp channel. */ typedef struct ExpState { Tcl_Channel channel; /* Channel associated with this file. */ char name[EXP_CHANNELNAMELEN+1]; /* expect and interact set variables to channel name, so for efficiency cache it here */ int fdin; /* input fd */ int fdout; /* output fd - usually the same as fdin, although may be different if channel opened by tcl::open */ Tcl_Channel channel_orig; /* If opened by someone else, i.e. tcl::open */ int fd_slave; /* slave fd if "spawn -pty" used */ /* this may go away if we find it is not needed */ /* it might be needed by inherited channels */ int validMask; /* OR'ed combination of TCL_READABLE, * TCL_WRITABLE, or TCL_EXCEPTION: indicates * which operations are valid on the file. */ int pid; /* pid or EXP_NOPID if no pid */ Tcl_Obj *buffer; /* input buffer */ int msize; /* # of bytes that buffer can hold (max) */ int umsize; /* # of bytes (min) that is guaranteed to match */ /* this comes from match_max command */ int printed; /* # of bytes written to stdout (if logging on) */ /* but not actually returned via a match yet */ int echoed; /* additional # of bytes (beyond "printed" above) */ /* echoed back but not actually returned via a match */ /* yet. This supports interact -echo */ int rm_nulls; /* if nulls should be stripped before pat matching */ int open; /* if fdin/fdout open */ int user_waited; /* if user has issued "wait" command */ int sys_waited; /* if wait() (or variant) has been called */ int registered; /* if channel registered */ WAIT_STATUS_TYPE wait; /* raw status from wait() */ int parity; /* if parity should be preserved */ 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 notified; /* If Tcl_NotifyChannel has been called and we */ /* have not yet read from the channel. */ int notifiedMask; /* Mask reported when notified. */ int fg_armed; /* If Tcl_CreateFileHandler is active for responding */ /* to foreground events */ #ifdef HAVE_PTYTRAP char *slave_name; /* Full name of slave, i.e., /dev/ttyp0 */ #endif /* HAVE_PTYTRAP */ /* may go away */ int leaveopen; /* If we should not call Tcl's close when we close - */ /* only relevant if Tcl does the original open */ 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; /* * If the channel is freed while in the middle of a bg event handler, * remember that and defer freeing of the ExpState structure until * it is safe. */ int freeWhenBgHandlerUnblocked; /* If channel is closed but not yet waited on, we tie up the fd by * attaching it to /dev/null. We play this little game so that we * can embed the fd in the channel name. If we didn't tie up the * fd, we'd get channel name collisions. I'd consider naming the * channels independently of the fd, but this makes debugging easier. */ int fdBusy; /* * stdinout and stderr never go away so that our internal refs to them * don't have to be invalidated. Having to worry about invalidating them * would be a major pain. */ int keepForever; /* Remember that "reserved" esPtrs are no longer in use. */ int valid; struct ExpState *nextPtr; /* Pointer to next file in list of all * file channels. */ } ExpState; #define EXP_SPAWN_ID_BAD ((ExpState *)0) #define EXP_TIME_INFINITY -1 #define exp_new(x) (x *)ckalloc(sizeof(x)) struct exp_state_list { ExpState *esPtr; struct exp_state_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_state_list *state_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 struct exp_cmd_data { char *name; Tcl_ObjCmdProc *objproc; Tcl_CmdProc *proc; ClientData data; int flags; }; #define exp_deleteProc NULL #define exp_deleteObjProc NULL #define streq(x,y) (0 == strcmp((x),(y))) //typedef struct { // Tcl_Channel channelPtr; // int toWrite; //} ExpSpawnState; /* Global variables */ extern int exp_default_match_max; extern int exp_default_parity; extern int exp_default_rm_nulls; extern Tcl_ChannelType expSpawnChanType; extern int expect_key; extern int exp_configure_count; /* # of times descriptors have been closed or indirect lists have been changed */ extern int exp_nostack_dump; /* TRUE if user has requested unrolling of stack with no trace */ extern char *exp_onexit_action; extern int exp_cmdlinecmds; extern int exp_interactive; extern FILE *exp_cmdfile; extern char *exp_cmdfilename; extern int exp_getpid; /* pid of Expect itself */ extern int exp_buffer_command_input; extern int exp_tcl_debugger_available; extern Tcl_Interp *exp_interp; extern void (*exp_event_exit) _ANSI_ARGS_((Tcl_Interp *)); /* for exp_tty.c */ extern int exp_dev_tty; /* file descriptor to /dev/tty or -1 if none */ extern int exp_ioctled_devtty; extern int exp_stdin_is_tty; extern int exp_stdout_is_tty; typedef struct TERMINAL exp_tty; extern exp_tty exp_tty_original; extern exp_tty exp_tty_current; extern exp_tty exp_tty_cooked; /* * Everything below here should eventually be moved into expect.h * and Expect-thread-safe variables. */ extern char *exp_pty_error; /* place to pass a string generated */ /* deep in the innards of the pty */ /* code but needed by anyone */ extern int exp_disconnected; /* proc. disc'd from controlling tty */ /* protos not yet moved to the Stubs table */ TCL_EXTERN(char *) exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *)); TCL_EXTERN(int) exp_one_arg_braced _ANSI_ARGS_((Tcl_Obj *)); TCL_EXTERN(int) exp_eval_with_one_arg _ANSI_ARGS_((ClientData, Tcl_Interp *, struct Tcl_Obj * CONST objv[])); TCL_EXTERN(void) exp_lowmemcpy _ANSI_ARGS_((char *,char *,int)); TCL_EXTERN(int) exp_flageq_code _ANSI_ARGS_((char *,char *,int)); TCL_EXTERN(void) expAdjust _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_buffer_shuffle _ANSI_ARGS_((Tcl_Interp *,ExpState *,int,char *,char *)); TCL_EXTERN(int) exp_close _ANSI_ARGS_((Tcl_Interp *,ExpState *)); TCL_EXTERN(void) exp_close_all _ANSI_ARGS_((Tcl_Interp *)); //TCL_EXTERN(void) exp_ecmd_remove_fd_direct_and_indirect // _ANSI_ARGS_((Tcl_Interp *,int)); TCL_EXTERN(void) exp_trap_on _ANSI_ARGS_((int)); TCL_EXTERN(int) exp_trap_off _ANSI_ARGS_((char *)); TCL_EXTERN(void) exp_strftime _ANSI_ARGS_((char *format, const struct tm *timeptr,Tcl_DString *dstring)); TCL_EXTERN(void) exp_init_pty _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_pty_exit _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_init_tty _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_init_stdio _ANSI_ARGS_((void)); //TCL_EXTERN(void) exp_init_expect _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_spawn_ids _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_spawn_id_vars _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_trap _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_init_send _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_init_unit_random _ANSI_ARGS_((void)); TCL_EXTERN(void) exp_init_sig _ANSI_ARGS_((void)); TCL_EXTERN(void) expChannelInit _ANSI_ARGS_((void)); TCL_EXTERN(int) expChannelCountGet _ANSI_ARGS_((void)); TCL_EXTERN(int) exp_tcl2_returnvalue _ANSI_ARGS_((int)); TCL_EXTERN(int) exp_2tcl_returnvalue _ANSI_ARGS_((int)); TCL_EXTERN(void) exp_rearm_sigchld _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(int) exp_string_to_signal _ANSI_ARGS_((Tcl_Interp *,char *)); TCL_EXTERN(struct exp_i *) exp_new_i_complex _ANSI_ARGS_((Tcl_Interp *, char *, int, Tcl_VarTraceProc *)); TCL_EXTERN(struct exp_i *) exp_new_i_simple _ANSI_ARGS_((ExpState *,int)); TCL_EXTERN(struct exp_state_list *) exp_new_state _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_free_i _ANSI_ARGS_((Tcl_Interp *,struct exp_i *, Tcl_VarTraceProc *)); TCL_EXTERN(void) exp_free_state _ANSI_ARGS_((struct exp_state_list *)); TCL_EXTERN(void) exp_free_state_single _ANSI_ARGS_((struct exp_state_list *)); TCL_EXTERN(void) exp_i_update _ANSI_ARGS_((Tcl_Interp *, struct exp_i *)); TCL_EXTERN(void) exp_create_commands _ANSI_ARGS_((Tcl_Interp *, struct exp_cmd_data *)); TCL_EXTERN(void) exp_init_main_cmds _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_expect_cmds _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_most_cmds _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_trap_cmds _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_interact_cmds _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_init_tty_cmds(); TCL_EXTERN(ExpState *) expStateCheck _ANSI_ARGS_((Tcl_Interp *,ExpState *,int,int,char *)); TCL_EXTERN(ExpState *) expStateCurrent _ANSI_ARGS_((Tcl_Interp *,int,int,int)); TCL_EXTERN(ExpState *) expStateFromChannelName _ANSI_ARGS_((Tcl_Interp *,char *,int,int,int,char *)); TCL_EXTERN(void) expStateFree _ANSI_ARGS_((ExpState *)); TCL_EXTERN(ExpState *) expCreateChannel _ANSI_ARGS_((Tcl_Interp *,int,int,int)); TCL_EXTERN(ExpState *) expWaitOnAny _ANSI_ARGS_((void)); TCL_EXTERN(ExpState *) expWaitOnOne _ANSI_ARGS_((void)); TCL_EXTERN(void) expExpectVarsInit _ANSI_ARGS_((void)); TCL_EXTERN(int) expStateAnyIs _ANSI_ARGS_((ExpState *)); TCL_EXTERN(int) expDevttyIs _ANSI_ARGS_((ExpState *)); TCL_EXTERN(int) expStdinOutIs _ANSI_ARGS_((ExpState *)); TCL_EXTERN(ExpState *) expStdinoutGet _ANSI_ARGS_((void)); TCL_EXTERN(ExpState *) expDevttyGet _ANSI_ARGS_((void)); TCL_EXTERN(int) expSizeGet _ANSI_ARGS_((ExpState *)); TCL_EXTERN(int) expSizeZero _ANSI_ARGS_((ExpState *)); /* for exp_event.c */ TCL_EXTERN(int) exp_get_next_event _ANSI_ARGS_((Tcl_Interp *,ExpState **, int, ExpState **, int, int)); TCL_EXTERN(int) exp_get_next_event_info _ANSI_ARGS_((Tcl_Interp *, ExpState *)); TCL_EXTERN(int) exp_dsleep _ANSI_ARGS_((Tcl_Interp *, double)); TCL_EXTERN(void) exp_init_event _ANSI_ARGS_((void)); //extern void (*exp_event_exit) _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(void) exp_event_disarm _ANSI_ARGS_((ExpState *,Tcl_FileProc *)); TCL_EXTERN(void) exp_event_disarm_bg _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_event_disarm_fg _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_arm_background_channelhandler _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_disarm_background_channelhandler _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_disarm_background_channelhandler_force _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_unblock_background_channelhandler _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_block_background_channelhandler _ANSI_ARGS_((ExpState *)); TCL_EXTERN(void) exp_background_channelhandler _ANSI_ARGS_((ClientData,int)); /* for exp_log.h */ TCL_EXTERN(void) expDiagInit _ANSI_ARGS_((void)); TCL_EXTERN(int) expDiagChannelOpen _ANSI_ARGS_((Tcl_Interp *,char *)); TCL_EXTERN(Tcl_Channel) expDiagChannelGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expDiagChannelClose _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(char *) expDiagFilename _ANSI_ARGS_((void)); TCL_EXTERN(int) expDiagToStderrGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expDiagToStderrSet _ANSI_ARGS_((int)); TCL_EXTERN(void) expDiagWriteBytes _ANSI_ARGS_((char *,int)); TCL_EXTERN(void) expDiagWriteChars _ANSI_ARGS_((char *,int)); TCL_EXTERN(void) expDiagWriteObj _ANSI_ARGS_((Tcl_Obj *)); TCL_EXTERN(void) expDiagLog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); TCL_EXTERN(void) expDiagLogU _ANSI_ARGS_((char *)); TCL_EXTERN(char *) expPrintify _ANSI_ARGS_((char *)); TCL_EXTERN(char *) expPrintifyObj _ANSI_ARGS_((Tcl_Obj *)); TCL_EXTERN(void) expLogInit _ANSI_ARGS_((void)); TCL_EXTERN(int) expLogChannelOpen _ANSI_ARGS_((Tcl_Interp *,char *,int)); TCL_EXTERN(Tcl_Channel) expLogChannelGet _ANSI_ARGS_((void)); TCL_EXTERN(int) expLogChannelSet _ANSI_ARGS_((Tcl_Interp *,char *)); TCL_EXTERN(void) expLogChannelClose _ANSI_ARGS_((Tcl_Interp *)); TCL_EXTERN(char *) expLogFilenameGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogAppendSet _ANSI_ARGS_((int)); TCL_EXTERN(int) expLogAppendGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogLeaveOpenSet _ANSI_ARGS_((int)); TCL_EXTERN(int) expLogLeaveOpenGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogAllSet _ANSI_ARGS_((int)); TCL_EXTERN(int) expLogAllGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogToStdoutSet _ANSI_ARGS_((int)); TCL_EXTERN(int) expLogToStdoutGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogDiagU _ANSI_ARGS_((char *)); TCL_EXTERN(int) expWriteBytesAndLogIfTtyU _ANSI_ARGS_((ExpState *,char *,int)); TCL_EXTERN(int) expLogUserGet _ANSI_ARGS_((void)); TCL_EXTERN(void) expLogUserSet _ANSI_ARGS_((int)); TCL_EXTERN(void) expLogInteractionU _ANSI_ARGS_((ExpState *,char *)); /* Protos for exp_win.c */ TCL_EXTERN(int) exp_window_size_set _ANSI_ARGS_((int fd)); TCL_EXTERN(int) exp_window_size_get _ANSI_ARGS_((int fd)); TCL_EXTERN(void) exp_win_rows_set _ANSI_ARGS_((char *rows)); TCL_EXTERN(void) exp_win_rows_get _ANSI_ARGS_((char *rows)); TCL_EXTERN(void) exp_win_columns_set _ANSI_ARGS_((char *columns)); TCL_EXTERN(void) exp_win_columns_get _ANSI_ARGS_((char *columns)); TCL_EXTERN(int) exp_win2_size_get _ANSI_ARGS_((int fd)); TCL_EXTERN(int) exp_win2_size_set _ANSI_ARGS_((int fd)); TCL_EXTERN(void) exp_win2_rows_set _ANSI_ARGS_((int fd, char *rows)); TCL_EXTERN(void) exp_win2_rows_get _ANSI_ARGS_((int fd, char *rows)); TCL_EXTERN(void) exp_win2_columns_set _ANSI_ARGS_((int fd, char *columns)); TCL_EXTERN(void) exp_win2_columns_get _ANSI_ARGS_((int fd, char *columns)); /* for exp_tty.c */ TCL_EXTERN(void) exp_tty_raw _ANSI_ARGS_((int set)); TCL_EXTERN(void) exp_tty_echo _ANSI_ARGS_((int set)); TCL_EXTERN(void) exp_tty_break(); TCL_EXTERN(int) exp_tty_raw_noecho(); TCL_EXTERN(int) exp_israw(); TCL_EXTERN(int) exp_isecho(); TCL_EXTERN(void) exp_tty_set(); TCL_EXTERN(int) exp_tty_set_simple _ANSI_ARGS_((exp_tty *tty)); TCL_EXTERN(int) exp_tty_get_simple _ANSI_ARGS_((exp_tty *tty)); /* from exp_int.h */ TCL_EXTERN(void) exp_console_set _ANSI_ARGS_((void)); TCL_EXTERN(void) expDiagLogPtrSet _ANSI_ARGS_((void (*)_ANSI_ARGS_((char *)))); TCL_EXTERN(void) expDiagLogPtr _ANSI_ARGS_((char *)); TCL_EXTERN(void) expDiagLogPtrX _ANSI_ARGS_((char *,int)); TCL_EXTERN(void) expDiagLogPtrStr _ANSI_ARGS_((char *,char *)); TCL_EXTERN(void) expDiagLogPtrStrStr _ANSI_ARGS_((char *,char *,char *)); TCL_EXTERN(void) expErrnoMsgSet _ANSI_ARGS_((char * (*) _ANSI_ARGS_((int)))); TCL_EXTERN(char *) expErrnoMsg _ANSI_ARGS_((int)); /* from expect.h */ TCL_EXTERN(void) exp_slave_control _ANSI_ARGS_((int,int)); /* not sure where to put this, yet. */ TCL_EXTERN(int) ExpPlatformSpawnOutput _ANSI_ARGS_(( ClientData instanceData, char *bufPtr, int toWrite, int *errorPtr)); TCL_EXTERN(int) ExpPlatformSpawnInput _ANSI_ARGS_(( ClientData instanceData, char *bufPtr, int toRead, int *errorPtr)); /* unsure if this should be here */ TCL_EXTERN(void) exp_ecmd_remove_state_direct_and_indirect _ANSI_ARGS_(( Tcl_Interp *interp, ExpState *esPtr)); /* *---------------------------------------------------------------- * Functions shared among Exp modules but not used by the outside * world: *---------------------------------------------------------------- */ extern void expErrorLog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); extern void expErrorLogU _ANSI_ARGS_((char *)); extern void expStdoutLog _ANSI_ARGS_(TCL_VARARGS(int,force_stdout)); extern void expStdoutLogU _ANSI_ARGS_((char *buf, int force_stdout)); extern void exp_debuglog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); #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 | /* * expIntDecls.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 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.2.5 2001/10/29 06:40:29 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: */ typedef struct ExpIntStubs { int magic; struct ExpIntStubHooks *hooks; } 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: */ #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 | /* ---------------------------------------------------------------------------- * expPlatIntDecls.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 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.2.4 2001/11/07 10:06:30 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, char * fullPath)); /* 1 */ TCL_EXTERN(DWORD) ExpWinCreateProcess _ANSI_ARGS_((int argc, char ** argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, Tcl_Pid * pidPtr, 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)); #endif /* __WIN32__ */ typedef struct ExpIntPlatStubs { int magic; struct ExpIntPlatStubHooks *hooks; #ifdef __WIN32__ DWORD (*expWinApplicationType) _ANSI_ARGS_((const char * originalName, char * fullPath)); /* 0 */ DWORD (*expWinCreateProcess) _ANSI_ARGS_((int argc, char ** argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, Tcl_Pid * pidPtr, PDWORD globalPidPtr)); /* 1 */ void (*expWinSyslog) _ANSI_ARGS_(TCL_VARARGS(DWORD,errId)); /* 2 */ TCHAR* (*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 */ #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 #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 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.2.5 2001/10/29 06:40:29 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: tclPort.h,v 1.5 1999/05/25 01:00:27 stanton 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__ */ |
Changes to generic/expSpawnChan.c.
1 | /* | | | | | | | > > | | | | | < > | | < > > > | | < > | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * expSpawnChan.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. * * 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 "tclInt.h" #include "tclPort.h" #include "expect_tcl.h" #include "exp_command.h" #include "expWin.h" static int ExpSpawnBlockProc _ANSI_ARGS_((ClientData instanceData, int mode)); static int ExpSpawnCloseProc _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp)); static int ExpSpawnInputProc _ANSI_ARGS_((ClientData instanceData, char *bufPtr, int bufSize, int *errorPtr)); static int ExpSpawnOutputProc _ANSI_ARGS_((ClientData instanceData, char *bufPtr, int toWrite, int *errorPtr)); static int ExpSpawnGetOptionProc _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp, char *nameStr, Tcl_DString *dsPtr)); static int ExpSpawnSetOptionProc _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp, char *nameStr, char *val)); static void ExpSpawnWatchProc _ANSI_ARGS_((ClientData instanceData, int mask)); static int ExpSpawnGetHandleProc _ANSI_ARGS_((ClientData instanceData, int direction, ClientData *handlePtr)); /* * This structure describes the channel type structure for Expect-based IO: */ Tcl_ChannelType expSpawnChanType = { "exp_spawn", /* Type name. */ TCL_CHANNEL_VERSION_1, /* Version of the channel type. */ ExpSpawnCloseProc, /* Close proc. */ ExpSpawnInputProc, /* Input proc. */ ExpSpawnOutputProc, /* Output proc. */ NULL, /* Seek proc. */ ExpSpawnSetOptionProc, /* Set option proc. */ ExpSpawnGetOptionProc, /* Get option proc. */ ExpSpawnWatchProc, /* Initialize notifier. */ ExpSpawnGetHandleProc, /* Get OS handles out of channel. */ NULL, /* Close2 proc */ ExpSpawnBlockProc /* Set blocking/nonblocking mode. * Expect channels are always blocking */ }; typedef struct ThreadSpecificData { /* * List of all exp channels currently open. This is per thread and is * used to match up fd's to channels, which rarely occurs. */ ExpState *firstExpPtr; int channelCount; /* this is process-wide as it is used to give user some hint as to why a spawn has failed by looking at process-wide resource usage */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* *---------------------------------------------------------------------- * * expChannelInit -- * * Inits the TSD structure for the calling thread context. * * Results: * nothing * * Side Effects: * A datakey and associated TSD structure now exists for the * calling thread context. * *---------------------------------------------------------------------- */ void expChannelInit() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->channelCount = 0; } /* *---------------------------------------------------------------------- * * expChannelCountGet -- * * . * * Results: * Count of how many spawn channels are open. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int expChannelCountGet() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->channelCount; } /* *---------------------------------------------------------------------- * * expSizeGet -- * * Get how much data is currently in the channel's buffer. * * Results: * bytes in use. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int expSizeGet(esPtr) ExpState *esPtr; { int len; Tcl_GetStringFromObj(esPtr->buffer,&len); return len; } /* *---------------------------------------------------------------------- * * expSizeZero -- * * Asks if the buffer is empty. * * Results: * Boolean. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int expSizeZero(esPtr) ExpState *esPtr; { int len; Tcl_GetStringFromObj(esPtr->buffer,&len); return (len == 0); } /* *---------------------------------------------------------------------- * * expStateFree -- * * Asks if the buffer is empty. * * Results: * Boolean. * * Side Effects: * None. * *---------------------------------------------------------------------- */ void expStateFree(esPtr) ExpState *esPtr; { if (esPtr->fdBusy) { // close(esPtr->fdin); /* BUG: not OS neutral */ // expPlatformStateFree(esPtr); } esPtr->valid = FALSE; if (!esPtr->keepForever) { ckfree((char *)esPtr); } } /* *---------------------------------------------------------------------- * * exp_close_all -- * * 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. * * Results: * A Tcl channel * * Side Effects: * Allocates and registers a channel * *---------------------------------------------------------------------- */ void exp_close_all(interp) Tcl_Interp *interp; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; /* no need to keep things in sync (i.e., tsdPtr, count) since we could only be doing this if we're exiting. Just close everything down. */ for (esPtr = tsdPtr->firstExpPtr; esPtr; esPtr = esPtr->nextPtr) { exp_close(interp, esPtr); } } /* *---------------------------------------------------------------------- * * expWaitOnAny -- * * 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. * * Results: * returns the ExpState or 0 if nothing to wait on * * Side Effects: * * *---------------------------------------------------------------------- */ ExpState * expWaitOnAny() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int result; ExpState *esPtr; for (esPtr = tsdPtr->firstExpPtr; esPtr; esPtr = esPtr->nextPtr) { if (esPtr->pid == exp_getpid) continue; /* skip ourself */ if (esPtr->user_waited) continue; /* one wait only! */ if (esPtr->sys_waited) break; restart: result = waitpid(esPtr->pid, &esPtr->wait, WNOHANG); /* BUG: not OS neutral */ if (result == esPtr->pid) break; if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart; else break; } } return esPtr; } /* *---------------------------------------------------------------------- * * expWaitOnOne -- * * Add comment here. * * Results: * * * Side Effects: * * *---------------------------------------------------------------------- */ ExpState * expWaitOnOne() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; int pid; /* should really be recoded using the common wait code in command.c */ WAIT_STATUS_TYPE status; pid = wait(&status); /* BUG: not OS neutral */ for (esPtr = tsdPtr->firstExpPtr; esPtr; esPtr = esPtr->nextPtr) { if (esPtr->pid == pid) { esPtr->sys_waited = TRUE; esPtr->wait = status; return esPtr; } } return 0; } /* *---------------------------------------------------------------------- * * ExpCreateSpawnChannel -- * * Create an expect spawn identifier * * Results: * A Tcl channel * * Side Effects: * Allocates and registers a channel * *---------------------------------------------------------------------- */ void exp_background_channelhandlers_run_all() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; /* kick off any that already have input waiting */ for (esPtr = tsdPtr->firstExpPtr; esPtr; esPtr = esPtr->nextPtr) { /* is bg_interp the best way to check if armed? */ if (esPtr->bg_interp && !expSizeZero(esPtr)) { exp_background_channelhandler((ClientData)esPtr,0); } } } /* *---------------------------------------------------------------------- * * ExpCreateSpawnChannel -- * * Create an expect spawn identifier |
︙ | ︙ | |||
70 71 72 73 74 75 76 | Tcl_Channel ExpCreateSpawnChannel(interp, chan) Tcl_Interp *interp; Tcl_Channel chan; { ExpSpawnState *ssPtr; | | > > > > | | | > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < | < < < | | | | | | | | < < | | | | | > | < | | | | | > > > | > | > > > > > > > | > > > | > > > > > > > > | > > > > > | > > > > > > > > > > > > > | | | | | | | | | | | | 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 | Tcl_Channel ExpCreateSpawnChannel(interp, chan) Tcl_Interp *interp; Tcl_Channel chan; { ExpSpawnState *ssPtr; ExpState *esPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); esPtr = (ExpState *) ckalloc((unsigned) sizeof(ExpState)); esPtr->nextPtr = tsdPtr->firstExpPtr; tsdPtr->firstExpPtr = esPtr; //ssPtr->channelPtr = chan; //ssPtr->toWrite = 0; esPtr->fdBusy = FALSE; /* * Setup the expect channel to always flush immediately */ sprintf(esPtr->name, "exp_spawn%d", tsdPtr->channelCount++); chan = Tcl_CreateChannel(&expSpawnChanType, esPtr->name, (ClientData) esPtr, TCL_READABLE|TCL_WRITABLE); Tcl_RegisterChannel(interp, chan); Tcl_SetChannelOption(interp, chan, "-blocking", "0"); Tcl_SetChannelOption(interp, chan, "-buffering", "none"); Tcl_SetChannelOption(interp, chan, "-translation","binary"); esPtr->msize = 0; /* initialize a dummy buffer */ esPtr->buffer = Tcl_NewStringObj("",0); Tcl_IncrRefCount(esPtr->buffer); esPtr->umsize = exp_default_match_max; /* this will reallocate object with an appropriate sized buffer */ expAdjust(esPtr); esPtr->printed = 0; esPtr->echoed = 0; esPtr->rm_nulls = exp_default_rm_nulls; esPtr->parity = exp_default_parity; esPtr->key = expect_key++; esPtr->force_read = FALSE; esPtr->fg_armed = FALSE; esPtr->channel_orig = 0; esPtr->fd_slave = EXP_NOFD; #ifdef HAVE_PTYTRAP esPtr->slave_name = 0; #endif /* HAVE_PTYTRAP */ esPtr->open = TRUE; esPtr->notified = FALSE; esPtr->user_waited = FALSE; esPtr->sys_waited = FALSE; esPtr->bg_interp = 0; esPtr->bg_status = unarmed; esPtr->bg_ecount = 0; esPtr->freeWhenBgHandlerUnblocked = FALSE; esPtr->keepForever = FALSE; esPtr->valid = TRUE; return chan; } /* *---------------------------------------------------------------------- * * ExpSpawnBlockProc -- * * Generic routine to set I/O to blocking or non-blocking. * * Results: * TCL_OK or TCL_ERROR. * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpSpawnBlockProc(instanceData, mode) ClientData instanceData; int mode; /* (in) Block or not */ { return 0; /* BUG: fix me! */ } /* *---------------------------------------------------------------------- * * ExpSpawnInputProc -- * * Generic read routine for expect console * * Returns: * Amount read or -1 with errorcode in errorPtr. * * Side Effects: * Buffer is updated. * *---------------------------------------------------------------------- */ int ExpSpawnInputProc(instanceData, buf, toRead, errorCodePtr) ClientData instanceData; char *buf; /* (in) Ptr to buffer */ int toRead; /* (in) sizeof buffer */ int *errorCodePtr; /* (out) error code */ { ExpState *esPtr = (ExpState *) instanceData; return ExpPlatformSpawnInput(esPtr, buf, toRead, errorCodePtr); } /* *---------------------------------------------------------------------- * * ExpSpawnOutputProc -- * * Write routine for expect console * * Results: * Amount written or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpSpawnOutputProc(instanceData, bufPtr, toWrite, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int toWrite; /* (in) amount to write */ int *errorPtr; /* (out) error code */ { return ExpPlatformSpawnOutput(instanceData, bufPtr, toWrite, errorPtr); } /* *---------------------------------------------------------------------- * * ExpSpawnCloseProc -- * * This procedure is called from the generic IO level to perform * channel-type-specific cleanup when an exp-based channel is closed. * * Results: * 0 if successful, errno if failed. * * Side effects: * Closes the device of the channel. * *---------------------------------------------------------------------- */ int ExpSpawnCloseProc(instanceData, interp) ClientData instanceData; Tcl_Interp *interp; { ExpState *esPtr = (ExpState *) instanceData; ExpState **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); esPtr->registered = FALSE; #if 0 /* Really should check that we created one first. Since we're sharing fds with Tcl, perhaps a filehandler was created with a plain tcl file - we wouldn't want to delete that. Although if user really close Expect's user_spawn_id, it probably doesn't matter anyway. */ Tcl_DeleteFileHandler(esPtr->fdin); #endif /*0*/ Tcl_DecrRefCount(esPtr->buffer); /* Actually file descriptor should have been closed earlier. */ /* So do nothing here */ /* * Conceivably, the process may not yet have been waited for. If this * becomes a requirement, we'll have to revisit this code. But for now, if * it's just Tcl exiting, the processes will exit on their own soon * anyway. */ for (nextPtrPtr = &(tsdPtr->firstExpPtr); (*nextPtrPtr) != NULL; nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { if ((*nextPtrPtr) == esPtr) { (*nextPtrPtr) = esPtr->nextPtr; break; } } tsdPtr->channelCount--; if (esPtr->bg_status == blocked || esPtr->bg_status == disarm_req_while_blocked) { esPtr->freeWhenBgHandlerUnblocked = 1; /* * If we're in the middle of a bg event handler, then the event * handler will have to take care of freeing esPtr. */ } else { expStateFree(esPtr); } return 0; } /* *---------------------------------------------------------------------- * * ExpSpawnSetOptionProc -- * * Set the value of an ExpSpawn channel option * * Results: * TCL_OK and dsPtr updated with the value or TCL_ERROR. * * Side Effects * None. * *---------------------------------------------------------------------- */ int ExpSpawnSetOptionProc(instanceData, interp, nameStr, valStr) ClientData instanceData; Tcl_Interp *interp; char *nameStr; /* (in) Name of option */ char *valStr; /* (in) New value of option */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->setOptionProc) (Tcl_GetChannelInstanceData(channelPtr), interp, nameStr, valStr); } /* *---------------------------------------------------------------------- * * ExpSpawnGetOptionProc -- * * 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. * *---------------------------------------------------------------------- */ int ExpSpawnGetOptionProc(instanceData, interp, nameStr, dsPtr) ClientData instanceData; Tcl_Interp *interp; char *nameStr; /* (in) Name of option to retrieve */ Tcl_DString *dsPtr; /* (in) String to place value */ { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->getOptionProc) (Tcl_GetChannelInstanceData(channelPtr), interp, nameStr, dsPtr); } /* *---------------------------------------------------------------------- * * ExpSpawnGetHandleProc -- * * 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 ExpSpawnGetHandleProc(instanceData, direction, handlePtr) ClientData instanceData; int direction; ClientData *handlePtr; { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; return (Tcl_GetChannelType(channelPtr)->getHandleProc) (Tcl_GetChannelInstanceData(channelPtr), direction, handlePtr); } /* *---------------------------------------------------------------------- * * ExpSpawnWatchProc -- * * Sets up event handling on a expect console Tcl_Channel using * the underlying channel type. * * Results: * Nothing * * Side Effects * None. * *---------------------------------------------------------------------- */ void ExpSpawnWatchProc(instanceData, mask) ClientData instanceData; int mask; { Tcl_Channel channelPtr = ((ExpSpawnState *)instanceData)->channelPtr; (Tcl_GetChannelType(channelPtr)->watchProc) (Tcl_GetChannelInstanceData(channelPtr), mask); return; } |
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 | /* * expStubInit.c -- * * This file contains the initializers for the Expect stub vectors. * * RCS: @(#) $Id: expStubInit.c,v 1.1.2.3 2001/10/29 20:54:09 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, }; ExpIntPlatStubs expIntPlatStubs = { TCL_STUB_MAGIC, NULL, #ifdef __WIN32__ ExpWinApplicationType, /* 0 */ ExpWinCreateProcess, /* 1 */ ExpWinSyslog, /* 2 */ ExpSyslogGetSysMsg, /* 3 */ Exp_WaitPid, /* 4 */ Exp_KillProcess, /* 5 */ ExpWinInit, /* 6 */ #endif /* __WIN32__ */ }; ExpPlatStubs expPlatStubs = { TCL_STUB_MAGIC, NULL, }; static ExpStubHooks expStubHooks = { &expPlatStubs, &expIntStubs, &expIntPlatStubs }; ExpStubs expStubs = { TCL_STUB_MAGIC, &expStubHooks, Expect_Init, /* 0 */ Expect_SafeInit, /* 1 */ Exp_CloseObjCmd, /* 2 */ Exp_ExpInternalCmd, /* 3 */ Exp_DisconnectCmd, /* 4 */ Exp_ExitCmd, /* 5 */ Exp_ExpContinueCmd, /* 6 */ Exp_ForkCmd, /* 7 */ Exp_ExpPidCmd, /* 8 */ Exp_GetpidDeprecatedCmd, /* 9 */ Exp_InterpreterObjCmd, /* 10 */ Exp_LogFileCmd, /* 11 */ Exp_LogUserCmd, /* 12 */ Exp_OpenCmd, /* 13 */ Exp_OverlayCmd, /* 14 */ Exp_InterReturnObjCmd, /* 15 */ Exp_SendObjCmd, /* 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_printify, /* 26 */ NULL, /* 27 */ NULL, /* 28 */ NULL, /* 29 */ NULL, /* 30 */ NULL, /* 31 */ exp_parse_argv, /* 32 */ exp_interpreter, /* 33 */ exp_interpret_cmdfile, /* 34 */ exp_interpret_cmdfilename, /* 35 */ exp_interpret_rcfiles, /* 36 */ exp_cook, /* 37 */ expCloseOnExec, /* 38 */ exp_getpidproc, /* 39 */ ExpCreateSpawnChannel, /* 40 */ }; /* !END!: Do not edit above this line. */ |
Deleted generic/exp_command.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to generic/exp_event.c.
1 2 3 4 | /* exp_event.c - event interface for Expect Written by: Don Libes, NIST, 2/6/90 | < | | < < < < < | < < < < < < < < < | | | < < < < < < < | < < < < | | < < < < < < < < | | < < < < < < < | | | < | < < | < < < < < | < < < < < < | < < < | | < < | < | > | > | < < < < | < < | < < | | | < < | < < < | < < < | < < < < < < < < < < < < < < < < < < < < < < < < < | | < | < < < < < < < | < | | | < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | | < < < < < < | | | < < < < < < < < < < | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < | > | > > | | | > > > > > | < < | > | | | | < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < | | < < < | | > | > | > > > > > > > | | < < < < | > | < | < < < < < < < < < | | < > | | > | > | | < | | > > > > > > | < < > | | > | | | | | | | | | > > > > > > > > | < > > > > > > > > > > | | < < < < < > | > > | > > > | < < | < < < | > > | > | < < < | > > > | | < < | | > | | | | | | | | | | < < | | | < | < < < < | | > | < < | | | < > | < > > > < < < < | < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | < < < < < < < < < < < < < < < < < < | | | < | < | < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < > > > | 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 | /* exp_event.c - event interface for Expect Written by: Don Libes, NIST, 2/6/90 I hereby place this software in the 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 <errno.h> #include <sys/types.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_PTYTRAP # include <sys/ptyio.h> #endif #include "expInt.h" typedef struct ThreadSpecificData { int rr; /* round robin ptr */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* Local Prototypes used only in this file */ static Tcl_FileProc exp_channelhandler; static Tcl_TimerProc exp_timehandler; static void exp_event_exit_real _ANSI_ARGS_((Tcl_Interp *interp)); void exp_event_disarm_bg(esPtr) ExpState *esPtr; { Tcl_DeleteChannelHandler(esPtr->channel,exp_background_channelhandler,(ClientData)esPtr); } static void exp_arm_background_channelhandler_force(esPtr) ExpState *esPtr; { Tcl_CreateChannelHandler(esPtr->channel, TCL_READABLE|TCL_EXCEPTION, exp_background_channelhandler, (ClientData)esPtr); esPtr->bg_status = armed; } void exp_arm_background_channelhandler(esPtr) ExpState *esPtr; { switch (esPtr->bg_status) { case unarmed: exp_arm_background_channelhandler_force(esPtr); break; case disarm_req_while_blocked: esPtr->bg_status = blocked; /* forget request */ break; case armed: case blocked: /* do nothing */ break; } } void exp_disarm_background_channelhandler(esPtr) ExpState *esPtr; { switch (esPtr->bg_status) { case blocked: esPtr->bg_status = disarm_req_while_blocked; break; case armed: esPtr->bg_status = unarmed; exp_event_disarm_bg(esPtr); break; case disarm_req_while_blocked: case unarmed: /* do nothing */ break; } } /* ignore block status and forcibly disarm handler - 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. */ void exp_disarm_background_channelhandler_force(esPtr) ExpState *esPtr; { switch (esPtr->bg_status) { case blocked: case disarm_req_while_blocked: case armed: esPtr->bg_status = unarmed; exp_event_disarm_bg(esPtr); break; case unarmed: /* do nothing */ break; } } /* this can only be called at the end of the bg handler in which */ /* case we know the status is some kind of "blocked" */ void exp_unblock_background_channelhandler(esPtr) ExpState *esPtr; { switch (esPtr->bg_status) { case blocked: exp_arm_background_channelhandler_force(esPtr); break; case disarm_req_while_blocked: exp_disarm_background_channelhandler_force(esPtr); break; } } /* this can only be called at the beginning of the bg handler in which */ /* case we know the status must be "armed" */ void exp_block_background_channelhandler(esPtr) ExpState *esPtr; { esPtr->bg_status = blocked; exp_event_disarm_bg(esPtr); } /*ARGSUSED*/ static void exp_timehandler(clientData) ClientData clientData; { *(int *)clientData = TRUE; } static void exp_channelhandler(clientData,mask) ClientData clientData; int mask; { ExpState *esPtr = (ExpState *)clientData; esPtr->notified = TRUE; esPtr->notifiedMask = mask; exp_event_disarm_fg(esPtr); } void exp_event_disarm_fg(esPtr) ExpState *esPtr; { /*printf("DeleteChannelHandler: %s\r\n",esPtr->name);*/ Tcl_DeleteChannelHandler(esPtr->channel,exp_channelhandler,(ClientData)esPtr); /* remember that ChannelHandler has been disabled so that */ /* it can be turned on for fg expect's as well as bg */ esPtr->fg_armed = FALSE; } /* returns status, one of EOF, TIMEOUT, ERROR or DATA */ /* can now return RECONFIGURE, too */ /*ARGSUSED*/ int exp_get_next_event(interp,esPtrs,n,esPtrOut,timeout,key) Tcl_Interp *interp; ExpState *(esPtrs[]); int n; /* # of esPtrs */ ExpState **esPtrOut; /* 1st ready esPtr, not set if none */ int timeout; /* seconds */ int key; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; int i; /* index into in-array */ #ifdef HAVE_PTYTRAP struct request_info ioctl_info; #endif int old_configure_count = exp_configure_count; int timerFired = FALSE; Tcl_TimerToken timerToken = 0;/* handle to Tcl timehandler descriptor */ /* We must delete any timer before returning. Doing so throughout * the code makes it unreadable; isolate the unreadable nonsense here. */ #define RETURN(x) { \ if (timerToken) Tcl_DeleteTimerHandler(timerToken); \ return(x); \ } for (;;) { /* if anything has been touched by someone else, report that */ /* an event has been received */ for (i=0;i<n;i++) { tsdPtr->rr++; if (tsdPtr->rr >= n) tsdPtr->rr = 0; esPtr = esPtrs[tsdPtr->rr]; if (esPtr->key != key) { esPtr->key = key; esPtr->force_read = FALSE; *esPtrOut = esPtr; RETURN(EXP_DATA_OLD); } else if ((!esPtr->force_read) && (!expSizeZero(esPtr))) { *esPtrOut = esPtr; RETURN(EXP_DATA_OLD); } else if (esPtr->notified) { /* this test of the mask should be redundant but SunOS */ /* raises both READABLE and EXCEPTION (for no */ /* apparent reason) when selecting on a plain file */ if (esPtr->notifiedMask & TCL_READABLE) { *esPtrOut = esPtr; esPtr->notified = FALSE; RETURN(EXP_DATA_NEW); } /* * at this point we know that the event must be TCL_EXCEPTION * indicating either EOF or HP ptytrap. */ #ifndef HAVE_PTYTRAP RETURN(EXP_EOF); #else if (ioctl(esPtr->fdin,TIOCREQCHECK,&ioctl_info) < 0) { expDiagLog("ioctl error on TIOCREQCHECK: %s", Tcl_PosixError(interp)); RETURN(EXP_TCLERROR); } if (ioctl_info.request == TIOCCLOSE) { RETURN(EXP_EOF); } if (ioctl(esPtr->fdin, 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 */ /* so simply continue by falling thru */ #endif /* !HAVE_PTYTRAP */ } } if (!timerToken) { if (timeout >= 0) { timerToken = Tcl_CreateTimerHandler(1000*timeout, exp_timehandler, (ClientData)&timerFired); } } /* make sure that all fds that should be armed are */ for (i=0;i<n;i++) { esPtr = esPtrs[i]; if (!esPtr->fg_armed) { /*printf("CreateChannelHandler: %s\r\n",esPtr->name);*/ Tcl_CreateChannelHandler( esPtr->channel, TCL_READABLE | TCL_EXCEPTION, exp_channelhandler, (ClientData)esPtr); esPtr->fg_armed = TRUE; } } Tcl_DoOneEvent(0); /* do any event */ if (timerFired) return(EXP_TIMEOUT); if (old_configure_count != exp_configure_count) { RETURN(EXP_RECONFIGURE); } } } /* Having been told there was an event for a specific ExpState, get it */ /* This returns status, one of EOF, TIMEOUT, ERROR or DATA */ /*ARGSUSED*/ int exp_get_next_event_info(interp,esPtr) Tcl_Interp *interp; ExpState *esPtr; { #ifdef HAVE_PTYTRAP struct request_info ioctl_info; #endif if (esPtr->notifiedMask & TCL_READABLE) return EXP_DATA_NEW; /* ready_mask must contain TCL_EXCEPTION */ #ifndef HAVE_PTYTRAP return(EXP_EOF); #else if (ioctl(esPtr->fdin,TIOCREQCHECK,&ioctl_info) < 0) { expDiagLog("ioctl error on TIOCREQCHECK: %s", Tcl_PosixError(interp)); return(EXP_TCLERROR); } if (ioctl_info.request == TIOCCLOSE) { return(EXP_EOF); } if (ioctl(esPtr->fdin, 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 */ /* call it an error for lack of anything more descriptive */ /* it will be thrown away by caller anyway */ return EXP_TCLERROR; #endif } /*ARGSUSED*/ int /* returns TCL_XXX */ exp_dsleep(interp,sec) Tcl_Interp *interp; double sec; { int timerFired = FALSE; Tcl_CreateTimerHandler((int)(sec*1000),exp_timehandler,(ClientData)&timerFired); while (!timerFired) { Tcl_DoOneEvent(0); } return TCL_OK; } static char destroy_cmd[] = "destroy ."; static void exp_event_exit_real(interp) Tcl_Interp *interp; { Tcl_Eval(interp,destroy_cmd); } /* set things up for later calls to event handler */ void exp_init_event() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->rr = 0; exp_event_exit = exp_event_exit_real; } |
Deleted generic/exp_event.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_main_exp.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_main_sub.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_main_tk.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_memmove.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to generic/exp_printify.c.
1 | /* exp_printify - printable versions of random ASCII strings | | | | | | | | > | | < | | > | | > > > > | > | | > > | > > | | > > > > > > > > > > > > > > | > | < | < | | | | | | < | | | | | | | | | | | | | | | | | 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 | /* exp_printify - printable versions of random ASCII strings * * 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. * * RCS: @(#) $Id: exp_printify.c,v 1.1.2.2 2001/10/29 23:34:48 davygrvy Exp $ */ #include "expInt.h" #ifdef NO_STRING_H #include "../compat/string.h" #else #include <string.h> /* for sprintf() */ #endif #include <ctype.h> /* for isascii() and isprint() */ typedef struct ThreadSpecificData { unsigned int destlen; char *dest; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* *---------------------------------------------------------------------- * * exp_printify -- * * Generate printable versions of random ASCII strings. Primarily * used by cmdExpect when -d forces it to print strings it is * examining. * * Results: * Pointer to the thread specific buffer. * * Side effects: * buffer is not freed. * * Comment: * Thread-safe. * *---------------------------------------------------------------------- */ char * exp_printify(s) char *s; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); unsigned int need; char *d; /* ptr into dest */ if (s == 0) return("<null>"); /* worst case is every character takes 4 to printify */ need = strlen(s)*4 + 1; if (need > tsdPtr->destlen) { if (tsdPtr->dest) ckfree(tsdPtr->dest); tsdPtr->dest = ckalloc(tsdPtr->destlen = need); } for (d = tsdPtr->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(tsdPtr->dest); } |
Deleted generic/exp_printify.h.
|
| < < < < < < |
Deleted generic/exp_regexp.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_regexp.h.
|
| < < < < < < < < |
Deleted generic/exp_strf.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted generic/exp_version.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to 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 | /* expect.c - 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 <sys/types.h> #include <stdio.h> #include <signal.h> #include <errno.h> #include <ctype.h> /* for isspace */ #include <time.h> /* for time(3) */ //#include "expect_cf.h" #include "exp_port.h" #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include "tclInt.h" #include "tclPort.h" #include "string.h" #include "exp_rename.h" #include "exp_prog.h" #include "exp_command.h" #include "exp_log.h" #include "exp_event.h" #include "exp_tty.h" #include "exp_tstamp.h" /* this should disappear when interact */ /* loses ref's to it */ #ifdef TCL_DEBUGGER #include "tcldbg.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" typedef struct ThreadSpecificData { int timeout; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* * addr of these placeholders appear as clientData in ExpectCmd * when called * as expect_user and expect_tty. It would be nicer * to invoked * expDevttyGet() but C doesn't allow this in an array initialization, sigh. */ static ExpState StdinoutPlaceholder; static ExpState DevttyPlaceholder; /* 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; Tcl_Obj *pat; /* original pattern spec */ Tcl_Obj *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 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? */ }; /* 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 */ #ifdef SIMPLE_EVENT static int alarm_fired; /* if alarm occurs */ #endif //extern void exp_background_channelhandlers_run_all(); /* exp_indirect_updateX is called by Tcl when an indirect variable is set */ /* 1-part Tcl variable names */ static char *exp_indirect_update1 _ANSI_ARGS_((Tcl_Interp *interp, struct exp_cmd_descriptor *ecmd, struct exp_i *exp_i)); /* 2-part Tcl variable names */ static char *exp_indirect_update2 _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)); static Tcl_ObjCmdProc Exp_ExpectObjCmd; static Tcl_ObjCmdProc Exp_ExpectGlobalObjCmd; static Tcl_ObjCmdProc Exp_ExpectObjCmd; static Tcl_CmdProc Exp_MatchMaxCmd; static Tcl_CmdProc Exp_RemoveNullsCmd; static Tcl_CmdProc Exp_ParityCmd; static Tcl_CmdProc Exp_TimestampCmd; #ifdef SIMPLE_EVENT /*ARGSUSED*/ static RETSIGTYPE sigalarm_handler(n) int n; /* unused, for compatibility with STDC */ { alarm_fired = TRUE; } #endif /*SIMPLE_EVENT*/ /* free up everything in ecase */ static void free_ecase(interp,ec,free_ilist) Tcl_Interp *interp; struct ecase *ec; int free_ilist; /* if we should free ilist */ { if (ec->i_list->duration == EXP_PERMANENT) { if (ec->pat) Tcl_DecrRefCount(ec->pat); if (ec->body) Tcl_DecrRefCount(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 up any argv structures in the ecases */ 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; } #if 0 /* no standard defn for this, and some systems don't even have it, so avoid */ /* the whole quagmire by calling it something else */ static char *exp_strdup(s) char *s; { char *news = ckalloc(strlen(s) + 1); strcpy(news,s); return(news); } #endif /* In many places, there is no need to malloc a copy of a string, since it */ /* will be freed before we return to Tcl */ 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); } } /* return TRUE if string appears to be a set of arguments 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 :-) */ 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; } /* 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->iread = FALSE; ec->timestamp = FALSE; 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. */ static int parse_expect_args(interp,eg,default_esPtr,objc,objv) Tcl_Interp *interp; struct exp_cmd_descriptor *eg; ExpState *default_esPtr; /* suggested ExpState 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); 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_esPtr != EXP_SPAWN_ID_BAD) { eg->i_list = exp_new_i_simple(default_esPtr,eg->duration); } else { default_esPtr = expStateCurrent(interp,0,0,1); if (!default_esPtr) goto error; eg->i_list = exp_new_i_simple(default_esPtr,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 */ ec.pat = objv[i]; if (eg->duration == EXP_PERMANENT) Tcl_IncrRefCount(ec.pat); i++; if (i < objc) { ec.body = objv[i]; if (eg->duration == EXP_PERMANENT) Tcl_IncrRefCount(ec.body); } else { ec.body = NULL; } *(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_esPtr != EXP_SPAWN_ID_BAD) { eg->i_list = exp_new_i_simple(default_esPtr,eg->duration); } else { default_esPtr = expStateCurrent(interp,0,0,1); if (!default_esPtr) goto error; eg->i_list = exp_new_i_simple(default_esPtr,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); 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 */ ExpState *esPtr; /* ExpState that matched */ Tcl_Obj *buffer; /* buffer that matched */ int match; /* # of bytes in buffer that matched */ /* or # of bytes in buffer at EOF */ }; /* *---------------------------------------------------------------------- * * string_case_first -- * * Find the first instance of a pattern in a string. * * Results: * Returns the pointer to the first instance of the pattern * in the given string, or NULL if no match was found. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * string_case_first(string,pattern) /* INTL */ register char *string; /* String. */ register char *pattern; /* Pattern, which may contain * special characters. */ { char *s, *p; int offset; Tcl_UniChar ch1, ch2; while (*string != 0) { s = string; p = pattern; while (*s) { s += Tcl_UtfToUniChar(s, &ch1); offset = Tcl_UtfToUniChar(p, &ch2); if (Tcl_UniCharToLower(ch1) != Tcl_UniCharToLower(ch2)) { break; } p += offset; } if (*p == '\0') { return string; } string++; } return NULL; } /* like eval_cases, but handles only a single cases that needs a real */ /* string match */ /* returns EXP_X where X is MATCH, NOMATCH, FULLBUFFER, TCLERRROR */ static int eval_case_string(interp,e,esPtr,o,last_esPtr,last_case,suffix) Tcl_Interp *interp; struct ecase *e; ExpState *esPtr; struct eval_out *o; /* 'output' - i.e., final case of interest */ /* next two args are for debugging, when they change, reprint buffer */ ExpState **last_esPtr; int *last_case; char *suffix; { Tcl_Obj *buffer; Tcl_RegExp re; Tcl_RegExpInfo info; char *str; int length, flags; int result; buffer = esPtr->buffer; str = Tcl_GetStringFromObj(buffer, &length); /* if ExpState or case changed, redisplay debug-buffer */ if ((esPtr != *last_esPtr) || e->Case != *last_case) { expDiagLog("\r\nexpect%s: does \"",suffix); expDiagLogU(expPrintify(str)); expDiagLog("\" (spawn_id %s) match %s ",esPtr->name,pattern_style[e->use]); *last_esPtr = esPtr; *last_case = e->Case; } if (e->use == PAT_RE) { expDiagLog("\""); expDiagLogU(expPrintify(Tcl_GetString(e->pat))); expDiagLog("\"? "); if (e->Case == CASE_NORM) { flags = TCL_REG_ADVANCED; } else { flags = TCL_REG_ADVANCED | TCL_REG_NOCASE; } re = Tcl_GetRegExpFromObj(interp, e->pat, flags); result = Tcl_RegExpExecObj(interp, re, buffer, 0 /* offset */, -1 /* nmatches */, 0 /* eflags */); if (result > 0) { o->e = e; /* * Retrieve the byte offset of the end of the * matched string. */ Tcl_RegExpGetInfo(re, &info); o->match = Tcl_UtfAtIndex(str, info.matches[0].end) - str; o->buffer = buffer; o->esPtr = esPtr; expDiagLogU(yes); return(EXP_MATCH); } else if (result == 0) { expDiagLogU(no); } else { /* result < 0 */ return(EXP_TCLERROR); } } else if (e->use == PAT_GLOB) { int match; /* # of bytes that matched */ expDiagLog("\""); expDiagLogU(expPrintify(Tcl_GetString(e->pat))); expDiagLog("\"? "); if (buffer) { match = Exp_StringCaseMatch(Tcl_GetString(buffer), Tcl_GetString(e->pat), (e->Case == CASE_NORM) ? 0 : 1, &e->simple_start); if (match != -1) { o->e = e; o->match = match; o->buffer = buffer; o->esPtr = esPtr; expDiagLogU(yes); return(EXP_MATCH); } } expDiagLogU(no); } else if (e->use == PAT_EXACT) { int patLength; char *pat = Tcl_GetStringFromObj(e->pat, &patLength); char *p; if (e->Case == CASE_NORM) { p = strstr(str, pat); } else { p = string_case_first(str, pat); } expDiagLog("\""); expDiagLogU(expPrintify(Tcl_GetString(e->pat))); expDiagLog("\"? "); if (p) { e->simple_start = p - str; o->e = e; o->match = patLength; o->buffer = buffer; o->esPtr = esPtr; expDiagLogU(yes); return(EXP_MATCH); } else expDiagLogU(no); } else if (e->use == PAT_NULL) { char *p; expDiagLogU("null? "); p = Tcl_UtfFindFirst(str, 0); if (p) { o->e = e; o->match = p-str; o->buffer = buffer; o->esPtr = esPtr; expDiagLogU(yes); return EXP_MATCH; } expDiagLogU(no); } else if ((Tcl_GetCharLength(esPtr->buffer) == esPtr->msize) && (length > 0)) { expDiagLogU(Tcl_GetString(e->pat)); expDiagLogU("? "); o->e = e; o->match = length; o->buffer = esPtr->buffer; o->esPtr = esPtr; expDiagLogU(yes); return(EXP_FULLBUFFER); } return(EXP_NOMATCH); } /* sets o.e if successfully finds a matching pattern, eof, timeout or deflt */ /* returns original status arg or EXP_TCLERROR */ static int eval_cases(interp,eg,esPtr,o,last_esPtr,last_case,status,esPtrs,mcount,suffix) Tcl_Interp *interp; struct exp_cmd_descriptor *eg; ExpState *esPtr; struct eval_out *o; /* 'output' - i.e., final case of interest */ /* next two args are for debugging, when they change, reprint buffer */ ExpState **last_esPtr; int *last_case; int status; ExpState *(esPtrs[]); int mcount; char *suffix; { int i; ExpState *em; /* ExpState 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_state_list *slPtr; for (slPtr=e->i_list->state_list; slPtr ;slPtr=slPtr->next) { em = slPtr->esPtr; if (expStateAnyIs(em) || em == esPtr) { 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_state_list *slPtr; int j; e = eg->ecd.cases[i]; if (e->use == PAT_TIMEOUT || e->use == PAT_DEFAULT || e->use == PAT_EOF) continue; for (slPtr = e->i_list->state_list; slPtr; slPtr = slPtr->next) { em = slPtr->esPtr; /* if em == EXP_SPAWN_ID_ANY, then user is explicitly asking */ /* every case to be checked against every ExpState */ if (expStateAnyIs(em)) { /* test against each spawn_id */ for (j=0;j<mcount;j++) { status = eval_case_string(interp,e,esPtrs[j],o, last_esPtr,last_case,suffix); if (status != EXP_NOMATCH) return(status); } } else { /* reject things immediately from wrong spawn_id */ if (em != esPtr) continue; status = eval_case_string(interp,e,esPtr,o,last_esPtr,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_state(interp,ecmd,esPtr,direct) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; ExpState *esPtr; int direct; { struct exp_i *exp_i, *next; struct exp_state_list **slPtr; for (exp_i=ecmd->i_list;exp_i;exp_i=next) { next = exp_i->next; if (!(direct & exp_i->direct)) continue; for (slPtr = &exp_i->state_list;*slPtr;) { if (esPtr == ((*slPtr)->esPtr)) { struct exp_state_list *tmp = *slPtr; *slPtr = (*slPtr)->next; exp_free_state_single(tmp); /* if last bg ecase, disarm spawn id */ if ((ecmd->cmdtype == EXP_CMD_BG) && (expStateAnyIs(esPtr))) { esPtr->bg_ecount--; if (esPtr->bg_ecount == 0) { exp_disarm_background_channelhandler(esPtr); esPtr->bg_interp = 0; } } continue; } slPtr = &(*slPtr)->next; } /* if left with no ExpStates (and is direct), get rid of it */ /* and any dependent ecases */ if (exp_i->direct == EXP_DIRECT && !exp_i->state_list) { exp_i_remove_with_ecases(interp,ecmd,exp_i); } } } /* this is called from exp_close to clean up the ExpState */ void exp_ecmd_remove_state_direct_and_indirect(interp,esPtr) Tcl_Interp *interp; ExpState *esPtr; { ecmd_remove_state(interp,&exp_cmds[EXP_CMD_BEFORE],esPtr,EXP_DIRECT|EXP_INDIRECT); ecmd_remove_state(interp,&exp_cmds[EXP_CMD_AFTER],esPtr,EXP_DIRECT|EXP_INDIRECT); ecmd_remove_state(interp,&exp_cmds[EXP_CMD_BG],esPtr,EXP_DIRECT|EXP_INDIRECT); /* force it - explanation in exp_tk.c where this func is defined */ exp_disarm_background_channelhandler_force(esPtr); } /* arm a list of background ExpState's */ static void state_list_arm(interp,slPtr) Tcl_Interp *interp; struct exp_state_list *slPtr; { /* for each spawn id in list, arm if necessary */ for (;slPtr;slPtr=slPtr->next) { ExpState *esPtr = slPtr->esPtr; if (expStateAnyIs(esPtr)) continue; if (esPtr->bg_ecount == 0) { exp_arm_background_channelhandler(esPtr); esPtr->bg_interp = interp; } esPtr->bg_ecount++; } } /* return TRUE if this ecase is used by this fd */ static int exp_i_uses_state(exp_i,esPtr) struct exp_i *exp_i; ExpState *esPtr; { struct exp_state_list *fdp; for (fdp = exp_i->state_list;fdp;fdp=fdp->next) { if (fdp->esPtr == esPtr) 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->Case) Tcl_AppendElement(interp,"-nocase"); if (ec->use == PAT_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,Tcl_GetString(ec->pat)); Tcl_AppendElement(interp,ec->body?Tcl_GetString(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_state_list *fdp; /* if more than one element, add braces */ if (exp_i->state_list->next) Tcl_AppendResult(interp," {",(char *)0); for (fdp = exp_i->state_list;fdp;fdp=fdp->next) { char buf[10]; /* big enough for a small int */ sprintf(buf,"%d",fdp->esPtr); Tcl_AppendElement(interp,buf); } if (exp_i->state_list->next) Tcl_AppendResult(interp,"} ",(char *)0); } } /* return current setting of the permanent expect_before/after/bg */ int expect_info(interp,ecmd,objc,objv) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { struct exp_i *exp_i; int i; int direct = EXP_DIRECT|EXP_INDIRECT; char *iflag = 0; int all = FALSE; /* report on all fds */ ExpState *esPtr = 0; static char *flags[] = {"-i", "-all", "-noindirect", (char *)0}; enum flags {EXP_ARG_I, EXP_ARG_ALL, EXP_ARG_NOINDIRECT}; /* start with 2 to skip over "cmdname -info" */ for (i = 2;i<objc;i++) { /* * Allow abbreviations of switches and report an error if we * get an invalid switch. */ int index; if (Tcl_GetIndexFromObj(interp, objv[i], flags, "flag", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum flags) index) { case EXP_ARG_I: i++; if (i >= objc) { Tcl_WrongNumArgs(interp, 1, objv,"-i spawn_id"); return TCL_ERROR; } break; case EXP_ARG_ALL: all = TRUE; break; case EXP_ARG_NOINDIRECT: direct &= ~EXP_INDIRECT; break; } } 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 (!iflag) { if (!(esPtr = expStateCurrent(interp,0,0,0))) { return TCL_ERROR; } } else if (!(esPtr = expStateFromChannelName(interp,iflag,0,0,0,"dummy"))) { /* not a valid ExpState so assume it is an indirect variable */ 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,iflag)) { 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_state(exp_i,esPtr)) continue; ecase_by_exp_i_append(interp,ecmd,exp_i); } return TCL_OK; } /* Exp_ExpectGlobalObjCmd is invoked to process expect_before/after/background */ /*ARGSUSED*/ int Exp_ExpectGlobalObjCmd(clientData, interp, objc, objv) ClientData clientData; Tcl_Interp *interp; int objc; Tcl_Obj *CONST objv[]; /* Argument objects. */ { int result = TCL_OK; struct exp_i *exp_i, **eip; struct exp_state_list *slPtr; /* temp for interating over state_list */ struct exp_cmd_descriptor eg; int count; 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 (slPtr=exp_i->state_list;slPtr;slPtr=slPtr->next) { ExpState *esPtr = slPtr->esPtr; /* validate all input descriptors */ if (!expStateAnyIs(esPtr)) { if (!expStateCheck(interp,esPtr,1,1,"expect")) { result = TCL_ERROR; goto cleanup; } } /* remove spawn id from exp_i */ ecmd_remove_state(interp,ecmd,esPtr,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); } |
︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 | /* * 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) { | | | | | | | > > > > > > > > > > > > > | < > > > | < | | | | > | > > | | < > | < | > > > > > > | | > > > > > > > | > > | > > > > | > > > > > > > > | | > | < | | | | | | < > | | | | | | | | > | > > > > > > > > | > > > > > > > > | > > | > | > > > > > | < < > | > > > > | | > > > | > > > > > | > > > > | < > > > > > | > > | > > > > | > > > > | | > | > > > > | < < > > > > > | > > > > > > > > > > > > > | | < < < > | < < < < < > | > > | | | | > > > > | | > | > > > | > > | < > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | | | < | < < < | | | > | > | | | | | | > | < | | < < | < < < < < < < < < | | | < | > < | | | | | | > | > | > | < < < | | > < < | < | < < < < | | < | | < < < < | < < < | | | | | | | | | | | | | | < | | | > > > > > > > | > > > | > | > > > > > > > > > > > > > > > > > > > > | | > > | > > | > | > > > | > > | > | | | > > > | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < < < < < < < < < | < < < < < < < < < | < < < < < < < < < < < < < < < < < < | | | | < < < < < | < | | < < < < < < < < < < < < < | < > | | | | | | | | | | | | | | | | | | | > > > | | | | | | | | | < < < > | | | | < < < < < < < | | | | | | | | | | | | | | < < < < < < < < < < < < < | | | | | | | | | | | | | | | | | > > > > | > | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | > > > > > > | < | < > > > > > > > > > | < < > > > > > | > | | > > > > > > > > > > > | < > > | | < < | > | < > | < < < > > > > | | < | > > > > | > > | < | > > > > | > > > > | | > > > > > > > | > > | > > > > | < > > > | | > > > > > > | > > > > > > > > > > > | > > | > > | | > | | | < < | | < < > > | > > | | > > > | < < < > > > > | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | < < > > | | | | | | | | > | | < | | | > | | | | | | | | | | | | | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | > > > > > | > | | | | < < | > > < < < < < < < < < < < < < < < < < < < < < < | | | | < > | | < > | | | < > | | < < | | | < | | | | | | | < | > > > > > > | | < < < < < < < < | > | < | | | | | | | | | | | > | > | | | | | | > | | | | | | | | | | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | /* * 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) { state_list_arm(interp,exp_i->state_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_channelhandlers_run_all(); } return(result); } /* adjusts file according to user's size request */ void expAdjust(esPtr) ExpState *esPtr; { int new_msize; int length; Tcl_Obj *newObj; char *string; int excessBytes; char *excessGuess; char *p; /* * Resize buffer to user's request * 2 + 1. * x2: in case the match straddles two bufferfuls. * +1: for trailing null. */ new_msize = esPtr->umsize*2 + 1; if (new_msize != esPtr->msize) { string = Tcl_GetStringFromObj(esPtr->buffer, &length); if (length > new_msize) { /* * too much data, forget about data at beginning of buffer */ excessBytes = length - new_msize; /* initial guess */ /* * Alas, string + excessBytes may be in the middle of a UTF char. * Find out for sure. */ excessGuess = string + excessBytes; for (p=string;;p=Tcl_UtfNext(p)) { if (p >= excessGuess) break; } /* now we can calculate a valid # of excess bytes */ excessBytes = p - string; newObj = Tcl_NewStringObj(string + excessBytes,length - excessBytes); } else { /* * too little data */ /* first copy what's there */ newObj = Tcl_NewStringObj(string,length); /* * Force object to allocate a buffer at least new_msize bytes long, * then reset correct string length. */ Tcl_SetObjLength(newObj,new_msize); Tcl_SetObjLength(newObj,length); } Tcl_IncrRefCount(newObj); Tcl_DecrRefCount(esPtr->buffer); esPtr->buffer = newObj; esPtr->key = expect_key++; esPtr->msize = new_msize; } } #if OBSOLETE /* Strip parity */ static void expParityStrip(obj,offsetBytes) Tcl_Obj *obj; int offsetBytes; { char *p, ch; int changed = FALSE; for (p = Tcl_GetString(obj) + offsetBytes;*p;p++) { ch = *p & 0x7f; if (ch != *p) changed = TRUE; else *p &= 0x7f; } if (changed) { /* invalidate the unicode rep */ if (obj->typePtr->freeIntRepProc) { obj->typePtr->freeIntRepProc(obj); } } } #endif /*OBSOLETE*/ /* This function is only used when debugging. It checks when a string's internal UTF is sane and whether an offset into the string appears to be at a UTF boundary. */ static void expValid(obj,offset) Tcl_Obj *obj; int offset; { char *s, *end; int len; s = Tcl_GetStringFromObj(obj,&len); if (offset > len) { printf("offset (%d) > length (%d)\n",offset,len); fflush(stdout); abort(); } /* first test for null terminator */ end = s + len; if (*end != '\0') { printf("obj lacks null terminator\n"); fflush(stdout); abort(); } /* check for valid UTF sequence */ while (*s) { Tcl_UniChar uc; s += Tcl_UtfToUniChar(s,&uc); if (s > end) { printf("UTF out of sync with terminator\n"); fflush(stdout); abort(); } } s += offset; while (*s) { Tcl_UniChar uc; s += Tcl_UtfToUniChar(s,&uc); if (s > end) { printf("UTF from offset out of sync with terminator\n"); fflush(stdout); abort(); } } } /* Strip UTF-encoded nulls from object, beginning at offset */ static int expNullStrip(obj,offsetBytes) Tcl_Obj *obj; int offsetBytes; { char *src, *src2; char *dest; Tcl_UniChar uc; int newsize; /* size of obj after all nulls removed */ src2 = src = dest = Tcl_GetString(obj) + offsetBytes; while (*src) { src += Tcl_UtfToUniChar(src,&uc); if (uc != 0) { dest += Tcl_UniCharToUtf(uc,dest); } } newsize = offsetBytes + (dest - src2); Tcl_SetObjLength(obj,newsize); return newsize; } /* returns # of bytes read or (non-positive) error of form EXP_XXX */ /* returns 0 for end of file */ /* If timeout is non-zero, set an alarm before doing the read, else assume */ /* the read will complete immediately. */ /*ARGSUSED*/ static int expIRead(interp,esPtr,timeout,save_flags) /* INTL */ Tcl_Interp *interp; ExpState *esPtr; int timeout; int save_flags; { int cc = EXP_TIMEOUT; int size = expSizeGet(esPtr); if (size + TCL_UTF_MAX >= esPtr->msize) exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect"); size = expSizeGet(esPtr); #ifdef SIMPLE_EVENT restart: alarm_fired = FALSE; if (timeout > -1) { signal(SIGALRM,sigalarm_handler); alarm((timeout > 0)?timeout:1); } #endif cc = Tcl_ReadChars(esPtr->channel, esPtr->buffer, esPtr->msize - (size / TCL_UTF_MAX), 1 /* append */); i_read_errno = errno; #ifdef SIMPLE_EVENT alarm(0); if (cc == -1) { /* check if alarm went off */ if (i_read_errno == EINTR) { if (alarm_fired) { return EXP_TIMEOUT; } else { if (Tcl_AsyncReady()) { int rc = Tcl_AsyncInvoke(interp,TCL_OK); if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc)); } goto restart; } } } #endif return cc; } /* * expRead() 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), expRead will also call * this a successful read (for the purposes if needing to pattern match against * it). */ /* 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) */ int expRead(interp,esPtrs,esPtrsMax,esPtrOut,timeout,key) Tcl_Interp *interp; ExpState *(esPtrs[]); /* If 0, then esPtrOut already known and set */ int esPtrsMax; /* number of esPtrs */ ExpState **esPtrOut; /* Out variable to leave new ExpState. */ int timeout; int key; { ExpState *esPtr; int size; 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 (esPtrs == 0) { /* we already know the ExpState, just find out what happened */ cc = exp_get_next_event_info(interp,*esPtrOut); tcl_set_flags = TCL_GLOBAL_ONLY; } else { cc = exp_get_next_event(interp,esPtrs,esPtrsMax,esPtrOut,timeout,key); tcl_set_flags = 0; } esPtr = *esPtrOut; if (cc == EXP_DATA_NEW) { /* try to read it */ cc = expIRead(interp,esPtr,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) { /* successfully read data */ } else { /* failed to read data - some sort of error was encountered such as * an interrupt with that forced an error return */ } } else if (cc == EXP_DATA_OLD) { 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 fd=%d): %s",esPtr->fdin, Tcl_PosixError(interp)); exp_close(interp,esPtr); } 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 */ size = expSizeGet(esPtr); if (size) write_count = size - esPtr->printed; else write_count = 0; if (write_count) { /* * Show chars to user if they've requested it, UNLESS they're seeing it * already because they're typing it and tty driver is echoing it. * Also send to Diag and Log if appropriate. */ expLogInteractionU(esPtr,Tcl_GetString(esPtr->buffer) + esPtr->printed); /* * strip 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 (esPtr->rm_nulls) size = expNullStrip(esPtr->buffer,esPtr->printed); esPtr->printed = 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,esPtr,save_flags,array_name,caller_name) /* INTL */ Tcl_Interp *interp; ExpState *esPtr; int save_flags; char *array_name; char *caller_name; { char *str; char *middleGuess; char *p; int length, newlen; int skiplen; char lostByte; /* * allow user to see data we are discarding */ expDiagLog("%s: set %s(spawn_id) \"%s\"\r\n", caller_name,array_name,esPtr->name); Tcl_SetVar2(interp,array_name,"spawn_id",esPtr->name,save_flags); /* * The internal storage buffer object should only be referred * to by the channel that uses it. We always copy the contents * out of the object before passing the data to anyone outside * of these routines. This ensures that the object always has * a refcount of 1 so we can safely modify the contents in place. */ if (Tcl_IsShared(esPtr->buffer)) { panic("exp_buffer_shuffle called with shared buffer object"); } str = Tcl_GetStringFromObj(esPtr->buffer,&length); /* guess at the middle */ middleGuess = str + length/2; /* crawl our way into the middle of the string * to make sure we are at a UTF char boundary */ for (p=str;*p;p = Tcl_UtfNext(p)) { if (p > middleGuess) break; /* ok, that's enough */ } /* * p is now at the beginning of a UTF char in the middle of the string */ /* * before doing move, show user data we are discarding */ skiplen = p-str; lostByte = *p; /* temporarily stick null in middle of string */ Tcl_SetObjLength(esPtr->buffer,skiplen); expDiagLog("%s: set %s(buffer) \"",caller_name,array_name); expDiagLogU(expPrintify(Tcl_GetString(esPtr->buffer))); expDiagLogU("\"\r\n"); Tcl_SetVar2(interp,array_name,"buffer",Tcl_GetString(esPtr->buffer), save_flags); /* * restore damage */ *p = lostByte; /* * move 2nd half of string down to 1st half */ newlen = length - skiplen; memmove(str,p, newlen); Tcl_SetObjLength(esPtr->buffer,newlen); esPtr->printed -= skiplen; if (esPtr->printed < 0) esPtr->printed = 0; } /* map EXP_ style return value to TCL_ style return value */ /* not defined to work on TCL_OK */ #ifdef _MSC_VER # pragma warning(disable: 4715) #endif 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; } } /* 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; } } #ifdef _MSC_VER # pragma warning(default: 4715) #endif /* 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. */ char * exp_get_var(interp,var) Tcl_Interp *interp; char *var; { char *val; if (NULL != (val = Tcl_GetVar(interp,var,0 /* local */))) return(val); return(Tcl_GetVar(interp,var,TCL_GLOBAL_ONLY)); } static int get_timeout(interp) Tcl_Interp *interp; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); char *t; if (NULL != (t = exp_get_var(interp,EXPECT_TIMEOUT))) { tsdPtr->timeout = atoi(t); } return(tsdPtr->timeout); } /* make a copy of a linked list (1st arg) and attach to end of another (2nd arg) */ static int update_expect_states(i_list,i_union) struct exp_i *i_list; struct exp_state_list **i_union; { struct exp_i *p; /* for each i_list in an expect statement ... */ for (p=i_list;p;p=p->next) { struct exp_state_list *slPtr; /* for each esPtr in the i_list */ for (slPtr=p->state_list;slPtr;slPtr=slPtr->next) { struct exp_state_list *tmpslPtr; struct exp_state_list *u; if (expStateAnyIs(slPtr->esPtr)) continue; /* check this one against all so far */ for (u = *i_union;u;u=u->next) { if (slPtr->esPtr == u->esPtr) goto found; } /* if not found, link in as head of list */ tmpslPtr = exp_new_state(slPtr->esPtr); tmpslPtr->next = *i_union; *i_union = tmpslPtr; found:; } } return TCL_OK; } #ifdef _MSC_VER # pragma warning(disable: 4715) #endif 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 } #ifdef _MSC_VER # pragma warning(default: 4715) #endif /* exp_indirect_update2 is called back via Tcl's trace handler whenever */ /* an indirect spawn id list is changed */ /*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_channelhandlers_run_all(); return msg; } static char * exp_indirect_update1(interp,ecmd,exp_i) Tcl_Interp *interp; struct exp_cmd_descriptor *ecmd; struct exp_i *exp_i; { struct exp_state_list *slPtr; /* temp for interating over state_list */ /* * disarm any ExpState's that lose all their ecases */ if (ecmd->cmdtype == EXP_CMD_BG) { /* clean up each spawn id used by this exp_i */ for (slPtr=exp_i->state_list;slPtr;slPtr=slPtr->next) { ExpState *esPtr = slPtr->esPtr; if (expStateAnyIs(esPtr)) 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 (!expStateCheck(interp,slPtr->esPtr,1,0,"")) continue; /* check before decrementing, ecount may not be */ /* positive if update is called before ecount is */ /* properly synchronized */ if (esPtr->bg_ecount > 0) { esPtr->bg_ecount--; } if (esPtr->bg_ecount == 0) { exp_disarm_background_channelhandler(esPtr); esPtr->bg_interp = 0; } } } /* * reread indirect variable */ exp_i_update(interp,exp_i); /* * check validity of all fd's in variable */ for (slPtr=exp_i->state_list;slPtr;slPtr=slPtr->next) { /* validate all input descriptors */ if (expStateAnyIs(slPtr->esPtr)) continue; if (!expStateCheck(interp,slPtr->esPtr,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) { state_list_arm(interp,exp_i->state_list); } return (char *)0; } int expMatchProcess(interp, eo, cc, bg, detail) Tcl_Interp *interp; struct eval_out *eo; /* final case of interest */ int cc; /* EOF, TIMEOUT, etc... */ int bg; /* 1 if called from background handler, */ /* else 0 */ char *detail; { ExpState *esPtr = 0; Tcl_Obj *body = 0; Tcl_Obj *buffer; 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 */ int result = TCL_OK; #define out(indexName, value) \ expDiagLog("%s: set %s(%s) \"",detail,EXPECT_OUT,indexName); \ expDiagLogU(expPrintify(value)); \ expDiagLogU("\"\r\n"); \ Tcl_SetVar2(interp, EXPECT_OUT,indexName,value,(bg ? TCL_GLOBAL_ONLY : 0)); if (eo->e) { e = eo->e; body = e->body; if (cc != EXP_TIMEOUT) { esPtr = eo->esPtr; match = eo->match; buffer = eo->buffer; } } else if (cc == EXP_EOF) { /* read an eof but no user-supplied case */ esPtr = eo->esPtr; match = eo->match; buffer = eo->buffer; } if (match >= 0) { char name[20], value[20]; int i; if (e && e->use == PAT_RE) { Tcl_RegExp re; int flags; Tcl_RegExpInfo info; if (e->Case == CASE_NORM) { flags = TCL_REG_ADVANCED; } else { flags = TCL_REG_ADVANCED | TCL_REG_NOCASE; } re = Tcl_GetRegExpFromObj(interp, e->pat, flags); Tcl_RegExpGetInfo(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(buffer, start, end); expDiagLog("%s: set %s(%s) \"",detail,EXPECT_OUT,name); expDiagLogU(expPrintifyObj(val)); expDiagLogU("\"\r\n"); Tcl_SetVar2Ex(interp,EXPECT_OUT,name,val,(bg ? TCL_GLOBAL_ONLY : 0)); } } 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 = Tcl_GetString(esPtr->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) { expDiagLogU("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->esPtr) { char *str; int length; out("spawn_id",esPtr->name); str = Tcl_GetStringFromObj(esPtr->buffer, &length); /* Save buf[0..match] */ /* temporarily null-terminate string in middle */ match_char = str[match]; str[match] = 0; out("buffer",str); /* remove middle-null-terminator */ str[match] = match_char; /* "!e" means no case matched - transfer by default */ if (!e || e->transfer) { /* delete matched chars from input buffer */ esPtr->printed -= match; if (length != 0) { memmove(str,str+match,length-match); } Tcl_SetObjLength(esPtr->buffer, length-match); } if (cc == EXP_EOF) { /* exp_close() deletes all background bodies */ /* so save eof body temporarily */ if (body) Tcl_IncrRefCount(body); exp_close(interp,esPtr); } } if (body) { if (!bg) { result = Tcl_EvalObjEx(interp,body,0); } else { result = Tcl_EvalObjEx(interp,body,TCL_EVAL_GLOBAL); if (result != TCL_OK) Tcl_BackgroundError(interp); } if (cc == EXP_EOF) Tcl_DecrRefCount(body); } return result; } /* this function is called from the background when input arrives */ /*ARGSUSED*/ void exp_background_channelhandler(clientData,mask) /* INTL */ ClientData clientData; int mask; { ExpState *esPtr; Tcl_Interp *interp; int cc; /* number of bytes returned in a single read */ /* or negative EXP_whatever */ struct eval_out eo; /* final case of interest */ ExpState *last_esPtr; /* for differentiating when multiple esPtrs */ /* to print out better debugging messages */ int last_case; /* as above but for case */ /* restore our environment */ esPtr = (ExpState *)clientData; interp = esPtr->bg_interp; /* temporarily prevent this handler from being invoked again */ exp_block_background_channelhandler(esPtr); /* * 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 { esPtr->notifiedMask = mask; esPtr->notified = FALSE; cc = expRead(interp,(ExpState **)0,0,&esPtr,EXP_TIME_INFINITY,0); } do_more_data: eo.e = 0; /* no final case yet */ eo.esPtr = 0; /* no final file selected yet */ eo.match = 0; /* nothing matched yet */ /* force redisplay of buffer when debugging */ last_esPtr = 0; 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], esPtr,&eo,&last_esPtr,&last_case,cc,&esPtr,1,"_background"); cc = eval_cases(interp,&exp_cmds[EXP_CMD_BG], esPtr,&eo,&last_esPtr,&last_case,cc,&esPtr,1,"_background"); cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER], esPtr,&eo,&last_esPtr,&last_case,cc,&esPtr,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.esPtr = esPtr; eo.match = expSizeGet(eo.esPtr); eo.buffer = eo.esPtr->buffer; expDiagLogU("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: expMatchProcess(interp, &eo, cc, 1 /* bg */,"expect_background"); /* * 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. */ /* * Connection could have been closed on us. In this case, * exitWhenBgStatusUnblocked will be 1 and we should disable the channel * handler and release the esPtr. */ if ((!esPtr->freeWhenBgHandlerUnblocked) && (esPtr->bg_status == blocked)) { if (0 != (cc = expSizeGet(esPtr))) { goto do_more_data; } } finish: exp_unblock_background_channelhandler(esPtr); if (esPtr->freeWhenBgHandlerUnblocked) expStateFree(esPtr); } /*ARGSUSED*/ int Exp_ExpectObjCmd(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 */ ExpState *esPtr = 0; int i; /* misc temporary */ struct exp_cmd_descriptor eg; struct exp_state_list *state_list; /* list of ExpStates to watch */ struct exp_state_list *slPtr; /* temp for interating over state_list */ ExpState **esPtrs; int mcount; /* number of esPtrs 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 */ ExpState *last_esPtr; /* 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; if (&StdinoutPlaceholder == (ExpState *)clientData) { clientData = (ClientData) expStdinoutGet(); } else if (&DevttyPlaceholder == (ExpState *)clientData) { clientData = (ClientData) expDevttyGet(); } /* make arg list for processing cases */ /* do it dynamically, since expect can be called recursively */ exp_cmd_init(&eg,EXP_CMD_FG,EXP_TEMPORARY); state_list = 0; esPtrs = 0; if (TCL_ERROR == parse_expect_args(interp,&eg, (ExpState *)clientData,objc,objv)) return TCL_ERROR; restart_with_update: /* validate all descriptors and flatten ExpStates into array */ if ((TCL_ERROR == update_expect_states(exp_cmds[EXP_CMD_BEFORE].i_list,&state_list)) || (TCL_ERROR == update_expect_states(exp_cmds[EXP_CMD_AFTER].i_list, &state_list)) || (TCL_ERROR == update_expect_states(eg.i_list,&state_list))) { result = TCL_ERROR; goto cleanup; } /* declare ourselves "in sync" with external view of close/indirect */ configure_count = exp_configure_count; /* count and validate state_list */ mcount = 0; for (slPtr=state_list;slPtr;slPtr=slPtr->next) { mcount++; /* validate all input descriptors */ if (!expStateCheck(interp,slPtr->esPtr,1,1,"expect")) { result = TCL_ERROR; goto cleanup; } } /* make into an array */ esPtrs = (ExpState **)ckalloc(mcount * sizeof(ExpState *)); for (slPtr=state_list,i=0;slPtr;slPtr=slPtr->next,i++) { esPtrs[i] = slPtr->esPtr; } 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_esPtr = 0; /* * end of restart code */ eo.e = 0; /* no final case yet */ eo.esPtr = 0; /* no final ExpState 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 = expRead(interp,esPtrs,mcount,&esPtr,remtime,key); } /*SUPPRESS 530*/ if (cc == EXP_EOF) { /* do nothing */ } else if (cc == EXP_TIMEOUT) { expDiagLogU("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_esPtr = 0; } cc = eval_cases(interp,&exp_cmds[EXP_CMD_BEFORE], esPtr,&eo,&last_esPtr,&last_case,cc,esPtrs,mcount,""); cc = eval_cases(interp,&eg, esPtr,&eo,&last_esPtr,&last_case,cc,esPtrs,mcount,""); cc = eval_cases(interp,&exp_cmds[EXP_CMD_AFTER], esPtr,&eo,&last_esPtr,&last_case,cc,esPtrs,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.esPtr = esPtr; eo.match = expSizeGet(eo.esPtr); eo.buffer = eo.esPtr->buffer; expDiagLogU("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 */ esPtr->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: if (result != TCL_ERROR) { result = expMatchProcess(interp, &eo, cc, 0 /* not bg */,"expect"); } cleanup: if (result == EXP_CONTINUE_TIMER) { reset_timer = FALSE; result = EXP_CONTINUE; } if ((result == EXP_CONTINUE) && (configure_count == exp_configure_count)) { expDiagLogU("expect: continuing expect\r\n"); goto restart; } if (state_list) { exp_free_state(state_list); state_list = 0; } if (esPtrs) { ckfree((char *)esPtrs); esPtrs = 0; } if (result == EXP_CONTINUE) { expDiagLogU("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); } /*ARGSUSED*/ static int Exp_TimestampCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; int argc; |
︙ | ︙ | |||
2731 2732 2733 2734 2735 2736 2737 | return TCL_OK; usage_error: exp_error(interp,"args: [-seconds #] [-format format]"); return TCL_ERROR; } | < < < < < < < < < < < < < | | | | > | < | | | | | < | | > | | > > | | | > | | | > | | > | > > | | | | | | | > | < | > > > > > | | | < < < | | | | | | | | | < | | < < < < < < < < > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > | | | | | | | | | | < < < < < < < < < < < < < < < < | | > > | < | | | | | | | | | | | | | | | | | > > > > | > > > > > | 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 | return TCL_OK; usage_error: exp_error(interp,"args: [-seconds #] [-format format]"); return TCL_ERROR; } /*ARGSUSED*/ int Exp_MatchMaxCmd(clientData,interp,argc,argv) ClientData clientData; Tcl_Interp *interp; int argc; char **argv; { int size = -1; ExpState *esPtr = 0; char *chanName = 0; int Default = FALSE; 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); } chanName = *argv; } else break; } if (Default && chanName) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (!Default) { if (!chanName) { if (!(esPtr = expStateCurrent(interp,0,0,0))) { return(TCL_ERROR); } } else { if (!(esPtr = expStateFromChannelName(interp,chanName,0,0,0,"match_max"))) return(TCL_ERROR); } } if (argc == 0) { if (Default) { size = exp_default_match_max; } else { size = esPtr->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 esPtr->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; ExpState *esPtr = 0; char *chanName = 0; int Default = FALSE; 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); } chanName = *argv; } else break; } if (Default && chanName) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (!Default) { if (!chanName) { if (!(esPtr = expStateCurrent(interp,0,0,0))) return(TCL_ERROR); } else { if (!(esPtr = expStateFromChannelName(interp,chanName,0,0,0,"remove_nulls"))) return(TCL_ERROR); } } if (argc == 0) { if (Default) { value = exp_default_rm_nulls; } else { value = esPtr->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 esPtr->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; ExpState *esPtr = 0; char *chanName = 0; int Default = FALSE; 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); } chanName = *argv; } else break; } if (Default && chanName) { exp_error(interp,"cannot do -d and -i at the same time"); return(TCL_ERROR); } if (!Default) { if (!chanName) { if (!(esPtr = expStateCurrent(interp,0,0,0))) { return(TCL_ERROR); } } else { if (!(esPtr = expStateFromChannelName(interp,chanName,0,0,0,"parity"))) { return(TCL_ERROR); } } } if (argc == 0) { if (Default) { parity = exp_default_parity; } else { parity = esPtr->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 esPtr->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(slPtr) struct exp_state_list *slPtr; { if (!slPtr) return; printf("%d ",slPtr->esPtr); exp_fd_print(slPtr->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("ExpStates: "); exp_fd_print(exp_i->state_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*/ void expExpectVarsInit() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->timeout = INIT_EXPECT_TIMEOUT; } static struct exp_cmd_data cmd_data[] = { {"expect", Exp_ExpectObjCmd, 0, (ClientData)0, 0}, {"expect_after",Exp_ExpectGlobalObjCmd, 0, (ClientData)&exp_cmds[EXP_CMD_AFTER],0}, {"expect_before",Exp_ExpectGlobalObjCmd,0, (ClientData)&exp_cmds[EXP_CMD_BEFORE],0}, {"expect_user", Exp_ExpectObjCmd, 0, (ClientData)&StdinoutPlaceholder,0}, {"expect_tty", Exp_ExpectObjCmd, 0, (ClientData)&DevttyPlaceholder,0}, {"expect_background",Exp_ExpectGlobalObjCmd,0, (ClientData)&exp_cmds[EXP_CMD_BG],0}, {"match_max", exp_proc(Exp_MatchMaxCmd), 0, 0}, {"remove_nulls",exp_proc(Exp_RemoveNullsCmd), 0, 0}, {"parity", exp_proc(Exp_ParityCmd), 0, 0}, {"timestamp", exp_proc(Exp_TimestampCmd), 0, 0}, {0}}; 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); 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"; #if 0 Tcl_CreateCommand(interp,"x", cmdX,(ClientData)0,exp_deleteProc); #endif } void exp_init_sig() { #if 0 signal(SIGALRM,sigalarm_handler); signal(SIGINT,sigint_handler); #endif } |
Changes to generic/expect.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* expect.h - include file for using the expect library, libexpect.a from C or C++ (i.e., without Tcl) 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. */ #ifndef _EXPECT_H #define _EXPECT_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 | /* expect.h - include file for using the expect library, libexpect.a from C or C++ (i.e., without Tcl) 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. */ #ifndef _EXPECT_H #define _EXPECT_H #include <stdio.h> #include <setjmp.h> /* * tcl.h -- * * This header file describes the externally-visible facilities * of the Tcl interpreter. * * Copyright (c) 1987-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1993-1996 Lucent Technologies. * Copyright (c) 1998-1999 Scriptics Corporation. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: expect.h,v 5.29 2000/01/06 23:22:05 wart Exp $ */ #ifndef _TCL #define _TCL #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ # endif #endif #ifdef __WIN32__ # ifndef STRICT # define STRICT # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # endif # ifndef HAS_STDARG # define HAS_STDARG 1 # endif # ifndef USE_PROTOTYPE # define USE_PROTOTYPE 1 # endif /* * Under Windows we need to call Tcl_Alloc in all cases to avoid competing * C run-time library issues. */ # ifndef USE_TCLALLOC # define USE_TCLALLOC 1 # endif #endif /* __WIN32__ */ /* * The following definitions set up the proper options for Macintosh * compilers. We use this method because there is no autoconf equivalent. */ #ifdef MAC_TCL # ifndef HAS_STDARG # define HAS_STDARG 1 # endif # ifndef USE_TCLALLOC # define USE_TCLALLOC 1 # endif # ifndef NO_STRERROR # define NO_STRERROR 1 # endif #endif /* * Utility macros: STRINGIFY takes an argument and wraps it in "" (double * quotation marks), JOIN joins two arguments. */ #define VERBATIM(x) x #ifdef _MSC_VER # define STRINGIFY(x) STRINGIFY1(x) # define STRINGIFY1(x) #x # define JOIN(a,b) JOIN1(a,b) # define JOIN1(a,b) a##b #else # ifdef RESOURCE_INCLUDED # define STRINGIFY(x) STRINGIFY1(x) # define STRINGIFY1(x) #x # define JOIN(a,b) JOIN1(a,b) # define JOIN1(a,b) a##b # else # ifdef __STDC__ # define STRINGIFY(x) #x # define JOIN(a,b) a##b # else # define STRINGIFY(x) "x" # define JOIN(a,b) VERBATIM(a)VERBATIM(b) # endif # endif #endif /* * A special definition used to allow this header file to be included * in resource files so that they can get obtain version information from * this file. Resource compilers don't like all the C stuff, like typedefs * and procedure declarations, that occur below. */ #ifndef RESOURCE_INCLUDED #ifndef BUFSIZ #include <stdio.h> #endif /* * Definitions that allow Tcl functions with variable numbers of * arguments to be used with either varargs.h or stdarg.h. TCL_VARARGS * is used in procedure prototypes. TCL_VARARGS_DEF is used to declare * the arguments in a function definiton: it takes the type and name of * the first argument and supplies the appropriate argument declaration * string for use in the function definition. TCL_VARARGS_START * initializes the va_list data structure and returns the first argument. */ #if defined(__STDC__) || defined(HAS_STDARG) # include <stdarg.h> # define TCL_VARARGS(type, name) (type name, ...) # define TCL_VARARGS_DEF(type, name) (type name, ...) # define TCL_VARARGS_START(type, name, list) (va_start(list, name), name) #else # include <varargs.h> # ifdef __cplusplus # define TCL_VARARGS(type, name) (type name, ...) # define TCL_VARARGS_DEF(type, name) (type va_alist, ...) # else # define TCL_VARARGS(type, name) () # define TCL_VARARGS_DEF(type, name) (va_alist) # endif # define TCL_VARARGS_START(type, name, list) \ (va_start(list), va_arg(list, type)) #endif /* * Macros used to declare a function to be exported by a DLL. * Used by Windows, maps to no-op declarations on non-Windows systems. * The default build on windows is for a DLL, which causes the DLLIMPORT * and DLLEXPORT macros to be nonempty. To build a static library, the * macro STATIC_BUILD should be defined. */ #ifdef STATIC_BUILD # define DLLIMPORT # define DLLEXPORT #else # if defined(__WIN32__) && (defined(_MSC_VER) || (defined(__GNUC__) && defined(__declspec))) # define DLLIMPORT __declspec(dllimport) # define DLLEXPORT __declspec(dllexport) # else # define DLLIMPORT # define DLLEXPORT # endif #endif /* * These macros are used to control whether functions are being declared for * import or export. If a function is being declared while it is being built * to be included in a shared library, then it should have the DLLEXPORT * storage class. If is being declared for use by a module that is going to * link against the shared library, then it should have the DLLIMPORT storage * class. If the symbol is beind declared for a static build or for use from a * stub library, then the storage class should be empty. * * The convention is that a macro called BUILD_xxxx, where xxxx is the * name of a library we are building, is set on the compile line for sources * that are to be placed in the library. When this macro is set, the * storage class will be set to DLLEXPORT. At the end of the header file, the * storage class will be reset to DLLIMPORt. */ #undef TCL_STORAGE_CLASS #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_TCL_STUBS # define TCL_STORAGE_CLASS # else # define TCL_STORAGE_CLASS DLLIMPORT # endif #endif /* * Definitions that allow this header file to be used either with or * without ANSI C features like function prototypes. */ #undef _ANSI_ARGS_ #undef CONST #if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE) # define _USING_PROTOTYPES_ 1 # define _ANSI_ARGS_(x) x # define CONST const #else # define _ANSI_ARGS_(x) () # define CONST #endif #ifdef __cplusplus # define EXTERN extern "C" TCL_STORAGE_CLASS #else # define EXTERN extern TCL_STORAGE_CLASS #endif /* * Macro to use instead of "void" for arguments that must have * type "void *" in ANSI C; maps them to type "char *" in * non-ANSI systems. */ #ifndef __WIN32__ #ifndef VOID # ifdef __STDC__ # define VOID void # else # define VOID char # endif #endif #else /* __WIN32__ */ /* * The following code is copied from winnt.h */ #ifndef VOID #define VOID void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif #endif /* __WIN32__ */ /* * Miscellaneous declarations. */ #ifndef NULL #define NULL 0 #endif typedef struct Tcl_RegExp_ *Tcl_RegExp; /* * The following declarations either map ckalloc and ckfree to * malloc and free, or they map them to procedures with all sorts * of debugging hooks defined in tclCkalloc.c. */ #ifdef TCL_MEM_DEBUG # define Tcl_Alloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__) # define Tcl_Free(x) Tcl_DbCkfree(x, __FILE__, __LINE__) # define Tcl_Realloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__) # define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__) # define ckfree(x) Tcl_DbCkfree(x, __FILE__, __LINE__) # define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__) #else /* * If USE_TCLALLOC is true, then we need to call Tcl_Alloc instead of * the native malloc/free. The only time USE_TCLALLOC should not be * true is when compiling the Tcl/Tk libraries on Unix systems. In this * case we can safely call the native malloc/free directly as a performance * optimization. */ # if USE_TCLALLOC # define ckalloc(x) Tcl_Alloc(x) # define ckfree(x) Tcl_Free(x) # define ckrealloc(x,y) Tcl_Realloc(x,y) # else # define ckalloc(x) malloc(x) # define ckfree(x) free(x) # define ckrealloc(x,y) realloc(x,y) # endif # define Tcl_DumpActiveMemory(x) # define Tcl_ValidateAllMemory(x,y) #endif /* !TCL_MEM_DEBUG */ /* * These function have been renamed. The old names are deprecated, but we * define these macros for backwards compatibilty. */ #define Tcl_Ckalloc Tcl_Alloc #define Tcl_Ckfree Tcl_Free #define Tcl_Ckrealloc Tcl_Realloc #define Tcl_Return Tcl_SetResult #define Tcl_TildeSubst Tcl_TranslateFileName /* * In later releases, Tcl_Panic will be the correct name to use. For now * we leave it as panic to avoid breaking existing binaries. */ #define Tcl_Panic panic #define Tcl_PanicVA panicVA #endif /* RESOURCE_INCLUDED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCL */ /* * end of tcl.h definitions */ /* * regexp definitions - from tcl8.0/tclRegexp.h */ /* * Definitions etc. for regexp(3) routines. * * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], * not the System V one. * * RCS: @(#) $Id: expect.h,v 5.29 2000/01/06 23:22:05 wart Exp $ */ #ifndef _REGEXP #define _REGEXP 1 #ifdef BUILD_tcl # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLEXPORT #endif /* * NSUBEXP must be at least 10, and no greater than 117 or the parser * will not work properly. */ #define NSUBEXP 20 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; EXTERN regexp *TclRegComp _ANSI_ARGS_((char *exp)); EXTERN int TclRegExec _ANSI_ARGS_((regexp *prog, char *string, char *start)); EXTERN void TclRegSub _ANSI_ARGS_((regexp *prog, char *source, char *dest)); EXTERN void exp_TclRegError _ANSI_ARGS_((char *msg)); EXTERN char *TclGetRegError _ANSI_ARGS_((void)); # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT #endif /* REGEXP */ /* * end of regexp definitions */ /* * finally - expect-specific definitions */ #include "expect_comm.h" enum exp_type { exp_end = 0, /* placeholder - no more cases */ exp_glob, /* glob-style */ exp_exact, /* exact string */ exp_regexp, /* regexp-style, uncompiled */ exp_compiled, /* regexp-style, compiled */ exp_null, /* matches binary 0 */ exp_bogus /* aid in reporting compatibility problems */ }; struct exp_case { /* case for expect command */ char *pattern; regexp *re; enum exp_type type; int value; /* value to be returned upon match */ }; EXTERN char *exp_buffer; /* buffer of matchable chars */ EXTERN char *exp_buffer_end; /* one beyond end of matchable chars */ EXTERN char *exp_match; /* start of matched string */ EXTERN char *exp_match_end; /* one beyond end of matched string */ EXTERN int exp_match_max; /* bytes */ EXTERN int exp_timeout; /* seconds */ EXTERN int exp_full_buffer; /* if true, return on full buffer */ EXTERN int exp_remove_nulls; /* if true, remove nulls */ EXTERN int exp_pty_timeout; /* see Cray hooks in source */ EXTERN int exp_pid; /* process-id of spawned process */ EXTERN int exp_autoallocpty; /* if TRUE, we do allocation */ EXTERN int exp_pty[2]; /* master is [0], slave is [1] */ EXTERN char *exp_pty_slave_name; /* name of pty slave device if we */ /* do allocation */ EXTERN char *exp_stty_init; /* initial stty args */ EXTERN int exp_ttycopy; /* copy tty parms from /dev/tty */ EXTERN int exp_ttyinit; /* set tty parms to sane state */ EXTERN int exp_console; /* redirect console */ #ifdef HAVE_SIGLONGJMP sigjmp_buf exp_readenv; /* for interruptable read() */ #else jmp_buf exp_readenv; /* for interruptable read() */ #endif /* HAVE_SIGLONGJMP */ EXTERN int exp_reading; /* whether we can longjmp or not */ #define EXP_ABORT 1 /* abort read */ #define EXP_RESTART 2 /* restart read */ EXTERN int exp_is_debugging; EXTERN int exp_loguser; EXTERN void (*exp_close_in_child)(); /* procedure to close files in child */ EXTERN void exp_slave_control _ANSI_ARGS_((int,int)); EXTERN int exp_logfile_all; EXTERN FILE *exp_debugfile; EXTERN FILE *exp_logfile; extern void exp_debuglog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); extern void exp_errorlog _ANSI_ARGS_(TCL_VARARGS(char *,fmt)); EXTERN int exp_disconnect _ANSI_ARGS_((void)); EXTERN FILE *exp_popen _ANSI_ARGS_((char *command)); EXTERN void (*exp_child_exec_prelude) _ANSI_ARGS_((void)); #ifndef EXP_DEFINE_FNS EXTERN int exp_spawnl _ANSI_ARGS_(TCL_VARARGS(char *,file)); EXTERN int exp_expectl _ANSI_ARGS_(TCL_VARARGS(int,fd)); EXTERN int exp_fexpectl _ANSI_ARGS_(TCL_VARARGS(FILE *,fp)); #endif EXTERN int exp_spawnv _ANSI_ARGS_((char *file, char *argv[])); EXTERN int exp_expectv _ANSI_ARGS_((int fd, struct exp_case *cases)); EXTERN int exp_fexpectv _ANSI_ARGS_((FILE *fp, struct exp_case *cases)); EXTERN int exp_spawnfd _ANSI_ARGS_((int fd)); #endif /* _EXPECT_H */ |
Added generic/tcldbg.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 | /* 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" #ifndef TCL_NEWEXTERN # ifdef __cplusplus # define OLDEXTERN extern "C" TCL_STORAGE_CLASS # else # define OLDEXTERN extern TCL_STORAGE_CLASS # endif # undef EXTERN # define EXTERN(a) OLDEXTERN a #endif #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT 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; char * Dbg_VarName; char * Dbg_DefaultCmdName; /* trivial interface, creates a "debug" command in your interp */ EXTERN(int) Tcldbg_Init _ANSI_ARGS_((Tcl_Interp *)); void Dbg_On _ANSI_ARGS_((Tcl_Interp *interp, int immediate)); void Dbg_Off _ANSI_ARGS_((Tcl_Interp *interp)); char ** Dbg_ArgcArgv _ANSI_ARGS_((int argc,char *argv[], int copy)); int Dbg_Active _ANSI_ARGS_((Tcl_Interp *interp)); Dbg_InterStruct Dbg_Interactor _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_InterProc *interactor, ClientData data)); Dbg_IgnoreFuncsProc * Dbg_IgnoreFuncs _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_IgnoreFuncsProc *)); Dbg_OutputStruct Dbg_Output _ANSI_ARGS_(( Tcl_Interp *interp, Dbg_OutputProc *, ClientData data)); #endif /* _NIST_DBG */ |
Added makefile.win.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | #============================================================================== # The Tcl/Tk SuperDuty Win32 Common-Denominator Makefile Multiplexor for: # # Microsoft NMAKE v1.62+ [MSVC++ v5+] # Borland MAKE v5.2 [Borland C++ Builder 5.5] # Watcom WMAKE v11.0 [OpenWatcom] # MinGW MAKE v3.79.1 [MinGW: Minimalist GNU For Windows] # # Tool specific syntax is NOT allowed in this file. We assume the brand of # 'make' follows the compiler to be used. This is not a perfect assumption, # but, I feel, is an excellent default. # #============================================================================== # RCS: @(#) $Id: makefile.win,v 1.1.2.3 2001/09/28 02:12:46 davygrvy Exp $ #============================================================================== ### Remove all '!' for MinGW.. Sorry, couldn't find another way to do this. #============================================== # Load the user info. #============================================== !include mkconfig.mif #============================================== # Within what context are we ? #============================================== !ifdef _NMAKE_VER !include "win\mkprepvc32.mif" # Microsoft Toolset !else !ifdef __LOADDLL__ !include "win\mkwc32.mif" # Watcom Toolset !else !ifdef __MAKE__ !include "win\mkbc32.mif" # Borland Toolset !else !ifdef BUILDLIB # Lcc-Win32 doesn't have an include directive... oh well. !else !ifdef MAKE_VERSION !include win/mkmgw32.mif # MinGW Toolset !else !error Unknown make tool. Toolset cannot be determined. !endif !endif !endif !endif !endif !ifndef BAILOUT #============================================== # Targets. #============================================== all : $(SYM) $(MAKECMD) all release : $(SYM) $(MAKECMD) expect test : $(SYM) $(MAKECMD) test debugger : $(SYM) $(MAKECMD) debugger slavedrv : $(SYM) $(MAKECMD) slavedrv telnet : $(SYM) $(MAKECMD) telnet genstubs : $(SYM) $(MAKECMD) genstubs install : $(SYM) $(MAKECMD) install winhelp : $(SYM) $(MAKECMD) winhelp cvsupdate : $(SYM) set CVS_RSH=$(CVS_RSH) $(CVSCMD) update $(CVS_OPTS) !endif |
Deleted pty_sgttyb.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted pty_termios.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted pty_unicos.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted tcldbg.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to 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 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 | /* * expUnixChan.c * * Channel driver for Expect channels. * Based on UNIX File channel from tclUnixChan.c * */ #include <sys/types.h> #include <stdio.h> #include <signal.h> #include <errno.h> #include <ctype.h> /* for isspace */ #include <time.h> /* for time(3) */ #include "expect_cf.h" #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tcl.h" #include "string.h" #include "exp_rename.h" #include "exp_prog.h" #include "exp_command.h" #include "exp_log.h" static int ExpCloseProc _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp)); static int ExpInputProc _ANSI_ARGS_((ClientData instanceData, char *buf, int toRead, int *errorCode)); static int ExpOutputProc _ANSI_ARGS_(( ClientData instanceData, char *buf, int toWrite, int *errorCode)); static void ExpWatchProc _ANSI_ARGS_((ClientData instanceData, int mask)); static int ExpGetHandleProc _ANSI_ARGS_((ClientData instanceData, int direction, ClientData *handlePtr)); /* * This structure describes the channel type structure for Expect-based IO: */ Tcl_ChannelType expChannelType = { "exp_spawn", /* Type name. */ /* Expect channels are always blocking */ NULL, /* Set blocking/nonblocking mode.*/ ExpCloseProc, /* Close proc. */ ExpInputProc, /* Input proc. */ ExpOutputProc, /* Output proc. */ NULL, /* Seek proc. */ NULL, /* Set option proc. */ NULL, /* Get option proc. */ ExpWatchProc, /* Initialize notifier. */ ExpGetHandleProc, /* Get OS handles out of channel. */ NULL, /* Close2 proc */ }; typedef struct ThreadSpecificData { /* * List of all exp channels currently open. This is per thread and is * used to match up fd's to channels, which rarely occurs. */ ExpState *firstExpPtr; int channelCount; /* this is process-wide as it is used to give user some hint as to why a spawn has failed by looking at process-wide resource usage */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* *---------------------------------------------------------------------- * * ExpInputProc -- * * This procedure is invoked from the generic IO level to read * input from an exp-based channel. * * Results: * The number of bytes read is returned or -1 on error. An output * argument contains a POSIX error code if an error occurs, or zero. * * Side effects: * Reads input from the input device of the channel. * *---------------------------------------------------------------------- */ static int ExpInputProc(instanceData, buf, toRead, errorCodePtr) ClientData instanceData; /* Exp state. */ char *buf; /* Where to store data read. */ int toRead; /* How much space is available * in the buffer? */ int *errorCodePtr; /* Where to store error code. */ { ExpState *esPtr = (ExpState *) instanceData; int bytesRead; /* How many bytes were actually * read from the input device? */ *errorCodePtr = 0; /* * Assume there is always enough input available. This will block * appropriately, and read will unblock as soon as a short read is * possible, if the channel is in blocking mode. If the channel is * nonblocking, the read will never block. */ bytesRead = read(esPtr->fdin, buf, (size_t) toRead); /*printf("ExpInputProc: read(%d,,) = %d\r\n",esPtr->fdin,bytesRead);*/ if (bytesRead > -1) { /* strip parity if requested */ if (esPtr->parity == 0) { char *end = buf+bytesRead; for (;buf < end;buf++) { *buf &= 0x7f; } } return bytesRead; } *errorCodePtr = errno; return -1; } /* *---------------------------------------------------------------------- * * ExpOutputProc-- * * This procedure is invoked from the generic IO level to write * output to an exp channel. * * Results: * The number of bytes written is returned or -1 on error. An * output argument contains a POSIX error code if an error occurred, * or zero. * * Side effects: * Writes output on the output device of the channel. * *---------------------------------------------------------------------- */ static int ExpOutputProc(instanceData, buf, toWrite, errorCodePtr) ClientData instanceData; /* Exp state. */ char *buf; /* The data buffer. */ int toWrite; /* How many bytes to write? */ int *errorCodePtr; /* Where to store error code. */ { ExpState *esPtr = (ExpState *) instanceData; int written = 0; *errorCodePtr = 0; if (toWrite < 0) Tcl_Panic("ExpOutputProc: called with negative char count"); while (toWrite > 0) { written = write(esPtr->fdout, buf, (size_t) toWrite); if (written == 0) { /* 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 * it is some transient condition. */ sleep(1); expDiagLogU("write() failed to write anything - will sleep(1) and retry...\n"); } else if (written < 0) { *errorCodePtr = errno; return -1; } buf += written; toWrite -= written; } return written; } /* *---------------------------------------------------------------------- * * ExpCloseProc -- * * This procedure is called from the generic IO level to perform * channel-type-specific cleanup when an exp-based channel is closed. * * Results: * 0 if successful, errno if failed. * * Side effects: * Closes the device of the channel. * *---------------------------------------------------------------------- */ /*ARGSUSED*/ static int ExpCloseProc(instanceData, interp) ClientData instanceData; /* Exp state. */ Tcl_Interp *interp; /* For error reporting - unused. */ { ExpState *esPtr = (ExpState *) instanceData; ExpState **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); esPtr->registered = FALSE; #if 0 /* Really should check that we created one first. Since we're sharing fds with Tcl, perhaps a filehandler was created with a plain tcl file - we wouldn't want to delete that. Although if user really close Expect's user_spawn_id, it probably doesn't matter anyway. */ Tcl_DeleteFileHandler(esPtr->fdin); #endif /*0*/ Tcl_DecrRefCount(esPtr->buffer); /* Actually file descriptor should have been closed earlier. */ /* So do nothing here */ /* * Conceivably, the process may not yet have been waited for. If this * becomes a requirement, we'll have to revisit this code. But for now, if * it's just Tcl exiting, the processes will exit on their own soon * anyway. */ for (nextPtrPtr = &(tsdPtr->firstExpPtr); (*nextPtrPtr) != NULL; nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { if ((*nextPtrPtr) == esPtr) { (*nextPtrPtr) = esPtr->nextPtr; break; } } tsdPtr->channelCount--; if (esPtr->bg_status == blocked || esPtr->bg_status == disarm_req_while_blocked) { esPtr->freeWhenBgHandlerUnblocked = 1; /* * If we're in the middle of a bg event handler, then the event * handler will have to take care of freeing esPtr. */ } else { expStateFree(esPtr); } return 0; } /* *---------------------------------------------------------------------- * * ExpWatchProc -- * * Initialize the notifier to watch the fd from this channel. * * Results: * None. * * Side effects: * Sets up the notifier so that a future event on the channel will * be seen by Tcl. * *---------------------------------------------------------------------- */ static void ExpWatchProc(instanceData, mask) ClientData instanceData; /* The exp state. */ int mask; /* Events of interest; an OR-ed * combination of TCL_READABLE, * TCL_WRITABLE and TCL_EXCEPTION. */ { ExpState *esPtr = (ExpState *) instanceData; /* * Make sure we only register for events that are valid on this exp. * Note that we are passing Tcl_NotifyChannel directly to * Tcl_CreateExpHandler with the channel pointer as the client data. */ mask &= esPtr->validMask; if (mask) { /*printf(" CreateFileHandler: %d (mask = %d)\r\n",esPtr->fdin,mask);*/ Tcl_CreateFileHandler(esPtr->fdin, mask, (Tcl_FileProc *) Tcl_NotifyChannel, (ClientData) esPtr->channel); } else { /*printf(" DeleteFileHandler: %d (mask = %d)\r\n",esPtr->fdin,mask);*/ Tcl_DeleteFileHandler(esPtr->fdin); } } /* *---------------------------------------------------------------------- * * ExpGetHandleProc -- * * Called from Tcl_GetChannelHandle to retrieve OS handles from * an exp-based channel. * * Results: * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if * there is no handle for the specified direction. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int ExpGetHandleProc(instanceData, direction, handlePtr) ClientData instanceData; /* The exp state. */ int direction; /* TCL_READABLE or TCL_WRITABLE */ ClientData *handlePtr; /* Where to store the handle. */ { ExpState *esPtr = (ExpState *) instanceData; if (direction & TCL_WRITABLE) { *handlePtr = (ClientData) esPtr->fdin; } if (direction & TCL_READABLE) { *handlePtr = (ClientData) esPtr->fdin; } else { return TCL_ERROR; } return TCL_OK; } int expChannelCountGet() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); return tsdPtr->channelCount; } int expSizeGet(esPtr) ExpState *esPtr; { int len; Tcl_GetStringFromObj(esPtr->buffer,&len); return len; } int expSizeZero(esPtr) ExpState *esPtr; { int len; Tcl_GetStringFromObj(esPtr->buffer,&len); return (len == 0); } void expStateFree(esPtr) ExpState *esPtr; { if (esPtr->fdBusy) { close(esPtr->fdin); } esPtr->valid = FALSE; if (!esPtr->keepForever) { ckfree((char *)esPtr); } } /* 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; { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; /* no need to keep things in sync (i.e., tsdPtr, count) since we could only be doing this if we're exiting. Just close everything down. */ for (esPtr = tsdPtr->firstExpPtr;esPtr;esPtr = esPtr->nextPtr) { exp_close(interp,esPtr); } } /* 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. * returns the ExpState or 0 if nothing to wait on */ ExpState * expWaitOnAny() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); int result; ExpState *esPtr; for (esPtr = tsdPtr->firstExpPtr;esPtr;esPtr = esPtr->nextPtr) { if (esPtr->pid == exp_getpid) continue; /* skip ourself */ if (esPtr->user_waited) continue; /* one wait only! */ if (esPtr->sys_waited) break; restart: result = waitpid(esPtr->pid,&esPtr->wait,WNOHANG); if (result == esPtr->pid) break; if (result == 0) continue; /* busy, try next */ if (result == -1) { if (errno == EINTR) goto restart; else break; } } return esPtr; } ExpState * expWaitOnOne() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; int pid; /* should really be recoded using the common wait code in command.c */ WAIT_STATUS_TYPE status; pid = wait(&status); for (esPtr = tsdPtr->firstExpPtr;esPtr;esPtr = esPtr->nextPtr) { if (esPtr->pid == pid) { esPtr->sys_waited = TRUE; esPtr->wait = status; return esPtr; } } } void exp_background_channelhandlers_run_all() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ExpState *esPtr; /* kick off any that already have input waiting */ for (esPtr = tsdPtr->firstExpPtr;esPtr;esPtr = esPtr->nextPtr) { /* is bg_interp the best way to check if armed? */ if (esPtr->bg_interp && !expSizeZero(esPtr)) { exp_background_channelhandler((ClientData)esPtr,0); } } } ExpState * expCreateChannel(interp,fdin,fdout,pid) Tcl_Interp *interp; int fdin; int fdout; int pid; { ExpState *esPtr; int mask; Tcl_ChannelType *channelTypePtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); channelTypePtr = &expChannelType; esPtr = (ExpState *) ckalloc((unsigned) sizeof(ExpState)); esPtr->nextPtr = tsdPtr->firstExpPtr; tsdPtr->firstExpPtr = esPtr; sprintf(esPtr->name,"exp%d",fdin); /* * For now, stupidly assume this. We we will likely have to revisit this * later to prevent people from doing stupid things. */ mask = TCL_READABLE | TCL_WRITABLE; /* not sure about this - what about adopted channels */ esPtr->validMask = mask | TCL_EXCEPTION; esPtr->fdin = fdin; esPtr->fdout = fdout; /* set close-on-exec for everything but std channels */ /* (system and stty commands need access to std channels) */ if (fdin != 0 && fdin != 2) { expCloseOnExec(fdin); if (fdin != fdout) expCloseOnExec(fdout); } esPtr->fdBusy = FALSE; esPtr->channel = Tcl_CreateChannel(channelTypePtr, esPtr->name, (ClientData) esPtr, mask); Tcl_RegisterChannel(interp,esPtr->channel); esPtr->registered = TRUE; Tcl_SetChannelOption(interp,esPtr->channel,"-buffering","none"); Tcl_SetChannelOption(interp,esPtr->channel,"-blocking","0"); Tcl_SetChannelOption(interp,esPtr->channel,"-translation","lf"); esPtr->pid = pid; esPtr->msize = 0; /* initialize a dummy buffer */ esPtr->buffer = Tcl_NewStringObj("",0); Tcl_IncrRefCount(esPtr->buffer); esPtr->umsize = exp_default_match_max; /* this will reallocate object with an appropriate sized buffer */ expAdjust(esPtr); esPtr->printed = 0; esPtr->echoed = 0; esPtr->rm_nulls = exp_default_rm_nulls; esPtr->parity = exp_default_parity; esPtr->key = expect_key++; esPtr->force_read = FALSE; esPtr->fg_armed = FALSE; esPtr->channel_orig = 0; esPtr->fd_slave = EXP_NOFD; #ifdef HAVE_PTYTRAP esPtr->slave_name = 0; #endif /* HAVE_PTYTRAP */ esPtr->open = TRUE; esPtr->notified = FALSE; esPtr->user_waited = FALSE; esPtr->sys_waited = FALSE; esPtr->bg_interp = 0; esPtr->bg_status = unarmed; esPtr->bg_ecount = 0; esPtr->freeWhenBgHandlerUnblocked = FALSE; esPtr->keepForever = FALSE; esPtr->valid = TRUE; tsdPtr->channelCount++; return esPtr; } void expChannelInit() { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->channelCount = 0; } |
Added win/.gitignore.
> > > > > > > | 1 2 3 4 5 6 7 | *.ncb *.opt *.plg Debug DebugU Release ReleaseU |
Deleted win/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/dllEntryPoint.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 | /* ---------------------------------------------------------------------------- * dllEntryPoint.c -- * * This file implements the Dll entry point as needed by 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 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.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #define WIN32_LEAN_AND_MEAN #include <windows.h> #ifdef _MSC_VER /* Only do this when MSVC++ is compiling us. */ # define DllEntryPoint DllMain # if defined(USE_TCL_STUBS) && (!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. */ # pragma comment(linker, "-nodefaultlib:msvcrt.lib") # endif #endif /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. If we are compiling * with Visual C++, this routine will be renamed to DllMain. * * Results: * Returns TRUE; * * Side effects: * None. * *---------------------------------------------------------------------- */ #ifndef STATIC_BUILD BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return TRUE; } #endif |
Deleted win/expAlloc.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted win/expDString.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to win/expWin.h.
︙ | ︙ | |||
20 21 22 23 24 25 26 | /* * 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 | > > > > | | > | > < < < < | | | | < | > | | > > > | 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 | /* * 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 FILEPOSINFO __FILE__ "(" STRINGIFY(__LINE__) ")" #define EXP_LOG0(errCode) ExpSyslog(errCode, FILEPOSINFO, 0) #define EXP_LOG1(errCode, arg1) ExpSyslog(errCode, FILEPOSINFO, arg1, 0) #define EXP_LOG2(errCode, arg1, arg2) ExpSyslog(errCode, FILEPOSINFO, 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_DOS 1 #define EXP_APPL_WIN3X 2 #define EXP_APPL_WIN32CUI 3 #define EXP_APPL_WIN32GUI 4 extern DWORD ExpApplicationType (const char *originalName, char *fullPath); extern DWORD ExpCreateProcess (int argc, char **argv, HANDLE inputHandle, HANDLE outputHandle, HANDLE errorHandle, int allocConsole, int hideConsole, int debug, int newProcessGroup, Tcl_Pid *pidPtr, PDWORD globalPidPtr); extern Tcl_Channel ExpCreateSpawnChannel (Tcl_Interp *, Tcl_Channel chan); extern void ExpSyslog TCL_VARARGS(DWORD,arg1); extern TCHAR* ExpSyslogGetSysMsg (DWORD); extern Tcl_Pid Exp_WaitPid (Tcl_Pid pid, int *statPtr, int options); extern void Exp_KillProcess (Tcl_Pid pid); extern void ExpInitWinProcessAPI (void); extern int ExpDynloadTclStubs (void); |
Changes to 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 | /* ---------------------------------------------------------------------------- * 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 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.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expInt.h" #include "expWin.h" //#include "tclPort.h" //#include "expect_tcl.h" //#include "exp_command.h" //#include "exp_rename.h" //#include "exp_log.h" //#include "exp_event.h" //#include "exp_prog.h" //#include "exp_tty.h" #ifdef TCL_DEBUGGER #include "Dbg.h" #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)); void exp_close_on_exec(fd) int fd; { /* This is here for place keeping purposes */ } |
︙ | ︙ | |||
142 143 144 145 146 147 148 | * 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 | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | * 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 |
︙ | ︙ | |||
188 189 190 191 192 193 194 | OVERLAPPED over; DWORD globalPid; Tcl_Channel channel = NULL; Tcl_Channel channel2 = NULL; Tcl_Channel spawnChan = NULL; TclFile masterRFile; TclFile masterWFile; | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | 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; char *val; int hide; int debug; char **nargv = NULL; int i, j; int usePipes = 0; |
︙ | ︙ | |||
226 227 228 229 230 231 232 | } 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")) { | < < < < < < | | < < < | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | } 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")) { exp_error(interp,"%s -open is unsupported on NT", argv0); return TCL_ERROR; } 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) { |
︙ | ︙ | |||
270 271 272 273 274 275 276 | } if (openarg) { if (argc != 0) { exp_error(interp,"usage: -[leave]open [fileXX]"); return TCL_ERROR; } | | > > > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | } if (openarg) { if (argc != 0) { exp_error(interp,"usage: -[leave]open [fileXX]"); return TCL_ERROR; } if (echo) { expStdoutLogU(argv0,0); expStdoutLogU(" [open ...]\r\n",0); } return ExpSpawnOpen(interp, openarg, leaveopen); } if (!openarg && (argc == 0)) { exp_error(interp,"usage: %s [spawn-args] program [program-args]", argv0); |
︙ | ︙ | |||
318 319 320 321 322 323 324 | 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, | | | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | 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 transport. 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, |
︙ | ︙ | |||
349 350 351 352 353 354 355 | sprintf(sockPort, "%d", SLAVE_PORT + sockPortInc); sockPortInc++; } useSocket = 1; } if (channel2 == NULL && hSlaveDrv == NULL ) { | | | | | 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 | sprintf(sockPort, "%d", SLAVE_PORT + sockPortInc); sockPortInc++; } useSocket = 1; } if (channel2 == NULL && hSlaveDrv == NULL ) { 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"); |
︙ | ︙ | |||
468 469 470 471 472 473 474 | */ Tcl_Close(interp, channel2); } /* * wait for slave driver to initialize before allowing user to send to it */ | | | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | */ 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) { |
︙ | ︙ | |||
541 542 543 544 545 546 547 | f->over.hEvent = hEvent; f->channel = spawnChan; f->Master = channel; debuglog("parent: now unsynchronized from child\r\n"); /* tell user id of new process */ | | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | f->over.hEvent = hEvent; f->channel = spawnChan; f->Master = channel; debuglog("parent: now unsynchronized from child\r\n"); /* tell user id of new process */ Tcl_SetVar(interp, SPAWN_ID_VARNAME, Tcl_GetChannelName(spawnChan), 0); Tcl_RegisterChannel(interp, spawnChan); sprintf(interp->result,"%d",(int) globalPid); exp_debuglog("spawn: returns {%s}\r\n",interp->result); ckfree((char *) nargv); return(TCL_OK); end: if (hSlaveDrv != NULL) CloseHandle(hSlaveDrv); if (hEvent != NULL) CloseHandle(hEvent); if (nargv != NULL) ckfree((char *) nargv); |
︙ | ︙ |
Added win/expWinDynloadTclStubs.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 | /* ---------------------------------------------------------------------------- * expWinDynloadTclStubs.c -- * * 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.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" void ExpDynloadTclStubs (void) { TCHAR TclDLLPath[MAX_PATH+1]; HMODULE hTclMod; typedef Tcl_Interp *(*LPFN_createInterpProc) (); LPFN_createInterpProc createInterpProc; Tcl_Interp *interp; char appname[MAX_PATH+1]; if (GetEnvironmentVariable(_T("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")) == NULL) { EXP_LOG1(MSG_STUBS_NOCREATEINTERP, TclDLLPath); } interp = createInterpProc(); if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { EXP_LOG1(MSG_STUBS_INITSTUBS, interp->result); } /* Discover the calling application. * Use the ascii API to be safe. */ GetModuleFileNameA(NULL, 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); } } |
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 | /* ---------------------------------------------------------------------------- * expWinInit.c -- * * Contains startup code needed for the Expect extension 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 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.2.2 2001/11/07 22:10:39 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" static ExpWinProcs asciiProcs = { 0, (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, DWORD, DWORD, HANDLE)) CreateFileA, (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, LPSTARTUPINFO, LPPROCESS_INFORMATION)) CreateProcessA, (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesA, (DWORD (WINAPI *)(CONST TCHAR *, TCHAR *, DWORD)) GetShortPathNameA, (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, TCHAR *, TCHAR **)) SearchPathA }; static ExpWinProcs unicodeProcs = { 1, (HANDLE (WINAPI *)(CONST TCHAR *, DWORD, DWORD, SECURITY_ATTRIBUTES *, DWORD, DWORD, HANDLE)) CreateFileW, (BOOL (WINAPI *)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, LPSTARTUPINFO, LPPROCESS_INFORMATION)) CreateProcessW, (DWORD (WINAPI *)(CONST TCHAR *)) GetFileAttributesW, (DWORD (WINAPI *)(CONST TCHAR *, TCHAR *, DWORD)) GetShortPathNameW, (DWORD (WINAPI *)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, TCHAR *, TCHAR **)) SearchPathW }; ExpWinProcs *expWinProcs = &asciiProcs; /* *---------------------------------------------------------------------- * 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; } else { expWinProcs = &asciiProcs; } } |
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 | /* ---------------------------------------------------------------------------- * 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 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.2.1 2001/11/07 10:04:57 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPWININT #define _EXPWININT #ifndef _EXPINT # ifndef _EXP # define STRICT /* Ask windows.h to be agressive about the HANDLE type. */ # define WINVER 0x0400 /* Make sure we get the Win95 API. */ # endif # include "expInt.h" #endif #ifndef _EXPPORT # include "expPort.h" #endif #undef TCL_STORAGE_CLASS #if defined(BUILD_spawndriver) # define TCL_STORAGE_CLASS extern TCL_CPP void ExpInitWinProcessAPI (void); extern TCL_CPP void ExpDynloadTclStubs (void); # include "expWinSlave.hpp" # include "spawndrvmc.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 typedef struct { int useWide; HANDLE (WINAPI *createFileProc)(CONST TCHAR *, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); BOOL (WINAPI *createProcessProc)(CONST TCHAR *, TCHAR *, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, CONST TCHAR *, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD (WINAPI *getFileAttributesProc)(CONST TCHAR *); DWORD (WINAPI *getShortPathNameProc)(CONST TCHAR *, TCHAR *, DWORD); DWORD (WINAPI *searchPathProc)(CONST TCHAR *, CONST TCHAR *, CONST TCHAR *, DWORD, TCHAR *, TCHAR **); } ExpWinProcs; extern ExpWinProcs *expWinProcs; #include "expIntPlatDecls.h" #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _EXPWININT */ |
Changes to 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 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 | /* ---------------------------------------------------------------------------- * 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 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.5 2001/11/07 10:04:57 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" #include <crtdbg.h> #ifdef _MSC_VER # pragma comment (lib, "advapi32.lib") #endif static HANDLE hSyslog = NULL; static HANDLE hToken; static TOKEN_USER *hUserTokPtr; static char sysMsgSpace[1024]; /* local protos */ static void ExpNTLog (DWORD errCode, char *errData[], int cnt); static TCHAR *Exp95Log (DWORD errCode, char *errData[], int cnt); static void AddEventSource(); #define GETSEVERITY(code) (UCHAR)((code >> 30) & 0x3) #define GETFACILITY(code) (WORD)((code >> 16) & 0x0FFF) #define GETCODE(code) (WORD)(code & 0xFFFF) /* *---------------------------------------------------------------------- * * ExpSyslog -- * * 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; } void ExpNTLog (DWORD errCode, char *errData[], int cnt) { DWORD dwSize = 0; WORD wSev; /* Write-out the registry data each time */ AddEventSource(); hSyslog = RegisterEventSource(NULL, _T("ExpectSlaveDrv")); /* aquire the user SID */ OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken); GetTokenInformation(hToken, TokenUser, NULL, dwSize, &dwSize); hUserTokPtr = (PTOKEN_USER) GlobalAlloc(GPTR, dwSize); GetTokenInformation(hToken, TokenUser, hUserTokPtr, dwSize, &dwSize); switch(GETSEVERITY(errCode)) { case STATUS_SEVERITY_WARNING: wSev = EVENTLOG_WARNING_TYPE; break; case STATUS_SEVERITY_SUCCESS: case STATUS_SEVERITY_INFORMATIONAL: wSev = EVENTLOG_INFORMATION_TYPE; break; case STATUS_SEVERITY_FATAL: wSev = EVENTLOG_ERROR_TYPE; break; } ReportEventA(hSyslog, wSev, GETFACILITY(errCode), errCode, hUserTokPtr->User.Sid, cnt, 0, errData, NULL); GlobalFree(hUserTokPtr); DeregisterEventSource(hSyslog); } void AddEventSource() { HKEY hk; DWORD dwData; TCHAR szBuf[MAX_PATH]; int len; /* * Add your source name as a subkey under the Application * key in the EventLog registry key. */ RegCreateKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\ExpectSlaveDrv"), &hk); /* * Set the name of the message file. This is us, literally. */ len = GetModuleFileName(GetModuleHandle(NULL), szBuf, MAX_PATH); /* * Add the name to the EventMessageFile subkey. */ RegSetValueEx(hk, _T("EventMessageFile"), 0, REG_EXPAND_SZ, (LPBYTE) szBuf, (len + 1)); /* We also do catagories, too. */ RegSetValueEx(hk, _T("CategoryMessageFile"), 0, REG_EXPAND_SZ, (LPBYTE) szBuf, (len + 1)); /* Last catagory (facility) */ dwData = FACILITY_MSPROTO; RegSetValueEx(hk, _T("CategoryCount"), 0, REG_DWORD, (LPBYTE) &dwData, sizeof(DWORD)); /* Set the supported event types in the TypesSupported subkey. */ dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; RegSetValueEx(hk, _T("TypesSupported"), 0, REG_DWORD, (LPBYTE) &dwData, sizeof(DWORD)); RegCloseKey(hk); } |
Added win/expWinMailboxSrv.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 | #include "expInt.h" #include "expPort.h" #include "d:\tomasoft_ws\mcl\include\cmcl.h" #pragma comment (lib, "d:/tomasoft_ws/mcl/lib/mcl.lib") Tcl_CmdProc expMakeSpawnChannel; static char *startNewMailbox(); static int mailboxNameId = 0; __declspec(dllexport) int Expect_Init(Tcl_Interp *interp) { if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } Tcl_CreateCommand(interp, "exp::test", expMakeSpawnChannel, 0L, 0L); return TCL_OK; } //Tcl_Channel int expMakeSpawnChannel(ClientData cd, Tcl_Interp *interp, int argc, char *argv[]) { char *val; int debug = 0; DWORD dwRet; TCHAR slavePath[MAX_PATH]; TCHAR imagePath[MAX_PATH]; char *mailboxName; Tcl_Pid slaveDrvPid; /* Process id of the slave */ DWORD globalPid; char **nargv = NULL; int i,j; // val = exp_get_var(interp, "exp_win_debug"); // if (val) { // if (Tcl_GetBoolean(NULL, val, &debug) != TCL_OK) { // // set it anyways. // debug = 1; // } // } else { // debug = 0; // } /* * Get the location of the slavedrv.exe from the $exp::library * variable set by Expect_Init(). */ val = Tcl_GetVar(interp, "::exp::library", TCL_GLOBAL_ONLY); TclWinNoBackslash(val); dwRet = SearchPath(val, "slavedrv.exe", NULL, MAX_PATH, slavePath, NULL); if (dwRet == 0) { Tcl_AppendResult(interp, "unable to find helper program slavedrv.exe", (char *) NULL); return 0L; } /* * See that the process we want to intercept is interceptable. */ dwRet = ExpWinApplicationType(argv[0], imagePath); switch (dwRet) { case EXP_APPL_NONE: TclWinConvertError(ERROR_FILE_NOT_FOUND); //exp_error(interp, "couldn't execute \"%s\": %s", // argv[0], Tcl_PosixError(interp)); return 0L; case EXP_APPL_WIN3X: case EXP_APPL_WIN32GUI: /* * Return an errorCode that is close to the truth. */ TclWinConvertError(ERROR_PIPE_NOT_CONNECTED); //exp_error(interp, "\"%s\" does not support the CUI subsystem and cannot be intercepted: %s", // argv[0], Tcl_PosixError(interp)); return 0L; } /* * Start a new mailbox IPC transport server for this channel. */ mailboxName = startNewMailbox(); /* * Adjust the arguements. */ nargv = (char **) ckalloc(sizeof(char *) * (argc+2)); nargv[0] = slavePath; nargv[1] = mailboxName; nargv[2] = debug ? "1" : "0"; j = 3; nargv[j++] = imagePath; for (i = 0; i < argc; i++, j++) { nargv[j] = argv[i]; } argc = j; /* * Create the new process. */ dwRet = ExpWinCreateProcess(argc, nargv, NULL, NULL, NULL, TRUE, !(debug), FALSE, FALSE, &slaveDrvPid, &globalPid); if (dwRet != 0) { TclWinConvertError(dwRet); //exp_error(interp, "couldn't execute \"%s\": %s", // argv[0],Tcl_PosixError(interp)); //goto end; return 0L; } /* * Block waiting for the slavedrv to connect to the named mailbox. */ /* * Register the new channel with Tcl */ return 0L; } char *startNewMailbox() { char *mailbox; char mailboxToExp[24]; char mailboxFromExp[24]; mailbox = ckalloc(24); sprintf(mailbox, "%s%08x%08x", "exp", GetCurrentProcessId(), mailboxNameId++); sprintf(mailboxToExp, "%sTo", mailbox); sprintf(mailboxFromExp, "%sFrom", mailbox); CMclMailbox *mailTo = new CMclMailbox(20, 128, mailboxToExp); CMclMailbox *mailFrom = new CMclMailbox(20, 128, mailboxFromExp); return mailbox; } |
Changes to 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 | /* ---------------------------------------------------------------------------- * 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 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.2.5 2001/10/29 06:40:29 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_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_DOS 1 #define EXP_APPL_WIN3X 2 #define EXP_APPL_WIN32CUI 3 #define EXP_APPL_WIN32GUI 4 #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 #include "expPlatDecls.h" #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _EXPWINPORT */ |
Changes to 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 | /* ---------------------------------------------------------------------------- * expWinProcess.c -- * * This file contains utility procedures. It primarily handles * 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 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.11 2001/11/07 10:04:57 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; /* *---------------------------------------------------------------------- * * 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. * * Comment: COPY OF NON_PUBLIC CORE FUNCTION! * *---------------------------------------------------------------------- */ static BOOL HasConsole() { HANDLE handle = CreateFile(_T("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, |
︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 | * 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 | > > | | | < | < > < | | > > > > > > > > > | > > | | < < > | | > > | > > > | > > | | > | > | | | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > > > > > > > > > > > > > > > > > > | | | < < | > | < | | > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > | > > > > > > > | | > > > > | > > | | > | > > > > < | | > > | | | | | > > > > > > > > > | > > > | > > > | | | < | > > > | > | | | | | | | | | > > > | 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 | * 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. * * Comment: COPY OF NON_PUBLIC CORE FUNCTION WITH CHANGES! * *---------------------------------------------------------------------- */ DWORD ExpWinApplicationType( const char *originalName, /* Name of the application to find. */ char fullName[]) /* Filled with complete path to * application. */ { int applType, i, nameLen, found; 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, ds; TCHAR *nativeName; WCHAR nativeFullPath[MAX_PATH]; /* needed for unicode space */ static char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; /* 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_DStringAppend(&nameBuf, originalName, -1); nameLen = Tcl_DStringLength(&nameBuf); for (i = 0; i < (int) (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); found = (*expWinProcs->searchPathProc)(NULL, nativeName, NULL, MAX_PATH, (TCHAR *) nativeFullPath, &rest); Tcl_DStringFree(&ds); if (found == 0) { continue; } /* * Ignore matches on directories or data files, return if identified * a known type. */ attr = (*expWinProcs->getFileAttributesProc)((TCHAR *) nativeFullPath); if ((attr == 0xffffffff) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { continue; } strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds)); Tcl_DStringFree(&ds); ext = strrchr(fullName, '.'); if ((ext != NULL) && (stricmp(ext, ".bat") == 0 || stricmp(ext, ".cmd") == 0)) { applType = EXP_APPL_DOS; break; } hFile = (*expWinProcs->createFileProc)((TCHAR *) nativeFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { continue; } 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_DOS; break; } continue; } if (p236.e_lfarlc < 0x40 || p236.e_lfanew == 0 /* reserved */) { /* * Old-style header only. Can't be more than a DOS executable. */ CloseHandle(hFile); applType = EXP_APPL_DOS; break; } /* * The LONG at p236.e_lfanew points to the real exe header only * when p236.e_lfarlc is set to 40h (or greater). */ SetFilePointer(hFile, p236.e_lfanew, NULL, FILE_BEGIN); 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). * 'MZ' old-style p236 DOS executable. */ if (header.pe.Signature == IMAGE_NT_SIGNATURE) { /* * Win32, "PE\0\0" which is short for "Portable Executable". */ if (header.pe.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC || !(header.pe.FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) { /* * Not an executable. Might be a dll or a COMDAT library. */ applType = EXP_APPL_NONE; break; } switch (header.pe.OptionalHeader.Subsystem) { case IMAGE_SUBSYSTEM_WINDOWS_CUI: case IMAGE_SUBSYSTEM_OS2_CUI: case IMAGE_SUBSYSTEM_POSIX_CUI: /* * image runs in the Windows, OS/2, or Posix character * subsystem. */ applType = EXP_APPL_WIN32CUI; break; default: /* * Non-CUI applications are run detached. Return a flag * that will indicate this error. */ applType = EXP_APPL_WIN32GUI; } } else if (header.ne.ne_magic == IMAGE_OS2_SIGNATURE) { switch (header.ne.ne_exetyp) { case 0x1: /* Microsoft/IBM OS/2 (default) */ case 0x3: /* Microsoft (European?) MS-DOS 4.x */ /* Only these might be character-mode. */ applType = EXP_APPL_DOS; break; default: applType = EXP_APPL_NONE; } } else if (header.le.e32_magic == IMAGE_OS2_SIGNATURE_LE || header.le.e32_magic == 0x584C /* 'LX' */ || header.le.e32_magic == 0x3357 /* 'W3' */) { /* * Virtual device drivers are not executables, per se. */ applType = EXP_APPL_NONE; } else { /* * NOTE: The Lahey Fortran90 compiler might make executables * that have a bogus signature and end-up here. */ applType = EXP_APPL_DOS; } break; } Tcl_DStringFree(&nameBuf); if (applType == EXP_APPL_NONE) { return EXP_APPL_NONE; } if ((applType == EXP_APPL_DOS) || (applType == EXP_APPL_WIN3X)) { /* * 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 *) nativeFullPath, (TCHAR *) nativeFullPath, MAX_PATH); strcpy(fullName, Tcl_WinTCharToUtf((TCHAR *) nativeFullPath, -1, &ds)); Tcl_DStringFree(&ds); } 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 **argv, /* Argument strings in UTF. */ 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 -- * |
︙ | ︙ | |||
479 480 481 482 483 484 485 | { TerminateProcess((HANDLE) pid, 0xFFFF); } /* *---------------------------------------------------------------------- * | | > > | | 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 | { TerminateProcess((HANDLE) pid, 0xFFFF); } /* *---------------------------------------------------------------------- * * ExpWinCreateProcess -- * * 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. * * Comment: *ALMOST* A COPY OF A NON_PUBLIC CORE FUNCTION! * *---------------------------------------------------------------------- */ DWORD ExpWinCreateProcess(argc, argv, inputHandle, outputHandle, errorHandle, allocConsole, hideConsole, debug, newProcessGroup, pidPtr, globalPidPtr) int argc; /* Number of arguments in following array. */ char **argv; /* Array of argument strings. argv[0] * contains the name of the executable * converted to native format (using the * Tcl_TranslateFileName call). Additional |
︙ | ︙ | |||
537 538 539 540 541 542 543 | PDWORD globalPidPtr; /* Globally unique pid */ { DWORD applType; int createFlags; Tcl_DString cmdLine; STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; | > | | < < < | > > < > > > > | 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 | PDWORD globalPidPtr; /* Globally unique pid */ { DWORD applType; int createFlags; Tcl_DString cmdLine; STARTUPINFO startInfo; PROCESS_INFORMATION procInfo; SECURITY_ATTRIBUTES secAtts; HANDLE hProcess, h; char execPath[MAX_PATH * TCL_UTF_MAX]; char *originalName; LONG result; result = 0; applType = ExpWinApplicationType(argv[0], execPath); if (applType == EXP_APPL_NONE) { return GetLastError(); } else if (applType == EXP_APPL_WIN32GUI) { return ERROR_BAD_PIPE; /* GUI applications can't use pipes. */ } originalName = argv[0]; argv[0] = execPath; Tcl_DStringInit(&cmdLine); hProcess = GetCurrentProcess(); /* * 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. */ ZeroMemory(&startInfo, sizeof(startInfo)); startInfo.cb = sizeof(startInfo); secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); secAtts.lpSecurityDescriptor = NULL; secAtts.bInheritHandle = TRUE; if (inputHandle || outputHandle || errorHandle) { startInfo.dwFlags = STARTF_USESTDHANDLES; if (! inputHandle) { inputHandle = GetStdHandle(STD_INPUT_HANDLE); } if (! outputHandle) { |
︙ | ︙ | |||
589 590 591 592 593 594 595 | /* * 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. */ | | > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > | | > > > > > > > > | > | | | | | | | | | | | | | | | | | | < > > | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | | < | > > > > > > > > > | 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 | /* * 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_DOS)) { 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 as foreground or * detached processes. The GUI window will still pop up to the * foreground. */ if (TclWinGetPlatformId() == VER_PLATFORM_WIN32_NT) { if (!allocConsole && HasConsole()) { createFlags = 0; } else if (applType == EXP_APPL_DOS || 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_DOS) { /* * 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; } // BUG: Fixme! Where is tclpipXX.dll ????? Set it! Tcl_DStringAppend(&cmdLine, "tclpip" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll ", -1); } } 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(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_DOS) { 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 |
︙ | ︙ |
Deleted win/expWinSlave.h.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
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 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 | /* ---------------------------------------------------------------------------- * 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 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.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #ifndef _EXPWINSLAVE_HPP #define _EXPWINSLAVE_HPP 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 (in UTF-8) */ 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 TCL_CPP void ExpAddToWaitQueue(HANDLE handle); extern TCL_CPP void ExpKillProcessList(); extern TCL_CPP DWORD WINAPI ExpSlaveDebugThread(LPVOID arg); extern TCL_CPP DWORD WINAPI ExpGetExecutablePathA(PSTR pathInOut); extern TCL_CPP DWORD WINAPI ExpGetExecutablePathW(PWSTR pathInOut); extern TCL_CPP BOOL ExpWriteMaster(int useSocket, HANDLE hFile, LPCVOID buf, DWORD n, LPOVERLAPPED over); extern TCL_CPP BOOL ExpReadMaster(int useSocket, HANDLE hFile, void *buf, DWORD n, PDWORD pCount, LPWSAOVERLAPPED over, PDWORD pError); extern TCL_CPP void ExpNewConsoleSequences(int useSocket, HANDLE hMaster, LPWSAOVERLAPPED over); extern TCL_CPP void ExpProcessFreeByHandle(HANDLE hProcess); extern TCL_CPP void ExpSetConsoleSize(HANDLE hConsoleInW, HANDLE hConsoleOut, int w, int h, int useSocket, HANDLE hMaster, LPWSAOVERLAPPED over); #ifdef __cplusplus #include "./Mcl/include/CMcl.h" class ExpSpawnTransportCli { public: virtual void ExpWriteMaster() = 0; virtual void ExpReadMaster() = 0; }; class ExpSpawnMailboxCli : public ExpSpawnTransportCli { public: ExpSpawnMailboxCli(const char *name); virtual void ExpWriteMaster(); virtual void ExpReadMaster(); private: CMclMailbox *MasterToExpect; CMclMailbox *MasterFromExpect; }; /* below not implimented yet */ class ExpSpawnSocketCli : public ExpSpawnTransportCli { public: ExpSpawnSocketCli(const char *name); virtual void ExpWriteMaster(); virtual void ExpReadMaster(); private: }; /* from expWinSpawnTransport.cpp */ extern ExpSpawnTransportCli *ExpWinSpawnOpenTransport(const char *name); class ExpSlaveTrap { }; class ExpSlaveTrapPipe : public ExpSlaveTrap { public: ExpSlaveTrapPipe(int, char **); }; class ExpSlaveTrapDbg : public ExpSlaveTrap { public: ExpSlaveTrapDbg(int, char **); }; extern ExpSlaveTrap *ExpWinSlaveOpenTrap(char *meth, int argc, char *argv[]); extern int ExpWinSlaveEvents(ExpSpawnTransportCli *transport, ExpSlaveTrap *trap); #endif /* __cplusplus */ #endif /* _EXPWINSLAVE_HPP */ |
Changes to win/expWinSlaveDbg.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 | /* ---------------------------------------------------------------------------- * expWinSlaveDbg.c -- * * 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 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 first WinNT * port. * * Copyright (c) 2001 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 * ---------------------------------------------------------------------------- * * TODO: (from Gordon) * o Maintain cursor information for each console screen buffer. * o Intercept additional console input and output characters to better * keep track of current console state. * o Keep all keyboard strokes within the slave until we see a call * made ReadConsoleInput, ReadConsole, or some call like that. * Maybe a better idea is to not echo characters until we see how * they are read. So never write more than a line at a time to * the console input, but as soon as wee see a call to ReadConsole, we * echo characters (if necessary) on the way into the call. * If the call is made instead to ReadConsoleInput, then we remove * a character from our echo list (assuming of course the input * event was a key stroke). This would give the most accurate * accounting of characters. * o I've been having trouble with cmd.exe. If there is a file such asa * x.in that you try to run, and there is no application tied to .in, * a graphical message pops up telling you there is no program * associated with this file. For some reason, if I run cmd.exe under * apispy32 from Matt Pietrek, the graphical message doesn't pop up. I * tried starting the program with the same sort of flags as he uses, * but it doesn't seem to work to make the messages go away. I suspect * that the messages are coming from the shell somehow. * * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" #include <imagehlp.h> #ifdef _MSC_VER # pragma comment (lib, "imagehlp.lib") #endif #include <stddef.h> #include <assert.h> #if 0 # define LOG_ENTRY(function) ExpSyslog("Expect SlaveDriver: " function) # define LOG_EXIT(function) ExpSyslog("Expect SlaveDriver: " function " exited") #else # define LOG_ENTRY(function) |
︙ | ︙ | |||
70 71 72 73 74 75 76 | #define EXP_FLAG_THREAD_ATTRS 0x08 #define EXP_FLAG_ENVIRONMENT 0x10 #define EXP_FLAG_CURR_DIR 0x20 #define EXP_FLAG_SI 0x40 #define EXP_FLAG_PI 0x80 #ifndef UNICODE | | < < | | < < | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #define EXP_FLAG_THREAD_ATTRS 0x08 #define EXP_FLAG_ENVIRONMENT 0x10 #define EXP_FLAG_CURR_DIR 0x20 #define EXP_FLAG_SI 0x40 #define EXP_FLAG_PI 0x80 #ifndef UNICODE //# define ExpCreateProcessInfo ExpCreateProcessInfoA //# define StartSubprocess StartSubprocessA #else //# define ExpCreateProcessInfo ExpCreateProcessInfoW //# define StartSubprocess StartSubprocessW #endif typedef struct _ExpProcess ExpProcess; typedef struct _ExpBreakpoint ExpBreakpoint; typedef struct _ExpCreateProcessInfo { TCHAR appName[8192]; |
︙ | ︙ | |||
203 204 205 206 207 208 209 | static char *SymbolPath; /* * Static functions in this file: */ | | | | | | | | | | | | 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 | static char *SymbolPath; /* * Static functions in this file: */ static void ExpCommonDebugger(); static BOOL ReadSubprocessMemory(ExpProcess *proc, LPVOID addr, LPVOID buf, DWORD len); static int ReadSubprocessStringA(ExpProcess *proc, PVOID base, PCHAR buf, int buflen); static int ReadSubprocessStringW(ExpProcess *proc, PVOID base, PWCHAR buf, int buflen); static BOOL WriteSubprocessMemory(ExpProcess *proc, LPVOID addr, LPVOID buf, DWORD len); static DWORD WINAPI CreateProcessThread(LPVOID *lparg); static void CreateVtSequence(ExpProcess *, COORD newPos, DWORD n); static BOOL SetBreakpoint(ExpProcess *, ExpBreakInfo *); static ExpBreakpoint * SetBreakpointAtAddr(ExpProcess *, ExpBreakInfo *, PVOID funcPtr); //static void StartSubprocessA(ExpProcess *, ExpThreadInfo *); //static void StartSubprocessW(ExpProcess *, ExpThreadInfo *); static void RefreshScreen(LPWSAOVERLAPPED over); static void OnBeep(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnFillConsoleOutputCharacter(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnGetStdHandle(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); |
︙ | ︙ | |||
250 251 252 253 254 255 256 | ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleA(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleW(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleOutputA(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleA(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleW(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleOutputA(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleOutputW(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleOutputCharacterA(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); static void OnWriteConsoleOutputCharacterW(ExpProcess *, ExpThreadInfo *, ExpBreakpoint *, PDWORD, DWORD); #if 1 /* XXX: Testing purposes only */ static void OnExpGetExecutablePathA(ExpProcess *, ExpThreadInfo *, |
︙ | ︙ | |||
282 283 284 285 286 287 288 | static void OnXFirstBreakpoint(ExpProcess *, LPDEBUG_EVENT); static void OnXLoadDll(ExpProcess *, LPDEBUG_EVENT); static void OnXUnloadDll(ExpProcess *, LPDEBUG_EVENT); static void OnXSecondBreakpoint(ExpProcess *, LPDEBUG_EVENT); static void OnXSecondChanceException(ExpProcess *,LPDEBUG_EVENT); static void OnXSingleStep(ExpProcess *, LPDEBUG_EVENT); | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | static void OnXFirstBreakpoint(ExpProcess *, LPDEBUG_EVENT); static void OnXLoadDll(ExpProcess *, LPDEBUG_EVENT); static void OnXUnloadDll(ExpProcess *, LPDEBUG_EVENT); static void OnXSecondBreakpoint(ExpProcess *, LPDEBUG_EVENT); static void OnXSecondChanceException(ExpProcess *,LPDEBUG_EVENT); static void OnXSingleStep(ExpProcess *, LPDEBUG_EVENT); //#ifndef UNICODE /* * Functions where we set breakpoints */ ExpBreakInfo BreakArrayKernel32[] = { {"FillConsoleOutputCharacterA", 5, OnFillConsoleOutputCharacter, EXP_BREAK_OUT}, |
︙ | ︙ | |||
325 326 327 328 329 330 331 | */ ExpDllBreakpoints BreakPoints[] = { {"kernel32.dll", BreakArrayKernel32}, {"user32.dll", BreakArrayUser32}, {NULL, NULL} }; | | | | | 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 | */ ExpDllBreakpoints BreakPoints[] = { {"kernel32.dll", BreakArrayKernel32}, {"user32.dll", BreakArrayUser32}, {NULL, NULL} }; //#endif /* !UNICODE */ //#ifndef UNICODE /* *---------------------------------------------------------------------- * * ExpProcessNew -- * * Allocates a new structure for debugging a process and * initializes it. * * Results: * A new structure * * Side Effects: * Memory is allocated, an event is created. * *---------------------------------------------------------------------- */ ExpProcess * ExpProcessNew(void) { ExpProcess *proc; proc = malloc(sizeof(ExpProcess)); proc->threadList = NULL; proc->threadCount = 0; proc->brkptList = NULL; |
︙ | ︙ | |||
389 390 391 392 393 394 395 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | * * Results: * None * *---------------------------------------------------------------------- */ void ExpProcessFree(ExpProcess *proc) { ExpThreadInfo *tcurr, *tnext; ExpBreakpoint *bcurr, *bnext; ExpProcess *pcurr, *pprev; for (tcurr = proc->threadList; tcurr != NULL; tcurr = tnext) { |
︙ | ︙ | |||
432 433 434 435 436 437 438 | } /* *---------------------------------------------------------------------- * * ExpProcessFreeByHandle -- * | | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | } /* *---------------------------------------------------------------------- * * ExpProcessFreeByHandle -- * * Find a process structure by its handle and free it. * * Results: * None * *---------------------------------------------------------------------- */ void |
︙ | ︙ | |||
500 501 502 503 504 505 506 | * Side Effects: * A process is created. * *---------------------------------------------------------------------- */ DWORD WINAPI | | | | | > | > > | > | | | > > | | > > > > > > < < < < < < < < < | 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 | * Side Effects: * A process is created. * *---------------------------------------------------------------------- */ DWORD WINAPI ExpSlaveDebugThread(LPVOID lparg) { ExpSlaveDebugArg *arg = (ExpSlaveDebugArg *) lparg; ExpProcess *proc; HConsole = arg->hConsole; HMaster = arg->hMaster; /* Set the master program */ UseSocket = arg->useSocket; /* Make sure the master does not ignore Ctrl-C */ SetConsoleCtrlHandler(NULL, FALSE); arg->result = ExpWinCreateProcess( arg->argc, arg->argv, arg->slaveStdin, arg->slaveStdout, arg->slaveStderr, FALSE, FALSE, arg->passThrough ? FALSE : TRUE, /* debug */ TRUE, /* newProcessGroup */ (Tcl_Pid *) &arg->process, &arg->globalPid); if (arg->result) { arg->lastError = GetLastError(); } /* Make sure we now ignore Ctrl-C */ SetConsoleCtrlHandler(NULL, TRUE); SetEvent(arg->event); if (arg->result) { ExitThread(0); } proc = ExpProcessNew(); proc->hPid = arg->globalPid; if (arg->passThrough) { ExpProcess *proc; proc = ExpProcessNew(); proc->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); proc->hProcess = arg->process; ExpAddToWaitQueue(proc->hProcess); } else { CloseHandle(arg->process); proc->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, arg->globalPid); arg->process = proc->hProcess; if (proc->hProcess == NULL) { arg->lastError = GetLastError(); ExitThread(0); } ExpAddToWaitQueue(proc->hProcess); proc->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ExpCommonDebugger(); } return 0; /* Never executes */ } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
623 624 625 626 627 628 629 | if (proc->hPid == debEvent.dwProcessId) { break; } } if (!proc && debEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) { char buf[50]; | | | | | > | 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | if (proc->hPid == debEvent.dwProcessId) { break; } } if (!proc && debEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT) { char buf[50]; wsprintfA(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]; wsprintfA(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. */ |
︙ | ︙ | |||
769 770 771 772 773 774 775 | * * Results: * If the module is known, return TRUE. Otherwise, return FALSE * *---------------------------------------------------------------------- */ | | | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | * * Results: * If the module is known, return TRUE. Otherwise, return FALSE * *---------------------------------------------------------------------- */ int LoadedModule(ExpProcess *proc, HANDLE hFile, LPVOID modname, int isUnicode, LPVOID baseAddr, DWORD debugOffset) { #undef PRINTF #if 0 #define PRINTF(x) printf x #else |
︙ | ︙ | |||
849 850 851 852 853 854 855 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXCreateProcess(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { ExpThreadInfo *threadInfo; CREATE_PROCESS_DEBUG_INFO *info = &pDebEvent->u.CreateProcessInfo; int known; if (proc == NULL) { |
︙ | ︙ | |||
908 909 910 911 912 913 914 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXCreateThread(ExpProcess *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. |
︙ | ︙ | |||
941 942 943 944 945 946 947 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXDeleteThread(ExpProcess *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. |
︙ | ︙ | |||
991 992 993 994 995 996 997 | * *---------------------------------------------------------------------- */ static CONTEXT FirstContext; static UCHAR FirstPage[PAGESIZE]; static HANDLE FirstThread; | | | | | 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 | * *---------------------------------------------------------------------- */ 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 OnXFirstBreakpoint(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { DWORD base; ExpThreadInfo *tinfo; #if 0 fprintf(stderr, "OnXFirstBreakpoint: proc=0x%08x\n", proc); |
︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 | FirstThread = tinfo->hThread; FirstContext.ContextFlags = CONTEXT_FULL; GetThreadContext(FirstThread, &FirstContext); tclEntry = Tcl_FindHashEntry(proc->funcTable, "VirtualAlloc"); if (tclEntry == NULL) { proc->nBreakCount++; /* Don't stop at second breakpoint */ | | | | | 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 | FirstThread = tinfo->hThread; FirstContext.ContextFlags = CONTEXT_FULL; GetThreadContext(FirstThread, &FirstContext); tclEntry = Tcl_FindHashEntry(proc->funcTable, "VirtualAlloc"); if (tclEntry == NULL) { proc->nBreakCount++; /* Don't stop at second breakpoint */ EXP_LOG0(MSG_DT_NOVIRT); return; } addr = (DWORD) Tcl_GetHashValue(tclEntry); 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; } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
1084 1085 1086 1087 1088 1089 1090 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXSecondBreakpoint(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { CONTEXT context; UCHAR retbuf[2048]; DWORD base; LPEXCEPTION_DEBUG_INFO exceptInfo; ExpBreakInfo *info; |
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 | 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))) { | | | 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 | 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++) { |
︙ | ︙ | |||
1134 1135 1136 1137 1138 1139 1140 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXBreakpoint(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { LPEXCEPTION_DEBUG_INFO exceptInfo; CONTEXT context; ExpThreadInfo *tinfo; ExpBreakpoint *pbrkpt, *brkpt; PDWORD pdw; |
︙ | ︙ | |||
1258 1259 1260 1261 1262 1263 1264 | * OnXSecondChanceException -- * * Handle a second chance exception * *---------------------------------------------------------------------- */ | | | 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 | * OnXSecondChanceException -- * * Handle a second chance exception * *---------------------------------------------------------------------- */ void OnXSecondChanceException(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { BOOL b; STACKFRAME frame; CONTEXT context; ExpThreadInfo *tinfo; Tcl_HashEntry *tclEntry; |
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 | proc->exeModule->dbgInfo->ImageFileName) { s = proc->exeModule->dbgInfo->ImageFileName; } else { s = ""; } fprintf(stderr, "Backtrace for %s\n", s); fprintf(stderr, "-------------------------------------\n"); | | | 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | 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, NULL, SymFunctionTableAccess, SymGetModuleBase, |
︙ | ︙ | |||
1394 1395 1396 1397 1398 1399 1400 | } 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); | | | | 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | } 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); } } error: if (ExpDebug) { Sleep(10000); } |
︙ | ︙ | |||
1424 1425 1426 1427 1428 1429 1430 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 | * * Results: * None * *---------------------------------------------------------------------- */ void OnXSingleStep(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { UCHAR code; /* * Now, we need to restore the breakpoint that we had removed. */ code = 0xcc; |
︙ | ︙ | |||
1451 1452 1453 1454 1455 1456 1457 | * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ | | | 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 | * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ void OnXLoadDll(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { WORD w; DWORD dw; DWORD ImageHdrOffset; PIMAGE_FILE_HEADER pfh; /* File header image in subprocess memory */ PIMAGE_SECTION_HEADER psh; |
︙ | ︙ | |||
1615 1616 1617 1618 1619 1620 1621 | * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ | | | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 | * * Side Effects: * Some information is printed * *---------------------------------------------------------------------- */ void OnXUnloadDll(ExpProcess *proc, LPDEBUG_EVENT pDebEvent) { Tcl_HashEntry *tclEntry; ExpModule *modPtr; /* * Display a message that the DLL has |
︙ | ︙ | |||
1661 1662 1663 1664 1665 1666 1667 | * * Results: * TRUE if successful, FALSE if unsuccessful. * *---------------------------------------------------------------------- */ | | | > | 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 | * * Results: * TRUE if successful, FALSE if unsuccessful. * *---------------------------------------------------------------------- */ BOOL SetBreakpoint(ExpProcess *proc, ExpBreakInfo *info) { Tcl_HashEntry *tclEntry; PVOID funcPtr; tclEntry = Tcl_FindHashEntry(proc->funcTable, info->funcName); if (tclEntry == NULL) { //EXP_LOG("Unable to set breakpoint at %s", info->funcName); return FALSE; } #if 0 fprintf(stderr, "%s: ", info->funcName); #endif /* * Set a breakpoint at the function start in the subprocess and * save the original code at the function start. */ funcPtr = Tcl_GetHashValue(tclEntry); SetBreakpointAtAddr(proc, info, funcPtr); return TRUE; } /* *---------------------------------------------------------------------- * * SetBreakpointAtAddr -- * |
︙ | ︙ | |||
1755 1756 1757 1758 1759 1760 1761 | * Side Effects: * Save the return value in an array of known console handles * with their statuses. * *---------------------------------------------------------------------- */ | | | 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | * Side Effects: * Save the return value in an array of known console handles * with their statuses. * *---------------------------------------------------------------------- */ void OnOpenConsoleW(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR name[256]; PVOID ptr; LOG_ENTRY("OpenConsoleW"); |
︙ | ︙ | |||
1802 1803 1804 1805 1806 1807 1808 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ | | | 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void OnWriteConsoleA(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[1024]; PVOID ptr; DWORD n; PCHAR p; |
︙ | ︙ | |||
1861 1862 1863 1864 1865 1866 1867 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ | | | 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void OnWriteConsoleW(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR buf[1024]; CHAR ansi[2048]; PVOID ptr; DWORD n; |
︙ | ︙ | |||
1927 1928 1929 1930 1931 1932 1933 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ | | | 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void OnFillConsoleOutputCharacter(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[4096]; int bufpos; UCHAR c; PVOID ptr; |
︙ | ︙ | |||
2052 2053 2054 2055 2056 2057 2058 | bufpos += strlen(&buf[bufpos]); memset(&buf[bufpos], c, postCols); bufpos += postCols; } } if (GetConsoleScreenBufferInfo(HConsole, &info) == FALSE) { char errbuf[200]; | | | | 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 | bufpos += strlen(&buf[bufpos]); memset(&buf[bufpos], c, postCols); bufpos += postCols; } } if (GetConsoleScreenBufferInfo(HConsole, &info) == FALSE) { char errbuf[200]; wsprintfA(errbuf, "handle=0x%08x", HConsole); 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; } |
︙ | ︙ | |||
2217 2218 2219 2220 2221 2222 2223 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ | | | 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void OnWriteConsoleOutputCharacterA(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[1024]; PVOID ptr; DWORD n; PCHAR p; |
︙ | ︙ | |||
2279 2280 2281 2282 2283 2284 2285 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ | | | 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | * * Side Effects: * Prints some output. * *---------------------------------------------------------------------- */ void OnWriteConsoleOutputCharacterW(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR buf[1024]; CHAR ansi[2048]; PVOID ptr; DWORD n; |
︙ | ︙ | |||
2366 2367 2368 2369 2370 2371 2372 | * Notes: * If this is ever used for real, there need to be ASCII * and UNICODE versions. * *---------------------------------------------------------------------- */ | | | 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 | * Notes: * If this is ever used for real, there need to be ASCII * and UNICODE versions. * *---------------------------------------------------------------------- */ void OnReadConsoleInput(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { LOG_ENTRY("ReadConsoleInput"); } /* |
︙ | ︙ | |||
2391 2392 2393 2394 2395 2396 2397 | * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ | | | 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 | * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ void OnSetConsoleMode(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { DWORD i; BOOL found; LOG_ENTRY("SetConsoleMode"); |
︙ | ︙ | |||
2433 2434 2435 2436 2437 2438 2439 | * Side Effects: * We reread the entire console and send it to the master. * Updates the current console cursor position * *---------------------------------------------------------------------- */ | | | 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 | * Side Effects: * We reread the entire console and send it to the master. * Updates the current console cursor position * *---------------------------------------------------------------------- */ void OnSetConsoleActiveScreenBuffer(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { LOG_ENTRY("SetConsoleActiveScreenBuffer"); if (*returnValue == FALSE) { return; |
︙ | ︙ | |||
2463 2464 2465 2466 2467 2468 2469 | * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ | | | 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 | * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ void OnSetConsoleCursorPosition(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { BOOL b; CHAR buf[50]; DWORD count; |
︙ | ︙ | |||
2500 2501 2502 2503 2504 2505 2506 | * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ | | | 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 | * * Side Effects: * Updates the current console cursor position * *---------------------------------------------------------------------- */ void OnSetConsoleWindowInfo(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { LOG_ENTRY("SetConsoleWindowInfo"); } /* |
︙ | ︙ | |||
2601 2602 2603 2604 2605 2606 2607 | * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ | | | 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 | * Side Effects: * Sets some flags that are used in determining echoing * characteristics of the slave driver. * *---------------------------------------------------------------------- */ void OnGetStdHandle(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { DWORD i; BOOL found; if (*returnValue == (DWORD) INVALID_HANDLE_VALUE) { |
︙ | ︙ | |||
2649 2650 2651 2652 2653 2654 2655 | * 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) * *---------------------------------------------------------------------- */ | | | 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 | * 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 OnBeep(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[50]; LOG_ENTRY("Beep"); |
︙ | ︙ | |||
2680 2681 2682 2683 2684 2685 2686 | * Redraw the entire screen * * Results: * None * *---------------------------------------------------------------------- */ | | | 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 | * Redraw the entire screen * * Results: * None * *---------------------------------------------------------------------- */ void RefreshScreen(LPOVERLAPPED over) { CONSOLE_SCREEN_BUFFER_INFO info; UCHAR buf[4096]; DWORD bufpos = 0; CHAR_INFO consoleBuf[4096]; COORD size = {ConsoleSize.X, ConsoleSize.Y}; |
︙ | ︙ | |||
2770 2771 2772 2773 2774 2775 2776 | * * Results: * None * *---------------------------------------------------------------------- */ | | | 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 | * * Results: * None * *---------------------------------------------------------------------- */ void OnIsWindowVisible(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { LOG_ENTRY("IsWindowVisible"); *returnValue = TRUE; } |
︙ | ︙ | |||
2801 2802 2803 2804 2805 2806 2807 | * 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. * *---------------------------------------------------------------------- */ | | | 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 | * 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 ReadSubprocessMemory(ExpProcess *proc, LPVOID addr, LPVOID buf, DWORD len) { DWORD oldProtection = 0; MEMORY_BASIC_INFORMATION mbi; BOOL ret = TRUE; DWORD offset; |
︙ | ︙ | |||
2961 2962 2963 2964 2965 2966 2967 | #if 0 /* Debugging purposes only */ if (ret == FALSE) { assert(ret != FALSE); } #endif return ret; } | | < < < < < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 | #if 0 /* Debugging purposes only */ if (ret == FALSE) { assert(ret != FALSE); } #endif return ret; } //#endif /* !UNICODE */ /* *---------------------------------------------------------------------- * * 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 OnWriteConsoleOutputA(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { CHAR buf[1024]; PVOID ptr; DWORD n; CHAR *p, *end; int maxbuf; BOOL b; COORD bufferSize; COORD bufferCoord; COORD curr; SMALL_RECT writeRegion; CHAR_INFO *charBuf, *pcb; SHORT x, y; LOG_ENTRY("WriteConsoleOutputA"); 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 == NULL) return; ReadSubprocessMemory(proc, ptr, &writeRegion,sizeof(SMALL_RECT)); ptr = (PVOID) threadInfo->args[1]; /* Get character array */ if (ptr == NULL) return; n = bufferSize.X * bufferSize.Y * sizeof(CHAR_INFO); charBuf = malloc(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); b = ExpWriteMaster(UseSocket, HMaster, buf, maxbuf, &proc->overlapped); 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; b = ExpWriteMaster(UseSocket, HMaster, buf, maxbuf, &proc->overlapped); buf[maxbuf] = 0; #if 0 ExpSyslog("Writing %s", buf); #endif } free(charBuf); LOG_EXIT("WriteConsoleOutputA"); } /* *---------------------------------------------------------------------- * * 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 OnWriteConsoleOutputW(ExpProcess *proc, ExpThreadInfo *threadInfo, ExpBreakpoint *brkpt, PDWORD returnValue, DWORD direction) { WCHAR buf[1024]; PVOID ptr; DWORD n; WCHAR *p, *end; int maxbuf; BOOL b; COORD bufferSize; COORD bufferCoord; COORD curr; SMALL_RECT writeRegion; CHAR_INFO *charBuf, *pcb; SHORT x, y; LOG_ENTRY("WriteConsoleOutputW"); if (*returnValue == 0) { return; } bufferSize = *((PCOORD) &threadInfo->args[2]); bufferCoord = *((PCOORD) &threadInfo->args[3]); |
︙ | ︙ | |||
3038 3039 3040 3041 3042 3043 3044 | 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++) { | < < < < | 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 | 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); b = ExpWriteMaster(UseSocket, HMaster, buf, maxbuf, &proc->overlapped); p = buf; } } curr.X = writeRegion.Left; |
︙ | ︙ | |||
3064 3065 3066 3067 3068 3069 3070 | buf[maxbuf] = 0; #if 0 ExpSyslog("Writing %s", buf); #endif } free(charBuf); | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 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 | buf[maxbuf] = 0; #if 0 ExpSyslog("Writing %s", buf); #endif } free(charBuf); LOG_EXIT("WriteConsoleOutputW"); } /* *---------------------------------------------------------------------- * * ReadSubprocessStringA -- * * Read a character string from the subprocess * * Results: * The length of the string * *---------------------------------------------------------------------- */ int ReadSubprocessStringA(ExpProcess *proc, PVOID base, PCHAR buf, int buflen) { CHAR *ip, *op; int i; ip = 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; } /* *---------------------------------------------------------------------- * * ReadSubprocessStringW -- * * Read a character string from the subprocess * * Results: * The length of the string * *---------------------------------------------------------------------- */ int ReadSubprocessStringW(ExpProcess *proc, PVOID base, PWCHAR buf, int buflen) { WCHAR *ip, *op; int i; ip = 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; } |
Changes to win/expWinSlaveDrv.c.
︙ | ︙ | |||
45 46 47 48 49 50 51 | * CHAR AsciiChar; * } uChar; * DWORD dwControlKeyState; * Response: None * *---------------------------------------------------------------------- */ | | < > | < < < | | > | < | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | * CHAR AsciiChar; * } uChar; * DWORD dwControlKeyState; * Response: None * *---------------------------------------------------------------------- */ #if !defined(BUILD_spawndrv) && !defined(STATIC_BUILD) # error "build instruction error" #endif #include "expWinInt.h" #pragma comment (lib, "ws2_32.lib") #define STATE_WAIT_CMD 0 /* Waiting for the next command */ #define STATE_CREATE 1 /* Doesn't happen currently */ #define STATE_KEY 2 /* Waiting for key params */ #define STATE_KILL 3 /* 1 Param: type of kill to do */ #define STATE_MOUSE 4 /* */ #define STATE_WRITE 5 /* Wait for the length of the data */ |
︙ | ︙ | |||
185 186 187 188 189 190 191 | * read from the child's STDOUT and STDERR. Anything read * from the pipe will be forwarded directly to the master on * the appropriate pipes. This should also take care of the * problems associated with blocking pipes. * *---------------------------------------------------------------------- */ | | | | | | | > > > > > > > > > > | > > | > > | 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 | * read from the child's STDOUT and STDERR. Anything read * from the pipe will be forwarded directly to the master on * the appropriate pipes. This should also take care of the * problems associated with blocking pipes. * *---------------------------------------------------------------------- */ #if 0 void main(argc, argv) int argc; char **argv; { HANDLE hConsoleInW; /* Console, writeable input handle */ HANDLE hConsoleOut; /* Console, readable output handle */ HANDLE hMaster; /* Pipe between master and us */ HANDLE hSlaveOut; /* Pipe from slave's STDOUT to us */ HANDLE hSlaveOutW; /* Pipe from slave's STDOUT to us */ HANDLE hProcess; /* Current process handle */ UCHAR cmdline[BUFSIZE]; BOOL bRet; DWORD dwResult; HANDLE hThread; DWORD threadId; ExpSlaveDebugArg debugInfo; PassThrough thruSlaveOut; int passThrough = 0; int useSocket = 0; int n; int sshd = 0; int port = 0; struct sockaddr_in sin; WSADATA SockData; #if 0 Sleep(22000); /* XXX: For debugging purposes */ #endif /* Select the unicode or ascii winprocs. */ ExpInitWinProcessAPI(); /* We use a few APIs from Tcl, dynamically load it. */ /* This exits on error. */ ExpDynloadTclStubs(); if (argc < 2) { EXP_LOG0(MSG_IO_ARGSWRONG); } /* This exits on error. */ ExpSpawnOpenClientMailbox(argv[1]); if (argc == 2) { /* This is how we use it from sshd */ useSocket = 1; sshd = 1; } else { if (argv[2][0] == '1') { passThrough = 1; |
︙ | ︙ | |||
241 242 243 244 245 246 247 | useSocket = 0; } } if (!useSocket) { hMaster = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); | | > > > | < < | < | < < > > > > > > > > > | | > | < < < | 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 | useSocket = 0; } } if (!useSocket) { hMaster = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (hMaster == INVALID_HANDLE_VALUE) { EXP_LOG2(MSG_NP_CANTOPEN, argv[1], ExpSyslogGetSysMsg(GetLastError())); } if (GetFileType(hMaster) != FILE_TYPE_PIPE) { EXP_LOG1(MSG_NP_BADTYPE, argv[1]); } } else { SOCKET fdmaster; dwResult = WSAStartup(WINSOCK_VERSION, &SockData); if (dwResult != 0) { EXP_LOG2(MSG_WS_CANTSTART, "2.2", ExpSyslogGetSysMsg(dwResult)); } fdmaster = WSASocket(PF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (fdmaster == INVALID_SOCKET) { EXP_LOG1(MSG_WS_CANTCREATEMASTERSOCK, ExpSyslogGetSysMsg(WSAGetLastError())); } /* * Now attach this to a specific port. */ sin.sin_family = AF_INET; /* get the port */ if (Tcl_GetInt(NULL, argv[1], &port) != TCL_OK || port < 0 || port > 65536) { EXP_LOG1(MSG_WS_PORTOUTOFRANGE, argv[1]); } sin.sin_port = (short) port; sin.sin_addr.s_addr = INADDR_LOOPBACK; if (connect(fdmaster, (struct sockaddr *) &sin, sizeof(sin)) == SOCKET_ERROR) { EXP_LOG2(MSG_WS_CANTCONNECTMASTERSOCK, argv[1], ExpSyslogGetSysMsg(WSAGetLastError())); } hMaster = (HANDLE) fdmaster; } ExpConsoleOut = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); |
︙ | ︙ | |||
302 303 304 305 306 307 308 | PipeRespondToMaster(useSocket, hMaster, GetLastError(), 0); ExitProcess(255); } InitializeWaitQueue(); if (sshd) { | | | | < | < | 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 | PipeRespondToMaster(useSocket, hMaster, GetLastError(), 0); ExitProcess(255); } InitializeWaitQueue(); if (sshd) { WSAOVERLAPPED over; ZeroMemory(&over, sizeof(WSAOVERLAPPED)); over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); bRet = ExpReadMaster(useSocket, hMaster, cmdline, BUFSIZE, &n, &over, &dwResult); CloseHandle(over.hEvent); cmdline[n] = 0; SetArgv(cmdline, &debugInfo.argc, &debugInfo.argv); } else { debugInfo.argc = argc-4; debugInfo.argv = &argv[4]; } /* * The subprocess needs to be created in the debugging thread. * Set all the args in debugInfo and start it up. */ hConsoleInW = CreateFile("CONIN$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hConsoleInW == NULL) { EXP_LOG2(MSG_DT_CANTGETCONSOLEHANDLE, "CONIN$", ExpSyslogGetSysMsg(GetLastError())); } hConsoleOut = CreateFile("CONOUT$", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hConsoleOut == NULL) { EXP_LOG2(MSG_DT_CANTGETCONSOLEHANDLE, "CONOUT$", ExpSyslogGetSysMsg(GetLastError())); } ExpConsoleInputMode = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT| ENABLE_PROCESSED_INPUT|ENABLE_MOUSE_INPUT; debugInfo.passThrough = passThrough; debugInfo.useSocket = useSocket; |
︙ | ︙ | |||
385 386 387 388 389 390 391 | if (sshd) { SshdProcessInput(hMaster, hConsoleInW, hConsoleOut); } else { ExpProcessInput(hMaster, hConsoleInW, hConsoleOut, useSocket, &debugInfo); } } | | | | | | | 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 | if (sshd) { SshdProcessInput(hMaster, hConsoleInW, hConsoleOut); } else { ExpProcessInput(hMaster, hConsoleInW, hConsoleOut, useSocket, &debugInfo); } } #endif /* *---------------------------------------------------------------------- * * ExpProcessInput -- * * The master in this case is Expect. Drives until everything exits. * * Results: * None. * *---------------------------------------------------------------------- */ static void ExpProcessInput(HANDLE hMaster, HANDLE hConsoleInW, HANDLE hConsoleOut, int useSocket, ExpSlaveDebugArg *debugInfo) { WSAOVERLAPPED over; UCHAR buffer[BUFSIZE]; DWORD dwState; DWORD dwHave; DWORD dwNeeded; DWORD dwTotalNeeded; BOOL bRet; DWORD dwResult; DWORD driverInCnt; /* Number of bytes read from expect pipe */ dwHave = 0; dwState = STATE_WAIT_CMD; dwNeeded = 1; ZeroMemory(&over, sizeof(WSAOVERLAPPED)); over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); while (1) { bRet = ExpReadMaster(useSocket, hMaster, &buffer[dwHave], dwNeeded-dwHave, &driverInCnt, &over, &dwResult); if ((bRet == TRUE && driverInCnt == 0) || (bRet == FALSE && dwResult == ERROR_BROKEN_PIPE)) { if( useSocket ) { /* * We should always break out because the hShutdown event got set * as the wait queue thread exited. */ if( WaitForSingleObject(hShutdown, 0) == WAIT_OBJECT_0 ) { fd_set monitor; int sts; /* * This means that all of the other threads have shut down cleanly. */ /* * This will signal shutdown to the other end, by sending the * FD_CLOSE. We need to hold the connection open until the |
︙ | ︙ | |||
457 458 459 460 461 462 463 | * Once we get the FD_CLOSE back from the master, then it is * safe to close the socket. */ closesocket((SOCKET) hMaster); } else { | | < < > | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | * Once we get the FD_CLOSE back from the master, then it is * safe to close the socket. */ closesocket((SOCKET) hMaster); } else { EXP_LOG1(MSG_IO_BADSHUTDOWN, ExpSyslogGetSysMsg(dwResult)); } } ExpKillProcessList(); ExitProcess(0); } else if (bRet == FALSE) { ExpKillProcessList(); EXP_LOG1(MSG_IO_UNEXPECTED, ExpSyslogGetSysMsg(dwResult)); } dwHave += driverInCnt; if (dwHave != dwNeeded) { continue; } dwHave = 0; |
︙ | ︙ | |||
519 520 521 522 523 524 525 | dwState = STATE_WRITE_DATA; break; case STATE_WRITE_DATA: if (WriteBufferToSlave(FALSE, useSocket, FALSE, hMaster, hConsoleInW, hConsoleOut, buffer, dwNeeded, &over) == FALSE) { | | | | 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 | dwState = STATE_WRITE_DATA; break; case STATE_WRITE_DATA: if (WriteBufferToSlave(FALSE, useSocket, FALSE, hMaster, hConsoleInW, hConsoleOut, buffer, dwNeeded, &over) == FALSE) { EXP_LOG1(MSG_MS_SLAVENOWRITABLE, ExpSyslogGetSysMsg(GetLastError())); } dwTotalNeeded -= dwNeeded; if (dwTotalNeeded) { dwNeeded = (dwTotalNeeded > BUFSIZE) ? BUFSIZE : dwTotalNeeded; } else { dwNeeded = 1; dwState = STATE_WAIT_CMD; } break; case STATE_KEY: case STATE_MOUSE: /* XXX: To be implemented */ break; default: /* If we ever get here, there is a problem */ EXP_LOG0(MSG_MS_BADSTATE); break; } } } /* *---------------------------------------------------------------------- |
︙ | ︙ | |||
561 562 563 564 565 566 567 | static void SshdProcessInput(HANDLE hMaster, HANDLE hConsoleInW, HANDLE hConsoleOut) { int n; UCHAR buffer[BUFSIZE]; BOOL b; DWORD dwError; | | | | < | 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 | static void SshdProcessInput(HANDLE hMaster, HANDLE hConsoleInW, HANDLE hConsoleOut) { int n; UCHAR buffer[BUFSIZE]; BOOL b; DWORD dwError; WSAOVERLAPPED over; ZeroMemory(&over, sizeof(WSAOVERLAPPED)); over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ExpNewConsoleSequences(TRUE, hMaster, &over); while (1) { ResetEvent(over.hEvent); b = ExpReadMaster(TRUE, hMaster, buffer, BUFSIZE, &n, &over, &dwError); /* * FIXME(eric) - the changes I put in for process shutdown have probably broken * this. */ if (!b) { ExpKillProcessList(); ExitProcess(0); } if (WriteBufferToSlave(TRUE, TRUE, FALSE, hMaster, hConsoleInW, hConsoleOut, buffer, n, &over) == FALSE) { EXP_LOG1(MSG_MS_SLAVENOWRITABLE, ExpSyslogGetSysMsg(GetLastError())); } } } /* *---------------------------------------------------------------------- * * InitializeWaitQueue -- |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | * When this thread exits, the main thread will be free to return. Just set * the event so that the main thread knows what's up. */ SetEvent(hShutdown); return 0; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1313 1314 1315 1316 1317 1318 1319 | * When this thread exits, the main thread will be free to return. Just set * the event so that the main thread knows what's up. */ SetEvent(hShutdown); return 0; } |
Added win/expWinSlaveEvents.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 | /* ---------------------------------------------------------------------------- * expWinSlaveEvents.cpp -- * * Processes all events. * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnTransport.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" /* *---------------------------------------------------------------------- * ExpWinSlaveEvents -- * * Process all events for the slavedrv application. * * Returns: * an exit code. * *---------------------------------------------------------------------- */ int ExpWinSlaveEvents (ExpSpawnTransportCli *transport, ExpSlaveTrap *masterCtrl) { return 0; } |
Changes to win/expWinSlaveKey.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 | /* ---------------------------------------------------------------------------- * expWinSlaveKey.c -- * * This has tables to do conversions from ASCII characters to * console keyboard input records. Using them, a slave process * can be driven as if someone was typing at the keyboard. * * ---------------------------------------------------------------------------- * * 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.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: exp.h,v 1.1.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #if !defined(BUILD_spawndrv) && !defined(STATIC_BUILD) # error "build instruction error" #endif #include "expWinInt.h" EXP_KEY ExpModifierKeyArray[] = { /* Control */ { 17, 29, 0}, /* LShift */ { 16, 42, 0}, /* RShift */ { 16, 54, 0}, /* Alt */ { 18, 56, 0}, }; |
︙ | ︙ |
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 | /* ---------------------------------------------------------------------------- * SlaveDrvMain.c -- * * 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]> * * Copyright (c) 2001 Telindustrie, LLC * work by David Gravereaux <[email protected]> * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSlaveMain.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.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 # endif #endif /* local protos */ static void SetArgv(int *argcPtr, char ***argvPtr); int #ifdef _UNICODE wmain (void) #else main (void) #endif { int argc; // Number of command-line arguments. char **argv; // Values of command-line arguments. ExpSpawnTransportCli *tclient; // class pointer of transport client. ExpSlaveTrap *masterCtrl; // trap method class pointer. // We use a few APIs from Tcl, dynamically load it now. ExpDynloadTclStubs(); // Select the unicode or ascii winprocs. Works in cooperation with // Tcl_WinUtfToTChar(). ExpWinInit(); // Use our custom commandline parser SetArgv(&argc, &argv); if (argc < 4) { EXP_LOG0(MSG_IO_ARGSWRONG); } // Open the client side of our IPC transport. tclient = ExpWinSpawnOpenTransport(argv[1]); // Create the process to be intercepted within the trap method requested. masterCtrl = ExpWinSlaveOpenTrap(argv[2], argc-3, &argv[3]); // Process events until the slave closes. // // We block on input/events coming from the slave and // input from the IPC coming from expect. return ExpWinSlaveEvents(tclient, masterCtrl); } /* HANDLE hConsoleInW; // Master side (us), writeable input handle. HANDLE hConsoleOut; // Master side (us), readable output handle. if ((hConsoleInW = CreateFile( _T("CONIN$"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { EXP_LOG2(MSG_DT_CANTGETCONSOLEHANDLE, "CONIN$", ExpSyslogGetSysMsg(GetLastError())); } if ((hConsoleOut = CreateFile( _T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { EXP_LOG2(MSG_DT_CANTGETCONSOLEHANDLE, "CONOUT$", ExpSyslogGetSysMsg(GetLastError())); } */ /* *------------------------------------------------------------------------- * * 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( int *argcPtr, /* Filled with number of argument strings. */ char ***argvPtr) /* Filled with argument strings in UTF (malloc'd). */ { char *p, *arg, *argSpace; char **argv; int argc, size, inquote, copy, slashes; TCHAR *cmdLineExt; Tcl_Encoding enc; Tcl_DString ds; cmdLineExt = GetCommandLine(); /* * We might have compiled spawndrv.exe as a native NT app for unicode. * This needs to be compile-time set rather than run-time as * GetCommandLine() could be GetCommandLineW() rather than * GetCommandLineA(). Tcl_WinTCharToUtf() is run-time based and will * flop on it's face if used here in this case. */ #ifdef _UNICODE enc = Tcl_GetEncoding(NULL, "unicode"); #else enc = NULL; /* Use system. cp1252? */ #endif Tcl_DStringInit(&ds); Tcl_ExternalToUtfDString(enc, (CONST char *)cmdLineExt, _tcslen(cmdLineExt), &ds); if (enc != NULL) { Tcl_FreeEncoding(enc); } /* * Precompute an overly pessimistic guess at the number of arguments * in the command line by counting non-space spans. */ size = 2; for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ size++; while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ p++; } if (*p == '\0') { break; } } } argSpace = (char *) ckalloc( (unsigned) (size * sizeof(char *) + Tcl_DStringLength(&ds) + 1)); argv = (char **) argSpace; argSpace += size * sizeof(char *); size--; p = Tcl_DStringValue(&ds); 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] = NULL; *argcPtr = argc; *argvPtr = argv; Tcl_DStringFree(&ds); } |
Added win/expWinSlaveTrap.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 | /* ---------------------------------------------------------------------------- * expWinSlaveTrap.cpp -- * * Generic routines for opening the client trap method. Has knowledge * of all trap types used. * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnTransport.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" /* *---------------------------------------------------------------------- * ExpWinSlaveOpenTrap -- * * The factory method for creating the trap method. * * Returns: * a polymorphed ExpSpawnTrap pointer or NULL for an error. * *---------------------------------------------------------------------- */ ExpSlaveTrap * ExpWinSlaveOpenTrap(char *meth, int argc, char *argv[]) { if (!strcmp(meth, "pipe")) { return new ExpSlaveTrapPipe(argc, argv); } else if (!strcmp(meth, "dbg")) { return new ExpSlaveTrapDbg(argc, argv); } else { return 0L; } } |
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 | /* ---------------------------------------------------------------------------- * expWinSlaveTrapDbg.cpp -- * * . * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnTransport.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" ExpSlaveTrapDbg::ExpSlaveTrapDbg(int argc, char *argv[]) { }; |
Added win/expWinSlaveTrapPipe.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 | /* ---------------------------------------------------------------------------- * expSlaveTrapPipe.cpp -- * * . * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnTransport.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" #define BUFSIZE 4096 ExpSlaveTrapPipe::ExpSlaveTrapPipe(int argc, char *argv[]) { }; class DrivePipeThread : public CMclThreadHandler { public: DrivePipeThread() { } private: unsigned ThreadHandlerProc(void) { OVERLAPPED over; DWORD nread; DWORD max; DWORD count, n; BOOL ret; UCHAR buf[BUFSIZE]; DWORD exitVal; LONG err; n = 0; if (hMaster != NULL) { over.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); } while (1) { ret = PeekNamedPipe(hIn, NULL, 0, NULL, &nread, NULL); if (ret == FALSE) { break; } if (nread == 0) { nread = 1; } do { max = sizeof(buf) - 1 - n; nread = min(nread, max); ret = ReadFile(hIn, &buf[n], nread, &count, NULL); if (ret == FALSE) { err = GetLastError(); goto done; } if (count > 0) { n += count; if (n - 1 >= sizeof(buf)) { break; } } else { break; } ret = PeekNamedPipe(hIn, NULL, 0, NULL, &nread, NULL); if (ret == FALSE) { err = GetLastError(); goto done; } /* * To allow subprocess to do something without continuous * process switching, give it a bit of processing time before * we check for more data. */ if (count == 1 && nread == 0) { Sleep(40); ret = PeekNamedPipe(hIn, NULL, 0, NULL, &nread, NULL); if (ret == FALSE) { err = GetLastError(); goto done; } } } while (nread > 0); // if (WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0) { // goto error; // } WriteFile(ExpConsoleOut, buf, n, &count, NULL); // ReleaseMutex(hMutex); ret = ExpWriteMaster(useSocket, hMaster, buf, n, &over); n = 0; if (ret == FALSE) { break; } } done: if (n > 0) { // if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0) { WriteFile(ExpConsoleOut, buf, n, &count, NULL); // ReleaseMutex(hMutex); ret = ExpWriteMaster(useSocket, hMaster, buf, n, &over); // } } error: CloseHandle(hIn); running = 0; if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE) { exitVal = 0; } else { exitVal = err; } ExitThread(exitVal); return 0; } HANDLE hIn; HANDLE hMaster; /* Output when we are using pipes */ int useSocket; BOOL running; HANDLE thread; }; |
Changes to win/expWinSpawnChan.c.
1 2 3 | /* * 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 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 | /* * expWinSpawnChan.c -- * * Implements the Windows specific portion of the exp * channel type. * * 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 "expInt.h" #include "expPort.h" #define PROTO_SLAVEWRITE(buf,len) \ { \ buf[0] = EXP_SLAVE_WRITE; \ buf[1] = len & 0xff; \ buf[2] = (len & 0xff00) >> 8; \ buf[3] = (len & 0xff0000) >> 16; \ buf[4] = (len & 0xff000000) >> 24; \ } #define PROTO_SLAVEWRITE_LEN 5 /* *---------------------------------------------------------------------- * * ExpPlatformSpawnOutput -- * * Windows specific write routine for the exp 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 */ { ExpState *esPtr = (ExpState *) instanceData; int n = 0; if (expSizeZero(esPtr)) { unsigned char proto[PROTO_SLAVEWRITE_LEN]; /* protocol header */ PROTO_SLAVEWRITE(proto, expSizeGet(esPtr)); n = (Tcl_GetChannelType(esPtr->channel)->outputProc) (Tcl_GetChannelInstanceData(esPtr->channel), proto, PROTO_SLAVEWRITE_LEN, errorPtr); if (n < 0) { return n; } if (n != PROTO_SLAVEWRITE_LEN) { return 0; } //ssPtr->toWrite = toWrite; } n = (Tcl_GetChannelType(esPtr->channel)->outputProc) (Tcl_GetChannelInstanceData(esPtr->channel), bufPtr, toWrite, errorPtr); //if (n > 0) { // ssPtr->toWrite -= n; //} return n; } /* *---------------------------------------------------------------------- * * ExpPlatformSpawnInput -- * * Read routine for exp channel * * Results: * Amount read or -1 with errorcode in errorPtr * * Side Effects: * None. * *---------------------------------------------------------------------- */ int ExpPlatformSpawnInput(instanceData, bufPtr, toRead, errorPtr) ClientData instanceData; char *bufPtr; /* (in) Ptr to buffer */ int toRead; /* (in) amount to read */ int *errorPtr; /* (out) error code */ { return 0; /* TODO: fix me! Make me work. */ } |
Added win/expWinSpawnCliTransport.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 | /* ---------------------------------------------------------------------------- * expWinSlaveCliTransport.cpp -- * * Generic routines for opening the client IPC transport. Has knowledge * of all transport types used. * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnTransport.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" /* *---------------------------------------------------------------------- * ExpWinSpawnOpenTransport -- * * The factory method for creating the client IPC transport from * the name asked of it. * * Returns: * a polymorphed ExpSpawnTransportCli pointer or NULL for an error. * *---------------------------------------------------------------------- */ ExpSpawnTransportCli * ExpWinSpawnOpenTransport(const char *name) { /* If the first 2 chars are 'm' and 'b', then it's a mailbox. */ if (name[0] == 'm' && name[1] == 'b') { return new ExpSpawnMailboxCli(name); } else if (name[0] == 's' && name[1] == 'k') { return new ExpSpawnSocketCli(name); } /* TODO: we can add more transports here when the time is right */ else return 0L; } |
Added win/expWinSpawnMailboxCli.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 | /* ---------------------------------------------------------------------------- * expWinSpawnMailboxCli.cpp -- * * Inter-Process-Communication (IPC) transport using shared memory (file * mapping). These are the client routines used by spawndrv.exe to * connect back to the "exp_spawn" channel driver within the Expect * extension. This is bi-directional like sockets and namedpipes. This * works for ALL versions of windows. This IPC method does not traverse * a network and is only local to a single computer. * * ---------------------------------------------------------------------------- * * 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 full Stubs complience * and any Win32 OS. * * ---------------------------------------------------------------------------- * URLs: http://expect.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinSpawnMailboxCli.cpp,v 1.1.2.1 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" ExpSpawnMailboxCli::ExpSpawnMailboxCli(const char *name) : MasterToExpect(0L), MasterFromExpect(0L) { TCHAR boxName[24]; DWORD err; /* Connect to the out-going. */ wsprintf(boxName, "%sTo", name); MasterToExpect = new CMclMailbox(boxName); /* Check status. */ err = MasterToExpect->Status(); if (err == NO_ERROR) { /* Not allowed to be the creator. */ delete MasterToExpect; EXP_LOG1(MSG_MB_CANTOPENCLIENT1, name); } else if (err != ERROR_ALREADY_EXISTS) { delete MasterToExpect; EXP_LOG2(MSG_MB_CANTOPENCLIENT2, name, ExpSyslogGetSysMsg(err)); } /* Connect to the in-coming. */ wsprintf(boxName, "%sFrom", name); MasterFromExpect = new CMclMailbox(boxName); /* Check status. */ err = MasterToExpect->Status(); if (err == NO_ERROR) { /* Not allowed to be the creator. */ delete MasterToExpect; EXP_LOG1(MSG_MB_CANTOPENCLIENT1, name); } else if (err != ERROR_ALREADY_EXISTS) { delete MasterToExpect; EXP_LOG2(MSG_MB_CANTOPENCLIENT2, name, ExpSyslogGetSysMsg(err)); } } void ExpSpawnMailboxCli::ExpWriteMaster() {}; void ExpSpawnMailboxCli::ExpReadMaster() {}; |
Added win/expWinSpawnSocketCli.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 | /* ---------------------------------------------------------------------------- * expWinSpawnSocketCli.cpp -- * * Socket client used as one of the IPC methods for spawndrv.exe * * ---------------------------------------------------------------------------- * * 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.nist.gov/ * http://expect.sf.net/ * http://bmrc.berkeley.edu/people/chaffee/expectnt.html * ---------------------------------------------------------------------------- * RCS: @(#) $Id: expWinInit.c,v 1.1.2.3 2001/11/09 01:17:40 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include "expWinInt.h" ExpSpawnSocketCli::ExpSpawnSocketCli(const char *name) { } void ExpSpawnSocketCli::ExpWriteMaster() {}; void ExpSpawnSocketCli::ExpReadMaster() {}; |
Changes to win/expWinTty.c.
1 2 3 4 | /* * expWinTty.c -- * * Implements some tty related functions. Handles interaction with | | | 1 2 3 4 5 6 7 8 9 10 11 12 | /* * expWinTty.c -- * * Implements some tty related functions. Handles interaction with * the console. This file uses only ANSI function headers. * * 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. * */ |
︙ | ︙ | |||
65 66 67 68 69 70 71 | * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void | | < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void exp_tty_raw(int set) { if (! consoleInitialized) { return; } if (set == 1) { consoleOutMode &= ~ENABLE_PROCESSED_OUTPUT; } else { |
︙ | ︙ | |||
97 98 99 100 101 102 103 | * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void | | < | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | * Side Effects: * May change the current console settings * *---------------------------------------------------------------------- */ void exp_tty_echo(int set) { if (! consoleInitialized) { return; } if (set == 1) { consoleInMode |= ENABLE_ECHO_INPUT; } else { |
︙ | ︙ | |||
128 129 130 131 132 133 134 | * Results: * The same string if in raw mode, the modified string otherwise * *---------------------------------------------------------------------- */ char * | | < < | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | * Results: * The same string if in raw mode, the modified string otherwise * *---------------------------------------------------------------------- */ char * exp_cook(char *s, int *len) { static unsigned int destlen = 0; static char *dest = 0; char *d; /* ptr into dest */ unsigned int need; if (s == 0) return("<null>"); |
︙ | ︙ |
Changes to 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 | // RCS: @(#) $Id: expect.rc,v 1.1.2.3 2001/10/14 22:13:43 davygrvy Exp $ #include <winver.h> #define RESOURCE_INCLUDED /* needed by tcl.h because it doesn't use RC_INVOKED */ #include "exp.h" 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 VS_FFI_FILEFLAGSMASK #if DEBUG FILEFLAGS VS_FF_DEBUG #else FILEFLAGS VS_FF_PRERELEASE /* 0x0L */ #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */ BEGIN VALUE "FileDescription", "Expect Tcl extension for Windows. Interacts with console applications\0" VALUE "OriginalFilename", "expect" STRINGIFY(EXP_MAJOR_VERSION) STRINGIFY(EXP_MINOR_VERSION) ".dll\0" VALUE "CompanyName", "Telindustrie, LLC\0" VALUE "FileVersion", EXP_PATCH_LEVEL "\0" VALUE "LegalCopyright", "Copyright \251 Telindustrie, LLC 2001\0" VALUE "ProductName", "Expect " EXP_VERSION " for Windows NT\0" VALUE "ProductVersion", EXP_PATCH_LEVEL "\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 |
Deleted win/expectlib.rc.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted win/makefile.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to win/msjexhnd.cpp.
︙ | ︙ | |||
130 131 132 133 134 135 136 | _tprintf( _T("Fault address: %08X %02X:%08X %s\n"), pExceptionRecord->ExceptionAddress, section, offset, szFaultingModule ); PCONTEXT pCtx = pExceptionInfo->ContextRecord; // Show the registers | | | | | | 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 | _tprintf( _T("Fault address: %08X %02X:%08X %s\n"), pExceptionRecord->ExceptionAddress, section, offset, szFaultingModule ); PCONTEXT pCtx = pExceptionInfo->ContextRecord; // Show the registers #ifdef _M_IX86 // Intel Only! _tprintf( _T("\nRegisters:\n") ); _tprintf(_T("EAX:%08X\nEBX:%08X\nECX:%08X\nEDX:%08X\nESI:%08X\nEDI:%08X\n"), pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, pCtx->Esi, pCtx->Edi ); _tprintf( _T("CS:EIP:%04X:%08X\n"), pCtx->SegCs, pCtx->Eip ); _tprintf( _T("SS:ESP:%04X:%08X EBP:%08X\n"), pCtx->SegSs, pCtx->Esp, pCtx->Ebp ); _tprintf( _T("DS:%04X ES:%04X FS:%04X GS:%04X\n"), pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs ); _tprintf( _T("Flags:%08X\n"), pCtx->EFlags ); #endif if ( !InitImagehlpFunctions() ) { OutputDebugString(_T("IMAGEHLP.DLL or its exported procs not found")); #ifdef _M_IX86 // Intel Only! // Walk the stack using x86 specific code IntelStackWalk( pCtx ); #endif return; } ImagehlpStackWalk( pCtx ); _SymCleanup( GetCurrentProcess() ); |
︙ | ︙ |
Changes to win/msjexhnd.h.
︙ | ︙ | |||
24 25 26 27 28 29 30 | static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo ); // Helper functions static LPTSTR GetExceptionString( DWORD dwCode ); static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset ); static void IntelStackWalk( PCONTEXT pContext ); | | | | | | | 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 | static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo ); // Helper functions static LPTSTR GetExceptionString( DWORD dwCode ); static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset ); static void IntelStackWalk( PCONTEXT pContext ); #if 1 static void ImagehlpStackWalk( PCONTEXT pContext ); #endif static int __cdecl _tprintf(const TCHAR * format, ...); #if 1 static BOOL InitImagehlpFunctions( void ); #endif // Variables used by the class static TCHAR m_szLogFileName[MAX_PATH]; static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter; static HANDLE m_hReportFile; #if 1 // Make typedefs for some IMAGEHLP.DLL functions so that we can use them // with GetProcAddress typedef BOOL (__stdcall * SYMINITIALIZEPROC)( HANDLE, LPSTR, BOOL ); typedef BOOL (__stdcall *SYMCLEANUPPROC)( HANDLE ); typedef BOOL (__stdcall * STACKWALKPROC) ( DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, |
︙ | ︙ | |||
63 64 65 66 67 68 69 | static SYMINITIALIZEPROC _SymInitialize; static SYMCLEANUPPROC _SymCleanup; static STACKWALKPROC _StackWalk; static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess; static SYMGETMODULEBASEPROC _SymGetModuleBase; static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr; | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | static SYMINITIALIZEPROC _SymInitialize; static SYMCLEANUPPROC _SymCleanup; static STACKWALKPROC _StackWalk; static SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess; static SYMGETMODULEBASEPROC _SymGetModuleBase; static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr; #endif }; extern MSJExceptionHandler g_MSJExceptionHandler; // global instance of class #endif |
Deleted win/panic.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
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 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 | # 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 Unicode !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 Unicode" !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 "slavedrv - Win32 Debug Unicode" (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 "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 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 /G5 /MD /W3 /GX /O2 /I "D:\tcl_workspace\tcl_head\generic" /I "..\generic" /I "$(IntDir)" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "USE_TCL_STUBS" /D "TCL_THREADS" /D "BUILD_spawndriver" /D "STATIC_BUILD" /YX"exp.h" /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /i "D:\tcl_workspace\tcl_head\generic" /i "..\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 gdi32.lib /nologo /machine:I386 /libpath:"D:\tcl_workspace\tcl_head\win\release" /subsystem:console,4.00 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "slavedrv - 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 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 /G5 /MDd /W3 /Gm /ZI /Od /I "D:\tcl_workspace\tcl_head\generic" /I "..\generic" /I "$(IntDir)" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "BUILD_exp" /D "USE_TCL_STUBS" /D "TCL_THREADS" /D "BUILD_spawndriver" /D "STATIC_BUILD" /FR /YX"exp.h" /FD /GZ /c # ADD BASE RSC /l 0x409 d "_DEBUG" # ADD RSC /l 0x409 /i "D:\tcl_workspace\tcl_head\generic" /i "..\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 gdi32.lib /nologo /debug /machine:I386 /pdbtype:sept /libpath:"D:\tcl_workspace\tcl_head\win\release" /subsystem:console,4.00 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "slavedrv - Win32 Debug Unicode" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "DebugU" # PROP BASE Intermediate_Dir "DebugU" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "DebugU" # PROP Intermediate_Dir "DebugU" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /MDd /W3 /Gm /ZI /Od /I "$(TCL_SRCDIR)\generic" /I "..\generic" /I "$(IntDir)" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /D "_CONSOLE" /D "BUILD_exp" /D "USE_TCL_STUBS" /D "TCL_THREADS" /D "BUILD_spawndriver" /D "STATIC_BUILD" /YX"exp.h" /FD /GZ /c # ADD CPP /nologo /G5 /MDd /W3 /Gm /ZI /Od /I "D:\tcl_workspace\tcl_head\generic" /I "..\generic" /I "$(IntDir)" /D "_DEBUG" /D "WIN32" /D "_UNICODE" /D "UNICODE" /D "_CONSOLE" /D "BUILD_exp" /D "USE_TCL_STUBS" /D "TCL_THREADS" /D "BUILD_spawndriver" /D "STATIC_BUILD" /YX"exp.h" /FD /GZ /c # ADD BASE RSC /l 0x409 /i "$(TCL_SRCDIR)\generic" /i "..\generic" /i "$(INTDIR)" /d "_DEBUG" # ADD RSC /l 0x409 /i "D:\tcl_workspace\tcl_head\generic" /i "..\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 /nologo /debug /machine:I386 /pdbtype:sept /libpath:"d:\tcl_workspace\tcl_head\win\release" /subsystem:console,4.00 # SUBTRACT BASE LINK32 /pdb:none # ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /debug /machine:I386 /pdbtype:sept /libpath:"D:\tcl_workspace\tcl_head\win\release" /subsystem:console,4.00 # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "slavedrv - Win32 Release" # Name "slavedrv - Win32 Debug" # Name "slavedrv - Win32 Debug Unicode" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\expWinDynloadTclStubs.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=.\expWinSlaveDbg.c # End Source File # Begin Source File SOURCE=.\expWinSlaveDrv.c # End Source File # Begin Source File SOURCE=.\expWinSlaveEvents.cpp # End Source File # Begin Source File SOURCE=.\expWinSlaveKey.c # End Source File # Begin Source File SOURCE=.\expWinSlaveMain.cpp # End Source File # Begin Source File SOURCE=.\expWinSlaveTrap.cpp # End Source File # Begin Source File SOURCE=.\expWinSlaveTrapDbg.cpp # End Source File # Begin Source File SOURCE=.\expWinSlaveTrapPipe.cpp # End Source File # Begin Source File SOURCE=.\expWinSpawnCliTransport.cpp # End Source File # Begin Source File SOURCE=.\expWinSpawnMailboxCli.cpp # End Source File # Begin Source File SOURCE=.\expWinSpawnSocketCli.cpp # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\generic\exp.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 # Begin Source File SOURCE=.\expWinInt.h # End Source File # Begin Source File SOURCE=.\expWinPort.h # End Source File # Begin Source File SOURCE=.\expWinSlave.hpp # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=.\spawndrv.rc # End Source File # Begin Source File SOURCE=.\spawndrvmc.mc !IF "$(CFG)" == "slavedrv - Win32 Release" # Begin Custom Build - Compiling message catalog... IntDir=.\Release InputPath=.\spawndrvmc.mc BuildCmds= \ mc -w -h "$(IntDir)" -r "$(IntDir)" $(InputPath) "$(IntDir)\spawndrvmc.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\spawndrvmc.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 InputPath=.\spawndrvmc.mc BuildCmds= \ mc -w -h "$(IntDir)" -r "$(IntDir)" $(InputPath) "$(IntDir)\spawndrvmc.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\spawndrvmc.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\MSG00409.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "slavedrv - Win32 Debug Unicode" # Begin Custom Build - Compiling message catalog... IntDir=.\DebugU InputPath=.\spawndrvmc.mc BuildCmds= \ mc -w -h "$(IntDir)" -r "$(IntDir)" $(InputPath) "$(IntDir)\spawndrvmc.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\spawndrvmc.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "$(IntDir)\MSG00409.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # End Group # End Target # End Project |
Added win/spawndrv.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 | /* ---------------------------------------------------------------------------- * spawndrv.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 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.2.5 2001/10/29 06:40:29 davygrvy Exp $ * ---------------------------------------------------------------------------- */ #include <winver.h> #define RESOURCE_INCLUDED /* needed by tcl.h because it doesn't use RC_INVOKED */ #include "exp.h" 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 VS_FFI_FILEFLAGSMASK #if defined(_DEBUG) FILEFLAGS VS_FF_DEBUG #elif EXP_RELEASE_LEVEL == TCL_FINAL_RELEASE FILEFLAGS 0x0L #else FILEFLAGS VS_FF_PRERELEASE #endif #if defined(_UNICODE) FILEOS VOS_NT_WINDOWS32 /* limit this to NT only */ #else FILEOS VOS__WINDOWS32 /* open to all */ #endif 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", EXP_PATCH_LEVEL "\0" VALUE "LegalCopyright", "Copyright \251 Telindustrie, LLC 2001\0" VALUE "ProductName", "Expect " EXP_VERSION " for Win32\0" VALUE "ProductVersion", EXP_PATCH_LEVEL "\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 "spawndrvmc.rc" |
Added win/spawndrvmc.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 | ;/* ---------------------------------------------------------------------------- ; * spawndrvmc.mc -- ; * ; * This file contains the message catalog for use with Win32 error ; * reporting through ReportEvent() and FormatMessage(). ; * ; * Copyright (c) 2001 Telindustrie, LLC ; * ; * Authors: David Gravereaux <[email protected]> ; * ; * See the file "license.terms" for information on usage and redistribution ; * of this file, and for a DISCLAIMER OF ALL WARRANTIES. ; * ---------------------------------------------------------------------------- ; */ 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=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 . |
Deleted win/tclHash.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |