Shmfile
Small shared library to use shared memory as a FILE* stream , with interprocess communication in mind
Install / Use
/learn @kata198/ShmfileREADME
shmfile
Small shared library to use shared memory as a FILE* , with interprocess communication in mind.
Basic Design
Overview
shmfile is desgined in an "owner/guest" format.
One process is the owner [FSHM_OWMER] of a shared mapping (given by a string name). It creates the mapping, and can destroy it.
Other processes then can map that same string name as guest [FSHM_GUEST].
The guest only needs to know the unique name that the owner picked to have access to the data.
Permissions
Permissions for who can map the same shm as FSHM_GUEST and what they can do with the shmfile are specified by the octal: "mode".
These follow the same rules as chmod.
For example, same user only and read-only would be 0400. Same user r/w, all other users r/o, 0644
You specify the mode when the owner creates the shmfile, which will later determine whomelse on the system may have access.
The permissions are specified by the FSHM_OWNER when creating the shmfile.
If fshm_open is used instead of fshm_guest_open to map an existing shmfile stream as FSHM_GUEST, the mode argument is ignored.
Usage
The fshm_open is the core function that returns a FILE* object, with a valid integer file descriptor [ fd ]. It is passed either FSHM_OWNER or FSHM_GUEST in the "flags" argument to define the operation.
The owner may also create an shmfile stream by using the helper function, fshm_create, and a guest may also map an existing shmfile stream by using the helper function, fshm_guest_open.
You can read/write the data using either the buffered I/O functions (like fread, fwrite, fseek) and flushing with fflush, OR
the unbuffered I/O functions (like read, write, lseek) by using the fd returned by fileno( fileObj ) where fileObj is the FILE* returned by one of the aforementioned functions.
The size is completely automatic, you do not need to allocate an underlying buffer -- any data written to it and flushed will expand the buffer automatically.
There is no built-in locking, so it's suggested if you are going to have multiple processes writing to the stream,
that you either use fixed-size sections for each process, or implement your own locking.
Public Functions
The following functions make up the public API of shmfile.
fshm_create - Create a new shmfile stream (convenience/helper function for fshm_open with fshm_flags as FSHM_OWNER)
FILE* fshm_create(const char *name, mode_t mode)
/**
* fshm_create - Create a new shmfile (as FSHM_OWNER)
* with a given mode.
*
*
* name - A unique name which corrosponds to this stream.
* Guests will use this name as a reference to map
* this shmfile stream.
*
* mode - An octal representing the "mode" for guest mappings.
* Mode has same meaning as with chmod.
* This mode will be used to determine how FSHM_GUEST
* mappings will be able to access this stream.
*
* See the 'fshm_open' function for more information
* on mode.
*
*
* RETURN VALUE -
* A pointer to a FILE structure which may be used
* with standard io functions (e.x. fread, fprintf, fseek)
*
* On error, this function will return NULL and `errno' will be set
*
* NOTES -
* * This is the same as calling fshm_open(name, mode, FSHM_OWNER)
*
* * See fshm_open for more info
*/
fshm_guest_open - Opens an existing shmfile stream (convenience/helper function for fshm_open with fshm_flags as FSHM_GUEST)
FILE *fshm_guest_open(const char *name);
/**
* fshm_guest_open - Maps an existing shmfile stream (as FSHM_GUEST)
* using the given name for reference.
*
*
* name - The name associated with an already-created fshmfile stream
*
*
* RETURN VALUE -
* A pointer to a FILE structure which may be used
* with standard io functions (e.x. fread, fprintf, fseek)
*
* On error, this function will return NULL and `errno' will be set
*
* NOTES -
* * This is the same as calling fshm_open(name, 0, FSHM_GUEST)
*
* * See fshm_open for more info
*/
fshm_open - Opens a shmfile stream
FILE* fshm_open(const char *name, mode_t mode, int fshm_flags);
This is the "core" function, and can be used both to create a new shared memory stream or open an existing stream. The FILE pointer returned allows you to use all the other I/O systems that come standard with libc.
/**
* fshm_open - Open a shared memory stream, either creating a new
* stream [FSHM_OWNER] or mapping an existing stream [FSHM_GUEST],
* and returning a FILE* object with an associated int fd.
* This will work with both FILE* and int filedes functions
* (e.x. fwrite and write, fread and read, etc).
*
* name - A unique name which corrosponds to this stream.
* If flags contain FSHM_OWNER, we attempt to create
* a stream using this name.
* Guests who wish to map this shmfile will provide
* this same name to reference which shmfile stream
* to map.
*
* mode - An octal representing the "mode" for this file stream.
* Mode has same meaning as with chmod.
*
* This mode will be used to determine how FSHM_GUEST
* mappings will be able to access this stream.
*
* It will also define the permissions (read/write/execute) for the
* owner / group-member / other
* relations on mappings.
*
*
* This field only has meaning when creating the shmfile ( FSHM_OWNER ).
* For an FSHM_GUEST open of an existing shmfile stream, this can be
* set to 0. Any other value will be ignored when flags contains FSHM_GUEST.
*
* Columns:
*
* - First column from left is always 0 for now (no sticky/setguid bit meaning)
*
* - Second column from left is permissions for owner (user who creates shmfile)
*
* - Third column from the left is permissions for users who are a member of
* the group associated with this stream.
* This could be primary group of creating user (FSHM_OWNER), or a different
* group (set by fshm_chgrp).
*
* - Fourth column from the left are permissions for any user which
* does NOT fall into any categories listed above
*
* Values:
*
* For each column, the number is derived by starting with 0
* and following these rules:
*
* - Add 4 to allow FSHM_GUEST mapping and read for represented set
* - Add 2 to allow writing to the mapping
* - Add 1 to allow execution
*
*
* Examples - Some examples of various #mode[s] and their meaning
*
* Allow current user only to map as guest, read/write:
* 0600
*
* Allow current user only to map as guest, read-only:
* 0400
*
* Allow current user to map as guest, read and write,
* allow a different user belonging to same primary group
* to map as guest read-only:
* 0640
*
* Allow anybody on system to map read/write:
* 0777
*
*
*
* fshm_flags - A list of flags OR'd together
*
* FSHM_OWNER - Specifies that this call will create the stream
* specified by #name . When the owner closes the stream,
* it will be destroyed.
*
* FSHM_GUEST - Specifies that this call will open an existing stream
* specified by #name . An FSHM_OWNER must have created
* this stream already, or the call will fail.
* Closing the stream as a guest will not destroy the file.
*
* FSHM_PERSIST - Do NOT remove this stream when the FSHM_OWNER closes it.
* fshm_force_destroy must be used to destroy the stream
* when this flag is provided.
*
* Return:
*
* A FILE* object on success, otherwise NULL and errno is set.
*
* NOTES:
*
* The idea here is to simply allow interprocess I/O that exists
* only in memory. One process creates the mapping ( FSHM_OWNER )
* and several other processes can inherit that mapping,
* and share data between them.
*
* There is a real FD associated with this FILE (unlike, open_memstream, for example).
*
* You may choose to use either the buffered variants ( like fwrite, fread),
* or the unbuffered variants (like write, read).
*
* Keep in mind that if you use the buffered functions, you must call fflush to
* sync the changes.
*
*
* You can use this object anywhere a FILE* is allowed, or anywhere an fd is allowed
* by calling fileno(X) where X is the FILE* returned by this function.
*
*/
fshm_chgrp - Change the group associated with an shmfile stream
int fshm_chgrp(FILE *fshm_file, gid_t group)
/**
* fshm_chgrp - Change the group associated with an existing shmfile stream
*
* You must be the the same user as the FSHM_OWNER of the given stream,
* or root in order to change the gid assigned to the shmfile.
*
* The shmfile created by fshm_open is assigned the gid
* matching the primary group of the creating user.
*
* The purpose is to allow guests in a different group access rights to
* this shmfile ( based on the group bits in the mode set with fshm_open ),
* but not just open up access for everybody ( using the "other" bits in mode ).
*
* As non-root, you may change the group to any groups to which you are a member.
* This includes your primary g
