1

I am trying to write a C++ program to delete the shared memory segments. I know it can be done from cmd prompt using

ipcs -m | awk '{ print $2 }' | xargs ipcrm -m

But I am trying to do it using C++ so that I create a shared memory garbage collector.

The idea is to delete shared memory segments that are not attached to any process( nattach ==0) or the status == NULL

genpfault
  • 51,148
  • 11
  • 85
  • 139
venuktan
  • 1,649
  • 2
  • 14
  • 29

4 Answers4

5

I finally have the the answer to my own question. It can be done using shmctl flags. shmctl(0,SHM_INFO,&shm_info); gives number of segments currently present.

shmctl(i , SHM_STAT , &shm_segment) gives the segment id

it can also be accessed by shm_segment.shm_id

#include <sys/shm.h>     

int delete_segment(int seg_id){
    if ((shmctl(seg_id,IPC_RMID,0))==-1){
    std::cout<<" ERROR(C++)with shmctl(IPC_RMID): "<<strerror(errno)<<std::endl;
    return -1;
    }else//on success
        return 0;
}

void clean_segments(){

    struct shmid_ds shm_info;
    struct shmid_ds shm_segment;
    int max_id = shmctl(0,SHM_INFO,&shm_info);
    if (max_id>=0){
        for (int i=0;i<=max_id;++i) {
                int shm_id = shmctl(i , SHM_STAT , &shm_segment);
                if (shm_id<=0)
                    continue;
                else if (shm_segment.shm_nattch==0){
                    delete_segment(shm_id);
                }
        }
    }
    return result;
}
venuktan
  • 1,649
  • 2
  • 14
  • 29
2

According to a source code of the ipcrm, it calls shmctl.

shmctl(id, IPC_RMID, NULL)
kamae
  • 1,825
  • 1
  • 16
  • 21
  • Yes, I know `shmctl(id, IPC_RMID, NULL)` but it only works if you have the segment ids. I need to be able to get a list of all current segment ids an check if there are any processes that are attached to it and check if they are active and delete the non active once's – venuktan Mar 03 '12 at 04:02
1

I would suggest executing strace ipcrm -m <your-arguments> and see what system calls it performs. In most cases that should be suficient (at least it will point you in the right direction), if not - look at the source code of ipcrm. I'm pretty sure you do not need any special privileges (ipcrm on my system does not have SUID or SGID bits set).

sirgeorge
  • 6,331
  • 1
  • 28
  • 33
0

The code below use I:

    void clean_segments(int startId, int endId) {
    for (int i=startId; i<=endId; ++i) {
        struct shmid_ds shm_segment;
        int shm_id = shmctl(i, SHM_STAT, &shm_segment);
        delete_segment(shm_id);
        printf("Segment %d has been deleted\n", shm_id);
    }}

clean_segments(1146894, 6357160);// example of using the code above