Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
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

Bookmark It

Search this book:
 
Previous Table of Contents Next



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 doesn’t 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 doesn’t 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. (That’s 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, they’re 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 don’t. 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 won’t make your cooked output raw, so it’s 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 script’s filename may not have the proper filename extension for your server’s configuration. This extension is usually .cgi, .plx, or .pl. In short, check your filename and location, and your server’s CGI-related configuration values.

Termination

Termination is nothing more than cleaning up after yourself and quitting. If you’ve locked any files, you must release them before letting the program end. If you’ve 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 hinder—or even break—the 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, it’s 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 script’s resources and cleans up just as thoroughly as the main exit routine does.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.