summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-10-05 13:58:55 -0400
committerJakob Kaivo <jkk@ung.org>2020-10-05 13:58:55 -0400
commit4000d4f81c877beb5c1d11c09f3c517c4a94feee (patch)
tree75117e60c0a73d6776c7826ceeac32921219d8fa
first draft
-rw-r--r--ipcrm.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/ipcrm.c b/ipcrm.c
new file mode 100644
index 0000000..6dca2b8
--- /dev/null
+++ b/ipcrm.c
@@ -0,0 +1,160 @@
+/*
+ * UNG's Not GNU
+ *
+ * Copyright (c) 2019, Jakob Kaivo <jkk@ung.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define _XOPEN_SOURECE 700
+#include <errno.h>
+#include <locale.h>
+#include <search.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <unistd.h>
+
+typedef enum { MSGID, SHMID, SEMID, MSGKEY, SHMKEY, SEMKEY } ipc_type;
+
+struct ipcrm {
+ struct ipcrm *next;
+ struct ipcrm *prev;
+ ipc_type type;
+ const char *id;
+};
+
+static struct ipcrm *ipcrm_q(ipc_type t, const char *id, struct ipcrm *head)
+{
+ struct ipcrm *add = calloc(1, sizeof(*add));
+ if (add == NULL) {
+ perror("ipcrm");
+ return NULL;
+ }
+ add->type = t;
+ add->id = id;
+ /* TODO: do ID translation and error checking at this point */
+
+ if (head == NULL) {
+ return add;
+ }
+
+ struct ipcrm *tail = head;
+ while (tail && tail->next) {
+ tail = tail->next;
+ }
+ insque(add, tail);
+
+ return head;
+}
+
+static int ipcrm(struct ipcrm *ipc)
+{
+ int id = atoi(ipc->id);
+ int ret = 0;
+
+ switch (ipc->type) {
+ case MSGID:
+ ret = msgctl(id, IPC_RMID, NULL);
+ break;
+
+ case MSGKEY:
+ /* TODO */
+ break;
+
+ case SEMID:
+ ret = semctl(id, 0, IPC_RMID);
+ break;
+
+ case SEMKEY:
+ /* TODO */
+ break;
+
+ case SHMID:
+ ret = shmctl(id, IPC_RMID, NULL);
+ break;
+
+ case SHMKEY:
+ /* TODO */
+ break;
+ }
+
+ if (ret == -1) {
+ fprintf(stderr, "ipcrm: %s: %s\n", ipc->id, strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ setlocale(LC_ALL, "");
+
+ int c;
+ int ret = 0;
+ struct ipcrm *list = NULL;
+
+ while ((c = getopt(argc, argv, "q:Q:s:S:m:M:")) != -1) {
+ switch(c) {
+ case 'q':
+ list = ipcrm_q(MSGID, optarg, list);
+ break;
+
+ case 'Q':
+ list = ipcrm_q(MSGKEY, optarg, list);
+ break;
+
+ case 's':
+ list = ipcrm_q(SEMID, optarg, list);
+ break;
+
+ case 'S':
+ list = ipcrm_q(SEMKEY, optarg, list);
+ break;
+
+ case 'm':
+ list = ipcrm_q(SHMID, optarg, list);
+ break;
+
+ case 'M':
+ list = ipcrm_q(SHMKEY, optarg, list);
+ break;
+
+ default:
+ return 1;
+ }
+
+ if (list == NULL) {
+ return 1;
+ }
+ }
+
+ while (list) {
+ printf("remove '%s' (%d)\n", list->id, list->type);
+ ret |= ipcrm(list);
+ list = list->next;
+ }
+
+ return ret;
+}