<<>> <> <> <> <> <<>> DIRECTORY UnixTypes; UnixShm0: CEDAR DEFINITIONS = BEGIN <> <> < and .>> IpcPerm: TYPE = MACHINE DEPENDENT RECORD [--common IPC access structure uid: UnixTypes.UID, -- (owner's) user id gid: UnixTypes.GID, -- (owner's) group id cuid: UnixTypes.UID, -- creator's user id cgid: UnixTypes.GID, -- creator's group id mode: CARD16, -- access modes; r/w permission; (set op sets only low 9 bits) seq: CARD16, -- slot usage sequence number key: CARD -- key ]; ShmIdDs: TYPE = MACHINE DEPENDENT RECORD [ <<--shared memory descriptor structure>> ipcPerm: IpcPerm, -- operation permission struct segsz: INT, -- size of segment in bytes lpid: UnixTypes.UID, -- process ID of last shmop cpid: UnixTypes.UID, -- process ID of creator nAttch: CARD16, -- number of current attaches unused1: CARD16, -- depending on C compiler's padding algorithm ! aTime: UnixTypes.Time, -- last shmat time dTime: UnixTypes.Time, -- last shmdt time cTime: UnixTypes.Time, -- last change time amp: POINTER -- segment anon¬map pointer ]; SharedMemoryIdentifier: TYPE = RECORD [val: CARD]; errorSharedMemoryIdentifier: SharedMemoryIdentifier = [CARD.LAST]; SharedMemoryKey: TYPE = RECORD [val: CARD]; ipcPRIVATE: SharedMemoryKey = [0]; --private key to create new SharedMemoryIdentifier ShmGetFlags: TYPE = RECORD [val: CARD]; <<--low order 9 bits for permission stuff>> ipcALLOC: ShmGetFlags = [0100000B]; -- entry currently allocated ipcCREAT: ShmGetFlags = [0001000B]; -- create entry if key doesn't exist ipcEXCL: ShmGetFlags = [0002000B]; -- fail if key exists allPerms: ShmGetFlags = [0000777B]; -- (not in found ipc.h) ShmGet: PROC [key: SharedMemoryKey, size: INT, shmflg: ShmGetFlags] RETURNS [shmId: SharedMemoryIdentifier] = TRUSTED MACHINE CODE { <> ".XR_ShmGet" }; IPCCtlCmd: TYPE = RECORD [val: CARD]; ipcRMID: IPCCtlCmd = [0]; -- remove identifier ipcSET: IPCCtlCmd = [1]; -- set options ipcSTAT: IPCCtlCmd = [2]; -- get options ShmCtl: PROC [shmId: SharedMemoryIdentifier, cmd: IPCCtlCmd, buf: POINTER TO ShmIdDs] RETURNS [UnixTypes.SysCallResult] = TRUSTED MACHINE CODE { <> ".XR_ShmCtl" }; ShmAtFlags: TYPE = RECORD [CARD]; noFlags: ShmAtFlags = [000000]; shmRDOnly: ShmAtFlags = [010000]; -- attach read-only (else read-write) shmRnd: ShmAtFlags = [020000]; -- round attach address to SHMBA RawVM: TYPE = POINTER; ShmAt: PROC [id: SharedMemoryIdentifier, addr: RawVM, flags: ShmAtFlags ¬ noFlags] RETURNS [INT] = TRUSTED MACHINE CODE { <> <> <> <> <> ".XR_ShmAt" }; ShmDt: PROC [addr: RawVM] RETURNS [UnixTypes.SysCallResult] = TRUSTED MACHINE CODE { <> <> ".XR_ShmDt" }; <<--The following procedures do not look like belonging here from a purist point of view. However, they are always needed together with the real shared memory stuff.>> VMReserve: PROC [nbytes: CARD] RETURNS [address: RawVM] = TRUSTED MACHINE CODE { <> ".XR_VMReserve" }; <<--VMReserve is not a Unix shared memory feature, but it is always needed together with ShmAt.>> UNTHREADEDShmCtl: UNSAFE PROC [shmId: SharedMemoryIdentifier, cmd: IPCCtlCmd, buf: POINTER TO ShmIdDs] RETURNS [UnixTypes.SysCallResult] = TRUSTED MACHINE CODE { <> "*#include \n"; "#include \n"; "#include \n"; ".shmctl" }; <<--UNTHREADEDShmCtl must not be used by normal Cedar code but only by a registered cleanup procedure from a Unix process.>> <> RegisterUNTHREADEDTerminationCleanupProc: UNSAFE PROC [cleanup: PROC [REF], data: REF ¬ NIL] RETURNS [UnixTypes.SysCallResult] = TRUSTED MACHINE CODE { <> ".XR_RegisterTerminationCleanupProc" }; <<--RegisterUNTHREADEDTerminationCleanupProc is not a Unix shared memory feature, but it is always necessary to provide cleanup when using Unix shared memory..>> END. <<>> <<>>