int shm_common_exists(int key) { struct shm_status sm; int retval; if (shmdrv_loaded) { memset(&sm, 0, sizeof(struct shm_status)); sm.driver_fd = shmdrv_driver_fd(); sm.key = key; sm.flags = 0; retval = shmdrv_status(&sm); close(sm.driver_fd); return retval == 0; } else { int shmfd; char segment_name[LINELEN]; sprintf(segment_name, SHM_FMT, INSTANCE_OF(key), key); if ((shmfd = shm_open(segment_name, O_RDWR, (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP))) < 0) { retval = 0; } else { close(shmfd); retval = 1; } return retval; } }
int _rtapi_shmem_exists(int userkey) { struct shm_status sm; sm.key = userkey; return !shmdrv_status(&sm); }
int shm_common_new(int key, int *size, int instance, void **shmptr, int create) { struct shm_status sm; int retval; int is_new = 0; if (shmdrv_loaded) { // use shmdrv kernel driver sm.driver_fd = shmdrv_driver_fd(); sm.key = key; sm.size = (size == NULL? 0: *size); sm.flags = 0; retval = shmdrv_status(&sm); // check if exists if (retval && !create) { // didnt exist, but just attach requested, so fail close(sm.driver_fd); return -ENOENT; } if (retval) { // didnt exist, so create retval = shmdrv_create(&sm); if (retval < 0) { return retval; } is_new = 1; } // now attach retval = shmdrv_attach(&sm, shmptr); if (retval < 0) { close(sm.driver_fd); return retval; } // if size was passed in as 0 (attach), fill in actual size if (size && (*size == 0)) *size = sm.size; close(sm.driver_fd); return is_new; } else { // use POSIX shared memory int shmfd, mmap_size; mode_t old_umask; char segment_name[LINELEN]; if ((size == 0) || (*size == 0)) mmap_size = 0; else mmap_size = *size; sprintf(segment_name, SHM_FMT, instance, key); old_umask = umask(0); //S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (create && ((shmfd = shm_open(segment_name, (O_CREAT | O_EXCL | O_RDWR), (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP))) > 0)) { // initial creation if (fchown(shmfd, getuid(),getgid())) perror("fchown"); if (ftruncate(shmfd, mmap_size)) perror("ftruncate"); is_new = 1; } else if((shmfd = shm_open(segment_name, O_RDWR, (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP))) < 0) { // just attach, and that failed: umask(old_umask); return -errno; } else { // shmfd open if (mmap_size == 0) { struct stat st; if (fstat(shmfd, &st)) { perror("fstat"); return -errno; } mmap_size = st.st_size; } } if((*shmptr = mmap(0, mmap_size, (PROT_READ | PROT_WRITE), MAP_SHARED, shmfd, 0)) == MAP_FAILED) { perror("shm_common_new:mmap"); close(shmfd); umask(old_umask); return -errno; } if (size) // return actual shm size as determined in attach *size = mmap_size; umask(old_umask); close(shmfd); return is_new; } }