190792Sgshapiro/* 2261370Sgshapiro * Copyright (c) 2000-2001, 2003, 2005 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro */ 990792Sgshapiro 1090792Sgshapiro#include <sm/gen.h> 11266711SgshapiroSM_RCSID("@(#)$Id: shm.c,v 1.20 2013-11-22 20:51:43 ca Exp $") 1290792Sgshapiro 1390792Sgshapiro#if SM_CONF_SHM 1490792Sgshapiro# include <stdlib.h> 1590792Sgshapiro# include <unistd.h> 1690792Sgshapiro# include <errno.h> 17157001Sgshapiro# include <sm/string.h> 1890792Sgshapiro# include <sm/shm.h> 1990792Sgshapiro 20120256Sgshapiro 2190792Sgshapiro/* 2290792Sgshapiro** SM_SHMSTART -- initialize shared memory segment. 2390792Sgshapiro** 2490792Sgshapiro** Parameters: 2590792Sgshapiro** key -- key for shared memory. 2690792Sgshapiro** size -- size of segment. 2790792Sgshapiro** shmflag -- initial flags. 2890792Sgshapiro** shmid -- pointer to return id. 2990792Sgshapiro** owner -- create segment. 3090792Sgshapiro** 3190792Sgshapiro** Returns: 3290792Sgshapiro** pointer to shared memory segment, 3390792Sgshapiro** NULL on failure. 3490792Sgshapiro** 3590792Sgshapiro** Side Effects: 3690792Sgshapiro** attaches shared memory segment. 3790792Sgshapiro*/ 3890792Sgshapiro 3990792Sgshapirovoid * 4090792Sgshapirosm_shmstart(key, size, shmflg, shmid, owner) 4190792Sgshapiro key_t key; 4290792Sgshapiro int size; 4390792Sgshapiro int shmflg; 4490792Sgshapiro int *shmid; 4590792Sgshapiro bool owner; 4690792Sgshapiro{ 4790792Sgshapiro int save_errno; 4890792Sgshapiro void *shm = SM_SHM_NULL; 4990792Sgshapiro 5090792Sgshapiro /* default: user/group accessible */ 5190792Sgshapiro if (shmflg == 0) 5290792Sgshapiro shmflg = SHM_R|SHM_W|(SHM_R>>3)|(SHM_W>>3); 5390792Sgshapiro if (owner) 5490792Sgshapiro shmflg |= IPC_CREAT|IPC_EXCL; 5590792Sgshapiro *shmid = shmget(key, size, shmflg); 5690792Sgshapiro if (*shmid < 0) 5790792Sgshapiro goto error; 5890792Sgshapiro 5990792Sgshapiro shm = shmat(*shmid, (void *) 0, 0); 6090792Sgshapiro if (shm == SM_SHM_NULL) 6190792Sgshapiro goto error; 6290792Sgshapiro 6390792Sgshapiro return shm; 6490792Sgshapiro 6590792Sgshapiro error: 6690792Sgshapiro save_errno = errno; 6790792Sgshapiro if (shm != SM_SHM_NULL || *shmid >= 0) 6890792Sgshapiro sm_shmstop(shm, *shmid, owner); 6990792Sgshapiro *shmid = SM_SHM_NO_ID; 7090792Sgshapiro errno = save_errno; 7190792Sgshapiro return (void *) 0; 7290792Sgshapiro} 7390792Sgshapiro 74120256Sgshapiro 7590792Sgshapiro/* 7690792Sgshapiro** SM_SHMSTOP -- stop using shared memory segment. 7790792Sgshapiro** 7890792Sgshapiro** Parameters: 7990792Sgshapiro** shm -- pointer to shared memory. 8090792Sgshapiro** shmid -- id. 8190792Sgshapiro** owner -- delete segment. 8290792Sgshapiro** 8390792Sgshapiro** Returns: 8490792Sgshapiro** 0 on success. 8590792Sgshapiro** < 0 on failure. 8690792Sgshapiro** 8790792Sgshapiro** Side Effects: 8890792Sgshapiro** detaches (and maybe removes) shared memory segment. 8990792Sgshapiro*/ 9090792Sgshapiro 91120256Sgshapiro 9290792Sgshapiroint 9390792Sgshapirosm_shmstop(shm, shmid, owner) 9490792Sgshapiro void *shm; 9590792Sgshapiro int shmid; 9690792Sgshapiro bool owner; 9790792Sgshapiro{ 9890792Sgshapiro int r; 9990792Sgshapiro 10090792Sgshapiro if (shm != SM_SHM_NULL && (r = shmdt(shm)) < 0) 10190792Sgshapiro return r; 10290792Sgshapiro if (owner && shmid >= 0 && (r = shmctl(shmid, IPC_RMID, NULL)) < 0) 10390792Sgshapiro return r; 10490792Sgshapiro return 0; 10590792Sgshapiro} 106120256Sgshapiro 107120256Sgshapiro 108147078Sgshapiro/* 109147078Sgshapiro** SM_SHMSETOWNER -- set owner/group/mode of shared memory segment. 110147078Sgshapiro** 111147078Sgshapiro** Parameters: 112147078Sgshapiro** shmid -- id. 113147078Sgshapiro** uid -- uid to use 114147078Sgshapiro** gid -- gid to use 115147078Sgshapiro** mode -- mode to use 116147078Sgshapiro** 117147078Sgshapiro** Returns: 118147078Sgshapiro** 0 on success. 119147078Sgshapiro** < 0 on failure. 120147078Sgshapiro*/ 121147078Sgshapiro 122147078Sgshapiroint 123147078Sgshapirosm_shmsetowner(shmid, uid, gid, mode) 124147078Sgshapiro int shmid; 125147078Sgshapiro uid_t uid; 126147078Sgshapiro gid_t gid; 127147078Sgshapiro mode_t mode; 128147078Sgshapiro{ 129147078Sgshapiro int r; 130147078Sgshapiro struct shmid_ds shmid_ds; 131147078Sgshapiro 132147078Sgshapiro memset(&shmid_ds, 0, sizeof(shmid_ds)); 133147078Sgshapiro if ((r = shmctl(shmid, IPC_STAT, &shmid_ds)) < 0) 134147078Sgshapiro return r; 135147078Sgshapiro shmid_ds.shm_perm.uid = uid; 136147078Sgshapiro shmid_ds.shm_perm.gid = gid; 137147078Sgshapiro shmid_ds.shm_perm.mode = mode; 138147078Sgshapiro if ((r = shmctl(shmid, IPC_SET, &shmid_ds)) < 0) 139147078Sgshapiro return r; 140147078Sgshapiro return 0; 141147078Sgshapiro} 14290792Sgshapiro#endif /* SM_CONF_SHM */ 143