msgget message queue always get permission denied

I want to use msgget() to obtain a message queue between two processes, here is my code:
the first one create the mq, the second one open it and add a message to it. But when I execute the second one, I get permission denied. I've already desperately tried everything I can think of to solve this problem. I even manually change the mode of the mq. But all I get is still permission denied. Somebody please help me.....:wall:

struct mymsg
{
        long mtype ;
        char data[1000] ;
};

int main()
{
        int msqid ;
        int* nod ;
        struct mymsg msg ;
        struct msqid_ds msgds ;
        key_t key ;
        key = ftok("/home/tefino/Documents/APUE_exercise/IPC/ipc",1) ;
        perror(NULL) ;
        msqid = msgget(key,O_RDWR|IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) ;
        perror(NULL) ;
        msgctl(msqid, IPC_STAT, &msgds) ;
        msgds.msg_perm.mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH ;
        msgctl(msqid, IPC_SET, &msgds) ;
        msgrcv(fd,&msg, 1000, 0,  0) ;
        perror(NULL) ;
        printf("%s\n", msg.data) ;
}
struct mymsg
{
        long mtype ;
        char data[1000] ;
};

int main()
{
        int msqid ;
        key_t key ;
        struct mymsg msg ;
        key = ftok("/home/tefino/Documents/APUE_exercise/IPC/ipc",1) ;
        gets(msg.data) ;
        msqid = msgget(key, O_WRONLY) ;
        perror(NULL) ;
        struct msqid_ds mds ;
        msgctl(msqid, IPC_STAT, &mds) ;
        mds.msg_perm.mode = S_IWUSR|S_IRUSR ;
        msgctl(msqid, IPC_SET, &mds) ;


        msgsnd(msqid, &msg, 1000, 0) ;
        perror(NULL) ;
}

There are many problems with your code. So let's start with the beginning and move towards a working solution.

First, you should always check the returned code from a system call, It it fails, prints error (e.g. using perror()) and immediately exits. This gives you the opportunity to fix right away the problem instead of continuing with some error condition.

This is for instance the case in your first program with ftok(). If this calls fails, you continue creating a queue with Id -1 (0xffffffff) . As quoted in the man page:

Make sure that you fixed the points mentioned above. If you still have problems, we shall work them on.

Greets,
/Lew

You need to start checking return values. You may not have been noticing that your second program wasn't even opening the queue at all...

The sender program should open it with O_RDWR as well.

You don't need to use the torturous individual flags for permissions when you create the queue. Just ... | 0666 suffices.

---------- Post updated at 09:36 AM ---------- Previous update was at 09:26 AM ----------

Once it's opened, you get 'invalid argument' when sending, because:

// from man page
           struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };