sl@0: /** @file ../include/sys/shm.h sl@0: @internalComponent sl@0: */ sl@0: sl@0: /** @fn shmget(key_t key, int size, int shmflg) sl@0: @param key sl@0: @param size sl@0: @param shmflg sl@0: @return Upon successful completion, shmget returns the positive integer identifier of a shared memory segment. sl@0: Otherwise, -1 is returned and errno set to indicate the error. sl@0: sl@0: @code sl@0: SHM_R Read access for user. sl@0: SHM_W Write access for user. sl@0: ( SHM_R>>3 ) sl@0: Read access for group. sl@0: ( SHM_W>>3 ) sl@0: Write access for group. sl@0: ( SHM_R>>6 ) sl@0: Read access for other. sl@0: ( SHM_W>>6 ) sl@0: Write access for other. sl@0: sl@0: @endcode sl@0: Based on the values of key and shmflg, shmget returns the identifier of a newly created or previously existing shared sl@0: memory segment. The key sl@0: is analogous to a filename: it provides a handle that names an sl@0: IPC object. sl@0: There are three ways to specify a key: IPC_PRIVATE may be specified, in which case a new IPC object sl@0: will be created. An integer constant may be specified. sl@0: If no IPC object corresponding sl@0: to key is specified and the IPC_CREAT bit is set in shmflg, a new one will be created. The ftok may be used to generate a key from a pathname. sl@0: sl@0: @code sl@0: sl@0: The mode of a newly created IPC object is determined by OR 'ing the following constants into the shmflg argument: SHM_R Read access for user. SHM_W Write access for user. ( SHM_R>>3 ) Read access for group. ( SHM_W>>3 ) Write access for group. ( SHM_R>>6 ) Read access for other. ( SHM_W>>6 ) Write access for other. sl@0: sl@0: @endcode sl@0: sl@0: When creating a new shared memory segment, size indicates the desired size of the new segment in bytes. sl@0: The size sl@0: of the segment may be rounded up to a multiple convenient to the sl@0: kernel (i.e., the page size). sl@0: sl@0: Examples: sl@0: @code sl@0: #include <sys/ipc.h> sl@0: #include <sys/shm.h> sl@0: #include <stdio.h> sl@0: #include <string.h> sl@0: #include <errno.h> sl@0: sl@0: #define SHM_SEG_SIZE 1024 sl@0: sl@0: int main(void) sl@0: { sl@0: int shm_id; sl@0: int perm; sl@0: /* sl@0: * Create a shared memory segment sl@0: */ sl@0: perm = SHM_R | SHM_W; sl@0: if ((shm_id = shmget(IPC_PRIVATE, SHM_SEG_SIZE, sl@0: IPC_CREAT | IPC_EXCL | perm)) sl@0: == -1) { sl@0: printf("Shared memory create failed with errno %d", errno); sl@0: return -1; sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: @endcode sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn shmat(int shmid, const void *shmaddr, int shmflg) sl@0: @param shmid sl@0: @param shmaddr sl@0: @param shmflg sl@0: Note: This description also covers the following functions - sl@0: shmdt() sl@0: sl@0: @return Upon success, shmat returns the address where the segment is attached; otherwise, -1 sl@0: is returned and errno is set to indicate the error. The shmdt function returns the value 0 if successful; otherwise the sl@0: value -1 is returned and errno is set to indicate the error. sl@0: sl@0: The shmat system call sl@0: attaches the shared memory segment identified by shmid to the calling process's address space. sl@0: The address where the segment sl@0: is attached is determined as follows: If shmaddr is 0, the segment is attached at an address selected by the sl@0: kernel. If shmaddr is nonzero and SHM_RND is not specified in shmflg, the segment is attached the specified address. (a nonzero addr is not supported) If addr is specified and SHM_RND is specified, addr is rounded down to the nearest multiple of SHMLBA.(a nonzero addr is not supported) sl@0: sl@0: The shmdt system call sl@0: detaches the shared memory segment at the address specified by shmaddr from the calling process's address space. sl@0: sl@0: Examples: sl@0: @code sl@0: #include <sys/ipc.h> sl@0: #include <sys/shm.h> sl@0: #include <stdio.h> sl@0: #include <string.h> sl@0: #include <errno.h> sl@0: sl@0: #define SHM_SEG_SIZE 1024 sl@0: sl@0: int main(void) sl@0: { sl@0: int shm_id; sl@0: char *shm_addr; sl@0: /* sl@0: * Create a shared memory segment sl@0: */ sl@0: if ((shm_id = shmget(IPC_PRIVATE, SHM_SEG_SIZE, sl@0: IPC_CREAT | IPC_EXCL | 0666)) sl@0: == -1) { sl@0: printf("Shared memory create failed with errno %d", errno); sl@0: return -1; sl@0: } sl@0: /* sl@0: * Attach the shared memory segment to the sl@0: * process address space sl@0: */ sl@0: if((shm_addr = (char *)shmat(shm_id, NULL, 0)) == (void *)-1) { sl@0: printf("Shared memory attach failed with errno %d", errno); sl@0: return -1; sl@0: } sl@0: /* sl@0: * Copy data to shared memory segment sl@0: */ sl@0: strcpy(shm_addr, "some_random_data"); sl@0: /* sl@0: * Detach the shared memory segment sl@0: */ sl@0: if(shmdt(shm_addr) == -1) { sl@0: printf("Shared memory detach failed with errno %d", errno); sl@0: } sl@0: /* sl@0: * Remove the shared memory segment sl@0: */ sl@0: if(shmctl(shm_id, IPC_RMID, NULL) == -1) { sl@0: printf("Shared memory destroy failed with errno %d", errno); sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: @endcode sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @fn shmdt(const void *shmaddr) sl@0: @param shmaddr sl@0: Refer to shmat() for the documentation sl@0: sl@0: sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: sl@0: /** @fn shmctl(int shmid, int cmd, struct shmid_ds *buf) sl@0: @param shmid sl@0: @param cmd sl@0: @param buf sl@0: @return The shmctl function returns the value 0 if successful; otherwise the sl@0: value -1 is returned and errno is set to indicate the error. sl@0: sl@0: @code sl@0: IPC_STAT Fetch the segment's struct shmid_ds , sl@0: storing it in the memory pointed to by buf. sl@0: IPC_SET Changes the shm_perm.uid, shm_perm.gid, and shm_perm.mode members of the segment's struct shmid_ds to match those of the struct pointed to by buf. sl@0: IPC_RMID Removes the segment from the system. sl@0: The removal will not take sl@0: effect until all processes having attached the segment have exited; sl@0: however, once the IPC_RMID operation has taken place, no further sl@0: processes will be allowed to attach the segment. sl@0: sl@0: @endcode sl@0: sl@0: Performs the action specified by cmd on the shared memory segment identified by shmid: sl@0: sl@0: IPC_STAT Fetch the segment's struct shmid_ds , sl@0: storing it in the memory pointed to by buf. sl@0: IPC_SET Changes the shm_perm.uid, shm_perm.gid, and shm_perm.mode members of the segment's struct shmid_ds to match those of the struct pointed to by buf. sl@0: IPC_RMID Removes the segment from the system. sl@0: sl@0: The removal will not take sl@0: effect until all processes having attached the segment have exited; sl@0: however, once the IPC_RMID operation has taken place, no further sl@0: processes will be allowed to attach the segment. sl@0: sl@0: The shmid_ds sl@0: structure is defined as follows: sl@0: @code sl@0: struct shmid_ds { sl@0: struct ipc_perm shm_perm; /* operation permission structure */ sl@0: int shm_segsz; /* size of segment in bytes */ sl@0: pid_t shm_lpid; /* process ID of last shared memory op */ sl@0: pid_t shm_cpid; /* process ID of creator */ sl@0: short shm_nattch; /* number of current attaches */ sl@0: time_t shm_atime; /* time of last shmat() */ sl@0: time_t shm_dtime; /* time of last shmdt() */ sl@0: time_t shm_ctime; /* time of last change by shmctl() */ sl@0: void *shm_internal; /* sysv stupidity */ sl@0: }; sl@0: @endcode sl@0: sl@0: Examples: sl@0: @code sl@0: #include <sys/ipc.h> sl@0: #include <sys/shm.h> sl@0: #include <stdio.h> sl@0: #include <string.h> sl@0: #include <errno.h> sl@0: sl@0: #define SHM_SEG_SIZE 1024 sl@0: sl@0: int main(void) sl@0: { sl@0: int shm_id; sl@0: char *shm_addr; sl@0: /* sl@0: * Create a shared memory segment sl@0: */ sl@0: if ((shm_id = shmget(IPC_PRIVATE, SHM_SEG_SIZE, sl@0: IPC_CREAT | IPC_EXCL | 0666)) sl@0: == -1) { sl@0: printf("Shared memory create failed with errno %d", errno); sl@0: return -1; sl@0: } sl@0: /* sl@0: * Attach the shared memory segment to the sl@0: * process address space sl@0: */ sl@0: if((shm_addr = (char *)shmat(shm_id, NULL, 0)) == (void *)-1) { sl@0: printf("Shared memory attach failed with errno %d", errno); sl@0: return -1; sl@0: } sl@0: /* sl@0: * Copy data to shared memory segment sl@0: */ sl@0: strcpy(shm_addr, "some_random_data"); sl@0: /* sl@0: * Detach the shared memory segment sl@0: */ sl@0: if(shmdt(shm_addr) == -1) { sl@0: printf("Shared memory detach failed with errno %d", errno); sl@0: } sl@0: /* sl@0: * Remove the shared memory segment sl@0: */ sl@0: if(shmctl(shm_id, IPC_RMID, NULL) == -1) { sl@0: printf("Shared memory destroy failed with errno %d", errno); sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: @endcode sl@0: sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: sl@0: /** @struct shmid_ds sl@0: sl@0: Defines a shared memory region sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_perm sl@0: inode's device sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_segsz sl@0: size of segment in bytes sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_lpid sl@0: process ID of last shared memory op sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_cpid sl@0: process ID of creator sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_nattch sl@0: number of current attaches sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_atime sl@0: time of last shmat() sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_dtime sl@0: time of last shmdt() sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_ctime sl@0: time of last change by shmctl() sl@0: */ sl@0: sl@0: /** @var shmid_ds::shm_internal sl@0: sysv stupidity sl@0: */ sl@0: sl@0: /** @def SHM_RDONLY sl@0: sl@0: Attach read-only (else read-write) sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def SHM_RND sl@0: sl@0: Round attach address to SHMLBA sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: /** @def SHMLBA sl@0: sl@0: Segment low boundary address multiple sl@0: sl@0: @publishedAll sl@0: @externallyDefinedApi sl@0: */ sl@0: sl@0: