Upload Tizen:Base source
[framework/base/util-linux-ng.git] / sys-utils / ipcrm.c
1 /*
2  * krishna balasubramanian 1993
3  *
4  * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
5  * - added Native Language Support
6  *
7  * 1999-04-02 frank zago
8  * - can now remove several id's in the same call
9  *
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16
17 #include <sys/types.h>
18 #include <sys/ipc.h>
19 #include <sys/shm.h>
20 #include <sys/msg.h>
21 #include <sys/sem.h>
22 #include "nls.h"
23
24 /* for getopt */
25 #include <unistd.h>
26 /* for tolower and isupper */
27 #include <ctype.h>
28
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;
38 };
39 #endif
40
41 static void usage(char *);
42
43 char *execname;
44
45 typedef enum type_id {
46         SHM,
47         SEM,
48         MSG
49 } type_id;
50
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;
58
59         arg.val = 0;
60
61         while(argc) {
62
63                 id = strtoul(argv[0], &end, 10);
64
65                 if (*end != 0) {
66                         printf (_("invalid id: %s\n"), argv[0]);
67                         nb_errors ++;
68                 } else {
69                         switch(type) {
70                         case SEM:
71                                 ret = semctl (id, 0, IPC_RMID, arg);
72                                 break;
73
74                         case MSG:
75                                 ret = msgctl (id, IPC_RMID, NULL);
76                                 break;
77                                 
78                         case SHM:
79                                 ret = shmctl (id, IPC_RMID, NULL);
80                                 break;
81                         }
82
83                         if (ret) {
84                                 printf (_("cannot remove id %s (%s)\n"),
85                                         argv[0], strerror(errno));
86                                 nb_errors ++;
87                         }
88                 }
89                 argc--;
90                 argv++;
91         }
92         
93         return(nb_errors);
94 }
95
96 static void deprecate_display_usage(void)
97 {
98         usage(execname);
99         printf (_("deprecated usage: %s {shm | msg | sem} id ...\n"),
100                 execname);
101 }
102
103 static int deprecated_main(int argc, char **argv)
104 {
105         execname = argv[0];
106
107         if (argc < 3) {
108                 deprecate_display_usage();
109                 exit(1);
110         }
111         
112         if (!strcmp(argv[1], "shm")) {
113                 if (remove_ids(SHM, argc-2, &argv[2]))
114                         exit(1);
115         }
116         else if (!strcmp(argv[1], "msg")) {
117                 if (remove_ids(MSG, argc-2, &argv[2]))
118                         exit(1);
119         } 
120         else if (!strcmp(argv[1], "sem")) {
121                 if (remove_ids(SEM, argc-2, &argv[2]))
122                         exit(1);
123         }
124         else {
125                 deprecate_display_usage();
126                 printf (_("unknown resource type: %s\n"), argv[1]);
127                 exit(1);
128         }
129
130         printf (_("resource(s) deleted\n"));
131         return 0;
132 }
133
134
135 /* print the new usage */
136 static void
137 usage(char *progname)
138 {
139         fprintf(stderr,
140                 _("usage: %s [ [-q msqid] [-m shmid] [-s semid]\n"
141                   "          [-Q msgkey] [-M shmkey] [-S semkey] ... ]\n"),
142                 progname);
143 }
144
145 int main(int argc, char **argv)
146 {
147         int   c;
148         int   error = 0;
149         char *prog = argv[0];
150
151         /* if the command is executed without parameters, do nothing */
152         if (argc == 1)
153                 return 0;
154
155         setlocale(LC_ALL, "");
156         bindtextdomain(PACKAGE, LOCALEDIR);
157         textdomain(PACKAGE);
158
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);
165
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);
171
172                 /* needed to delete semaphores */
173                 union semun arg;
174                 arg.val = 0;
175
176                 /* we don't need case information any more */
177                 c = tolower(c);
178
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;
186                 }
187
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;
196                         }
197
198                         /* convert key to id */
199                         id = ((c == 'q') ? msgget(key, 0) :
200                               (c == 'm') ? shmget(key, 0, 0) :
201                               semget(key, 0, 0));
202
203                         if (id < 0) {
204                                 char *errmsg;
205                                 error++;
206                                 switch(errno) {
207                                 case EACCES:
208                                         errmsg = _("permission denied for key");
209                                         break;
210                                 case EIDRM:
211                                         errmsg = _("already removed key");
212                                         break;
213                                 case ENOENT:
214                                         errmsg = _("invalid key");
215                                         break;
216                                 default:
217                                         errmsg = _("unknown error in key");
218                                         break;
219                                 }
220                                 fprintf(stderr, "%s: %s (%s)\n",
221                                         prog, errmsg, optarg);
222                                 continue;
223                         }
224                 } else {
225                         /* ids are in decimal */
226                         id = strtoul(optarg, NULL, 10);
227                 }
228
229                 result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
230                           (c == 'm') ? shmctl(id, IPC_RMID, NULL) : 
231                           semctl(id, 0, IPC_RMID, arg));
232
233                 if (result < 0) {
234                         char *errmsg;
235                         error++;
236                         switch(errno) {
237                         case EACCES:
238                         case EPERM:
239                                 errmsg = iskey
240                                         ? _("permission denied for key")
241                                         : _("permission denied for id");
242                                 break;
243                         case EINVAL:
244                                 errmsg = iskey
245                                         ? _("invalid key")
246                                         : _("invalid id");
247                                 break;
248                         case EIDRM:
249                                 errmsg = iskey
250                                         ? _("already removed key")
251                                         : _("already removed id");
252                                 break;
253                         default:
254                                 errmsg = iskey
255                                         ? _("unknown error in key")
256                                         : _("unknown error in id");
257                                 break;
258                         }
259                         fprintf(stderr, _("%s: %s (%s)\n"),
260                                 prog, errmsg, optarg);
261                         continue;
262                 }
263         }
264
265         /* print usage if we still have some arguments left over */
266         if (optind != argc) {
267                 fprintf(stderr, _("%s: unknown argument: %s\n"),
268                         prog, argv[optind]);
269                 usage(prog);
270         }
271
272         /* exit value reflects the number of errors encountered */
273         return error;
274 }