12736Sdfr/* 22736Sdfr * Copyright (c) 1994 Adam Glass 32736Sdfr * All rights reserved. 42736Sdfr * 52736Sdfr * Redistribution and use in source and binary forms, with or without 62736Sdfr * modification, are permitted provided that the following conditions 72736Sdfr * are met: 82736Sdfr * 1. Redistributions of source code must retain the above copyright 92736Sdfr * notice, this list of conditions and the following disclaimer. 102736Sdfr * 2. Redistributions in binary form must reproduce the above copyright 112736Sdfr * notice, this list of conditions and the following disclaimer in the 122736Sdfr * documentation and/or other materials provided with the distribution. 132736Sdfr * 3. All advertising materials mentioning features or use of this software 142736Sdfr * must display the following acknowledgement: 152736Sdfr * This product includes software developed by Adam Glass. 162736Sdfr * 4. The name of the Author may not be used to endorse or promote products 172736Sdfr * derived from this software without specific prior written permission. 182736Sdfr * 192736Sdfr * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND 202736Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 212736Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 222736Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL Adam Glass BE LIABLE 232736Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 242736Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 252736Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 262736Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 272736Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 282736Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 292736Sdfr * SUCH DAMAGE. 30174891Sedwin * 312736Sdfr */ 322736Sdfr 3399112Sobrien#include <sys/cdefs.h> 3499112Sobrien__FBSDID("$FreeBSD$"); 3527420Scharnier 36174891Sedwin#include <sys/param.h> 37174891Sedwin#define _KERNEL 38174750Sedwin#include <sys/sem.h> 39174750Sedwin#include <sys/shm.h> 40174891Sedwin#include <sys/msg.h> 41174891Sedwin#undef _KERNEL 42174750Sedwin 4327420Scharnier#include <ctype.h> 4427420Scharnier#include <err.h> 45174891Sedwin#include <grp.h> 46174891Sedwin#include <kvm.h> 472736Sdfr#include <stdio.h> 482736Sdfr#include <stdlib.h> 492736Sdfr#include <unistd.h> 502736Sdfr 51174891Sedwin#include "ipc.h" 522736Sdfr 53174891Sedwinint signaled; 54174891Sedwinint errflg; 55174891Sedwinint rmverbose = 0; 562736Sdfr 57174891Sedwinvoid usage(void); 5887285Sdwmalone 59174891Sedwinint msgrm(key_t, int); 60174891Sedwinint shmrm(key_t, int); 61174891Sedwinint semrm(key_t, int); 62174891Sedwinvoid not_configured(int); 63174891Sedwin 64174750Sedwinvoid 65174750Sedwinusage(void) 662736Sdfr{ 67174750Sedwin 68174750Sedwin fprintf(stderr, 69174891Sedwin "usage: ipcrm [-W] [-v[v]]\n" 70174891Sedwin " [-q msqid] [-m shmid] [-s semid]\n" 71174750Sedwin " [-Q msgkey] [-M shmkey] [-S semkey] ...\n"); 722736Sdfr exit(1); 732736Sdfr} 742736Sdfr 75174750Sedwinint 76174750Sedwinmsgrm(key_t key, int id) 772736Sdfr{ 78174750Sedwin 79174891Sedwin if (key == -1 || id == -1) { 80174891Sedwin struct msqid_kernel *kxmsqids; 81174891Sedwin size_t kxmsqids_len; 82174891Sedwin int num; 83174891Sedwin 84174891Sedwin kget(X_MSGINFO, &msginfo, sizeof(msginfo)); 85174891Sedwin kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni; 86174891Sedwin kxmsqids = malloc(kxmsqids_len); 87174891Sedwin kget(X_MSQIDS, kxmsqids, kxmsqids_len); 88174891Sedwin num = msginfo.msgmni; 89174891Sedwin while (num-- && !signaled) 90174891Sedwin if (kxmsqids[num].u.msg_qbytes != 0) { 91174891Sedwin id = IXSEQ_TO_IPCID(num, 92174891Sedwin kxmsqids[num].u.msg_perm); 93174891Sedwin if (msgctl(id, IPC_RMID, NULL) < 0) { 94174891Sedwin if (rmverbose > 1) 95174891Sedwin warn("msqid(%d): ", id); 96174891Sedwin errflg++; 97174891Sedwin } else 98174891Sedwin if (rmverbose) 99174891Sedwin printf( 100174891Sedwin "Removed %s %d\n", 101174891Sedwin IPC_TO_STRING('Q'), 102174891Sedwin id); 103174891Sedwin } 104174891Sedwin return signaled ? -1 : 0; /* errors maybe handled above */ 105174891Sedwin } 106174891Sedwin 107174750Sedwin if (key) { 108174750Sedwin id = msgget(key, 0); 109174750Sedwin if (id == -1) 110174750Sedwin return -1; 111174750Sedwin } 112174891Sedwin 113174750Sedwin return msgctl(id, IPC_RMID, NULL); 1142736Sdfr} 1152736Sdfr 116174750Sedwinint 117174750Sedwinshmrm(key_t key, int id) 1182736Sdfr{ 119174750Sedwin 120174891Sedwin if (key == -1 || id == -1) { 121174891Sedwin struct shmid_kernel *kxshmids; 122174891Sedwin size_t kxshmids_len; 123174891Sedwin int num; 124174891Sedwin 125174891Sedwin kget(X_SHMINFO, &shminfo, sizeof(shminfo)); 126174891Sedwin kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni; 127174891Sedwin kxshmids = malloc(kxshmids_len); 128174891Sedwin kget(X_SHMSEGS, kxshmids, kxshmids_len); 129174891Sedwin num = shminfo.shmmni; 130174891Sedwin while (num-- && !signaled) 131174891Sedwin if (kxshmids[num].u.shm_perm.mode & 0x0800) { 132174891Sedwin id = IXSEQ_TO_IPCID(num, 133174891Sedwin kxshmids[num].u.shm_perm); 134174891Sedwin if (shmctl(id, IPC_RMID, NULL) < 0) { 135174891Sedwin if (rmverbose > 1) 136174891Sedwin warn("shmid(%d): ", id); 137174891Sedwin errflg++; 138174891Sedwin } else 139174891Sedwin if (rmverbose) 140174891Sedwin printf( 141174891Sedwin "Removed %s %d\n", 142174891Sedwin IPC_TO_STRING('M'), 143174891Sedwin id); 144174891Sedwin } 145174891Sedwin return signaled ? -1 : 0; /* errors maybe handled above */ 146174891Sedwin } 147174891Sedwin 148174750Sedwin if (key) { 149174750Sedwin id = shmget(key, 0, 0); 150174750Sedwin if (id == -1) 151174750Sedwin return -1; 152174750Sedwin } 153174891Sedwin 154174750Sedwin return shmctl(id, IPC_RMID, NULL); 1552736Sdfr} 1562736Sdfr 157174750Sedwinint 158174750Sedwinsemrm(key_t key, int id) 1592736Sdfr{ 160174750Sedwin union semun arg; 1612736Sdfr 162174891Sedwin if (key == -1 || id == -1) { 163174891Sedwin struct semid_kernel *kxsema; 164174891Sedwin size_t kxsema_len; 165174891Sedwin int num; 166174891Sedwin 167174891Sedwin kget(X_SEMINFO, &seminfo, sizeof(seminfo)); 168174891Sedwin kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni; 169174891Sedwin kxsema = malloc(kxsema_len); 170174891Sedwin kget(X_SEMA, kxsema, kxsema_len); 171174891Sedwin num = seminfo.semmni; 172174891Sedwin while (num-- && !signaled) 173174891Sedwin if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) { 174174891Sedwin id = IXSEQ_TO_IPCID(num, 175174891Sedwin kxsema[num].u.sem_perm); 176174891Sedwin if (semctl(id, IPC_RMID, NULL) < 0) { 177174891Sedwin if (rmverbose > 1) 178174891Sedwin warn("semid(%d): ", id); 179174891Sedwin errflg++; 180174891Sedwin } else 181174891Sedwin if (rmverbose) 182174891Sedwin printf( 183174891Sedwin "Removed %s %d\n", 184174891Sedwin IPC_TO_STRING('S'), 185174891Sedwin id); 186174891Sedwin } 187174891Sedwin return signaled ? -1 : 0; /* errors maybe handled above */ 188174891Sedwin } 189174891Sedwin 190174750Sedwin if (key) { 191174750Sedwin id = semget(key, 0, 0); 192174750Sedwin if (id == -1) 193174750Sedwin return -1; 194174750Sedwin } 195174891Sedwin 196174750Sedwin return semctl(id, 0, IPC_RMID, arg); 1972736Sdfr} 1982736Sdfr 199174750Sedwinvoid 200174750Sedwinnot_configured(int signo __unused) 2012736Sdfr{ 202174750Sedwin 203174750Sedwin signaled++; 2042736Sdfr} 2058874Srgrimes 206174750Sedwinint 207174750Sedwinmain(int argc, char *argv[]) 2082736Sdfr{ 209174891Sedwin int c, result, target_id; 210174750Sedwin key_t target_key; 2112736Sdfr 212174891Sedwin while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) { 213174891Sedwin 214174891Sedwin signaled = 0; 215174891Sedwin switch (c) { 216174891Sedwin case 'v': 217174891Sedwin rmverbose++; 218174891Sedwin break; 219174891Sedwin case 'y': 220174891Sedwin use_sysctl = 0; 221174891Sedwin break; 222174891Sedwin } 223174891Sedwin } 224174891Sedwin 225174891Sedwin optind = 1; 226174750Sedwin errflg = 0; 227174750Sedwin signal(SIGSYS, not_configured); 228174891Sedwin while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) { 2292736Sdfr 230174750Sedwin signaled = 0; 231174750Sedwin switch (c) { 232174750Sedwin case 'q': 233174750Sedwin case 'm': 234174750Sedwin case 's': 235174750Sedwin target_id = atoi(optarg); 236174750Sedwin if (c == 'q') 237174750Sedwin result = msgrm(0, target_id); 238174750Sedwin else if (c == 'm') 239174750Sedwin result = shmrm(0, target_id); 240174750Sedwin else 241174750Sedwin result = semrm(0, target_id); 242174750Sedwin if (result < 0) { 243174750Sedwin errflg++; 244174750Sedwin if (!signaled) 245174750Sedwin warn("%sid(%d): ", 246174750Sedwin IPC_TO_STR(toupper(c)), target_id); 247174750Sedwin else 248174750Sedwin warnx( 249174750Sedwin "%ss are not configured " 250174750Sedwin "in the running kernel", 251174750Sedwin IPC_TO_STRING(toupper(c))); 252174750Sedwin } 253174750Sedwin break; 254174750Sedwin case 'Q': 255174750Sedwin case 'M': 256174750Sedwin case 'S': 257174750Sedwin target_key = atol(optarg); 258174750Sedwin if (target_key == IPC_PRIVATE) { 259174750Sedwin warnx("can't remove private %ss", 260174750Sedwin IPC_TO_STRING(c)); 261174750Sedwin continue; 262174750Sedwin } 263174750Sedwin if (c == 'Q') 264174750Sedwin result = msgrm(target_key, 0); 265174750Sedwin else if (c == 'M') 266174750Sedwin result = shmrm(target_key, 0); 267174750Sedwin else 268174750Sedwin result = semrm(target_key, 0); 269174750Sedwin if (result < 0) { 270174750Sedwin errflg++; 271174750Sedwin if (!signaled) 272174750Sedwin warn("%ss(%ld): ", 273174750Sedwin IPC_TO_STR(c), target_key); 274174750Sedwin else 275174750Sedwin warnx("%ss are not configured " 276174750Sedwin "in the running kernel", 277174750Sedwin IPC_TO_STRING(c)); 278174750Sedwin } 279174750Sedwin break; 280174891Sedwin case 'v': 281174891Sedwin case 'y': 282174891Sedwin /* Handled in other getopt() loop */ 283174891Sedwin break; 284174891Sedwin case 'W': 285174891Sedwin msgrm(-1, 0); 286174891Sedwin shmrm(-1, 0); 287174891Sedwin semrm(-1, 0); 288174891Sedwin break; 289174750Sedwin case ':': 290174750Sedwin fprintf(stderr, 291174750Sedwin "option -%c requires an argument\n", optopt); 292174750Sedwin usage(); 293174750Sedwin case '?': 294174750Sedwin fprintf(stderr, "unrecognized option: -%c\n", optopt); 295174750Sedwin usage(); 296174750Sedwin } 2972736Sdfr } 2982736Sdfr 299174750Sedwin if (optind != argc) { 300174750Sedwin fprintf(stderr, "unknown argument: %s\n", argv[optind]); 301174750Sedwin usage(); 302174750Sedwin } 303174750Sedwin exit(errflg); 3042736Sdfr} 305