summaryrefslogtreecommitdiffstats
path: root/sys-utils/ipcrm.c
blob: 3e3a9ba02a216824bf005795f761f12673968441 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * krishna balasubramanian 1993
 *
 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
 * - added Native Language Support
 *
 * 1999-04-02 frank zago
 * - can now remove several id's in the same call
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include "nls.h"

#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
/* according to X/OPEN we have to define it ourselves */
union semun {
	int val;
	struct semid_ds *buf;
	unsigned short int *array;
	struct seminfo *__buf;
};
#endif

char *execname;

typedef enum type_id {
	SHM,
	SEM,
	MSG
} type_id;

static int
remove_ids(type_id type, int argc, char **argv) {
	int id;
	int ret = 0;		/* for gcc */
	char *end;
	int nb_errors = 0;
	union semun arg;

	arg.val = 0;

	while(argc) {

		id = strtoul(argv[0], &end, 10);

		if (*end != 0) {
			printf (_("invalid id: %s\n"), argv[0]);
			nb_errors ++;
		} else {
			switch(type) {
			case SEM:
				ret = semctl (id, 0, IPC_RMID, arg);
				break;

			case MSG:
				ret = msgctl (id, IPC_RMID, NULL);
				break;
				
			case SHM:
				ret = shmctl (id, IPC_RMID, NULL);
				break;
			}

			if (ret) {
				printf (_("cannot remove id %s (%s)\n"),
					argv[0], strerror(errno));
				nb_errors ++;
			}
		}
		argc--;
		argv++;
	}
	
	return(nb_errors);
}

static void display_usage(void)
{
	printf (_("usage: %s {shm | msg | sem} id ...\n"), execname);
}

int main(int argc, char **argv)
{
	execname = argv[0];

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	if (argc < 3) {
		display_usage();
		exit(1);
	}
	
	if (!strcmp(argv[1], "shm")) {
		if (remove_ids(SHM, argc-2, &argv[2])) {
			exit(1);
		}
	}
	else if (!strcmp(argv[1], "msg")) {
		if (remove_ids(MSG, argc-2, &argv[2])) {
			exit(1);
		}
	} 
	else if (!strcmp(argv[1], "sem")) {
		if (remove_ids(SEM, argc-2, &argv[2])) {
			exit(1);
		}
	}
	else {
		display_usage();
		printf (_("unknown resource type: %s\n"), argv[1]);
		exit(1);
	}

	printf (_("resource(s) deleted\n"));
	return 0;
}