add opendir alias
[minix.git] / commands / ipcrm / ipcrm.c
blobd04df67ab898c9dd1114f728ce91298e33288a39
1 /*
2 * krishna balasubramanian 1993
4 * 1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL>
5 * - added Native Language Support
7 * 1999-04-02 frank zago
8 * - can now remove several id's in the same call
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/ipc.h>
19 #include <sys/shm.h>
20 #include <sys/sem.h>
22 /* for getopt */
23 #include <unistd.h>
24 /* for tolower and isupper */
25 #include <ctype.h>
27 #define _(a) a
29 #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
30 /* union semun is defined by including <sys/sem.h> */
31 #else
32 /* according to X/OPEN we have to define it ourselves */
33 union semun {
34 int val;
35 struct semid_ds *buf;
36 unsigned short int *array;
37 struct seminfo *__buf;
39 #endif
41 static void usage(char *);
43 char *execname;
45 typedef enum type_id {
46 SHM,
47 SEM,
48 MSG
49 } type_id;
51 static int
52 remove_ids(type_id type, int argc, char **argv) {
53 int id;
54 int ret = 0; /* for gcc */
55 char *end;
56 int nb_errors = 0;
57 union semun arg;
59 arg.val = 0;
61 while(argc) {
63 id = strtoul(argv[0], &end, 10);
65 if (*end != 0) {
66 printf (_("invalid id: %s\n"), argv[0]);
67 nb_errors ++;
68 } else {
69 switch(type) {
70 case SEM:
71 #if 0
72 ret = semctl (id, 0, IPC_RMID, arg);
73 #endif
74 break;
76 case MSG:
77 #if 0
78 ret = msgctl (id, IPC_RMID, NULL);
79 #endif
80 break;
82 case SHM:
83 ret = shmctl (id, IPC_RMID, NULL);
84 break;
87 if (ret) {
88 printf (_("cannot remove id %s (%s)\n"),
89 argv[0], strerror(errno));
90 nb_errors ++;
93 argc--;
94 argv++;
97 return(nb_errors);
100 static void deprecate_display_usage(void)
102 usage(execname);
103 printf (_("deprecated usage: %s {shm | msg | sem} id ...\n"),
104 execname);
107 static int deprecated_main(int argc, char **argv)
109 execname = argv[0];
111 if (argc < 3) {
112 deprecate_display_usage();
113 exit(1);
116 if (!strcmp(argv[1], "shm")) {
117 if (remove_ids(SHM, argc-2, &argv[2]))
118 exit(1);
120 else if (!strcmp(argv[1], "msg")) {
121 if (remove_ids(MSG, argc-2, &argv[2]))
122 exit(1);
124 else if (!strcmp(argv[1], "sem")) {
125 if (remove_ids(SEM, argc-2, &argv[2]))
126 exit(1);
128 else {
129 deprecate_display_usage();
130 printf (_("unknown resource type: %s\n"), argv[1]);
131 exit(1);
134 printf (_("resource(s) deleted\n"));
135 return 0;
139 /* print the new usage */
140 static void
141 usage(char *progname)
143 fprintf(stderr,
144 _("usage: %s [ [-q msqid] [-m shmid] [-s semid]\n"
145 " [-Q msgkey] [-M shmkey] [-S semkey] ... ]\n"),
146 progname);
149 int main(int argc, char **argv)
151 int c;
152 int error = 0;
153 char *prog = argv[0];
155 /* if the command is executed without parameters, do nothing */
156 if (argc == 1)
157 return 0;
159 /* check to see if the command is being invoked in the old way if so
160 then run the old code */
161 if (strcmp(argv[1], "shm") == 0 ||
162 strcmp(argv[1], "msg") == 0 ||
163 strcmp(argv[1], "sem") == 0)
164 return deprecated_main(argc, argv);
166 /* process new syntax to conform with SYSV ipcrm */
167 while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
168 int result;
169 int id = 0;
170 int iskey = isupper(c);
172 /* needed to delete semaphores */
173 union semun arg;
174 arg.val = 0;
176 /* we don't need case information any more */
177 c = tolower(c);
179 /* make sure the option is in range */
180 if (c != 'q' && c != 'm' && c != 's') {
181 fprintf(stderr, _("%s: illegal option -- %c\n"),
182 prog, c);
183 usage(prog);
184 error++;
185 return error;
188 if (iskey) {
189 /* keys are in hex or decimal */
190 key_t key = strtoul(optarg, NULL, 0);
191 if (key == IPC_PRIVATE) {
192 error++;
193 fprintf(stderr, _("%s: illegal key (%s)\n"),
194 prog, optarg);
195 continue;
198 /* convert key to id */
199 #if 0
200 id = ((c == 'q') ? msgget(key, 0) :
201 (c == 'm') ? shmget(key, 0, 0) :
202 semget(key, 0, 0));
203 #endif
204 id = (c == 'm') ? shmget(key, 0, 0) :
205 ((c == 's') ? semget(key, 0, 0) : -1);
207 if (id < 0) {
208 char *errmsg;
209 error++;
210 switch(errno) {
211 case EACCES:
212 errmsg = _("permission denied for key");
213 break;
214 case EIDRM:
215 errmsg = _("already removed key");
216 break;
217 case ENOENT:
218 errmsg = _("invalid key");
219 break;
220 default:
221 errmsg = _("unknown error in key");
222 break;
224 fprintf(stderr, "%s: %s (%s)\n",
225 prog, errmsg, optarg);
226 continue;
228 } else {
229 /* ids are in decimal */
230 id = strtoul(optarg, NULL, 10);
233 #if 0
234 result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
235 (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
236 semctl(id, 0, IPC_RMID, arg));
237 #endif
238 result = (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
239 ((c == 's') ? semctl(id, 0, IPC_RMID) : -1);
241 if (result < 0) {
242 char *errmsg;
243 error++;
244 switch(errno) {
245 case EACCES:
246 case EPERM:
247 errmsg = iskey
248 ? _("permission denied for key")
249 : _("permission denied for id");
250 break;
251 case EINVAL:
252 errmsg = iskey
253 ? _("invalid key")
254 : _("invalid id");
255 break;
256 case EIDRM:
257 errmsg = iskey
258 ? _("already removed key")
259 : _("already removed id");
260 break;
261 default:
262 errmsg = iskey
263 ? _("unknown error in key")
264 : _("unknown error in id");
265 break;
267 fprintf(stderr, _("%s: %s (%s)\n"),
268 prog, errmsg, optarg);
269 continue;
273 /* print usage if we still have some arguments left over */
274 if (optind != argc) {
275 fprintf(stderr, _("%s: unknown argument: %s\n"),
276 prog, argv[optind]);
277 usage(prog);
280 /* exit value reflects the number of errors encountered */
281 return error;