10f66f451Sopenharmony_ci/* ipcrm.c - remove msg que, sem or shared memory
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2014 Ashwini Kumar <ak.ashwini1981@gmail.com>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ipcrm.html
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ci
80f66f451Sopenharmony_ciUSE_IPCRM(NEWTOY(ipcrm, "m*M*s*S*q*Q*", TOYFLAG_USR|TOYFLAG_BIN))
90f66f451Sopenharmony_ci
100f66f451Sopenharmony_ciconfig IPCRM
110f66f451Sopenharmony_ci  bool "ipcrm"
120f66f451Sopenharmony_ci  default n
130f66f451Sopenharmony_ci  help
140f66f451Sopenharmony_ci    usage: ipcrm [ [-q msqid] [-m shmid] [-s semid]
150f66f451Sopenharmony_ci              [-Q msgkey] [-M shmkey] [-S semkey] ... ]
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    -mM Remove memory segment after last detach
180f66f451Sopenharmony_ci    -qQ Remove message queue
190f66f451Sopenharmony_ci    -sS Remove semaphore
200f66f451Sopenharmony_ci*/
210f66f451Sopenharmony_ci
220f66f451Sopenharmony_ci#define FOR_ipcrm
230f66f451Sopenharmony_ci#include "toys.h"
240f66f451Sopenharmony_ci#include <sys/ipc.h>
250f66f451Sopenharmony_ci#include <sys/shm.h>
260f66f451Sopenharmony_ci#include <sys/sem.h>
270f66f451Sopenharmony_ci#include <sys/msg.h>
280f66f451Sopenharmony_ci
290f66f451Sopenharmony_ciGLOBALS(
300f66f451Sopenharmony_ci  struct arg_list *qkey;
310f66f451Sopenharmony_ci  struct arg_list *qid;
320f66f451Sopenharmony_ci  struct arg_list *skey;
330f66f451Sopenharmony_ci  struct arg_list *sid;
340f66f451Sopenharmony_ci  struct arg_list *mkey;
350f66f451Sopenharmony_ci  struct arg_list *mid;
360f66f451Sopenharmony_ci)
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_cistatic void do_ipcrm(int key, int ipc, char *name)
390f66f451Sopenharmony_ci{
400f66f451Sopenharmony_ci  char *c;
410f66f451Sopenharmony_ci  int id, ret = 0;
420f66f451Sopenharmony_ci
430f66f451Sopenharmony_ci  id = strtol(name, &c, 0);
440f66f451Sopenharmony_ci  if (*c) {
450f66f451Sopenharmony_ci    error_msg("invalid number :%s", name);
460f66f451Sopenharmony_ci    return;
470f66f451Sopenharmony_ci  }
480f66f451Sopenharmony_ci
490f66f451Sopenharmony_ci  if (key) {
500f66f451Sopenharmony_ci    if (id == IPC_PRIVATE) {
510f66f451Sopenharmony_ci      error_msg("illegal key (%s)", name);
520f66f451Sopenharmony_ci      return;
530f66f451Sopenharmony_ci    }
540f66f451Sopenharmony_ci    id = ((ipc == 1)?shmget(id, 0, 0) :
550f66f451Sopenharmony_ci         (ipc == 2)? msgget(id, 0): semget(id, 0, 0));
560f66f451Sopenharmony_ci    if (id < 0) {
570f66f451Sopenharmony_ci      perror_msg("key (%s)", name);
580f66f451Sopenharmony_ci      return;
590f66f451Sopenharmony_ci    }
600f66f451Sopenharmony_ci  }
610f66f451Sopenharmony_ci
620f66f451Sopenharmony_ci  if (ipc == 1) ret = shmctl(id, IPC_RMID, NULL);
630f66f451Sopenharmony_ci  else if (ipc == 2) ret = msgctl(id, IPC_RMID, NULL);
640f66f451Sopenharmony_ci  else if (ipc == 3) ret = semctl(id, 0, IPC_RMID, NULL);
650f66f451Sopenharmony_ci
660f66f451Sopenharmony_ci  if (ret < 0) perror_msg("%s (%s)", ((key)? "key": "id"), name);
670f66f451Sopenharmony_ci}
680f66f451Sopenharmony_ci
690f66f451Sopenharmony_civoid ipcrm_main(void)
700f66f451Sopenharmony_ci{
710f66f451Sopenharmony_ci  ++toys.argv;
720f66f451Sopenharmony_ci  if (toys.optc && (!strcmp(*toys.argv, "shm") ||
730f66f451Sopenharmony_ci        !strcmp(*toys.argv, "sem") || !strcmp(*toys.argv, "msg"))) {
740f66f451Sopenharmony_ci    int t = (toys.argv[0][1] == 'h')? 1 : (toys.argv[0][1] == 's')? 2:3;
750f66f451Sopenharmony_ci
760f66f451Sopenharmony_ci    while (*(++toys.argv)) do_ipcrm(0, t, *toys.argv);
770f66f451Sopenharmony_ci  } else {
780f66f451Sopenharmony_ci    struct arg_list *tmp;
790f66f451Sopenharmony_ci
800f66f451Sopenharmony_ci    for (tmp = TT.mkey; tmp; tmp = tmp->next) do_ipcrm(1, 1, tmp->arg);
810f66f451Sopenharmony_ci    for (tmp = TT.mid; tmp; tmp = tmp->next) do_ipcrm(0, 1, tmp->arg);
820f66f451Sopenharmony_ci    for (tmp = TT.qkey; tmp; tmp = tmp->next) do_ipcrm(1, 2, tmp->arg);
830f66f451Sopenharmony_ci    for (tmp = TT.qid; tmp; tmp = tmp->next) do_ipcrm(0, 2, tmp->arg);
840f66f451Sopenharmony_ci    for (tmp = TT.skey; tmp; tmp = tmp->next) do_ipcrm(1, 3, tmp->arg);
850f66f451Sopenharmony_ci    for (tmp = TT.sid; tmp; tmp = tmp->next) do_ipcrm(0, 3, tmp->arg);
860f66f451Sopenharmony_ci    if (toys.optc) help_exit("unknown argument: %s", *toys.optargs);
870f66f451Sopenharmony_ci  }
880f66f451Sopenharmony_ci}
89