1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* 34*7c478bd9Sstevel@tonic-gate * ipcrm - IPC remove 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * Remove specified message queues, 37*7c478bd9Sstevel@tonic-gate * semaphore sets and shared memory ids. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/ipc.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/msg.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/sem.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/shm.h> 45*7c478bd9Sstevel@tonic-gate #include <errno.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h> 47*7c478bd9Sstevel@tonic-gate #include <zone.h> 48*7c478bd9Sstevel@tonic-gate #include <stdio.h> 49*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 50*7c478bd9Sstevel@tonic-gate #include <signal.h> 51*7c478bd9Sstevel@tonic-gate #include <locale.h> 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define NULL_MSG ((struct msqid_ds *)NULL) 54*7c478bd9Sstevel@tonic-gate #define NULL_SEM ((struct semid_ds *)NULL) 55*7c478bd9Sstevel@tonic-gate #define NULL_SHM ((struct shmid_ds *)NULL) 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate #define USAGE "usage: ipcrm [-z zone] [ [-q msqid] [-m shmid] " \ 58*7c478bd9Sstevel@tonic-gate "[-s semid]\n\t [-Q msgkey] [-M shmkey] [-S semkey] ... ]\n" 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #define IPC_KEYMATCH(perm, zoneid, key) \ 61*7c478bd9Sstevel@tonic-gate ((perm).ipcx_key == (key) && (perm).ipcx_zoneid == (zoneid)) 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate static char opts[] = "z:q:m:s:Q:M:S:"; /* allowable options for getopt */ 64*7c478bd9Sstevel@tonic-gate extern char *optarg; /* arg pointer for getopt */ 65*7c478bd9Sstevel@tonic-gate extern int optind; /* option index for getopt */ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate static zoneid_t zoneid; 68*7c478bd9Sstevel@tonic-gate static int zflg; 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate static int *idlist, nids; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate static void 73*7c478bd9Sstevel@tonic-gate oops(char *thing, char *arg) 74*7c478bd9Sstevel@tonic-gate { 75*7c478bd9Sstevel@tonic-gate char *e; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate switch (errno) { 78*7c478bd9Sstevel@tonic-gate case ENOENT: /* key not found */ 79*7c478bd9Sstevel@tonic-gate case EINVAL: /* id not found */ 80*7c478bd9Sstevel@tonic-gate e = "not found"; 81*7c478bd9Sstevel@tonic-gate break; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate case EPERM: 84*7c478bd9Sstevel@tonic-gate e = "permission denied"; 85*7c478bd9Sstevel@tonic-gate break; 86*7c478bd9Sstevel@tonic-gate default: 87*7c478bd9Sstevel@tonic-gate e = "unknown error"; 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: %s(%s): %s\n"), thing, arg, e); 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* convert string to numeric key */ 94*7c478bd9Sstevel@tonic-gate static key_t 95*7c478bd9Sstevel@tonic-gate getkey(char *kp) 96*7c478bd9Sstevel@tonic-gate { 97*7c478bd9Sstevel@tonic-gate key_t k; 98*7c478bd9Sstevel@tonic-gate char *tp; /* will point to char that terminates strtol scan */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate if ((k = (key_t)strtol(kp, &tp, 0)) == IPC_PRIVATE || *tp != '\0') { 101*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: illegal key: %s\n"), 102*7c478bd9Sstevel@tonic-gate kp); 103*7c478bd9Sstevel@tonic-gate return (0); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate return (k); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* 109*7c478bd9Sstevel@tonic-gate * Gets list of all IPC ids (of a particular type) visible in the 110*7c478bd9Sstevel@tonic-gate * caller's zone. Returns number of ids retrieved. On return, idlist 111*7c478bd9Sstevel@tonic-gate * is set to point to an array of ids at least as large as the number 112*7c478bd9Sstevel@tonic-gate * retrieved. 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate static uint_t 115*7c478bd9Sstevel@tonic-gate getids(int (*idsfunc)(int *, uint_t, uint_t *)) 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate uint_t n; 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate for (;;) { 120*7c478bd9Sstevel@tonic-gate if (idsfunc(idlist, nids, &n) != 0) 121*7c478bd9Sstevel@tonic-gate goto err; /* should never happen */ 122*7c478bd9Sstevel@tonic-gate if (n <= nids) 123*7c478bd9Sstevel@tonic-gate break; 124*7c478bd9Sstevel@tonic-gate idlist = realloc(idlist, (nids = n) * sizeof (int)); 125*7c478bd9Sstevel@tonic-gate if (idlist == NULL) 126*7c478bd9Sstevel@tonic-gate goto err; 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate return (n); 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate err: 131*7c478bd9Sstevel@tonic-gate perror("ipcrm"); 132*7c478bd9Sstevel@tonic-gate exit(1); 133*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate static int 137*7c478bd9Sstevel@tonic-gate msggetid(char *arg) 138*7c478bd9Sstevel@tonic-gate { 139*7c478bd9Sstevel@tonic-gate int id = atol(arg); 140*7c478bd9Sstevel@tonic-gate struct msqid_ds64 qds; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (!zflg) 143*7c478bd9Sstevel@tonic-gate return (id); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate if (msgctl64(id, IPC_STAT64, &qds) < 0) { 146*7c478bd9Sstevel@tonic-gate oops("msgctl", arg); 147*7c478bd9Sstevel@tonic-gate return (-1); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate if (qds.msgx_perm.ipcx_zoneid != zoneid) { 150*7c478bd9Sstevel@tonic-gate /* 151*7c478bd9Sstevel@tonic-gate * Not in right zone, pretend the call failed. 152*7c478bd9Sstevel@tonic-gate * Message should be the same as that returned if 153*7c478bd9Sstevel@tonic-gate * msggetid succeeds but the subsequent IPC_RMID fails 154*7c478bd9Sstevel@tonic-gate * with EINVAL. 155*7c478bd9Sstevel@tonic-gate */ 156*7c478bd9Sstevel@tonic-gate errno = EINVAL; 157*7c478bd9Sstevel@tonic-gate oops("msgctl", arg); 158*7c478bd9Sstevel@tonic-gate return (-1); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate return (id); 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate static int 164*7c478bd9Sstevel@tonic-gate msggetkey(char *kp) 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate key_t k; 167*7c478bd9Sstevel@tonic-gate int id, i; 168*7c478bd9Sstevel@tonic-gate uint_t n; 169*7c478bd9Sstevel@tonic-gate struct msqid_ds64 qds; 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate if ((k = getkey(kp)) == 0) 172*7c478bd9Sstevel@tonic-gate return (-1); 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate if (!zflg) { 175*7c478bd9Sstevel@tonic-gate /* lookup in local zone is simple */ 176*7c478bd9Sstevel@tonic-gate if ((id = msgget(k, 0)) == -1) 177*7c478bd9Sstevel@tonic-gate oops("msgget", kp); 178*7c478bd9Sstevel@tonic-gate return (id); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate n = getids(msgids); 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* search for right key and zone combination */ 184*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 185*7c478bd9Sstevel@tonic-gate id = idlist[i]; 186*7c478bd9Sstevel@tonic-gate if (msgctl64(id, IPC_STAT64, &qds) < 0) 187*7c478bd9Sstevel@tonic-gate continue; 188*7c478bd9Sstevel@tonic-gate if (IPC_KEYMATCH(qds.msgx_perm, zoneid, k)) 189*7c478bd9Sstevel@tonic-gate return (id); /* found it, no need to look further */ 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: unknown key: %s\n"), kp); 192*7c478bd9Sstevel@tonic-gate return (-1); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate static int 196*7c478bd9Sstevel@tonic-gate semgetid(char *arg) 197*7c478bd9Sstevel@tonic-gate { 198*7c478bd9Sstevel@tonic-gate int id = atol(arg); 199*7c478bd9Sstevel@tonic-gate struct semid_ds64 sds; 200*7c478bd9Sstevel@tonic-gate union semun { 201*7c478bd9Sstevel@tonic-gate int val; 202*7c478bd9Sstevel@tonic-gate struct semid_ds64 *buf; 203*7c478bd9Sstevel@tonic-gate ushort_t *array; 204*7c478bd9Sstevel@tonic-gate } semarg; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate if (!zflg) 207*7c478bd9Sstevel@tonic-gate return (id); 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate semarg.buf = &sds; 210*7c478bd9Sstevel@tonic-gate if (semctl64(id, 0, IPC_STAT64, semarg) < 0) { 211*7c478bd9Sstevel@tonic-gate oops("semctl", arg); 212*7c478bd9Sstevel@tonic-gate return (-1); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate if (sds.semx_perm.ipcx_zoneid != zoneid) { 215*7c478bd9Sstevel@tonic-gate /* 216*7c478bd9Sstevel@tonic-gate * Not in right zone, pretend the call failed. 217*7c478bd9Sstevel@tonic-gate * Message should be the same as that returned if 218*7c478bd9Sstevel@tonic-gate * semgetid succeeds but the subsequent IPC_RMID fails 219*7c478bd9Sstevel@tonic-gate * with EINVAL. 220*7c478bd9Sstevel@tonic-gate */ 221*7c478bd9Sstevel@tonic-gate errno = EINVAL; 222*7c478bd9Sstevel@tonic-gate oops("semctl", arg); 223*7c478bd9Sstevel@tonic-gate return (-1); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate return (id); 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate static int 229*7c478bd9Sstevel@tonic-gate semgetkey(char *kp) 230*7c478bd9Sstevel@tonic-gate { 231*7c478bd9Sstevel@tonic-gate key_t k; 232*7c478bd9Sstevel@tonic-gate int id, i; 233*7c478bd9Sstevel@tonic-gate uint_t n; 234*7c478bd9Sstevel@tonic-gate struct semid_ds64 sds; 235*7c478bd9Sstevel@tonic-gate union semun { 236*7c478bd9Sstevel@tonic-gate int val; 237*7c478bd9Sstevel@tonic-gate struct semid_ds64 *buf; 238*7c478bd9Sstevel@tonic-gate ushort_t *array; 239*7c478bd9Sstevel@tonic-gate } semarg; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate if ((k = getkey(kp)) == 0) 242*7c478bd9Sstevel@tonic-gate return (-1); 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate if (!zflg) { 245*7c478bd9Sstevel@tonic-gate /* lookup in local zone is simple */ 246*7c478bd9Sstevel@tonic-gate if ((id = semget(k, 0, 0)) == -1) 247*7c478bd9Sstevel@tonic-gate oops("semget", kp); 248*7c478bd9Sstevel@tonic-gate return (id); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate n = getids(semids); 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate semarg.buf = &sds; 254*7c478bd9Sstevel@tonic-gate /* search for right key and zone combination */ 255*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 256*7c478bd9Sstevel@tonic-gate int id; 257*7c478bd9Sstevel@tonic-gate id = idlist[i]; 258*7c478bd9Sstevel@tonic-gate if (semctl64(id, 0, IPC_STAT64, semarg) < 0) 259*7c478bd9Sstevel@tonic-gate continue; 260*7c478bd9Sstevel@tonic-gate if (IPC_KEYMATCH(sds.semx_perm, zoneid, k)) 261*7c478bd9Sstevel@tonic-gate return (id); /* found it, no need to look further */ 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: unknown key: %s\n"), kp); 265*7c478bd9Sstevel@tonic-gate return (-1); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate static int 269*7c478bd9Sstevel@tonic-gate shmgetid(char *arg) 270*7c478bd9Sstevel@tonic-gate { 271*7c478bd9Sstevel@tonic-gate int id = atol(arg); 272*7c478bd9Sstevel@tonic-gate struct shmid_ds64 mds; 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate if (!zflg) 275*7c478bd9Sstevel@tonic-gate return (id); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if (shmctl64(id, IPC_STAT64, &mds) < 0) { 278*7c478bd9Sstevel@tonic-gate oops("shmctl", arg); 279*7c478bd9Sstevel@tonic-gate return (-1); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate if (mds.shmx_perm.ipcx_zoneid != zoneid) { 282*7c478bd9Sstevel@tonic-gate /* 283*7c478bd9Sstevel@tonic-gate * Not in right zone, pretend the call failed. 284*7c478bd9Sstevel@tonic-gate * Message should be the same as that returned if 285*7c478bd9Sstevel@tonic-gate * shmgetid succeeds but the subsequent IPC_RMID fails 286*7c478bd9Sstevel@tonic-gate * with EINVAL. 287*7c478bd9Sstevel@tonic-gate */ 288*7c478bd9Sstevel@tonic-gate errno = EINVAL; 289*7c478bd9Sstevel@tonic-gate oops("shmctl", arg); 290*7c478bd9Sstevel@tonic-gate return (-1); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate return (id); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate static int 296*7c478bd9Sstevel@tonic-gate shmgetkey(char *kp) 297*7c478bd9Sstevel@tonic-gate { 298*7c478bd9Sstevel@tonic-gate key_t k; 299*7c478bd9Sstevel@tonic-gate int id, i; 300*7c478bd9Sstevel@tonic-gate uint_t n; 301*7c478bd9Sstevel@tonic-gate struct shmid_ds64 mds; 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if ((k = getkey(kp)) == 0) 304*7c478bd9Sstevel@tonic-gate return (-1); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if (!zflg) { 307*7c478bd9Sstevel@tonic-gate /* lookup in local zone is simple */ 308*7c478bd9Sstevel@tonic-gate if ((id = shmget(k, 0, 0)) == -1) 309*7c478bd9Sstevel@tonic-gate oops("shmget", kp); 310*7c478bd9Sstevel@tonic-gate return (id); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate n = getids(shmids); 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* search for right key and zone combination */ 316*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 317*7c478bd9Sstevel@tonic-gate int id; 318*7c478bd9Sstevel@tonic-gate id = idlist[i]; 319*7c478bd9Sstevel@tonic-gate if (shmctl64(id, IPC_STAT64, &mds) < 0) 320*7c478bd9Sstevel@tonic-gate continue; 321*7c478bd9Sstevel@tonic-gate if (IPC_KEYMATCH(mds.shmx_perm, zoneid, k)) 322*7c478bd9Sstevel@tonic-gate return (id); /* found it, no need to look further */ 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: unknown key: %s\n"), kp); 325*7c478bd9Sstevel@tonic-gate return (-1); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate /* convert string containing zone name or id to a numeric id */ 330*7c478bd9Sstevel@tonic-gate static zoneid_t 331*7c478bd9Sstevel@tonic-gate getzone(char *arg) 332*7c478bd9Sstevel@tonic-gate { 333*7c478bd9Sstevel@tonic-gate zoneid_t zoneid; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate if (zone_get_id(arg, &zoneid) != 0) { 336*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ipcrm: unknown zone: %s\n"), 337*7c478bd9Sstevel@tonic-gate arg); 338*7c478bd9Sstevel@tonic-gate exit(1); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate return (zoneid); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate int 344*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 345*7c478bd9Sstevel@tonic-gate { 346*7c478bd9Sstevel@tonic-gate int o; /* option flag */ 347*7c478bd9Sstevel@tonic-gate int err; /* error count */ 348*7c478bd9Sstevel@tonic-gate int ipc_id; /* id to remove */ 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 351*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * If one or more of the IPC modules is not 354*7c478bd9Sstevel@tonic-gate * included in the kernel, the corresponding 355*7c478bd9Sstevel@tonic-gate * system calls will incur SIGSYS. Ignoring 356*7c478bd9Sstevel@tonic-gate * that signal makes the system call appear 357*7c478bd9Sstevel@tonic-gate * to fail with errno == EINVAL, which can be 358*7c478bd9Sstevel@tonic-gate * interpreted appropriately in oops(). 359*7c478bd9Sstevel@tonic-gate */ 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate (void) signal(SIGSYS, SIG_IGN); 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate /* 364*7c478bd9Sstevel@tonic-gate * If no -z argument is specified, only objects in the current 365*7c478bd9Sstevel@tonic-gate * zone can be removed with keys. 366*7c478bd9Sstevel@tonic-gate */ 367*7c478bd9Sstevel@tonic-gate zoneid = getzoneid(); 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * Go through the options. The first pass looks only for -z 371*7c478bd9Sstevel@tonic-gate * since this option can affect the processing of keys. The 372*7c478bd9Sstevel@tonic-gate * second pass looks for the other options and ignores -z. 373*7c478bd9Sstevel@tonic-gate */ 374*7c478bd9Sstevel@tonic-gate err = 0; 375*7c478bd9Sstevel@tonic-gate while ((o = getopt(argc, argv, opts)) != EOF) { 376*7c478bd9Sstevel@tonic-gate switch (o) { 377*7c478bd9Sstevel@tonic-gate case 'z': 378*7c478bd9Sstevel@tonic-gate zflg++; 379*7c478bd9Sstevel@tonic-gate zoneid = getzone(optarg); 380*7c478bd9Sstevel@tonic-gate break; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate case 'q': /* skip the rest of the flags */ 383*7c478bd9Sstevel@tonic-gate case 'm': 384*7c478bd9Sstevel@tonic-gate case 's': 385*7c478bd9Sstevel@tonic-gate case 'Q': 386*7c478bd9Sstevel@tonic-gate case 'M': 387*7c478bd9Sstevel@tonic-gate case 'S': 388*7c478bd9Sstevel@tonic-gate break; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate case '?': /* anything else is an error */ 391*7c478bd9Sstevel@tonic-gate default: 392*7c478bd9Sstevel@tonic-gate err++; 393*7c478bd9Sstevel@tonic-gate break; 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate if (err || (optind < argc)) { 398*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE)); 399*7c478bd9Sstevel@tonic-gate return (err); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate if (zflg > 1) { 403*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 404*7c478bd9Sstevel@tonic-gate gettext("multiple -z options not allowed\n")); 405*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE)); 406*7c478bd9Sstevel@tonic-gate return (1); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate optind = 1; /* rewind for pass 2 */ 410*7c478bd9Sstevel@tonic-gate while ((o = getopt(argc, argv, opts)) != EOF) { 411*7c478bd9Sstevel@tonic-gate switch (o) { 412*7c478bd9Sstevel@tonic-gate case 'z': /* zone identifier */ 413*7c478bd9Sstevel@tonic-gate break; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate case 'q': /* message queue */ 416*7c478bd9Sstevel@tonic-gate if ((ipc_id = msggetid(optarg)) < 0) { 417*7c478bd9Sstevel@tonic-gate err++; 418*7c478bd9Sstevel@tonic-gate } else if (msgctl(ipc_id, IPC_RMID, NULL_MSG) == -1) { 419*7c478bd9Sstevel@tonic-gate oops("msgctl", optarg); 420*7c478bd9Sstevel@tonic-gate err++; 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate break; 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate case 'm': /* shared memory */ 425*7c478bd9Sstevel@tonic-gate if ((ipc_id = shmgetid(optarg)) < 0) { 426*7c478bd9Sstevel@tonic-gate err++; 427*7c478bd9Sstevel@tonic-gate } else if (shmctl(ipc_id, IPC_RMID, NULL_SHM) == -1) { 428*7c478bd9Sstevel@tonic-gate oops("shmctl", optarg); 429*7c478bd9Sstevel@tonic-gate err++; 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate break; 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate case 's': /* semaphores */ 434*7c478bd9Sstevel@tonic-gate if ((ipc_id = semgetid(optarg)) < 0) { 435*7c478bd9Sstevel@tonic-gate err++; 436*7c478bd9Sstevel@tonic-gate } else if (semctl(ipc_id, 0, IPC_RMID, NULL_SEM) == 437*7c478bd9Sstevel@tonic-gate -1) { 438*7c478bd9Sstevel@tonic-gate oops("semctl", optarg); 439*7c478bd9Sstevel@tonic-gate err++; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate break; 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate case 'Q': /* message queue (by key) */ 444*7c478bd9Sstevel@tonic-gate if ((ipc_id = msggetkey(optarg)) == -1) { 445*7c478bd9Sstevel@tonic-gate err++; 446*7c478bd9Sstevel@tonic-gate break; 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate if (msgctl(ipc_id, IPC_RMID, NULL_MSG) == -1) { 449*7c478bd9Sstevel@tonic-gate oops("msgctl", optarg); 450*7c478bd9Sstevel@tonic-gate err++; 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate break; 453*7c478bd9Sstevel@tonic-gate 454*7c478bd9Sstevel@tonic-gate case 'M': /* shared memory (by key) */ 455*7c478bd9Sstevel@tonic-gate if ((ipc_id = shmgetkey(optarg)) == -1) { 456*7c478bd9Sstevel@tonic-gate err++; 457*7c478bd9Sstevel@tonic-gate break; 458*7c478bd9Sstevel@tonic-gate } 459*7c478bd9Sstevel@tonic-gate if (shmctl(ipc_id, IPC_RMID, NULL_SHM) == -1) { 460*7c478bd9Sstevel@tonic-gate oops("shmctl", optarg); 461*7c478bd9Sstevel@tonic-gate err++; 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate break; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate case 'S': /* semaphores (by key) */ 466*7c478bd9Sstevel@tonic-gate if ((ipc_id = semgetkey(optarg)) == -1) { 467*7c478bd9Sstevel@tonic-gate err++; 468*7c478bd9Sstevel@tonic-gate break; 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate if (semctl(ipc_id, 0, IPC_RMID, NULL_SEM) == -1) { 471*7c478bd9Sstevel@tonic-gate oops("semctl", optarg); 472*7c478bd9Sstevel@tonic-gate err++; 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate break; 475*7c478bd9Sstevel@tonic-gate } 476*7c478bd9Sstevel@tonic-gate } 477*7c478bd9Sstevel@tonic-gate return (err); 478*7c478bd9Sstevel@tonic-gate } 479