Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-lcc!ames!oliveb!intelca!mipos3!omepd!littlei!ogcvax!schaefer From: schaefer@ogcvax.UUCP (Barton E. Schaefer) Newsgroups: comp.sys.cbm Subject: Out of the depths of C-Power ... Message-ID: <1267@ogcvax.UUCP> Date: Fri, 1-May-87 15:21:02 EDT Article-I.D.: ogcvax.1267 Posted: Fri May 1 15:21:02 1987 Date-Received: Sun, 3-May-87 06:22:18 EDT Reply-To: schaefer@ogcvax.UUCP (Barton E. Schaefer) Organization: Oregon Graduate Center, Beaverton, OR Lines: 125 Keywords: C-Power Power-C opendir file Summary: Answers to my own question, and more [***] Well. Here I am about to answer my own question about opendir() in C-Power (thanks to those who sent helpful suggestions). I did what I should have done quite a while ago and wrote a program to examine the C-64 file descriptor tables during C-Power disk operations. So, for those interested, here's what I found out, plus some other comments on C-Power functions and fixes. According to the C-Power open() manual page, file numbers 5-9 are safe to use in open() when fopen() is also in use, and file numbers 1-4 are reserved for system use. Here's a breakdown of file number usage: File # C-Power Use ====== =========== 1 Standard input. Is not actually opened unless input is redirected, so references to stdin normally read the keyboard. 2 Standard output. Is not actually opened unless output is redirected, so references to stdout normally write the screen. Never closed if output was directed to a file. Files to which output was redirected can be closed by the shell command "disk v". (Is there another way, besides an explicit close(2) before exiting?) 3 Unknown at present. Never opened in my tests. 4 Directory functions. Opened on disk drive channel 4 by opendir(). Closed by closedir(). 5-9 Unused, unless specified by user in open(). Disk drive channels 5-9 should be used with these file numbers, but channel 15 can also be open()'d to send disk commands (see note on file number 15). 10-13 Opened by fopen() on disk drive channels 11-14. The first fopen() uses file number 13, the next uses 12, etc. See warning below on use of fopen(). 14 Unused, but probably not safe for use with open(). 15 Error channel. Opened on disk drive channel 15 by both fopen() and opendir(), read by ferror(), and closed only by exit() or abort(). See note below on opendir() bug. Note that multiple file numbers can reference channel 15 at the same time. 16+ Unused. According to the C-64 manual, file numbers up to 255 are legal, but 128 and above cause carriage return to map to return-linefeed and are intended for use with non-CBM printers. Safe to use with disk drive channels 5-9 and with printers or other devices. Notes and Warnings on C-Power I/O Calls ======================================= ferror() Fails (understandably) to detect inability to open the error channel. This mainly affects opendir() (see below). DO NOT call ferror() before calling one of fopen() or opendir(). fopen() Opens two files, the one returned and file 15 for ferror(). WARNING: This call can foul up the C-64's descriptor tables! If fopen() is called when no channel is available, it will return successfully and cause a file number with a non-existant channel to be entered in the descriptor tables. The disk error will be caught by ferror(), but DO NOT fclose() the file that fopen() returned! If you close this file, which has no channel, the 1541 will close one of the other open files instead. In addition to the obvious problems, this can cause the error channel to be closed, which will break ferror(). fread() Returns 0 if (elsize * nelem) is greater than the number of bytes in the file. The file IS read, but it is not possible to determine how many elements were read. getchar() When reading the keyboard (stdin not redirected), sees a carriage return at the beginning of a line as two characters -- a space followed by a return. This probably applies to getc() and fgetc(stdin) as well. open() File numbers 5-9 and 16-127 can be used with this call. Disk channels 5-9 are safe. opendir() Opens two file numbers, file 4 on channel 4 for the directory and file 15 on channel 15 for use by ferror(). Unfortunately, lacks a test (apparently present in fopen()) to see if file 15 is already open. This causes opendir() to fail if called a second time or if called after fopen(). See fix below. Does NOT accept the syntax "opendir(0:)" as suggested in some manuals. (Maybe this syntax is ok for C-128?) Opens only drive 8 (or, possibly, the work drive as specified by the "work" shell command -- I have only one drive so I'm not sure). Suggested Fix for opendir() =========================== Append the following to all work-disk copies of "dir.h": /*---------------------------------------------------------------------------*/ _diropen() { if (opendir()) return(1); else { close(15); return(opendir()); } } #define opendir() _diropen() /*---------------------------------------------------------------------------*/ Note that the #define must be AFTER the definition of _diropen(). Hope all you C-Power and Power-C users out there find this helpful. If anyone wants a copy of my file-table dump program, send me E-mail and I'll take the time to upload it and send the source. -- Bart Schaefer Dept. of CS&E CSNET: schaefer@Oregon-Grad Oregon Graduate Center UUCP: {ihnp4,seismo,sun}!verdix \ 19600 NW Von Neumann Dr {hplabs,ucbvax,decvax}!tektronix !ogcvax!schaefer Beaverton, OR 97006