COHERENT manpages

This page displays the COHERENT manpage for shmget() [Create or get shared-memory segment].

List of available manpages
Index


shmget() -- General Function (libc)

Create or get shared-memory segment
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(memkey, size, flag)
key_t memkey; int size, flag;

shmget() creates a shared-memory identifier, associated data structure, and
shared-memory segment, links them to the identifier memkey, and returns the
shared-memory identifier that it has associated with memkey.

memkey is  an identifier  that your  application generates to  identify its
shared-memory segments.   To guarantee that each key  is unique, you should
use the function call ftok() to generate keys.

size gives the  size, in bytes, of the shared-memory  segment that you want
shmget() to create.

flag can be bitwise OR'd to include the following constants:

IPC_ALLOC This process  already has  a shared-memory segment;  please fetch
          it.

IPC_CREAT If this  process does not  already have a  shared-memory segment,
          please create one.

IPC_EXCL  Fail if a shared-memory segment already exists for this process.

IPC_NOWAIT
          Fail if the process must wait to obtain a shared-memory segment.

When it  creates a shared-memory  segment, shmget() also creates  a copy of
structure shmid_ds, which  is defined in header file <sys/shm.h>, and
which describes the shared-memory segment.  It is defined as follows:

struct shmid_ds {
     struct ipc_perm               shm_perm;/* operation permission struct */
     int shm_segsz;                /* segment size */
     char *__unused;               /* for binary compatibility */
     char __pad [4];               /* for binary compatibility */
     pid_t shm_lpid;               /* pid of last shmop */
     pid_t shm_cpid;               /* pid of creator */
     unsigned short shm_nattch;    /* current # attached */
     unsigned short shm_cnattach;  /* for binary compatibility */
     time_t shm_atime;             /* last shmat time */
     time_t shm_dtime;             /* last shmdt time */
     time_t shm_ctime;             /* last change time */
};

Field  shm_perm  is  a  structure  of  type  ipc_perm,  which  header  file
<sys/ipc.h> defines as follows:

struct ipc_perm {
     unsigned short uid;           /* owner's user id */
     unsigned short gid;           /* owner's group id */
     unsigned short cuid;          /* creator's user id */
     unsigned short cgid;          /* creator's group id */
     unsigned short mode;          /* access modes */
     unsigned short seq;           /* slot usage sequence number */
     key_t key;                    /* key */
};

shmget() initializes shm_id as follows:

-> It   sets  fields   shm_perm.guid,   shm_perm.uid,  shm_perm.cgid,   and
   shm_perm.gid to, respectively, the effective user ID and effective group
   ID of the calling process.

-> It sets the low-order nine  bits of field shm_perm.mode to the low-order
   nine bits  of flag. These  nine bits define access  permissions: the top
   three bits  give the owner's access  permissions (read, write, execute),
   the middle three bits the owning group's access permissions, and the low
   three bits access permissions for others.

-> It sets field shm_segsz equal to size.

-> It sets  fields shm_atime, shm_dtime, shm_lpid,  and shm_nattch to zero,
   and field shm_ctime to the current time.

shmget() fails if any of the following is true:

-> size  is smaller  than one  byte,  or larger  than 0x10000  (the system-
   imposed maximum).  shmget() sets errno to EINVAL.

-> A  shared-memory  identifier   exists  for  memkey  but  permission,  as
   specified by flag's low-order nine bits, is not granted (EACCES).

-> A  shared-memory  identifier exists  for  memkey, but  the  size of  its
   associated  segment is  less than  size,  and size  does not  equal zero
   (EINVAL).

-> A shared-memory  identifier does  not exist  for memkey and  (flag &
   IPC_CREAT) is false (ENOENT).

-> shmget() tried to create  a shared-memory segment, but could not because
   100 (the COHERENT-defined maximum) already exist (ENOSPC).

-> shmget()  tried to  create  a shared-memory  identifier,  but could  not
   because not enough physical memory is available (ENOMEM).

-> A shared-memory identifier  already exists for memkey, but flag requests
   that shmget() create an exclusive segment it -- i.e.

       ( (flag & IPC_CREAT) && (flag & IPC_EXCL) )

   is true (EEXIST).

If all  goes well,  shmget() returns  a shared-memory identifier,  which is
always a non-negative integer.  Otherwise,  it returns -1 and sets errno to
an appropriate value.

Example

The  following demonstrates  how to  use COHERENT's  shared-memory feature.
Please note that this example will not work with versions of COHERENT prior
to release 4.2.

The example  consists of two programs: writeshm,  which captures input from
the keyboard and writes it into a shared-memory segment; and readshm, which
reads and  displays from the  shared-memory segment the  text that writeshm
put there.  Each program terminates when you type ``end''.

Note that this  example is most effective if you  run each program from its
own virtual console.

The first program gives the source for writeshm:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

main()
{
    int iShmId; /* Segment id */
    char *cpShm; /* Pointer to the segment */
    key_t key; /* Segment key */

    key = ftok("/etc/passwd", 'S'); /* Get a key */

    /* if a shared-memory segment exists, get it; otherwise, create one */
    if ((iShmId = shmget(key, 256, 0644 | IPC_CREAT)) < 0) {
        perror("get");
        exit(1);
    }

    /* Attach segment to process. Use an attach address of zero to
     * let the system find a correct virtual address to attach.
     */
    if ((cpShm = shmat(iShmId, 0, 0644)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }
    printf("Server is ready.\n");
    printf("Any message to continue, 'end' to exit\n");

    for (;;) {
        printf("Enter the message -> ");
        gets(cpShm);
        if (!strcmp(cpShm, "end")) {
            puts("Bye");
            shmdt(cpShm);   /* Detach segment */
            break;
        }
    }
}

The next program gives the source for readshm:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

main()
{
    int iShmId; /* Segment id */
    char *cpShm; /* Pointer to the segment */
    key_t key; /* Segment key */
    char cBuf[16]; /* Read buffer */

    /* Get a key */
    key = ftok("/etc/passwd", 'S');

    /* Get shared memory id. If it does not exist, do *not* create it. */
    if ((iShmId = shmget(key, 256, 0644)) < 0) {
        perror("get");
        exit(1);
    }

    /* attach shared-memory segment to the process */
    if ((cpShm = shmat(iShmId, 0, 0644)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }
    printf("Client is ready\n");

    for (;;) {
        printf("Press enter to read the message -> ");
        gets(cBuf);
        printf("Got: \"%s\"\n", cpShm);

        /* Exit on the 'end': detach and remove segment */
        if (!strcmp(cpShm, "end")) {
            struct shmid_ds stShmId;

            puts("Bye");
            shmdt(cpShm);
            if (shmctl(iShmId, IPC_RMID, &stShmId)) {
                perror("shmctl");
                exit(1);
            }
            break;
        }
    }
}

Files

/usr/include/sys/ipc.h
/usr/include/sys/shm.h

<i>See Alsoi>

<a href="manpage.php?page=ftok"><b>ftok(),b>a>
<a href="manpage.php?page=ipcrm"><b>ipcrm,b>a>
<a href="manpage.php?page=ipcs"><b>ipcs,b>a>
<a href="manpage.php?page=libc"><b>libc,b>a>
<a href="manpage.php?page=libsocket"><b>libsocket,b>a>
<a href="manpage.php?page=shmat"><b>shmat(),b>a>
<a href="manpage.php?page=shmctl"><b>shmctl(),b>a>
<a href="manpage.php?page=shmdt"><b>shmdt()b>a>

<i>Notesi>

Prior to release 4.2, COHERENT implemented shared memory through the driver
shm. In  release 4.2, and  subsequent releases, COHERENT  implements shared
memory as a set of functions that conform in large part to the UNIX System-
V standard.

The kernel variables SHMMAX  and SHMMNI set, respectively, the maximum size
of a  shared-memory segment and  the number of  shared-memory segments that
can exist  at any  given time.  Daredevil  system operators who  have large
amounts of memory  at their disposal may wish to  change these variables to
increase the system-defined  limits.  For details on how to  do so, see the
Lexicon entry mtune.