View | Details | Raw Unified | Return to bug 118292
Collapse All | Expand All

(-)usr.bin/ipcrm/Makefile (+2 lines)
Lines 1-5 Link Here
1
# $FreeBSD: src/usr.bin/ipcrm/Makefile,v 1.6 2002/02/08 22:31:40 markm Exp $
1
# $FreeBSD: src/usr.bin/ipcrm/Makefile,v 1.6 2002/02/08 22:31:40 markm Exp $
2
2
3
PROG=	ipcrm
3
PROG=	ipcrm
4
DPADD=  ${LIBKVM}
5
LDADD=  -lkvm
4
6
5
.include <bsd.prog.mk>
7
.include <bsd.prog.mk>
(-)usr.bin/ipcrm/ipcrm.c (-111 / +389 lines)
Lines 32-54 Link Here
32
#include <sys/cdefs.h>
32
#include <sys/cdefs.h>
33
__FBSDID("$FreeBSD: src/usr.bin/ipcrm/ipcrm.c,v 1.11 2002/09/04 23:29:02 dwmalone Exp $");
33
__FBSDID("$FreeBSD: src/usr.bin/ipcrm/ipcrm.c,v 1.11 2002/09/04 23:29:02 dwmalone Exp $");
34
34
35
#include <sys/types.h>
36
#include <sys/sysctl.h>
37
#include <sys/cdefs.h>
38
#define _KERNEL
39
#include <sys/ipc.h>
40
#include <sys/msg.h>
41
#include <sys/sem.h>
42
#include <sys/shm.h>
43
#undef _KERNEL
35
#include <ctype.h>
44
#include <ctype.h>
36
#include <err.h>
45
#include <err.h>
37
#include <signal.h>
46
#include <signal.h>
38
#include <stdio.h>
47
#include <stdio.h>
39
#include <stdlib.h>
48
#include <stdlib.h>
40
#include <unistd.h>
49
#include <unistd.h>
41
#include <sys/types.h>
50
#include <assert.h>
42
#include <sys/ipc.h>
51
#include <limits.h>
43
#include <sys/msg.h>
52
#include <fcntl.h>
44
#include <sys/sem.h>
53
#include <nlist.h>
45
#include <sys/shm.h>
54
#include <kvm.h>
46
55
47
#define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
56
#define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
48
#define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
57
#define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
49
	(x == 'M' ? "shared memory segment" : "semaphore"))
58
			  (x == 'M' ? "shared memory segment" : "semaphore"))
50
59
51
int signaled;
60
/* Copied from ipcs/ipcs.c */
61
/* SysCtlGatherStruct structure. */
62
struct scgs_vector {
63
	const char *sysctl;
64
	off_t offset;
65
	size_t size;
66
};
67
68
static struct semid_kernel	*sema;
69
static struct seminfo	seminfo;
70
static struct msginfo	msginfo;
71
static struct msqid_kernel	*msqids;
72
static struct shminfo	shminfo;
73
static struct shmid_kernel	*shmsegs;
74
75
void	kget(int idx, void *addr, size_t size);
76
void	sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec);
77
78
static struct nlist symbols[] = {
79
	{"sema"},
80
#define X_SEMA		0
81
	{"seminfo"},
82
#define X_SEMINFO	1
83
	{"msginfo"},
84
#define X_MSGINFO	2
85
	{"msqids"},
86
#define X_MSQIDS	3
87
	{"shminfo"},
88
#define X_SHMINFO	4
89
	{"shmsegs"},
90
#define X_SHMSEGS	5
91
	{NULL}
92
};
93
94
#define	SHMINFO_XVEC				\
95
	X(shmmax, sizeof(int))			\
96
	X(shmmin, sizeof(int))			\
97
	X(shmmni, sizeof(int))			\
98
	X(shmseg, sizeof(int))			\
99
	X(shmall, sizeof(int))
100
101
#define	SEMINFO_XVEC				\
102
	X(semmap, sizeof(int))			\
103
	X(semmni, sizeof(int))			\
104
	X(semmns, sizeof(int))			\
105
	X(semmnu, sizeof(int))			\
106
	X(semmsl, sizeof(int))			\
107
	X(semopm, sizeof(int))			\
108
	X(semume, sizeof(int))			\
109
	X(semusz, sizeof(int))			\
110
	X(semvmx, sizeof(int))			\
111
	X(semaem, sizeof(int))
112
113
#define	MSGINFO_XVEC				\
114
	X(msgmax, sizeof(int))			\
115
	X(msgmni, sizeof(int))			\
116
	X(msgmnb, sizeof(int))			\
117
	X(msgtql, sizeof(int))			\
118
	X(msgssz, sizeof(int))			\
119
	X(msgseg, sizeof(int))
120
121
#define	X(a, b)	{ "kern.ipc." #a, __offsetof(TYPEC, a), (b) },
122
#define	TYPEC	struct shminfo
123
struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } };
124
#undef	TYPEC
125
#define	TYPEC	struct seminfo
126
struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } };
127
#undef	TYPEC
128
#define	TYPEC	struct msginfo
129
struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } };
130
#undef	TYPEC
131
#undef	X
132
133
static int errflg;
134
static int signaled;
135
static int use_sysctl = 1;
52
136
53
void usage(void);
137
void usage(void);
54
int msgrm(key_t, int);
138
int msgrm(key_t, int);
Lines 56-62 Link Here
56
int semrm(key_t, int);
140
int semrm(key_t, int);
57
void not_configured(int);
141
void not_configured(int);
58
142
59
void usage(void)
143
void
144
usage(void)
60
{
145
{
61
	fprintf(stderr, "%s\n%s\n",
146
	fprintf(stderr, "%s\n%s\n",
62
		"usage: ipcrm [-q msqid] [-m shmid] [-s semid]",
147
		"usage: ipcrm [-q msqid] [-m shmid] [-s semid]",
Lines 64-172 Link Here
64
	exit(1);
149
	exit(1);
65
}
150
}
66
151
67
int msgrm(key_t key, int id)
152
int
153
msgrm(key_t key, int id)
154
{
155
	if (key) {
156
		id = msgget(key, 0);
157
		if (id == -1)
158
			return -1;
159
	}
160
	if (id == -1) {
161
		struct msqid_kernel *kxmsqids;
162
		size_t kxmsqids_len;
163
		int num;
164
165
		kget(X_MSGINFO, &msginfo, sizeof(msginfo));
166
		kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni;
167
		kxmsqids = malloc(kxmsqids_len);
168
		kget(X_MSQIDS, kxmsqids, kxmsqids_len);
169
		num = msginfo.msgmni;
170
		while (num-- && !signaled)
171
			if (kxmsqids[num].u.msg_qbytes != 0) {
172
				id = IXSEQ_TO_IPCID(num, kxmsqids[num].u.msg_perm);
173
				if (msgctl(id, IPC_RMID, NULL) < 0) {
174
					warn("msqid(%d): ", id);
175
					errflg++;
176
				}
177
			}
178
		return signaled ? -1 : 0;	/* errors maybe handled above */
179
	}
180
	return msgctl(id, IPC_RMID, NULL);
181
}
182
183
int
184
shmrm(key_t key, int id)
185
{
186
	if (key) {
187
		id = shmget(key, 0, 0);
188
		if (id == -1)
189
			return -1;
190
	}
191
	if (id == -1) {
192
		struct shmid_kernel *kxshmids;
193
		size_t kxshmids_len;
194
		int num;
195
196
		kget(X_SHMINFO, &shminfo, sizeof(shminfo));
197
		kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni;
198
		kxshmids = malloc(kxshmids_len);
199
		kget(X_SHMSEGS, kxshmids, kxshmids_len);
200
		num = shminfo.shmmni;
201
		while (num-- && !signaled)
202
			if (kxshmids[num].u.shm_perm.mode & 0x0800) {
203
				id = IXSEQ_TO_IPCID(num, kxshmids[num].u.shm_perm);
204
				if (shmctl(id, IPC_RMID, NULL) < 0) {
205
					warn("shmid(%d): ", id);
206
					errflg++;
207
				}
208
			}
209
		return signaled ? -1 : 0;	/* errors maybe handled above */
210
	}
211
	return shmctl(id, IPC_RMID, NULL);
212
}
213
214
int
215
semrm(key_t key, int id)
68
{
216
{
69
    if (key) {
217
	union semun arg;
70
	id = msgget(key, 0);
218
71
	if (id == -1)
219
	if (key) {
72
	    return -1;
220
		id = semget(key, 0, 0);
73
    }
221
		if (id == -1)
74
    return msgctl(id, IPC_RMID, NULL);
222
			return -1;
75
}
223
	}
76
224
	if (id == -1) {
77
int shmrm(key_t key, int id)
225
		struct semid_kernel *kxsema;
78
{
226
		size_t kxsema_len;
79
    if (key) {
227
		int num;
80
	id = shmget(key, 0, 0);
228
81
	if (id == -1)
229
		kget(X_SEMINFO, &seminfo, sizeof(seminfo));
82
	    return -1;
230
		kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni;
83
    }
231
		kxsema = malloc(kxsema_len);
84
    return shmctl(id, IPC_RMID, NULL);
232
		kget(X_SEMA, kxsema, kxsema_len);
85
}
233
		num = seminfo.semmni;
86
234
		while (num-- && !signaled)
87
int semrm(key_t key, int id)
235
			if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) {
88
{
236
				id = IXSEQ_TO_IPCID(num, kxsema[num].u.sem_perm);
89
    union semun arg;
237
				if (semctl(id, IPC_RMID, NULL) < 0) {
90
238
					warn("semid(%d): ", id);
91
    if (key) {
239
					errflg++;
92
	id = semget(key, 0, 0);
240
				}
93
	if (id == -1)
241
			}
94
	    return -1;
242
		return signaled ? -1 : 0;	/* errors maybe handled above */
95
    }
243
	}
96
    return semctl(id, 0, IPC_RMID, arg);
244
	return semctl(id, 0, IPC_RMID, arg);
97
}
245
}
98
246
99
void not_configured(int signo __unused)
247
void
100
{
248
not_configured(int signo __unused)
101
    signaled++;
249
{
102
}
250
	signaled++;
103
251
}
104
int main(int argc, char *argv[])
252
105
{
253
int
106
    int c, result, errflg, target_id;
254
main(int argc, char *argv[])
107
    key_t target_key;
255
{
108
256
	int c, result, target_id;
109
    errflg = 0;
257
	key_t target_key;
110
    signal(SIGSYS, not_configured);
258
111
    while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:")) != -1) {
259
	errflg = 0;
112
260
	signal(SIGSYS, not_configured);
113
	signaled = 0;
261
	while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:y")) != -1) {
114
	switch (c) {
262
115
	case 'q':
263
		signaled = 0;
116
	case 'm':
264
		switch (c) {
117
	case 's':
265
		case 'q':
118
	    target_id = atoi(optarg);
266
		case 'm':
119
	    if (c == 'q')
267
		case 's':
120
		result = msgrm(0, target_id);
268
			target_id = atoi(optarg);
121
	    else if (c == 'm')
269
			if (c == 'q')
122
		result = shmrm(0, target_id);
270
				result = msgrm(0, target_id);
123
	    else
271
			else if (c == 'm')
124
		result = semrm(0, target_id);
272
				result = shmrm(0, target_id);
125
	    if (result < 0) {
273
			else
126
		errflg++;
274
				result = semrm(0, target_id);
127
		if (!signaled)
275
			if (result < 0) {
128
		    warn("%sid(%d): ", IPC_TO_STR(toupper(c)), target_id);
276
				errflg++;
129
		else
277
				if (!signaled)
130
		    warnx("%ss are not configured in the running kernel",
278
					warn("%sid(%d): ", IPC_TO_STR(toupper(c)), target_id);
131
			  IPC_TO_STRING(toupper(c)));
279
				else
132
	    }
280
					warnx("%ss are not configured in the running kernel",
133
	    break;
281
					      IPC_TO_STRING(toupper(c)));
134
	case 'Q':
282
			}
135
	case 'M':
283
			break;
136
	case 'S':
284
		case 'Q':
137
	    target_key = atol(optarg);
285
		case 'M':
138
	    if (target_key == IPC_PRIVATE) {
286
		case 'S':
139
		warnx("can't remove private %ss", IPC_TO_STRING(c));
287
			target_key = atol(optarg);
140
		continue;
288
			if (target_key == IPC_PRIVATE) {
141
	    }
289
				warnx("can't remove private %ss", IPC_TO_STRING(c));
142
	    if (c == 'Q')
290
				continue;
143
		result = msgrm(target_key, 0);
291
			}
144
	    else if (c == 'M')
292
			if (c == 'Q')
145
		result = shmrm(target_key, 0);
293
				result = msgrm(target_key, 0);
146
	    else
294
			else if (c == 'M')
147
		result = semrm(target_key, 0);
295
				result = shmrm(target_key, 0);
148
	    if (result < 0) {
296
			else
149
		errflg++;
297
				result = semrm(target_key, 0);
150
		if (!signaled)
298
			if (result < 0) {
151
		    warn("%ss(%ld): ", IPC_TO_STR(c), target_key);
299
				errflg++;
152
		else
300
				if (!signaled)
153
		    warnx("%ss are not configured in the running kernel",
301
					warn("%ss(%ld): ", IPC_TO_STR(c), target_key);
154
			  IPC_TO_STRING(c));
302
				else
155
	    }
303
					warnx("%ss are not configured in the running kernel",
156
	    break;
304
					      IPC_TO_STRING(c));
157
	case ':':
305
			}
158
	    fprintf(stderr, "option -%c requires an argument\n", optopt);
306
			break;
159
	    usage();
307
		case 'y':
160
	case '?':
308
			use_sysctl = 0;
161
	    fprintf(stderr, "unrecognized option: -%c\n", optopt);
309
			break;
162
	    usage();
310
		case ':':
163
	}
311
			fprintf(stderr, "option -%c requires an argument\n", optopt);
164
    }
312
			usage();
165
313
		case '?':
166
    if (optind != argc) {
314
			fprintf(stderr, "unrecognized option: -%c\n", optopt);
167
	    fprintf(stderr, "unknown argument: %s\n", argv[optind]);
315
			usage();
168
	    usage();
316
		}
169
    }
317
	}
170
    exit(errflg);
318
319
	if (optind != argc) {
320
		fprintf(stderr, "unknown argument: %s\n", argv[optind]);
321
		usage();
322
	}
323
	exit(errflg);
324
}
325
326
/* The remainder is from ipcs/ipcs.c */
327
void
328
sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr)
329
{
330
	struct scgs_vector *xp;
331
	size_t tsiz;
332
	int rv;
333
334
	for (xp = vecarr; xp->sysctl != NULL; xp++) {
335
		assert(xp->offset <= size);
336
		tsiz = xp->size;
337
		rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset,
338
				  &tsiz, NULL, 0);
339
		if (rv == -1)
340
			err(1, "sysctlbyname: %s", xp->sysctl);
341
		if (tsiz != xp->size)
342
			errx(1, "%s size mismatch (expected %d, got %d)",
343
			     xp->sysctl, xp->size, tsiz);
344
	}
345
}
346
347
void
348
kget(int idx, void *addr, size_t size)
349
{
350
	char *symn;			/* symbol name */
351
	size_t tsiz;
352
	int rv;
353
	unsigned long kaddr;
354
	const char *sym2sysctl[] = {	/* symbol to sysctl name table */
355
		"kern.ipc.sema",
356
		"kern.ipc.seminfo",
357
		"kern.ipc.msginfo",
358
		"kern.ipc.msqids",
359
		"kern.ipc.shminfo",
360
		"kern.ipc.shmsegs" };
361
362
	assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl));
363
	if (!use_sysctl) {
364
		kvm_t *kd;
365
		char	kvmoferr[_POSIX2_LINE_MAX];  /* Error buf for kvm_openfiles. */
366
		char   *core = NULL, *namelist = NULL;
367
368
		kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, kvmoferr);
369
		if (kd == NULL)
370
			errx(1, "kvm_openfiles: %s", kvmoferr);
371
		switch (kvm_nlist(kd, symbols)) {
372
		case 0:
373
			break;
374
		case -1:
375
			errx(1, "unable to read kernel symbol table");
376
		default:
377
#ifdef notdef		/* they'll be told more civilly later */
378
			warnx("nlist failed");
379
			for (i = 0; symbols[i].n_name != NULL; i++)
380
				if (symbols[i].n_value == 0)
381
					warnx("symbol %s not found",
382
					      symbols[i].n_name);
383
#endif
384
			break;
385
		}
386
		symn = symbols[idx].n_name;
387
		if (*symn == '_')
388
			symn++;
389
		if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0)
390
			errx(1, "symbol %s undefined", symn);
391
		/*
392
		 * For some symbols, the value we retrieve is
393
		 * actually a pointer; since we want the actual value,
394
		 * we have to manually dereference it.
395
		 */
396
		switch (idx) {
397
		case X_MSQIDS:
398
			tsiz = sizeof(msqids);
399
			rv = kvm_read(kd, symbols[idx].n_value,
400
				      &msqids, tsiz);
401
			kaddr = (u_long)msqids;
402
			break;
403
		case X_SHMSEGS:
404
			tsiz = sizeof(shmsegs);
405
			rv = kvm_read(kd, symbols[idx].n_value,
406
				      &shmsegs, tsiz);
407
			kaddr = (u_long)shmsegs;
408
			break;
409
		case X_SEMA:
410
			tsiz = sizeof(sema);
411
			rv = kvm_read(kd, symbols[idx].n_value,
412
				      &sema, tsiz);
413
			kaddr = (u_long)sema;
414
			break;
415
		default:
416
			rv = tsiz = 0;
417
			kaddr = symbols[idx].n_value;
418
			break;
419
		}
420
		if ((unsigned)rv != tsiz)
421
			errx(1, "%s: %s", symn, kvm_geterr(kd));
422
		if ((unsigned)kvm_read(kd, kaddr, addr, size) != size)
423
			errx(1, "%s: %s", symn, kvm_geterr(kd));
424
		kvm_close(kd);
425
	} else {
426
		switch (idx) {
427
		case X_SHMINFO:
428
			sysctlgatherstruct(addr, size, shminfo_scgsv);
429
			break;
430
		case X_SEMINFO:
431
			sysctlgatherstruct(addr, size, seminfo_scgsv);
432
			break;
433
		case X_MSGINFO:
434
			sysctlgatherstruct(addr, size, msginfo_scgsv);
435
			break;
436
		default:
437
			tsiz = size;
438
			rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz,
439
					  NULL, 0);
440
			if (rv == -1)
441
				err(1, "sysctlbyname: %s", sym2sysctl[idx]);
442
			if (tsiz != size)
443
				errx(1, "%s size mismatch "
444
				     "(expected %d, got %d)",
445
				     sym2sysctl[idx], size, tsiz);
446
			break;
447
		}
448
	}
171
}
449
}
172
450
(-)usr.bin/ipcrm/ipcrm.1 (-2 / +16 lines)
Lines 52-67 Link Here
52
.It Fl q Ar msqid
52
.It Fl q Ar msqid
53
Remove the message queue associated with the id
53
Remove the message queue associated with the id
54
.Ar msqid
54
.Ar msqid
55
from the system.
55
from the system. If msqid is -1 then attempt to remove all message queues.
56
.It Fl m Ar shmid
56
.It Fl m Ar shmid
57
Mark the shared memory segment associated with id
57
Mark the shared memory segment associated with id
58
.Ar shmid
58
.Ar shmid
59
for removal.
59
for removal.
60
This marked segment will be destroyed after the last detach.
60
This marked segment will be destroyed after the last detach.
61
If shmid is -1 then attempt to remove all shared memory segments.
61
.It Fl s Ar semid
62
.It Fl s Ar semid
62
Remove the semaphore set associated with id
63
Remove the semaphore set associated with id
63
.Ar semid
64
.Ar semid
64
from the system.
65
from the system. If semid is -1 then attempt to remove all semaphores.
65
.It Fl Q Ar msgkey
66
.It Fl Q Ar msgkey
66
Remove the message queue associated with key
67
Remove the message queue associated with key
67
.Ar msgkey
68
.Ar msgkey
Lines 75-80 Link Here
75
Remove the semaphore set associated with key
76
Remove the semaphore set associated with key
76
.Ar semkey
77
.Ar semkey
77
from the system.
78
from the system.
79
.It Fl y
80
Use the
81
.Xr kvm 3
82
interface instead of the
83
.Xr sysctl 3
84
interface to extract the required information.
85
If
86
.Nm
87
is to operate on the running system,
88
using
89
.Xr kvm 3
90
will require read privileges to
91
.Pa /dev/kmem .
78
.El
92
.El
79
.Pp
93
.Pp
80
The identifiers and keys associated with these System V IPC objects can be
94
The identifiers and keys associated with these System V IPC objects can be

Return to bug 118292