分享

IPC keys and permissions

 昵称11438445 2013-01-06

IPC keys and permissions

I thought this issue had been cleared in the tutorials, but it seems there are
still problems.

The correct (portable) way to specify the access permission flags when
creating an IPC (with shmget(2), msgget(2), semget(2)) is to bitwise OR the
permission constants defined in the headers. I just checked, and they happen
to be equal to the permission bits for files, but you shouldn't rely on this -
and your source will be much more readable if you use them.

The constants are:

For semaphores (from sys/sem.h)

#define SEM_A   0200    /* alter permission */
#define SEM_R   0400    /* read permission */

For message queues (from sys/msg.h)

#define MSG_R   0400    /* read permission */
#define MSG_W   0200    /* write permission */

For shared memory (from sys/shm.h)

#define SHM_R   0400    /* read permission */
#define SHM_W   0200    /* write permission */
Moreover, you should generate IPC keys correctly: just putting a "#define KEY 0100" and hoping for the best is not enough. You should make sure that no unrelated processes access your IPCs. So - if your IPC are used by processes related by a fork() (parent-children-grandchildren...) use IPC_PRIVATE as the key - if your IPC are used by proceses without a common ancestor, or if you just want to be fancy, create a file in a directory of your own, % touch /my/private/idaho/myfile make sure the directory is not searchable by the rest of the world % chmod a-x /my/private/idaho In your source, generate a key using ftok(3), passing to it the full path of that file. key_t mykey=ftok("/my/private/idaho/myfile", 'a') use the same file, but different values of the second argument to ftok(3), the character, to get different keys. And don't forget that: #define BEING_FANCY_WITHOUT_A_GOOD_REASON "Foolish" Examples: #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/msg.h> /* A record in a shared memory area */ typedef struct foobar { int a,b; } Foobar; /* semaphore wait */ void semwait(int id) { struct sembuf buf; buf.sem_num=0; buf.sem_op=-1; buf.sem_flg=0; if (-1==semop(id, &buf, 1)) { perror("semop"); exit(1); } } /* semaphore signal */ void semsignal(int id) { struct sembuf buf; buf.sem_num=0; buf.sem_op=+1; buf.sem_flg=0; if (-1==semop(id, &buf, 1)) { perror("semop"); exit(1); } } /* a message structure */ typedef char Msgtxt[20]; typedef struct _message { long type; Msgtxt s; } Message; int main(int argc, char *argv[]) { int shid=0; int semid; int qid; int i, j; Foobar *blah; union semun un; Message msg = {1, "blahblah"}; Message rcv; /* Get a private message queue */ if (-1==(qid=msgget(IPC_PRIVATE, MSG_R|MSG_W))) { perror("msgget"); exit(1); } /* Send a message to yourself */ if (-1==msgsnd(qid, &msg, sizeof(Msgtxt), 0)) { perror("msgsnd"); exit(1); } /* Receive it, print results */ if (-1==msgrcv(qid, &rcv, sizeof(Msgtxt), 1, 0)) { perror("msgrcv"); exit(1); } printf("rcv: %d - %s\n\n",rcv.type, rcv.s); sleep(3); /* Get a semaphore to protect shared memory area */ if (-1==(semid=semget(IPC_PRIVATE, 1, SEM_R|SEM_A))) { perror("semget"); exit(1); } /* Initialize it */ un.val=1; if (-1==semctl(semid, 0, SETVAL, un)) { perror("semctl-1"); exit(1); } /* Get shared memory area */ if (-1==(shid=shmget(IPC_PRIVATE, 10*sizeof(Foobar), SHM_R|SHM_W))) { perror("shmget"); exit(1); } /* Attach it */ if (-1==(blah=(Foobar *)shmat(shid, 0, 0))) { perror("shmat"); exit(1); } /* Fork off a child, write and read something // in the shared aread both in parent and in child */ if (!fork()) { fprintf(stderr, "Hiya this is my dear child person\n"); for (j=0; j<10; j++) { semwait(semid); for (i=0; i<10; i++) { blah[i].a=blah[i].b=2; } semsignal(semid); sleep(1); /* Otherwise it exits too soon */ semwait(semid); for (i=0; i<10; i++) { fprintf(stderr, "\ta %d b %d\n", blah[i].a, blah[i].b); } semsignal(semid); } exit(0); } /* Do the same in the parent */ for (j=0; j<10; j++) { semwait(semid); for (i=0; i<10; i++) { blah[i].a=blah[i].b=1; } semsignal(semid); sleep(1); semwait(semid); for (i=0; i<10; i++) { fprintf(stderr, "a %d b %d\n", blah[i].a, blah[i].b); } semsignal(semid); } /* Be a good girl/boy: CLEAN AFTER YOURSELF */ wait(NULL); /* Detach and clear shmem */ if (-1==shmdt((void*)blah)) { perror("shmdt"); exit(1); } if (-1==shmctl(shid, IPC_RMID, NULL)) { perror("shctl"); exit(1); } /* Clear sem */ if (-1==semctl(semid, 1, IPC_RMID, un)) { perror("semctl-2"); exit(1); } /* Clear msgq */ if (-1==msgctl(qid, IPC_RMID, NULL)) { perror("msgctl"); exit(1); } return 0; }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多