Copyright (c) Hyperion Entertainment and contributors.
AmiWest Lesson 3
Contents
AmiWest Lesson 3: Input and Output
Debug Output
One of the first things you will need is some way to output text for debugging purposes. Exec has a simple function which is provided for this purpose and it is used as follows:
IExec->DebugPrintF("my debug message\n");
The text may go to the default serial port, a debug buffer or even a console window via a tool called Sashimi.
More information about this debugging facility can be found at Debug Logging and Redirecting Debug Output.
Console Input and Output
There are many options when it comes to choosing an API for console input and output. This can really confuse beginnners so I thought I would try and briefly explain the fundamentals.
All console input and output is done via DOS streams. That means whatever fancy interface is on the surface it all boils down to working with DOS streams. Three different streams are available for every Process:
- Input
- Output
- ErrorOutput
Usually, Output and ErrorOutput will share the same stream but this is not a requirement.
The ISO C standard also defines input and output streams:
- stdin
- stdout
- stderr
The C startup code will auto-magically create these standard streams for you and assign them to the DOS-provided streams mentioned above.
Whether you use printf() or IDOS->Printf() they will both ultimately end up using the DOS Output stream. However, this doesn't mean you can just mix and match to taste. The reason is that each of these calls are buffered. The C library could use its own buffering or it could depend on DOS buffering. Programmers should not assume one or the other and instead should be consistent in their choice of API.
File Input and Output
File input and output has many APIs to choose from. At the most basic level we have IDOS->Read() and IDOS->Write(). These functions are simple unbuffered large data movers.
Buffered data movers IDOS->FRead() and IDOS->FWrite() are also provided. Buffering is usually employed to batch together smaller data moves to more efficiently transfer them in larger chunks.
When it comes to ISO C, you have fread() and fwrite() which can used to read and write data. These functions use buffering and you cannot make any assumptions regarding how they are buffered. Underneath, they will ultimately call the DOS functions mentioned above.
The UNIX operating system also defines a common set of input and output functions based on read() and write(). The behaviour of these functions is governed by the POSIX standard and not ISO C. Given the popularity of UNIX, these functions are also provided by the C libraries used on AmigaOS. Again, they ultimately will call the DOS functions mentioned above.
Although each of these APIs are essentially independent, they also allow for programmers to convert from one API to the other. For example, the fileno() function will return the POSIX file handle for a ISO C stream. The clib2 function __get_default_file() allows access to the underlying BPTR pointer from DOS.
It is important to understand that each of the APIs above are not meant to be mixed especially on the same file at the same time. Although it is possible to mix APIs that doesn't mean it is a good idea and it will lead to less portable and less robust software.