title: IPC_RMID not work on linux with C++
body: <p>I'm trying to solve my school project in C++. I have to create 15 processes and they have to run in order what means that processes run in this order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 0. It work but when I try to remove semaphore from the memory I am getting error from semctl. On the end I use "semctl(semid, 0, IPC_RMID, 0" but I get error 22 which means EINVAL but it doesn't make sense and I try to remove semaphore from parrent process so I should have privileges to do that.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/ipc.h&gt;
  #include &lt;sys/sem.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;sys/wait.h&gt;
  
  union semun {
              int val;
              struct semid_ds *buf;
              ushort *array;
                   };
  struct sembuf sops[1];
  int semid;
  
   int wait_sem(int index, int pid){
         fprintf(stderr, "\n------- Proces %d do operation wait (-1) on semaphore %d\n",pid, index);
                    sops[0].sem_num = index;
                    sops[0].sem_op = -1;
                    sops[0].sem_flg = 0 ;
       if  (semop(semid, sops, 1)&lt;0){
               perror("semop fail wait");
               return 1;
           }
           else
               return 0;
    }
  
   int signal_sem(int index, int pid){
        fprintf(stderr, "\n++++++ Proces %d vykonava operaciu signal (1) na semafore %d\n",pid,index);
              sops[0].sem_num = index;
              sops[0].sem_op = 1;
              sops[0].sem_flg = 0;
       if  (semop(semid, sops, 1)&lt;0){
              perror("semop fail signal");
              return 1;
           }
           else
              return 0;
    }
  
   void createSem(key_t paKey, int paSemFlg, int paNsems)
   {
       printf ("uid=%d euid=%d\n", (int) getuid (), (int) geteuid ());
       (semid = semget(paKey, paNsems, paSemFlg));
  
  
       for (int i = 0; i &lt; paNsems; ++i) {
           semctl(semid, i, SETVAL, 0);
       }
   }
  
   void kic()
   {
       printf("\naaaaaaaaaaaaaa\n");
   }
  
   int  main() {
  
            key_t key = 1234;
            int semflg = IPC_CREAT | 0666;
            int nsems = 15;
            int semid;
            fprintf(stderr, "%d=", sops);
            createSem(IPC_PRIVATE, semflg, nsems);
          if (semid == -1) {
              perror("semget: semget failed");
          return 1;
          }
          else
              fprintf(stderr, "semget: semget sucess: semid = %d, parrent pid %d\n", semid, getpid());
  
  
     int PROCESS_ID = 0;
     pid_t PID;
  
     for (int i = 1; i &lt; nsems; i++) {
         PID = fork();
         if(PID == 0)
         {
             PROCESS_ID = i;
             break;
         }
     }
  
     if(PID == -1)
     {
         printf("\nPID ERROR");
     }
  
     if(PID != 0) //parrent
     {
         printf("\n\nparrent with ID %d", PROCESS_ID);
         signal_sem(PROCESS_ID+1, PROCESS_ID);
         wait_sem(PROCESS_ID, PROCESS_ID);
         printf ("uid=%d euid=%d\n", (int) getuid (), (int) geteuid ());
         printf("\nEND %d\n", getpid());
         int s;
         wait(&amp;s);
  
         if((semctl(semid, 0, IPC_RMID, 0))==-1)
         {
             int a = errno;
             printf("\nERROR IPC_RMID %d\n", a);
         }
     }
  
     if(PID == 0)//child
     {
         if(wait_sem(PROCESS_ID, PROCESS_ID) == 0){
             printf("\nI am child with ID %d", PROCESS_ID);
             int ID_NEXT_PROCESS = 1+PROCESS_ID;
             if(ID_NEXT_PROCESS == nsems)
                 ID_NEXT_PROCESS = 0;
             signal_sem(ID_NEXT_PROCESS, PROCESS_ID);
             return 0;
         }
  
     }
      return 0;
    }
  </code></pre>