Specification for GEMDOS File Sharing & Record Locking
------------------------------------------------------

The following information describes the methods that will be used
when GEMDOS is extended to allow file sharing and record locking.
Please note that at this time, despite the fact that this document
discusses how certain aspects of these extensions relate to
networking, this is not a full-fledged network specification.
Developers are encouraged to write software with multiuser
capabilities in mind when at all possible.


Detecting The Extensions
------------------------

An application can determine if the extensions are available by
checking the Cookie Jar for the presence of an "_FLK" cookie.  See
the STE TOS RELEASE NOTES for more information on the Cookie Jar.


_FLK cookie
-----------

The cookie "_FLK" indicates the presence of file and record locking
extensions to GEMDOS.  If this cookie is not found, then the
application should assume that file and record locking extensions are
not installed and make no GEMDOS calls that rely on them, or pass
parameters to GEMDOS functions other than those given in the standard
GEMDOS documentation.  The value field of the "_FLK" cookie should
contain a version number.

If the _FLK cookie is found, then the following extensions and
changes to GEMDOS should be observed:


New GEMDOS call:
----------------

LONG Flock( handle, mode, start, length );

WORD handle;
WORD mode;
LONG start;
LONG length;

GEMDOS Function code = $5C,
(92 decimal)

The Flock() function is designed to lock a specified portion of an
open file to prevent other processes from accessing and/or modifying
that part of the file.

The handle parameter is the GEMDOS file handle of the open file.

The mode parameter specifies if the portion of the file is being
locked or unlocked.  Valid values are:

0 = Create a lock, starting at start and extending for length bytes.

1 = Remove a previously set lock.  Parameters start and length must
match a previous lock.

The start parameter is the offset from the start of the file, in
bytes, where the lock will begin.

The length parameter is the length of the locked area, in bytes.  Once
a lock has been set using a certain handle, other file handles will
not be able to read or write the locked area of the file.  If there
are outstanding locks when a file handle is closed, the behavior is
undefined.

If you duplicate a file handle, any existing locks are inherited by
the duplicate file handle.  If you use Fforce() to redirect a
standard handle to a file with locks, the locks are inherited.

Flock() returns an error code in d0.L, see the section below on
GEMDOS Extensions Error Codes for details.

NOTE: File locks should be used as though they are strictly advisory.
Do not rely on getting back error codes from Fread() and/or Fwrite().
A program which is aware of record locking should set a lock on the
file immediately before accessing it and clear the lock immediately
afterwards.


Changed GEMDOS call:
--------------------

WORD Fopen( filename, mode );

CHAR *filename;
WORD mode;

GEMDOS Function $3D,
(61 decimal)
																
The Fopen() call is designed to open an existing file and return a
file handle that can be used for accessing that file.  Additional
information relating to file sharing can now be included in the mode
parameter.

The filename parameter is a pointer to a character array containing
the filename of the file to be opened.  If only the filename is
given, without a drive and/or path specification, the file is assumed
to reside on the current default drive in the current default path.

The mode parameter indicates how the file is to be used.  Previously
only bits 0-2 were used with this parameter.  Bits 0-2 are still used
to indicate the file access, which indicates what you want to do with
the file.  Bits 4-6 are now used to specify the file sharing modes.
The sharing mode you use indicates what sort of access you want to
allow other processes which may want to use the file.

	Bit #	7 6 5 4 3 2 1 0
			---------------
			I . . . . . . .  Inheritance Flag
			. S S S . . . .  Sharing Mode
			. . . . R . . .  Reserved
			. . . . . A A A  Access code

Bits 0-2 of mode are used for the file access mode.  This is the same
as the original version of GEMDOS without the extensions.  The bits
have the following meanings:

	File Access Modes

	Bit #	2 1 0
			-----
			0 0 0 = Read only access
			0 0 1 = Write only access
			0 1 0 = Read/Write access

Bit 3 of mode is reserved and should always be set to zero.

Bits 4-6 of mode are the sharing mode bits and define what will
happen when more than one program attempts to open the same file.
The sharing mode is set by the first process to open a file, and
subsequent Fopen() calls to the same file will fail if they attempt to
set a conflicting mode.  You can open the file again in a more
restrictive mode.  There are five sharing modes, as shown in the table
below.

	File Sharing Modes

	Bit #	6 5 4 of mode parameter
			-----
			0 0 0 = Compatibility mode
			0 0 1 = Deny Read/Writes, file may not be re-opened
			0 1 0 = Deny Writes, file may be re-opened for read only
			0 1 1 = Deny Reads, file may be re-opened for write only
			1 0 0 = Deny None, file may be re-opened for read/write

When a second attempt is made to open a file which is already open,
GEMDOS tests the sharing mode the file was originally opened with
against the access requested in the second operation, and allows the
second open to succeed only if the two modes are compatible.  For
example, if the file is originally opened with the Deny Writes flag
set, then you can open the file again only for reading, not for write
or read/write.

An open will fail if its share mode denies something which another
handle already has.  For example, an open for read access with Deny
Writes will fail if the file is already open for Write access.

Compatibility mode is designed to allow existing programs to
function, and it is assumed that programs using compatibility mode
are not aware of file sharing and the related specialized error
messages.

A compatibility mode open call for read access can be mutated into
another mode if the file's read-only flag is set.  In this case, the
mode is mutated into the Deny Writes sharing mode.  From that moment
on, it isn't a compatibility mode open attempt any more, and you
should refer to the rules for opens with Read Access and Deny Writes
sharing mode instead.

Otherwise, the access and sharing modes work pretty much as expected.
An attempt to open in a "deny" mode will fail if someone already has
the file open with the access you want to deny.  If it succeeds, then
the file cannot be reopened with the access you deny.

If you attempt to open a file in compatibility mode and the mutation
described above does not occur, it will succeed only if the file isn't
open at all already, or if it is opened by the same process in
compatibility mode.  Once open in compatibility mode, the file can't
be opened by any other process in any mode, and cannot be opened by
the same process in anything but compatibility mode.

Bit 7 of mode indicates if a child process can inherit the use of this
file.  When a child process inherits a file handle, it inherits the
file's access and sharing codes.  If bit 7 = 0, a child process can
use the same handle as the parent to access the file.  If bit 7 = 1,
the child process must open the file itself to obtain a new handle,
and existing file sharing restrictions must be observed.  However,
regions of the file locked by the parent are not accessible to the
child.

Standard GEMDOS error messages apply as before, as well as the new
error codes described below.


Changed GEMDOS call:
--------------------
WORD Fcreate( filename, attribs );

CHAR *filename;
WORD attribs;

GEMDOS Function $3C,
(60 decimal)
																
When a file is created using the Fcreate() call, the sharing mode is
set as though the file already existed and you opened it for
read/write access with Compatibility Mode specified.

If a file already exists and is already open when you try to create
it, then you should get an access denied error (without the extensions
the behavior is undefined).

Otherwise, Fcreate() functions as before.



GEMDOS Extensions Error Codes:
------------------------------

EOK        (0)  Operation was successful, no error.

ELOCKED  (-58)  Record is locked.  Returned if requested portion of
                file is already locked, or if it overlaps a locked
                portion.  This error will also be returned from
                Fread() and Fwrite() calls when a ccessing portions of
                the file which have been locked to different file
                handles.

ENSLOCK (-59)   Matching Lock not found.  Returned if the values
                specified for a lock removal operation do not match a
                lock set operation for the same handle.

All other standard GEMDOS error messages also apply.



Networking
----------
																
Since one of the primary reasons for needing file sharing and record
locking is to allow multiple nodes on a network to share files, we
will discuss a few things about networks.


_NET cookie
-----------

The cookie "_NET" indicates the presence of networking software.  It
does not imply anything about file and record locking.  It is the
responsibility of the networking software to install the "_NET" cookie
and initialize the pointer to the structure.  If the "_FLK" cookie is
not available, it is the responsibility of the networking software to
install the GEMDOS extensions and the "_FLK" cookie as well.

The value field of the cookie is a pointer to a structure of the
format shown below.  Additional network-specific information should be
stored immediately following this structure.

	struct netinfo {
		long	publisher_id;	/* Special code for publisher, */
								/* to be assigned by ATARI (USA) */
								/* Usually a four-byte ASCII string */
								/* such as "ATRI" */

		long	version;		/* Version number of the network, */
								/* to be assigned by the publisher */
	}


Publisher ID's assigned as of May 29, 1991
------------------------------------------
The following Publisher ID codes have been assigned as of the above
date.  These are the values contained in the publisher_id field of the
structure pointed to by the _NET cookie.

	Application Design Software  =  "A&D\0"
	Pams Software  = "PAMS"
	Itos Software  =  "ITOS"


Installing & Checking For The Cookies
-------------------------------------

An application should only check the cookie that covers the resources
it needs.  In other words, an application should not be checking the
"_NET" cookie if all it is worried about is file locking.
Accordingly, a program that sends EMAIL across a network probably only
wants to know about the network and won't care about file and record
locking.

It is also the responsibility of the networking software to create a
cookie jar if no existing one is found.  See the STE TOS RELEASE
NOTES for more information on the cookie jar.




Comments and Suggestions, Anyone?
---------------------------------

I am at this time soliciting comments and suggestions regarding
certain aspects of this specification.

First, we're interested in standardizing at least part of the
information following the structure pointed to by the "_NET" cookie.
What sort of information should go here that an application should
know before making calls to the network software?  What calls, if any,
can an application assume are available if it finds a generic _NET
cookie?  What calls should be common to all networks?  We would like
to specify as much of this as possible, as quickly as possible, so
that products from different publishers of networking software can
store this information in the same place and conform to the standard.

Secondly, as stated before, this specification currently covers only
file sharing and record locking.  Aspects of what the "_NET" cookie
should indicate are still mostly undefined.  However, we would also
like to solicit opinions and ideas about other aspects of a network
implementation.  However, please keep in mind that the specification
so far conforms very closely to MSDOS, and we would like to stick with
that as much as possible.

Finally, there have been a couple of other networking extension
outlines distributed by various developers throughout the world.
However, compatibility with these protocols is not a primary concern,
as these developers are willing to modify their software as needed to
conform with an official Atari specification.   This is mentioned
because at least one of these outlines contains a much wider range of
functions than this specification, and some people may feel that this
specification gives up a lot of functionality.  However, careful
examination will reveal that there is a lot of redundancy to the
functions detailed in that outline.  For example, a separate file
locking function is not required, because you can simply do an Fopen()
call with the sharing mode set to Deny Read/Write, and the file will
be untouchable by any other process.  Also, separate functions for
locking and unlocking are unnecessary, as the flag in the Flock()
function detailed above allow it to both lock and unlock records.

Please address any questions or comments to:

Mike Fulton
Atari Developer Support
1196 Borregas Ave.
Sunnyvale, CA  94089
U.S.A.

(408) 745-8821 - voice
(408) 745-2094 - fax

GEnie = Mike-Fulton
CIS = 75300,1141
Internet = 75300.1141@compuserve.com