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.