Back in 1993 I modified SCF. Here it is in 2010 and I think I did the wrong thing.
The problem was simple: in certain cases, we want to limit the number of open paths for a particular device to 1. For example, if process A wanted to open a path to /P and start printing, then process B wanted to open a path to /P also, both could write on top of each other. The SHARE. bit is an IOMan notion that says "hey, wait a minute, this device can only be opened ONE AT A TIME".
It turns out that device drivers and device descriptors have a byte in their header called the MODE byte. This byte defines all modes that this driver and descriptor support together: READ., WRITE., EXEC. (only applicable for RBF devices)... others, and SHARE. When a path is opened to a device, IOMan will do a logical AND of the MODE byte of the driver and descriptor in question, and then compare the result of the logical AND to the mode byte passed in the I$Open call (in register A). IF the comparison matches, IOMan lets the open proceed; otherwise it fails the I$Open with an E$BMode error. The idea here is that the caller to I$Open cannot pass a mode that isn't supported by both the driver and its descriptor.
Back to the SHARE. bit: this means that if a particular driver and descriptor want to support exclusivity in device use (i.e. not allow multiple open paths to a device), then both the driver and descriptor must have the SHARE. bit set in their respective mode bytes in their header. In the case of the printer driver and the printer descriptor, the SHARE. bit should be set. So far so good.
Enter my solution in 1993. At that time, SCF didn't look at the SHARE. bit at all, so exclusivity for a device was not possible. My goal was add this functionality by modifying SCF's Open call to (a) look at the SHARE. bit in the mode byte of the driver and (b) look at the SHARE. bit in the mode byte of the descriptor. If both were set AND there was already a path open to the device we were opening, return an E$DevBsy error; otherwise, let the open proceed.
Looking back, this was the wrong approach, and here's why:
The MODE bytes in the driver and descriptor are advertisements of capabilities. They say to IOMan, "hey, here's what I can do" and as noted earlier, the mode byte passed to register A in the I$Open call must agree with the capability bits in both MODE bytes. My mistake was to look at the SHARE. bit in the driver and descriptor mode bytes ONLY as a determinant to whether or not to enforce exclusivity.
What I SHOULD have done was the following:
1. In the SCF Open call, look at the user's passed mode byte (which by this point has been copied into the path descriptor's PD.MOD location) and see if the SHARE. bit is set. If not, goto step 3 ELSE
2. determine if there is an open path already for this device. If not, goto step 3 else return E$DevBsy (enforce exclusivity)
3. here there is an open path already existing, but we have not passed the SHARE. bit. However, the path already open may have wanted exclusivity, so we look at ITS PD.MOD byte and if the SHARE. bit is set, we return E$DevBsy (enforce exclusivity)
The idea here is that the user, upon opening a path to the device, MUST pass SHARE. as part of the mode bits in register A, in order to indicate to SCF that he wishes to enforce exclusive access to that device. SCF can grant or deny the I$Open based on whether or not someone else has already opened a path to that device. Likewise, if the user does not set the SHARE. bit upon calling I$Open, but someone else already HAS, then the user should not be allowed to open a path to that device; it's already "taken" by someone else who asked for, and was granted, exclusivity.
Anonymous
Update: Step 2 above should read:
"2. determine if there is an open path already for this device. If not,
continue opening the path as normal else return E$DevBsy (enforce exclusivity)"
With that correction it makes sense.
But what of the scenario where I may have a session of minicom running against a 'shell -=/t2' on the coco, and need to move a file by way of sz or rz (linux's floppy driver can no longer access any 256 byte sector formats so I have to move files by other methods). Will this disallow rz or sz access to that shells stdio for the file transfer?
Assuming shell doesn't call the I$Open of /T2 with the SHARE. bit set in the regA parameter (and I verified that it does not), and also assuming that rz/sz do not do the same, then there will be no problem. Only when the SHARE. bit is set in regA of I$Open do these checks for exclusivity come into play.
Actually Gene, if rz/sz inherits the standard paths to do its I/O, this doesn't even come into play because rz/sz won't be calling I$Open anyway.
I think it's safe to say that no programs or utilities opens an SCF device with the SHARE. bit set in regA because it was never implemented in SCF to begin with, so I think the risk of breaking existing software is non-existent.
I suppose the best way to check that, short of building it and testing it, would be to lok at the rzsz-3.36 code I built it from originally when Paul Jerkatis couldn't build it on his system. He insisted on using the Microware version of c.prep, and I don't think he ever understood that a tfr r,r was the equ of 8 pairs of 1 bit shifts with carries.
From the rz.c src's:
doopen:
openit(name, openmode);
#ifdef MD
if ( !fout)
if (make_dirs(name))
openit(name, openmode);
#endif
if ( !fout)
return ZFERR;
return 0;
}
So if openmode is set correctly, it should work.
BTW, do you have this rzsz-3.3.6 source code?
Ahh, I see your last comment now, and you are probably 100% correct.
Do it. ;-)
Actually7, that snip was incomplete, here is the rest of that:
openit(name, openmode)
char *name, *openmode;
{
fout = fopen(name, openmode);
}
check the docs for fopen in any copy of k&r I guess.
OTOH, if we don't spec the device path, I don't think this code is ever called, so for my scenario, its probably moot.
At first glance, what you suggest makes sense. However, it may be more complicated than in the above explanation.
Paths have two aspects regards sharing. There is PE, PW, PR vs E, W, R as well as S. The above discussion does not make a distinction between public and shareable attributes. Looking at the OS-9 manual, I'm not sure I see the distinction but there should be one.
Any changes made to SCF must address the public / shareable distinction, whatever it is.
Historically speaking, PE PW and PR have been exclusively the domain of RBF as it relates to permissions. Just as SHARE. was ignored by SCF until now, I see no reason why we have to address PE, PW and PR. We can draw a line in the sand and say that for SCF devices, only SHARE, READ and WRITE are applicable modes, and that is how we address it.