|
|
|
To access the contents, click the chapter and section titles.
Platinum Edition Using HTML 4, XML, and Java 1.2
(Publisher: Macmillan Computer Publishing)
Author(s): Eric Ladd
ISBN: 078971759x
Publication Date: 11/01/98
Row, Row, Row Your Script…
In the UNIX world, a character stream is a special kind of file. STDIN and STDOUT are character streams by default. The operating system helpfully parses streams for you, making sure that everything going through is proper 7-bit ASCII or an approved control code.
Seven-bit? Yes. For HTML, this doesnt matter. However, if your script sends graphical data, using a character-oriented stream means instant death. The solution is to switch the stream over to binary mode. In Perl you do this using binmode; in C, you do this with the setmode function: setmode(fileno(stdout), O_BINARY). You can change horses in midstream with the complementary setmode(fileno(stdout), O_TEXT). A typical graphics script will output the headers in character mode and then switch to binary mode for the graphical data.
In the Windows NT world, streams behave the same way for compatibility reasons. A nice simple \n in your output is converted to \r\n for you when you write to STDOUT. This doesnt happen with regular Windows NT system calls, such as WriteFile(); you must specify \r\n explicitly if you want CRLF.
Those who speak mainly UNIX will frown at the term CRLF, whereas those who program on other platforms might not recognize \n or \r\n. CRLF, meet \r\n. \r is how C programmers specify a carriage return (CR) character. \n is how C programmers specify a line feed (LF) character. (Thats Chr$(10) for LF and Chr$(13) for CR to you Basic programmers.)
Alternate words for character mode and binary mode are cooked and raw, respectively, although these terms more generally mean processed and unprocessed as well. Whatever words you use and whatever platform, another problem occurs with streams: by default, theyre buffered. Buffered means that the operating system hangs onto the data until a line-terminating character is seen, the buffer fills up, or the stream is closed. This means that if you mix buffered printf() statements with unbuffered fwrite() or fprintf() statements, things will probably come out jumbled even though they may all write to STDOUT. The printf() statement writes buffered to the stream; file-oriented routines output directly. The result is an out-of-order mess.
You may lay the blame for this at the feet of backward compatibility. Beyond the existence of many old programs, streams have no reason to default to buffered and cooked. These should be options that you turn on when you want them, not that you turn off when you dont. Fortunately, you can get around this problem with the statement setvbuf(stdout, NULL, _IONBF, 0), which turns off all buffering for the STDOUT stream.
Another solution is to avoid mixing types of output statements; even so, that wont make your cooked output raw, so its a good idea to turn off buffering anyway. Many servers and browsers are cranky and dislike receiving input in drabs and twaddles.
Listing 28.9 shows a pseudocode representation of a simple processing phase whose objective is to have the browser display all the environment variables gathered in the initialization phase.
This has the effect of creating a simple HTML document containing a bulleted list. Each item in the list is a variable, expressed as name=value.
Listing 28.9 A Pseudocode Script to Show Variables Gathered During Initialization
output header content-type: text/html\n
output required blank line to terminate header \n
output <html>
output <head><title>Variable Report</title></head>
output <body bgcolor=\#FFFFFF\>
output <h1>Variable Report</h1>
output <ul>
for each variable known
output <li>
output variable-name
output =
output variable-value
loop until all variables printed
output </ul>
output </body>
output </html>
|
| TROUBLESHOOTING TIP
|
| If your document displays without explicit error but is empty, make sure that you included a blank line following the header line(s) at the beginning of the .cgi script, before the output for the body of your document. Sometimes you may even need to use two blank lines to get your document content to show.
|
|
| TROUBLESHOOTING TIP
|
| If your script shows in the browser, instead of its output, your script is not being executed. Three usual causes exist for your script being treated as data instead of running as a program. One is that your server may not be properly configured for CGI. Another is that your script may be in the incorrect directory. Your scripts may need to be in a designated CGI script directory, often called cgi-bin. Lastly, your scripts filename may not have the proper filename extension for your servers configuration. This extension is usually .cgi, .plx, or .pl. In short, check your filename and location, and your servers CGI-related configuration values.
|
|
Termination
Termination is nothing more than cleaning up after yourself and quitting. If youve locked any files, you must release them before letting the program end. If youve allocated memory, semaphores, or other objects, you must free them. Failure to do so may result in a one-shot wonder of a script: one that works only the first time. Worse yet, your script may hinderor even breakthe server itself or other scripts by failing to free up resources and release locks.
On some platforms, most noticeably Windows NT, and to a lesser extent, UNIX, your file handles and memory objects are closed and reclaimed when your process terminates. Even so, its unwise to rely on the operating system to clean up your mess. For instance, under Windows NT, the behavior of the file system is undefined when a program locks all or part of a file and then terminates without releasing the locks.
Make sure that your error-exit routine, if you have one (and you should), knows about your scripts resources and cleans up just as thoroughly as the main exit routine does.
|