Annotation of MiNT/doc/filesys.doc, revision 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.