Annotation of MiNT/doc/filesys.doc, revision 1.1.1.1

1.1       root        1: MiNT File Systems
                      2: 
                      3: 
                      4: 
                      5: MiNT allows loadable file systems, which means that it should be quite
                      6: 
                      7: easy to implement networked file systems, dynamically re-sizable ram
                      8: 
                      9: disks, or other nifty things (for example, Stephen Henson's minix.xfs
                     10: 
                     11: file system allows access to Minix partitions from TOS). Writing
                     12: 
                     13: these is not difficult, but there are a lot of data structures that
                     14: 
                     15: must be understood first. (These data structures are given in the
                     16: 
                     17: file "filesys.h".)
                     18: 
                     19: 
                     20: 
                     21: A note on conventions: a declaration like:
                     22: 
                     23:        short foo P_((char *bar, long baz));
                     24: 
                     25: means that "foo" is a function that returns a 16 bit integer, and that
                     26: 
                     27: expects a pointer to a character and a 32 bit integer as its two
                     28: 
                     29: arguments. "ushort" is an unsigned 16 bit integer; "ulong" is an
                     30: 
                     31: unsigned 32 bit integer.
                     32: 
                     33: 
                     34: 
                     35: File Cookies
                     36: 
                     37: 
                     38: 
                     39: Files and directories are represented in the kernel by "cookies".
                     40: 
                     41: The contents of the cookie are mostly file system dependent, i.e. the
                     42: 
                     43: kernel interprets only the "fs" and "dev" field of the cookie, and the
                     44: 
                     45: contents of the other fields may be used by a file system as it sees fit.
                     46: 
                     47: 
                     48: 
                     49: A file cookie has the following structure:
                     50: 
                     51: 
                     52: 
                     53: typedef struct f_cookie {
                     54: 
                     55:        FILESYS *fs;            /* file system that knows about this cookie */
                     56: 
                     57:        ushort  dev;            /* device info (e.g. Rwabs device number) */
                     58: 
                     59:        ushort  aux;            /* extra data that the file system may want */
                     60: 
                     61:        long    index;          /* this+dev uniquely identifies a file */
                     62: 
                     63: } fcookie;
                     64: 
                     65: 
                     66: 
                     67: (The "FILESYS" data type is defined below.)
                     68: 
                     69: The interpretation of the "aux" field is entirely file system dependent. The
                     70: 
                     71: "index" field is not presently used by the kernel, but file systems
                     72: 
                     73: should (if possible) make this field uniquely identify a file or directory
                     74: 
                     75: on a device.
                     76: 
                     77: 
                     78: 
                     79: File System Structure
                     80: 
                     81: 
                     82: 
                     83: This is the structure that tells the kernel about the file system,
                     84: 
                     85: and gives the entry points for routines which the kernel can call in order
                     86: 
                     87: to manipulate files and directories. Note that actual input/output
                     88: 
                     89: operations are performed by a device driver; most file systems have just
                     90: 
                     91: one associated device driver, but some may have more. See the section on
                     92: 
                     93: device drivers for more information on these.
                     94: 
                     95: 
                     96: 
                     97: Unless otherwise specified, all of the functions should return 0 for
                     98: 
                     99: success and an appropriate (long negative) error code for failure. Also,
                    100: 
                    101: note that it is the kernel's responsibility to do all access checking;
                    102: 
                    103: the file system may assume that the file's permissions have been checked
                    104: 
                    105: and are compatible with the current process' uid and the operation
                    106: 
                    107: selected.
                    108: 
                    109: 
                    110: 
                    111: Parameters are passed to file system driver functions on the stack.
                    112: 
                    113: The file system drivers should preserve registers d2-d7 and a2-a7,
                    114: 
                    115: and return any results in register d0. Note that this may differ from
                    116: 
                    117: your compiler's default conventions (for example, Alcyon C preserves
                    118: 
                    119: only registers d3-d7 and a3-a7); in this case, an assembly language
                    120: 
                    121: wrapper will be necessary.
                    122: 
                    123: 
                    124: 
                    125: typedef struct filesys {
                    126: 
                    127:        struct  filesys *next;
                    128: 
                    129: 
                    130: 
                    131: This is a link to the next file system in the kernel's list. It will be
                    132: 
                    133: filled in by the kernel; the file system should leave it as NULL.
                    134: 
                    135: 
                    136: 
                    137:        long    fsflags;
                    138: 
                    139: These flags give some information about the file system. Currently, three
                    140: 
                    141: flags are defined:
                    142: 
                    143: 
                    144: 
                    145: #define FS_KNOPARSE     0x01   /* kernel shouldn't do parsing */
                    146: 
                    147: #define FS_CASESENSITIVE 0x02  /* file names are case sensitive */
                    148: 
                    149: #define FS_NOXBIT       0x04   /* if a file can be read, it can be executed */
                    150: 
                    151: 
                    152: 
                    153: Other bits may be defined in future releases of MiNT; for now all other
                    154: 
                    155: bits in this flag should be 0. Most file systems will have only the
                    156: 
                    157: FS_NOXBIT flag; networked file systems may have FS_KNOPARSE for
                    158: 
                    159: reasons of efficiency, and file systems that must be compatible with Unix
                    160: 
                    161: or similar specifications may be case sensitive and hence have FS_CASESENSITIVE
                    162: 
                    163: set.
                    164: 
                    165: 
                    166: 
                    167:        long    (*root) P_((short drv, fcookie *fc));
                    168: 
                    169: This is the entry point for a routine to find a file cookie for the root
                    170: 
                    171: directory of BIOS device "drv" (an integer in the range 0-31 inclusive).
                    172: 
                    173: This function is called by the kernel when initializing a drive; the kernel
                    174: 
                    175: will query each file system in turn for a file cookie representing the
                    176: 
                    177: root directory of the drive. If the file system recognizes the data on
                    178: 
                    179: the drive as being valid for a file system that it recognizes, it should
                    180: 
                    181: fill in the cookie pointed to by "fc" and return 0. Otherwise, it should
                    182: 
                    183: return a negative error code (EDRIVE is a good choice) to indicate that the
                    184: 
                    185: drive must belong to another file system. Note that this function is called
                    186: 
                    187: at boot up time and also at any time when media change is detected on a drive.
                    188: 
                    189: 
                    190: 
                    191:        long    (*lookup) P_((fcookie *dir, char *name, fcookie *fc));
                    192: 
                    193: Translate a file name into a cookie. "dir" is the cookie for a directory,
                    194: 
                    195: returned by a previous call to (*lookup) or (*root). "name" is either the
                    196: 
                    197: name of a file in that directory (if fsflags & FS_KNOPARSE == 0) or a path
                    198: 
                    199: name relative to that directory (if fsflags & FS_KNOPARSE == FS_KNOPARSE).
                    200: 
                    201: If the file is not found, an appropriate error code (like EFILNF) should be
                    202: 
                    203: returned. If the file is found, the cookie "*fc" should be filled in with
                    204: 
                    205: appropriate data, and either 0 or EMOUNT returned. EMOUNT should be returned
                    206: 
                    207: only if "name" is ".." and "dir" represents the root directory of a drive;
                    208: 
                    209: 0 should be returned otherwise. Note that a lookup call with a null name
                    210: 
                    211: or with "." should always succeed and return a cookie representing the
                    212: 
                    213: directory itself. Also note that symbolic links should *never* be followed.
                    214: 
                    215: 
                    216: 
                    217:        long    (*creat) P_((fcookie *dir, char *name, ushort mode,
                    218: 
                    219:                                short attrib, fcookie *fc)
                    220: 
                    221: Create a new file named "name" in the directory whose cookie is "dir".
                    222: 
                    223: "mode" gives the file's type and access permissions, as follows:
                    224: 
                    225:        /* file types */
                    226: 
                    227:        #define S_IFMT  0170000         /* mask to select file type */
                    228: 
                    229:        #define S_IFCHR 0020000         /* BIOS special file */
                    230: 
                    231:        #define S_IFDIR 0040000         /* directory file */
                    232: 
                    233:        #define S_IFREG 0100000         /* regular file */
                    234: 
                    235:        #define S_IFIFO 0120000         /* FIFO */
                    236: 
                    237:        #define S_IMEM  0140000         /* memory region or process */
                    238: 
                    239:        #define S_IFLNK 0160000         /* symbolic link */
                    240: 
                    241: 
                    242: 
                    243:        /* special bits: setuid, setgid, sticky bit */
                    244: 
                    245:        #define S_ISUID 04000           /* change euid when executing this file */
                    246: 
                    247:        #define S_ISGID 02000           /* change egid when executing this file */
                    248: 
                    249:        #define S_ISVTX 01000           /* not implemented */
                    250: 
                    251: 
                    252: 
                    253:        /* file access modes for user, group, and other*/
                    254: 
                    255:        #define S_IRUSR 0400            /* read access for user */
                    256: 
                    257:        #define S_IWUSR 0200            /* write access for user */
                    258: 
                    259:        #define S_IXUSR 0100            /* execute access for user */
                    260: 
                    261:        #define S_IRGRP 0040            /* ditto for group... */
                    262: 
                    263:        #define S_IWGRP 0020
                    264: 
                    265:        #define S_IXGRP 0010
                    266: 
                    267:        #define S_IROTH 0004            /* ditto for everyone else */
                    268: 
                    269:        #define S_IWOTH 0002
                    270: 
                    271:        #define S_IXOTH 0001
                    272: 
                    273: 
                    274: 
                    275: "attrib" gives the standard TOS attribute byte. This is slightly redundant
                    276: 
                    277: with "mode" (i.e. the FA_RDONLY bit should agree with the settings of
                    278: 
                    279: S_IWUSR, S_IWGRP, and S_IWOTH, and FA_DIR should be set if and only if
                    280: 
                    281: the file's format is S_IFDIR) but is provided for convenience for standard
                    282: 
                    283: DOS compatible file systems.
                    284: 
                    285: 
                    286: 
                    287: The kernel will make the "creat" call only after using "lookup" in an attempt
                    288: 
                    289: to find the file. The file system should create the file (if possible) and
                    290: 
                    291: set the cookie pointed to by "fc" to represent the newly created file.
                    292: 
                    293: If an error of any sort occurs, an appropriate error number is returned,
                    294: 
                    295: otherwise 0 is returned. Also note that the kernel will not try to
                    296: 
                    297: create directories this way; it will use "mkdir" (q.v.) instead.
                    298: 
                    299: 
                    300: 
                    301:        DEVDRV *(*getdev) P_((fcookie *fc, long *devspecial))
                    302: 
                    303: Get the device driver which should be used to do i/o on the file whose
                    304: 
                    305: cookie is "fc". If an error occurs, a NULL pointer should be returned
                    306: 
                    307: and an error code placed in the long pointed to by "devspecial"; otherwise,
                    308: 
                    309: "devspecial" should be set to a device-driver specific value which will
                    310: 
                    311: be placed by the kernel in the "devinfo" field of the FILEPTR structure
                    312: 
                    313: passed to the device driver's open routine. (The interpretation of
                    314: 
                    315: this value is a matter for the file system and the device driver, the
                    316: 
                    317: kernel doesn't care.)
                    318: 
                    319: 
                    320: 
                    321: If the call to (*getdev) succeeds, a pointer to a device driver structure
                    322: 
                    323: (see below) is returned; if it fails, a NULL pointer should be returned and
                    324: 
                    325: an appropriate error number placed in *devspecial.
                    326: 
                    327: 
                    328: 
                    329:        long    (*getxattr) P_((fcookie *file, XATTR *xattr));
                    330: 
                    331: Get a file's attributes. The XATTR structure pointed to by "xattr" should
                    332: 
                    333: be filled in with the data for the file or directory represented by
                    334: 
                    335: the cookie "*file", and 0 returned. If a fatal error occurs (e.g. media
                    336: 
                    337: change) an error code is returned instead. The XATTR structure is defined
                    338: 
                    339: as follows:
                    340: 
                    341: 
                    342: 
                    343: /* structure for getxattr */
                    344: 
                    345:        typedef struct xattr {
                    346: 
                    347:        ushort  mode;
                    348: 
                    349: file types and permissions; same as the mode passed to (*creat) (see above)
                    350: 
                    351:        long    index;
                    352: 
                    353: file index; this should if possible be a unique number for the file, so that
                    354: 
                    355: no two files on the same physical drive could have the same index. It is
                    356: 
                    357: not mandatory that this match the "index" field of the fcookie structure
                    358: 
                    359: for the file.
                    360: 
                    361:        ushort  dev;
                    362: 
                    363: physical device on which the file is located; normally set to file->dev
                    364: 
                    365:        ushort  reserved1;
                    366: 
                    367: set to 0
                    368: 
                    369:        ushort  nlink;
                    370: 
                    371: number of hard links to the file; normally 1
                    372: 
                    373:        ushort  uid;
                    374: 
                    375: a number representing the user that owns the file
                    376: 
                    377:        ushort  gid;
                    378: 
                    379: the group ownership of the file
                    380: 
                    381:        long    size;
                    382: 
                    383: length of the file, in bytes
                    384: 
                    385:        short   mtime, mdate;
                    386: 
                    387: last modification time and date of the file, in standard GEMDOS format
                    388: 
                    389:        short   atime, adate;
                    390: 
                    391: last access time and date for the file, in standard GEMDOS format; if the
                    392: 
                    393: file system does not keep separate record of these, they should be the same
                    394: 
                    395: as mtime and mdate
                    396: 
                    397:        short   ctime, cdate;
                    398: 
                    399: file creation time and date, in standard GEMDOS format; if the file system
                    400: 
                    401: does not keep separate record of these, they should be the same as mtime
                    402: 
                    403: and mdate
                    404: 
                    405:        short   attr;
                    406: 
                    407: TOS attribute byte for the file in the lower 8 bits; the upper 8 should
                    408: 
                    409: be 0
                    410: 
                    411:        short   reserved2;
                    412: 
                    413: reserved, set to 0
                    414: 
                    415:        long    reserved3[2];
                    416: 
                    417: reserved, set both long words to 0
                    418: 
                    419:        } XATTR;
                    420: 
                    421: 
                    422: 
                    423:        long    (*chattr) P_((fcookie *file, short attr));
                    424: 
                    425: Change the TOS attributes of the file whose cookie is "*file" to "attr".
                    426: 
                    427: Only the lower 8 bits of "attr" should be considered significant, for now.
                    428: 
                    429: The kernel will not allow changes if the file's current attributes include
                    430: 
                    431: the FA_DIR bit or the FA_LABEL bit. Not all filesystems will support all
                    432: 
                    433: TOS attribute bits, but FA_RDONLY should probably be supported if possible;
                    434: 
                    435: usually setting the FA_RDONLY bit should be equivalent to turning off all
                    436: 
                    437: write permissions to the file.
                    438: 
                    439: 
                    440: 
                    441:        long    (*chown) P_((fcookie *file, short uid, short gid));
                    442: 
                    443: Change a file's user and group ownership to "uid" and "gid" respectively.
                    444: 
                    445: The kernel checks access permissions before making this call, so file
                    446: 
                    447: systems do not have to. If the file system does not support a concept
                    448: 
                    449: of ownership, or does not allow changes to ownership, it should return
                    450: 
                    451: EINVFN.
                    452: 
                    453: 
                    454: 
                    455:        long    (*chmode) P_((fcookie *file, ushort mode));
                    456: 
                    457: Change a file's access permissions. "mode" is similar to the field in
                    458: 
                    459: the XATTR structure or the value passed to creat, except that _only_
                    460: 
                    461: the permission bits are significant; (mode & S_IFMT) will always be 0.
                    462: 
                    463: In the event that the file system supports only a subset of permissions
                    464: 
                    465: (e.g. the TOS file system can only control write access to the file)
                    466: 
                    467: then it may consider only the relevant bits of "mode".
                    468: 
                    469: 
                    470: 
                    471:        long    (*mkdir) P_((fcookie *dir, char *name, ushort mode));
                    472: 
                    473: Make a new subdirectory called "name" of the directory whose cookie is
                    474: 
                    475: "*dir". The new directory should have the file permissions given by
                    476: 
                    477: "mode & ~S_IFMT". Note that the file system should do all appropriate
                    478: 
                    479: initializations for the new directory, including making entries for
                    480: 
                    481: "." and "..". Note also that the kernel verifies that "mode & S_IFMT"
                    482: 
                    483: is S_IFDIR before making this call.
                    484: 
                    485: 
                    486: 
                    487:        long    (*rmdir) P_((fcookie *dir, char *name));
                    488: 
                    489: Delete the subdirectory called "name" of the directory whose cookie is
                    490: 
                    491: "*dir". It is also a good idea to allow removal of symbolic links via
                    492: 
                    493: this call, since a symbolic link to a directory looks like a directory
                    494: 
                    495: to a normal TOS program.
                    496: 
                    497: 
                    498: 
                    499:        long    (*remove) P_((fcookie *dir, char *name));
                    500: 
                    501: Delete the file called "name" in the directory "*dir". This function should
                    502: 
                    503: act like the Unix "unlink" call, i.e. if the file has more than 1 hard
                    504: 
                    505: link to it, only this particular link to the file should be removed and
                    506: 
                    507: the file contents should not be affected. Directories should not be removed
                    508: 
                    509: by this function. Symbolic links definitely should be removed by this
                    510: 
                    511: function; whether other types of special files are removed by this function
                    512: 
                    513: is up to the file system.
                    514: 
                    515: 
                    516: 
                    517:        long    (*getname) P_((fcookie *relto, fcookie *dir, char *pathname));
                    518: 
                    519: This is analogous to the "getcwd()" operation in Unix. It should get the name
                    520: 
                    521: of the directory whose cookie is "*dir", expressed as a path relative
                    522: 
                    523: to the directory whose cookie is "*relto"; normally, this is the root
                    524: 
                    525: directory, but the file system should not assume this. The resulting path
                    526: 
                    527: is placed in the array pointed to by *pathname, which is PATH_MAX bytes
                    528: 
                    529: long. If *relto and *dir are the same directory, then an empty string
                    530: 
                    531: should be placed in *pathname.
                    532: 
                    533: 
                    534: 
                    535: Example: if "*relto" is the directory "\FOO", and "*dir" is the directory
                    536: 
                    537: "\FOO\BAR\SUB", then after the call "pathname" should contain "\BAR\SUB".
                    538: 
                    539: 
                    540: 
                    541:        long    (*rename) P_((fcookie *olddir, char *oldname,
                    542: 
                    543:                            fcookie *newdir, char *newname));
                    544: 
                    545: Rename the file with name "oldname" contained in the directory whose cookie
                    546: 
                    547: is "*olddir" to the name "newname" in the directory whose cookie is "*newdir".
                    548: 
                    549: The file system need not actually support cross-directory renames, or
                    550: 
                    551: indeed any sort of renames at all; if no renames at all are supported, EINVFN
                    552: 
                    553: should be returned.
                    554: 
                    555: 
                    556: 
                    557:        long    (*opendir) P_((DIR *dirh, short tosflag));
                    558: 
                    559: Open a directory for reading. "dirh" is a pointer to a structure as defined
                    560: 
                    561: below; the file cookie for the directory being opened may be found there.
                    562: 
                    563: "tosflag" is a copy of "dirh->flags" and is in a sense redundant. The
                    564: 
                    565: file system should initialize the "fsstuff" and "index" fields of "*dirh"
                    566: 
                    567: to whatever it needs for carrying out a successful search.
                    568: 
                    569: 
                    570: 
                    571: /* structure for opendir/readdir/closedir */
                    572: 
                    573: typedef struct dirstruct {
                    574: 
                    575:        fcookie fc;             /* cookie for this directory */
                    576: 
                    577:        ushort  index;          /* index of the current entry */
                    578: 
                    579:        ushort  flags;          /* flags (e.g. tos or not) */
                    580: 
                    581: #define TOS_SEARCH     0x01
                    582: 
                    583: /* if TOS_SEARCH is set, this call originated from a TOS Fsfirst() system
                    584: 
                    585:  * call -- if possible, the returned names should be acceptable to a
                    586: 
                    587:  * "naive" TOS program
                    588: 
                    589:  */
                    590: 
                    591:        char    fsstuff[60];    /* anything else the file system wants */
                    592: 
                    593: } DIR;
                    594: 
                    595: 
                    596: 
                    597:        long    (*readdir) P_((DIR *dirh, char *name, short namelen, fcookie *fc));
                    598: 
                    599: Read the next name from the directory whose DIR structure (see above)
                    600: 
                    601: is "*dirh". The name should be copied into "name" (if dirh->flags & TOS_SEARCH
                    602: 
                    603: is nonzero) or "name+4" if dirh->flags & TOS_SEARCH is 0; in the latter case,
                    604: 
                    605: the first 4 bytes of "name" should be a unique index for the file. "namelen"
                    606: 
                    607: is the total size of the buffer for "name"; if the next file name (plus index,
                    608: 
                    609: if appopriate, and including the trailing 0) is too long for the buffer, as
                    610: 
                    611: much of it as will fit should be copied in and ENAMETOOLONG returned. If no
                    612: 
                    613: more file names remain unread in the directory, ENMFIL should be returned
                    614: 
                    615: and "name" left unchanged. Otherwise, 0 should be returned.
                    616: 
                    617: Note that volume labels should not be read by this function; only
                    618: 
                    619: "readlabel" (q.v.) should see these.
                    620: 
                    621: 
                    622: 
                    623:        long    (*rewinddir) P_((DIR *dirh));
                    624: 
                    625: Reset the file system specific fields of "*dirh" so that the next call to
                    626: 
                    627: "readdir" on this directory will return the first file name in the directory.
                    628: 
                    629: 
                    630: 
                    631:        long    (*closedir) P_((DIR *dirh));
                    632: 
                    633: Called by the kernel when the directory "*dirh" is not going to be searched
                    634: 
                    635: any more; if the file system needs to clean up any structures or free memory
                    636: 
                    637: allocated for the search it can do so here.
                    638: 
                    639: 
                    640: 
                    641:        long    (*pathconf) P_((fcookie *dir, short which));
                    642: 
                    643: Get path configuration information for the directory whose cookie is
                    644: 
                    645: "*dir". "which" indicates what kind of information should be returned,
                    646: 
                    647: as follows:
                    648: 
                    649: 
                    650: 
                    651: /* The requests for pathconf() */
                    652: 
                    653: #define DP_IOPEN       0       /* internal limit on # of open files */
                    654: 
                    655: #define DP_MAXLINKS    1       /* max number of hard links to a file */
                    656: 
                    657: #define DP_PATHMAX     2       /* max path name length */
                    658: 
                    659: #define DP_NAMEMAX     3       /* max length of an individual file name */
                    660: 
                    661: #define DP_ATOMIC      4       /* # of bytes that can be written atomically */
                    662: 
                    663: #define DP_TRUNC       5       /* file name truncation behavior */
                    664: 
                    665: /* possible return values for DP_TRUNC */
                    666: 
                    667: #      define  DP_NOTRUNC      0       /* long names cause an error */
                    668: 
                    669: #      define  DP_AUTOTRUNC    1       /* long names are truncated */
                    670: 
                    671: #      define  DP_DOSTRUNC     2       /* DOS 8+3 rules are used */
                    672: 
                    673: #define DP_CASE                6       /* file name case conversion */
                    674: 
                    675: /* possible values returned for DP_CASE */
                    676: 
                    677: #      define  DP_CASESENS     0       /* case sensitive */
                    678: 
                    679: #      define  DP_CASECONV     1       /* case always converted */
                    680: 
                    681: #      define  DP_CASEINSENS   2       /* case insensitive, preserved */
                    682: 
                    683: 
                    684: 
                    685: #define DP_MAXREQ      6       /* highest legal request */
                    686: 
                    687: /* Dpathconf and Sysconf return this when a value is not limited
                    688: 
                    689:    (or is limited only by available memory) */
                    690: 
                    691: #define UNLIMITED      0x7fffffffL
                    692: 
                    693: 
                    694: 
                    695:        long    (*dfree) P_((fcookie *dir, long *buf));
                    696: 
                    697: Determine bytes used and free on the disk that the directory whose cookie
                    698: 
                    699: is "*dir" is contained on. "buf" points to the same kind of buffer that
                    700: 
                    701: the "Dfree" system call uses; see the documentation for that call.
                    702: 
                    703: 
                    704: 
                    705:        long    (*writelabel) P_((fcookie *dir, char *name));
                    706: 
                    707: Create a volume label with the indicated name on the drive which contains
                    708: 
                    709: the directory whose cookie is "*dir". If a label already exists, the file
                    710: 
                    711: system may either fail the call with EACCDN or re-write the label. If the
                    712: 
                    713: file system doesn't support the notion of labels, it should return EINVFN.
                    714: 
                    715: 
                    716: 
                    717:        long    (*readlabel) P_((fcookie *dir, char *name, short namelen));
                    718: 
                    719: Read the volume label for the disk whose root directory has the cookie
                    720: 
                    721: "*dir" into the buffer "name", which is "namelen" bytes long. If the
                    722: 
                    723: volume label (including trailing 0) won't fit, return ENAMETOOLONG. If
                    724: 
                    725: *dir is not the cookie of a root directory, or if no volume label
                    726: 
                    727: exists (perhaps because the file system doesn't support them), return
                    728: 
                    729: EFILNF.
                    730: 
                    731: 
                    732: 
                    733:        long    (*symlink) P_((fcookie *dir, char *name, char *to));
                    734: 
                    735: Create a symbolic link called "name" in the directory whose cookie is
                    736: 
                    737: "*dir". The link should contain the 0-terminated string "to". If the file
                    738: 
                    739: system doesn't support symbolic links, it should return EINVFN.
                    740: 
                    741: 
                    742: 
                    743:        long    (*readlink) P_((fcookie *file, char *buf, short buflen));
                    744: 
                    745: Read the contents of the symbolic link whose cookie is "*file" into the
                    746: 
                    747: buffer "buf", which is "buflen" bytes long. If the contents (including the
                    748: 
                    749: trailing 0) won't fit, return ENAMETOOLONG; if the file system doesn't
                    750: 
                    751: do symbolic links, return EINVFN.
                    752: 
                    753: 
                    754: 
                    755:        long    (*hardlink) P_((fcookie *fromdir, char *fromname,
                    756: 
                    757:                                fcookie *todir, char *toname));
                    758: 
                    759: Create a hard link called "toname" in the directory whose cookie is
                    760: 
                    761: "*todir" for the file named "fromname" in the directory whose cookie is
                    762: 
                    763: "*fromdir". If the file system doesn't do hard links, return EINVFN.
                    764: 
                    765: 
                    766: 
                    767:        long    (*fscntl) P_((fcookie *dir, char *name, short cmd, long arg));
                    768: 
                    769: Perform an operation on the file whose name is "name", in the directory with
                    770: 
                    771: cookie "*dir". "cmd" and "arg" specify the operation, and are file system
                    772: 
                    773: specific. See the documentation for Dcntl() for more details. Most file
                    774: 
                    775: systems will just return EINVFN for any values of "cmd" and "arg"; this call
                    776: 
                    777: is here so that you can provide users with a way to manipulate various special
                    778: 
                    779: features of your file system.
                    780: 
                    781: 
                    782: 
                    783:        long    (*dskchng) P_((short drv));
                    784: 
                    785: Check for media change. "drv" is the BIOS device number on which the
                    786: 
                    787: kernel thinks there has been a change. This function is called only
                    788: 
                    789: when the kernel detects what the BIOS claims is a definite disk change
                    790: 
                    791: (i.e. Mediach returning 2 or Mediach returning 1 and Rwabs returning -14).
                    792: 
                    793: This may be the result of a program trying to force a media change; if the
                    794: 
                    795: file system agrees that a change has occured, it should perform any
                    796: 
                    797: appropriate actions (e.g. invalidating buffers) and return 1; the kernel
                    798: 
                    799: will then invalidate any open files or directories on the device and
                    800: 
                    801: re-check what file system the device belongs  If no change, in fact, occured,
                    802: 
                    803: a 0 should be returned to tell the kernel not to worry.
                    804: 
                    805: 
                    806: 
                    807:        long    zero;
                    808: 
                    809: A long word present to allow for future expansion; this must always be set
                    810: 
                    811: to 0 by file systems (for now).
                    812: 
                    813: } FILESYS;
                    814: 
                    815: 
                    816: 
                    817: typedef struct fileptr {
                    818: 
                    819:        short   links;      /* number of copies of this descriptor */
                    820: 
                    821:        ushort  flags;      /* file open mode and other file flags */
                    822: 
                    823: #define O_RWMODE       0x03    /* isolates file read/write mode */
                    824: 
                    825: #      define O_RDONLY 0x00
                    826: 
                    827: #      define O_WRONLY 0x01
                    828: 
                    829: #      define O_RDWR   0x02
                    830: 
                    831: #      define O_EXEC   0x03    /* execute file; used by kernel only */
                    832: 
                    833: 
                    834: 
                    835: #define O_APPEND       0x08    /* all writes go to the end of the file */
                    836: 
                    837: 
                    838: 
                    839: #define O_SHMODE       0x70    /* isolates file sharing mode */
                    840: 
                    841: #      define O_COMPAT 0x00    /* compatibility mode */
                    842: 
                    843: #      define O_DENYRW 0x10    /* deny both read and write access */
                    844: 
                    845: #      define O_DENYW  0x20    /* deny write access to others */
                    846: 
                    847: #      define O_DENYR  0x30    /* deny read access to others */
                    848: 
                    849: #      define O_DENYNONE 0x40  /* don't deny any access to others */
                    850: 
                    851: 
                    852: 
                    853: #define O_NOINHERIT    0x80    /* children can't access via this file descriptor */
                    854: 
                    855: #define O_NDELAY       0x100   /* don't block for i/o on this file */
                    856: 
                    857: #define O_CREAT                0x200   /* create file if it doesn't exist */
                    858: 
                    859: #define O_TRUNC                0x400   /* truncate file to 0 bytes if it does exist */
                    860: 
                    861: #define O_EXCL         0x800   /* fail open if file exists */
                    862: 
                    863: #define O_TTY          0x2000  /* file is a terminal */
                    864: 
                    865: #define O_HEAD         0x4000  /* file is a pseudo-terminal "master" */
                    866: 
                    867: #define O_LOCK         0x8000  /* file has been locked */
                    868: 
                    869: 
                    870: 
                    871: The "flags" is constructed by or'ing together exactly one read/write mode,
                    872: 
                    873: one sharing mode, and any number of the other bits. Device drivers can
                    874: 
                    875: ignore the O_CREAT flag, since file creation is handled by the kernel.
                    876: 
                    877: The O_TRUNC flag, however, should be respected; the file should be
                    878: 
                    879: truncated to 0 length if this flag is set.
                    880: 
                    881: 
                    882: 
                    883:        long    pos;        /* position in file */
                    884: 
                    885: The kernel doesn't actually use this field, except to initialize it to
                    886: 
                    887: 0; it is recommended that device drivers that allow seeking should use it
                    888: 
                    889: to store the current position in the file (relative to the start of
                    890: 
                    891: the file). Other device drivers may use it for other purposes.
                    892: 
                    893:        long    devinfo;    /* device driver specific info */
                    894: 
                    895: This field is passed back to the kernel from the file system from the
                    896: 
                    897: "getdev" call; its interpretation is file system specific, except that
                    898: 
                    899: if this is a terminal device (i.e. the O_TTY bit is set in "flags") then
                    900: 
                    901: this must be a pointer to a struct tty for this terminal.
                    902: 
                    903:        fcookie fc;         /* file system cookie for this file */
                    904: 
                    905: This is the cookie for the file, as returned by the file system "lookup"
                    906: 
                    907: function during opening of the file.
                    908: 
                    909:        struct devdrv *dev; /* device driver that knows how to deal with this */
                    910: 
                    911: This is the device driver returned by the "getdev" call.
                    912: 
                    913:        struct fileptr *next; /* link to next fileptr for this file */
                    914: 
                    915: This field may be used by device drivers to keep a linked list of file
                    916: 
                    917: pointers that refer to the same physical file, for example, in order to
                    918: 
                    919: implement file sharing or locking code.
                    920: 
                    921: } FILEPTR;
                    922: 
                    923: 
                    924: 
                    925: 
                    926: 
                    927: The Device Driver Structure
                    928: 
                    929: 
                    930: 
                    931: All of the functions in the device driver structure, like those in the
                    932: 
                    933: file system structure, are called in supervisor mode and with the
                    934: 
                    935: GCC calling conventions. They must preserve registers d2-d7 and a2-a7,
                    936: 
                    937: and results are to be returned in register d0. The BIOS, XBIOS,
                    938: 
                    939: GEMDOS, AES, and VDI must not be called directly from the device
                    940: 
                    941: driver; but GEMDOS and BIOS functions may be called indirectly via
                    942: 
                    943: the tables found in the kerinfo structure.
                    944: 
                    945: 
                    946: 
                    947: typedef struct devdrv {
                    948: 
                    949:        long (*open)    P_((FILEPTR *f));
                    950: 
                    951: This routine is called by the kernel during a file "open", after it has
                    952: 
                    953: constructed a FILEPTR for the file being opened and determined the device
                    954: 
                    955: driver. The device driver should check the contents of the FILEPTR and
                    956: 
                    957: make any changes or initializations necessary. If for some reason the open
                    958: 
                    959: call should be failed, an appropriate error code must be returned (in which
                    960: 
                    961: case the kernel will free the FILEPTR structure automatically). For example,
                    962: 
                    963: if the file sharing mode in f->flags is not compatible with the sharing
                    964: 
                    965: mode of another open FILEPTR referring to the same physical file, EACCDN should
                    966: 
                    967: be returned.
                    968: 
                    969: 
                    970: 
                    971:        long (*write)   P_((FILEPTR *f, char *buf, long bytes));
                    972: 
                    973: Write "bytes" bytes from the buffer pointed to by "buf" to the file with
                    974: 
                    975: FILEPTR "f". Return the number of bytes actually written. If the file
                    976: 
                    977: pointer has the O_APPEND bit set, the kernel will automatically perform
                    978: 
                    979: an "lseek" to the end of the file before calling the "write" function.
                    980: 
                    981: If the device driver cannot ensure the atomicity of the "lseek" + "write"
                    982: 
                    983: combination, it should take whatever steps are necessary here to ensure
                    984: 
                    985: that files with O_APPEND really do have all writes go to the end of the
                    986: 
                    987: file.
                    988: 
                    989: 
                    990: 
                    991:        long (*read)    P_((FILEPTR *f, char *buf, long bytes));
                    992: 
                    993: Read "bytes" bytes from the file with FILEPTR "f" into the buffer pointed
                    994: 
                    995: to by "buf". Return the number of bytes actually read.
                    996: 
                    997: 
                    998: 
                    999:        long (*lseek)   P_((FILEPTR *f, long where, short whence));
                   1000: 
                   1001: Seek to a new position in the file. "where" is the new position; "whence"
                   1002: 
                   1003: says what "where" is relative to, as follows:
                   1004: 
                   1005: /* lseek() origins */
                   1006: 
                   1007: #define        SEEK_SET        0               /* from beginning of file */
                   1008: 
                   1009: #define        SEEK_CUR        1               /* from current location */
                   1010: 
                   1011: #define        SEEK_END        2               /* from end of file */
                   1012: 
                   1013: 
                   1014: 
                   1015:        long (*ioctl)   P_((FILEPTR *f, short mode, void *buf));
                   1016: 
                   1017: Perform a device specific function. "mode" is the function desired. All devices
                   1018: 
                   1019: should support the FIONREAD and FIONWRITE functions, and the file locking
                   1020: 
                   1021: Fcntl functions if appropriate (see the documentation for the GEMDOS
                   1022: 
                   1023: Fcntl function).
                   1024: 
                   1025: 
                   1026: 
                   1027:        long (*datime)  P_((FILEPTR *f, short *timeptr, short rwflag));
                   1028: 
                   1029: Get or set the date/time of the file. "timeptr" is a pointer to two words,
                   1030: 
                   1031: the first of which is the time and the second of which is the date.
                   1032: 
                   1033: If "rwflag" is 0, the time and date of the file should be placed into timeptr.
                   1034: 
                   1035: If "rwflag" is nonzero, then the time and date of the file should be set to
                   1036: 
                   1037: agree with the time and date pointed to by timeptr.
                   1038: 
                   1039: 
                   1040: 
                   1041:        long (*close)   P_((FILEPTR *f, short pid));
                   1042: 
                   1043: Called every time an open file is closed. Note that the file is "really"
                   1044: 
                   1045: being closed if f->links == 0, otherwise, the FILEPTR is still being used
                   1046: 
                   1047: by some process. However, if the device driver supports file locking
                   1048: 
                   1049: then all locks held on the file by process pid should be released on
                   1050: 
                   1051: any close, even if f->links > 0. Some things to watch out for:
                   1052: 
                   1053: (1) "pid" is not necessarily the current process; some system calls
                   1054: 
                   1055:     (e.g. Fmidipipe, Pexec) can sometimes close files in a process
                   1056: 
                   1057:     other than the current one.
                   1058: 
                   1059: (2) Device drivers should set the O_LOCK bit on f->flag when the F_SETLK
                   1060: 
                   1061:     or F_SETLKW ioctl is made; they can then test for this bit when the file
                   1062: 
                   1063:     is being closed, and remove locks only if O_LOCK is set. Note that all locks
                   1064: 
                   1065:     held by process pid and referring to the same physical file as "f" may
                   1066: 
                   1067:     be removed if O_LOCK is set, not just the locks that were associated with
                   1068: 
                   1069:     the particular FILEPTR "f". If the FILEPTR has never had any lock Fcntl()
                   1070: 
                   1071:     calls made on it, locks on the associated physical file need not be (and
                   1072: 
                   1073:     should not be) removed when it is closed.
                   1074: 
                   1075: 
                   1076: 
                   1077:        long (*select)  P_((FILEPTR *f, long proc, short mode));
                   1078: 
                   1079: Called by Fselect() when "f" is one of the file handles a user has chosen to
                   1080: 
                   1081: do a select on. If mode is O_RDONLY, the select is for reading; if
                   1082: 
                   1083: it is O_WRONLY, it is for writing (if it is for both reading and writing,
                   1084: 
                   1085: the function will be called twice). The select function should return
                   1086: 
                   1087: 1 if the device is ready for reading or writing (i.e. if a read or write
                   1088: 
                   1089: call to the device will not block); otherwise, it should take whatever
                   1090: 
                   1091: steps are necessary to arrange to wake up the process whose PROC structure is
                   1092: 
                   1093: pointed to by "proc" when the appropriate I/O on the device becomes possible.
                   1094: 
                   1095: Normally, this will be done by calling the "wakeselect" function (as passed
                   1096: 
                   1097: by the kernel in "struct kerinfo") with "proc" as its parameter.
                   1098: 
                   1099: 
                   1100: 
                   1101:        void (*unselect) P_((FILEPTR *f, long proc, short mode));
                   1102: 
                   1103: Called when the kernel is returning from an Fselect that had previously
                   1104: 
                   1105: selected this file or device; the device driver should no longer notify
                   1106: 
                   1107: "proc" when I/O is possible for this file or device. "mode" is the same
                   1108: 
                   1109: mode as was passed to the select() function (see above), i.e. either
                   1110: 
                   1111: O_RDONLY or O_WRONLY; as with select(), unselect() will be called twice
                   1112: 
                   1113: if both input and output were selected for.
                   1114: 
                   1115: 
                   1116: 
                   1117:        long reserved[3];
                   1118: 
                   1119: Reserved longwords for future expansion. These must be set to 0.
                   1120: 
                   1121: } DEVDRV;
                   1122: 
                   1123: 
                   1124: 
                   1125: 
                   1126: 
                   1127: 
                   1128: 
                   1129: How the File System Is Booted
                   1130: 
                   1131: 
                   1132: 
                   1133: A loadable file system is an ordinary TOS executable file with an
                   1134: 
                   1135: extension of ".xfs". MiNT searches its current directory (normally the
                   1136: 
                   1137: root directory of the boot disk) when it is starting for all such
                   1138: 
                   1139: files, and loads them with Pexec mode 3. It then does a jump to
                   1140: 
                   1141: subroutine call to the first instruction of the loaded program,
                   1142: 
                   1143: passing on the stack a pointer to a structure of type "struct kerinfo"
                   1144: 
                   1145: (see below) which describes the version of MiNT and provides entry points
                   1146: 
                   1147: for various utility functions.
                   1148: 
                   1149: 
                   1150: 
                   1151: The file system should *not* set up a stack or shrink its basepage
                   1152: 
                   1153: (so the ordinary C startup code is not necessary). MiNT has already provided
                   1154: 
                   1155: a stack of about 8K or so, and has shrunk the basepage to the bare minimum.
                   1156: 
                   1157: The file system initialization point (like all file system functions) is
                   1158: 
                   1159: called in supervisor mode; it must never switch back to user mode. It
                   1160: 
                   1161: may use registers d0, d1, a0, and a1 as scratch registers; all other
                   1162: 
                   1163: registers must be preserved.
                   1164: 
                   1165: 
                   1166: 
                   1167: What the file system initialization code *should* do is to check that an
                   1168: 
                   1169: appropriate version of MiNT is running and to otherwise check the system
                   1170: 
                   1171: configuration to see if it is appropriate for the file system driver.
                   1172: 
                   1173: If so, a pointer to a FILESYS structure should be returned; if not, a NULL
                   1174: 
                   1175: pointer should be returned.
                   1176: 
                   1177: 
                   1178: 
                   1179: Note that it is not necessary to actually check during initialization for
                   1180: 
                   1181: the presence of disks with the appropriate file system types; MiNT will
                   1182: 
                   1183: call the file system "root" function for each drive in the system, and so
                   1184: 
                   1185: such checks should be done in the "root" function.
                   1186: 
                   1187: 
                   1188: 
                   1189: If the file system driver wishes to add new drives to the system,
                   1190: 
                   1191: it should update the drive configuration variable stored at 0x4c2 to
                   1192: 
                   1193: reflect the presence of these new drives.
                   1194: 
                   1195: 
                   1196: 
                   1197: File system drivers should *not* make any calls to the BIOS or GEMDOS
                   1198: 
                   1199: directly; all such calls should be made through the vectors provided by
                   1200: 
                   1201: the kernel as part of the struct kerinfo. File system drivers should
                   1202: 
                   1203: never call the AES, VDI, or XBIOS.
                   1204: 
                   1205: 
                   1206: 
                   1207: All functions made visible to file systems through the kerinfo
                   1208: 
                   1209: structure should be called using the GCC/Lattice C calling conventions,
                   1210: 
                   1211: i.e.:
                   1212: 
                   1213: (1) parameters are passed on the stack, aligned on 16 bit boundaries
                   1214: 
                   1215: (2) registers d0-d1 and a0-a1 are scratch registers and may be modified
                   1216: 
                   1217:     by the called functions
                   1218: 
                   1219: (3) if the function returns a value, it will be returned in register
                   1220: 
                   1221:     d0
                   1222: 
                   1223: 
                   1224: 
                   1225: /*
                   1226: 
                   1227:  * this is the structure passed to loaded file systems to tell them
                   1228: 
                   1229:  * about the kernel
                   1230: 
                   1231:  */
                   1232: 
                   1233: 
                   1234: 
                   1235: typedef long (*Func)();
                   1236: 
                   1237: 
                   1238: 
                   1239: struct kerinfo {
                   1240: 
                   1241:        short   maj_version;    /* kernel version number */
                   1242: 
                   1243:        short   min_version;    /* minor kernel version number */
                   1244: 
                   1245:        ushort  default_mode;   /* default file access permissions */
                   1246: 
                   1247:        short   reserved1;      /* room for expansion */
                   1248: 
                   1249: 
                   1250: 
                   1251: /* OS functions */
                   1252: 
                   1253: /* NOTE: these tables are definitely READ ONLY!!!! */
                   1254: 
                   1255:        Func    *bios_tab;      /* pointer to the BIOS entry points */
                   1256: 
                   1257:        Func    *dos_tab;       /* pointer to the GEMDOS entry points */
                   1258: 
                   1259: 
                   1260: 
                   1261: /* media change vector: call this if a device driver detects a disk
                   1262: 
                   1263:  * change during a read or write operation. The parameter is the BIOS device
                   1264: 
                   1265:  * number of the disk that changed.
                   1266: 
                   1267:  */
                   1268: 
                   1269:        void    (*drvchng) P_((ushort));
                   1270: 
                   1271: 
                   1272: 
                   1273: /* Debugging stuff */
                   1274: 
                   1275:        void    (*trace) P_((char *, ...));     /* informational messages */
                   1276: 
                   1277:        void    (*debug) P_((char *, ...));     /* error messages */
                   1278: 
                   1279:        void    (*alert) P_((char *, ...));     /* really serious errors */
                   1280: 
                   1281:        void    (*fatal) P_((char *, ...));     /* fatal errors */
                   1282: 
                   1283: 
                   1284: 
                   1285: /* memory allocation functions */
                   1286: 
                   1287: /* kmalloc and kfree should be used for most purposes, and act like malloc
                   1288: 
                   1289:  * and free respectively. umalloc and ufree may be used to allocate/free memory
                   1290: 
                   1291:  * that is attached to the current process, and which is freed automatically
                   1292: 
                   1293:  * when the process exits; this is generally not of much use to a file system
                   1294: 
                   1295:  * driver
                   1296: 
                   1297:  */
                   1298: 
                   1299:        void *  (*kmalloc) P_((long));
                   1300: 
                   1301:        void    (*kfree) P_((void *));
                   1302: 
                   1303:        void *  (*umalloc) P_((long));
                   1304: 
                   1305:        void    (*ufree) P_((void *));
                   1306: 
                   1307: 
                   1308: 
                   1309: /* utility functions for string manipulation */
                   1310: 
                   1311: 
                   1312: 
                   1313: /* strnicmp, stricmp: like strncmp and strcmp, respectively, except
                   1314: 
                   1315:  * that case is ignored
                   1316: 
                   1317:  */
                   1318: 
                   1319:        short   (*strnicmp) P_((char *, char *, short));
                   1320: 
                   1321:        short   (*stricmp) P_((char *, char *));
                   1322: 
                   1323: 
                   1324: 
                   1325: /* strlwr: convert a string to lower case. Returns the address of the string */
                   1326: 
                   1327:        char *  (*strlwr) P_((char *));
                   1328: 
                   1329: /* strupr: convert a string to upper case. Returns the address of the string */
                   1330: 
                   1331:        char *  (*strupr) P_((char *));
                   1332: 
                   1333: 
                   1334: 
                   1335: /* sprintf: like the C library sprintf call, but using this one means you
                   1336: 
                   1337:  * can avoid linking another one. Note: floating point formats are not
                   1338: 
                   1339:  * supported! Also: this sprintf will put at most SPRINTF_MAX characters
                   1340: 
                   1341:  * into the output string.
                   1342: 
                   1343:  */
                   1344: 
                   1345:        short   (*sprintf) P_((char *, const char *, ...));
                   1346: 
                   1347: 
                   1348: 
                   1349: /* utility functions for manipulating time */
                   1350: 
                   1351: /* convert "ms" milliseconds into a DOS time (in td[0]) and date (in td[1]) */
                   1352: 
                   1353:        void    (*millis_time) P_((ulong ms, short *td));
                   1354: 
                   1355: 
                   1356: 
                   1357: /* convert a DOS style time and date into a Unix style time; returns the
                   1358: 
                   1359:  * Unix time
                   1360: 
                   1361:  */
                   1362: 
                   1363:        long    (*unixtim) P_((ushort time, ushort date));
                   1364: 
                   1365: 
                   1366: 
                   1367: /* convert a Unix time into a DOS time (in the high word of the returned
                   1368: 
                   1369:  * value) and date (in the low word)
                   1370: 
                   1371:  */
                   1372: 
                   1373:        long    (*dostim) P_((long));
                   1374: 
                   1375: 
                   1376: 
                   1377: /* utility functions for dealing with pauses */
                   1378: 
                   1379: /* go to sleep temporarily for about "n" milliseconds (the exact time
                   1380: 
                   1381:  * slept may vary
                   1382: 
                   1383:  */
                   1384: 
                   1385:        void    (*nap) P_((ushort n));
                   1386: 
                   1387: 
                   1388: 
                   1389: /* wait on system queue "que" until a condition occurs */
                   1390: 
                   1391:        void    (*sleep) P_((short que, long cond));
                   1392: 
                   1393: /* wake all processes on queue "que" that are waiting for condition "cond" */
                   1394: 
                   1395:        void    (*wake) P_((short que, long cond));
                   1396: 
                   1397: 
                   1398: 
                   1399: /* wake a process that is doing a select(); "param" should be the process
                   1400: 
                   1401:  * code passed to select()
                   1402: 
                   1403:  */
                   1404: 
                   1405:        void    (*wakeselect) P_((long param));
                   1406: 
                   1407: 
                   1408: 
                   1409: /* file system utility functions */
                   1410: 
                   1411: /* "list" is a list of open files; "f" is a new file that is being opened.
                   1412: 
                   1413:  * If the file sharing mode of "f" conflicts with any of the FILEPTRs
                   1414: 
                   1415:  * in the list, then this returns 1, otherwise 0.
                   1416: 
                   1417:  */
                   1418: 
                   1419:        short   (*denyshare) P_((FILEPTR *list, FILEPTR *f));
                   1420: 
                   1421: 
                   1422: 
                   1423: /* denylock() checks a list of locks to see if the new lock conflicts
                   1424: 
                   1425:  * with any one in the list. If so, the first conflicting lock
                   1426: 
                   1427:  * is returned; otherwise, a NULL is returned.
                   1428: 
                   1429:  * This function is only available if maj_version > 0 or min_version >= 94.
                   1430: 
                   1431:  * Otherwise, it will be a null pointer.
                   1432: 
                   1433:  */
                   1434: 
                   1435:        LOCK *  (*denylock) P_((LOCK *list, LOCK *new));
                   1436: 
                   1437: 
                   1438: 
                   1439: /* reserved for future use */
                   1440: 
                   1441:        long    res2[9];
                   1442: 
                   1443: };
                   1444: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.