size_t mm_core_maxsegsize(void) { return mm_core_align2page((MM_SHM_MAXSEGSIZE-SIZEOF_mem_core)-mm_core_pagesize()); }
void *mm_core_create(size_t usersize, const char *file) { mem_core *mc; void *area = ((void *)-1); #if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE) || defined(MM_SHMT_IPCSHM) int fdmem = -1; #endif int fdsem = -1; #if defined(MM_SEMT_IPCSEM) int fdsem_rd = -1; #endif #if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE) char *fnmem; #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) char *fnsem; #endif size_t size; #if defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE) int zero = 0; #endif #if defined(MM_SHMT_IPCSHM) struct shmid_ds shmbuf; #endif #if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE) char shmfilename[MM_MAXPATH]; #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) char semfilename[MM_MAXPATH]; #endif #if defined(MM_SHMT_BEOS) area_id temparea; #endif char filename[MM_MAXPATH]; if (usersize <= 0 || usersize > mm_core_maxsegsize()) { errno = EINVAL; return NULL; } if (file == NULL) { sprintf(filename, MM_CORE_DEFAULT_FILE, (int)getpid()); file = filename; } mm_core_init(); size = mm_core_align2page(usersize+SIZEOF_mem_core); #if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE) sprintf(shmfilename, "%s.mem", file); fnmem = shmfilename; #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) sprintf(semfilename, "%s.sem", file); fnsem = semfilename; #endif #if defined(MM_SHMT_MMANON) if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0)) == (void *)MAP_FAILED) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map anonymous area"); #endif /* MM_SHMT_MMANON */ #if defined(MM_SHMT_BEOS) if ((temparea = create_area("mm", (void*)&area, B_ANY_ADDRESS, size, B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA)) < 0) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to create the memory area"); #endif /* MM_SHMT_BEOS */ #if defined(MM_SHMT_MMPOSX) shm_unlink(fnmem); /* Ok when it fails */ if ((fdmem = shm_open(fnmem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open tempfile"); if (ftruncate(fdmem, mm_core_mapoffset+size) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to truncate tempfile"); write(fdmem, &zero, sizeof(zero)); if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map tempfile"); shm_unlink(fnmem); close(fdmem); fdmem = -1; mm_core_mapoffset += size; #endif /* MM_SHMT_MMPOSX */ #if defined(MM_SHMT_MMZERO) if ((fdmem = open("/dev/zero", O_RDWR, MM_CORE_FILEMODE)) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open /dev/zero"); if (lseek(fdmem, mm_core_mapoffset+size, SEEK_SET) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to seek in /dev/zero"); write(fdmem, &zero, sizeof(zero)); if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map /dev/zero"); close(fdmem); fdmem = -1; mm_core_mapoffset += size; #endif /* MM_SHMT_MMZERO */ #if defined(MM_SHMT_MMFILE) unlink(fnmem); if ((fdmem = open(fnmem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open memory file"); if (ftruncate(fdmem, mm_core_mapoffset+size) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to truncate memory file"); write(fdmem, &zero, sizeof(zero)); if ((area = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fdmem, mm_core_mapoffset)) == (void *)MAP_FAILED) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to memory map memory file"); close(fdmem); fdmem = -1; mm_core_mapoffset += size; #endif /* MM_SHMT_MMFILE */ #if defined(MM_SHMT_IPCSHM) if ((fdmem = shmget(IPC_PRIVATE, size, (SHM_R|SHM_W|IPC_CREAT))) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire shared memory segment"); if ((area = (void *)shmat(fdmem, NULL, 0)) == ((void *)-1)) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to attach shared memory"); if (shmctl(fdmem, IPC_STAT, &shmbuf) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to get status of shared memory"); shmbuf.shm_perm.uid = getuid(); shmbuf.shm_perm.gid = getgid(); if (shmctl(fdmem, IPC_SET, &shmbuf) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set status of shared memory"); if (shmctl(fdmem, IPC_RMID, NULL) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to remove shared memory in advance"); #endif /* MM_SHMT_IPCSHM */ #if defined(MM_SEMT_FLOCK) unlink(fnsem); if ((fdsem = open(fnsem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open semaphore file"); #if defined(F_SETFD) && defined(FD_CLOEXEC) if (fcntl(fdsem, F_SETFD, FD_CLOEXEC) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set close-on-exec flag"); #endif #endif /* MM_SEMT_FLOCK */ #if defined(MM_SEMT_FCNTL) unlink(fnsem); if ((fdsem = open(fnsem, O_RDWR|O_CREAT|O_EXCL, MM_CORE_FILEMODE)) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to open semaphore file"); #if defined(F_SETFD) && defined(FD_CLOEXEC) if (fcntl(fdsem, F_SETFD, FD_CLOEXEC) == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to set close-on-exec flag"); #endif #endif /* MM_SEMT_FCNTL */ #if defined(MM_SEMT_IPCSEM) fdsem = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR); if (fdsem == -1 && errno == EEXIST) fdsem = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR); if (fdsem == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire semaphore"); mm_core_semctlarg.val = 0; semctl(fdsem, 0, SETVAL, mm_core_semctlarg); fdsem_rd = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR); if (fdsem_rd == -1 && errno == EEXIST) fdsem_rd = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR); if (fdsem_rd == -1) FAIL(MM_ERR_CORE|MM_ERR_SYSTEM, "failed to acquire semaphore"); mm_core_semctlarg.val = 0; semctl(fdsem_rd, 0, SETVAL, mm_core_semctlarg); #endif /* MM_SEMT_IPCSEM */ /* * Configure the memory core parameters */ mc = (mem_core *)area; mc->mc_size = size; mc->mc_usize = usersize; mc->mc_pid = getpid(); #if defined(MM_SHMT_IPCSHM) mc->mc_fdmem = fdmem; #endif #if defined(MM_SEMT_FLOCK) mc->mc_fdsem[0].pid = getpid(); mc->mc_fdsem[0].fd = fdsem; mc->mc_fdsem[1].pid = 0; mc->mc_fdsem[1].fd = -1; #else mc->mc_fdsem = fdsem; #endif #if defined(MM_SEMT_BEOS) mc->mc_semid = create_sem(0, "mm_semid"); mc->mc_ben = 0; #endif #if defined(MM_SHMT_BEOS) mc->mc_areaid = temparea; #endif #if defined(MM_SEMT_IPCSEM) mc->mc_fdsem_rd = fdsem_rd; mc->mc_readers = 0; #endif #if defined(MM_SHMT_MMFILE) memcpy(mc->mc_fnmem, fnmem, MM_MAXPATH); #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) memcpy(mc->mc_fnsem, fnsem, MM_MAXPATH); #endif /* * Return successfully established core */ return ((void *)&(mc->mc_base.mw_cp)); /* * clean-up sequence (CUS) for error situation */ BEGIN_FAILURE #if defined(MM_SHMT_MMANON) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMFILE) if (area != ((void *)-1)) munmap((caddr_t)area, size); #endif #if defined(MM_SHMT_IPCSHM) if (area != ((void *)-1)) shmdt(area); #endif #if defined(MM_SHMT_MMPOSX) || defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE) if (fdmem != -1) close(fdmem); #endif #if defined(MM_SEMT_BEOS) delete_sem(mc->mc_semid); #endif #if defined(MM_SHMT_BEOS) delete_area(mc->mc_areaid); #endif #if defined(MM_SHMT_IPCSHM) if (fdmem != -1) shmctl(fdmem, IPC_RMID, NULL); #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) if (fdsem != -1) close(fdsem); #endif #if defined(MM_SEMT_IPCSEM) if (fdsem != -1) semctl(fdsem, 0, IPC_RMID, 0); if (fdsem_rd != -1) semctl(fdsem_rd, 0, IPC_RMID, 0); #endif #if defined(MM_SHMT_MMFILE) unlink(fnmem); #endif #if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL) unlink(fnsem); #endif return NULL; END_FAILURE }
API_EXPORT(void) ap_mm_display_info(AP_MM *mm) STUB_STMT(mm_display_info(mm)) API_EXPORT(void *) ap_mm_core_create(size_t size, char *file) STUB(mm_core_create(size, file), NULL) API_EXPORT(int) ap_mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group) STUB(mm_core_permission(core, mode, owner, group), -1) API_EXPORT(void) ap_mm_core_delete(void *core) STUB_STMT(mm_core_delete(core)) API_EXPORT(size_t) ap_mm_core_size(void *core) STUB(mm_core_size(core), 0) API_EXPORT(int) ap_mm_core_lock(void *core, ap_mm_lock_mode mode) STUB(mm_core_lock(core, mode), FALSE) API_EXPORT(int) ap_mm_core_unlock(void *core) STUB(mm_core_unlock(core), FALSE) API_EXPORT(size_t) ap_mm_core_maxsegsize(void) STUB(mm_core_maxsegsize(), 0) API_EXPORT(size_t) ap_mm_core_align2page(size_t size) STUB(mm_core_align2page(size), 0) API_EXPORT(size_t) ap_mm_core_align2word(size_t size) STUB(mm_core_align2word(size), 0) API_EXPORT(void) ap_mm_lib_error_set(unsigned int type, const char *str) STUB_STMT(mm_lib_error_set(type, str)) API_EXPORT(char *) ap_mm_lib_error_get(void) STUB(mm_lib_error_get(), NULL) API_EXPORT(int) ap_mm_lib_version(void) STUB(mm_lib_version(), 0) #endif /* EAPI */