SkillAgentSearch skills...

Shmfile

Small shared library to use shared memory as a FILE* stream , with interprocess communication in mind

Install / Use

/learn @kata198/Shmfile
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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
View on GitHub
GitHub Stars8
CategoryDevelopment
Updated7mo ago
Forks2

Languages

C

Security Score

82/100

Audited on Aug 20, 2025

No findings