OVERVIEW: HARDCOPY is a program that "clones" the CLI output stream and sends it to two places at one time: the normal CLI window, and a file. With it, you can create a hardcopy listing of all the activity that went on in a CLI window. This can be useful for documentation purposes, error analysis, and error reporting. The advantage of using HARDCOPY instead of output-redirection is that you still see the output in the CLI window (as well as capture it in a file). This makes getting a hardcopy listing of an interactive session much easier. HARDCOPY's major drawback is that it only copies text that goes to or from the CLI window; it does not record any of the activity that occurs in programs that open their own Intuition windows. It will, however, record all data entered in CON and RAW windows opened from the CLI window from which a HARDCOPY is being made. USING HARDCOPY: To use HARDCOPY, type: 1> HARCOPY TO where is the name of a file where HARDCOPY will record your CLI session. This can be on disk, in RAM:, or even directly to PRT:. Note that HARDCOPY will be writing to this file every time something happens in your CLI window, so if you are HARDCOPYing to disk, make sure you select a disk that can stay in a disk drive! HARDCOPY will try to start up a new process that will monitor your CLI and copy its output to the file you have selected. In order to start the monitoring process, HARDCOPY uses the Execute() function. This function requires the RUN command to be in the C: directory. If your workbench disk is not in a drive, you will get a disk-insert requester, so don't be alarmed. Once the monitoring process is started, HARDCOPY waits for it to signal that it is ready to begin copying to the file (you will receive a message informing you of this). In a few seconds, you should get another message that says the hardcopy session is beginning. If you get an error message (like "Unknown command HARDCOPY"), or if HARDCOPY seems to hang (it does not return to the CLI prompt), then follow the instructions under ERROR RECOVERY. Once the HARDCOPY monitor process is under way, you should be returned to the CLI prompt. At this point you can enter commands normally. All the input from and output to the CLI window (or any CON or RAW window opened from the CLI) will be routed to the file as well as the CLI window. When you want to stop sending HARDCOPY output to the file, issue the command 1> HARDCOPY END This will signal the monitor process to close the file and stop running. You should receive a message informing you that the HARDCOPY transcript is complete. At this point, you can use the output file in whatever way you choose. USAGE NOTES: To avoid disk swapping due to the HARDCOPY process, make sure the HARDCOPY output file is on a disk that will remain in one of the disk drives. RAM: is good for small HARDCOPY sessions, but it can fill up faster than you think! Don't HARDCOPY TO *. When anything appears in your CLI window, HARDCOPY will try to write it to the output file. Since the output file is your CLI, HARDCOPY will see its own output as something that must be copied. This will cause am infinite loop, or a deadlock situation, depending on when the output occurs. Don't ENDCLI without first ending your HARDCOPY session. If you do, the CLI window won't close (since HARDCOPY is still using it), but you will not be able to enter any more commands. See the ERROR RECOVERY section for information on what to do if this occurs. HARDCOPY uses the Execute() call, which requires the RUN command to be in the C: directory. HARDCOPY executes the HARDCOPY command, so the HARDCOPY command itself must be in the current directory, or in the current PATH searched by the Execute() call. You can not TYPE, EDIT, or otherwise look at or change the HARDCOPY output file until after you issue the HARDCOPY END command. You can not have more than one HARDCOPY session going to the same file. HARDCOPY creates a new version of the file each time it is invoked, so it will destroy the current version of the specified output file, if one already exists. ERROR RECOVERY: There are two kinds of errors that can occur: HARDCOPY may fail to start the monitoring process, or something may happen to your CLI so that you need to end the HARDCOPY monitor "by hand". When you start HARDCOPY, it spawns a new process to do the monitoring for you. HARDCOPY waits to make sure that this process is running and ready to record your output before it lets you enter more commands (it informs you of this with a "waiting" message). If an error message appears while HARDCOPY is waiting, or if HARDCOPY never completes (you don't get the CLI prompt back), then you should wait till all the disk activity (if any) stops, and then press CTRL-E. This will stop HARDCOPY from waiting for the monitor process to start up (this may leave a monitor process active). Use the STATUS command to check that there is no HARDCOPY monitor process running. If there is, try typing HARDCOPY END. If that does not work, then use the BREAK command to send a CTRL-C and then a CTRL-E to the HARDCOPY monitor process (see the example below). If something happens to your CLI so that you can not enter the HARDCOPY END command (for instance, you type ENDCLI while there is a HARDCOPY session in progress), then you can stop HARDCOPY from another CLI. Use the STATUS command to find the process number of the HARDCOPY monitor. Then use BREAK to send it a CTRL-C. If the monitored CLI is still active, make sure some input or output occurs to the window (unfortunately, type-ahead does not qualify as input). Once you have done this (or if it is not possible), then use BREAK again to send a CTRL-E to the HARDCOPY process. Use STATUS to verify that the process really is gone. For example, suppose you have two CLIs running (1 and 2), and had a HARDCOPY session in progress for CLI number 2, but forgot about it and typed ENDCLI without having ended the HARDCOPY session. You should do the following (from CLI number 1): 1> STATUS ; see what processes there are Task 1: Loaded as command: STATUS ; this CLI Task 4: Loaded as command: HARDCOPY ; HARDCOPY monitor process 1> BREAK 4 ALL ; send it a CTRL-C and CTRL-E 1> STATUS ; check what we've done Task 1: Loaded as command: STATUS 1> ; monitor is gone! Now suppose you have two CLIs running (1 and 2), and had a HARDCOPY session in progress for CLI number 2, but ran a program that entered an infinite loop, so you can not end the HARDCOPY session by typing HARDCOPY END. You should do the following (from CLI number 1): 1> STATUS ; see what processes there are Task 1: Loaded as command: STATUS ; this CLI Task 2: Loaded as command: LoopForEver ; CLI 2 in an infinite loop Task 4: Loaded as command: HARDCOPY ; HARDCOPY monitor process 1> BREAK 4 C ; send monitor a CTRL-C ; click in CLI window 2, and force some I/O to occur; ; click back in CLI window 1; 1> STATUS ; check what we've done Task 1: Loaded as command: STATUS Task 2: Loaded as command: LoopForEver ; nothing we can do about this 1> ; but monitor is gone! USES FOR HARDCOPY: I see HARDCOPY as a useful method of documenting CLI functions. For instance, it can be used to make a transcript of what people have to do to start up your program or customize their environment to make your program more useful, or what they have to do the move your program to a hard disk, etc. HARDCOPY can be used to make an error log during compilation of programs when you want to see the errors AND record them in a file (where you can use an editor to look at the error log at the same time as the source code). If you are running a program that sets up its own screen and eventually crashes, you can have it use printf() to send diagnostic messages to the CLI window, and have them recorded to a file even if the program crashes before you can flip the screen to look at the CLI window. You can use HARDCOPY to capture the exact input you used to produce an error, so that you can report the error easier (and so people will believe that it really occured). You can HARDCOPY TO PRT: to produce a printed listing of your work as it happens. HARDCOPY can be used to have your CLI session show up in two CON windows simultaneously. (Pretty useless, but it looks neat! Use 1> HARDCOPY TO CON:0/0/640/100/Hardcopy to see what I mean.) I expect there are other uses, but I can't think of them. I wrote it mostly as an exercise, and because I've always wanted to be able to do this on a VAX running VMS, but never could. If you come up with interesting uses, please let me know. TECHNICAL NOTES: HARDCOPY is based on MONPROC by Phillip Lindsay of Commodore-Amiga, and is an example of a real-life program that uses his method to monitor the AmigaDOS activity of a process. It was the simplest and most useful example I could think of, but undoubtedly there are others. Phillip pointed out that the pr_PktWait field of the Process structure is used for an alternate taskwait() routine. AmigaDOS calls this routine whenever a process is waiting for AmigaDOS messages to be issued or returned. HARDCOPY installs its own code in this field. This code waits for AmigaDOS packets to arrive, and then signals a monitoring process. This process checks to see if the packet is to or from the CLI window. If it is, it writes the contents of the packet's data buffer to the output file. Then it signals the pr_PktWait routine that it is through writing (via a semaphore). At that point, the packet wait routine returns the packet to the process for its own use. HARDCOPY assumes that all READ and WRITE packets with dp_Arg1 fields equal to zero are CLI I/O packets. This assumption probably is wrong, but it holds in enough cases to make this program useful. If someone finds cases where this fails, please let me know. The HARDCOPY TO command simply sets up the monitoring process and passes it a pointer to the process to be monitored (via an undocumented command-line argument). The monitor process signals HARDCOPY TO that it is ready via a CTRL-C (HARDCOPY TO is waiting for either the CTRL-C from the monitor or a CTRL-E from the user). The monitor process runs as a separate process, but the CLI process executes the pr_PktWait routine, which shares data with the HARDCOPY monitor process, including the signal and semaphore used to coordinate the activity of the packet wait routine and the HARDCOPY process. This gets to be somewhat confusing when you look at the code, so try to remember that the PacketWait() routine (and the StartHardCopy() and EndHardCopy() routines) run in the monitored CLI process, while the rest of the program runs in the monitoring HARDCOPY process, asynchronously. When the user wants to end the hardcopy session, he runs HARDCOPY END, which sends a CTRL-C to the monitor (the monitor stores a pointer to itself in the tc_UserData field of the monitored CLI task; HARDCOPY END looks here for the address of the task to signal). When the monitor process receives the CTRL-C, it de-installs the pr_PktWait code. At this point, since HARDCOPY END is running in the CLI window, and since it is not performing a taskwait(), it is safe to remove the pr_PktWait code (that is, the CLI process is not currently running it). Just to be sure, however, the monitor waits for a CTRL-E. HARDCOPY END writes a message that the session is complete (ensuring that pr_PktWait is not in use anymore), and signals the CTRL-E to the monitor process. The extra CTRL-E is there mainly so that you can stop HARDCOPY monitors "by hand" using the BREAK command. The time between the BREAK C and BREAK E commands is used to make sure some I/O takes place in the monitored CLI window. This ensures that the monitored process is no longer waiting in the PacketWait() routine when HARDCOPY receives the CTRL-E and its code is removed from memory. HOW TO COMPILE AND LINK HARDCOPY: HARDCOPY was developed using the Lattice C Compiler version 3.10. Phillip Lindsay's code was originally designed for the Manx Aztec C compiler, and I have tried to keep it as compatable as possible. I do not own the Manx compiler, however, so I don't know that it still works with it. I suspect that it will need nothing more than minor adjustments. To compile and link with Lattice, use the command: 1> LC -v -L HARDCOPY The -v suppresses stack overflow checking. THIS IS CRITICAL! HARDCOPY will fail if it is not compiled in this fashion. I do not believe that Manx has overflow checking. The executable should be placed in the C: directory. AUTHOR: Davide P. Cervone DPVC@UORDBV.BITNET University of Rochester Computing Center dpvc@tut.cc.rochester.EDU Taylor Hall dpvc@ur-tut.UUCP Rochester New York 14627 (716) 275-2811