How to fix the error Permission denied while using msgrcv in C

227 views Asked by At

I want to make a programm in C that receive a message from messaging queue. I have the existing code here :

typedef struct {
    long id;
    char mes[20];
} message;

int main() {
    
    key_t cle = ftok(".",0);
    
    if(cle == -1){
        perror("ftok");
        return -1;
    }
    
    int msqId = msgget(cle, IPC_CREAT | IPC_EXCL ) ;
    if (msqId == -1) {
        msqId = msgget(cle, IPC_EXCL);
        if (msqId == -1) {
            perror("msgget");
            return -1;
        }
    }

    message mes;

    while (1) {
        int received = msgrcv(msqId, &mes, sizeof(message)-sizeof(long), 0, 0);
        
        if(received == -1){
            perror("msgrcv");
            return -1;
        }
        
        printf ("Server: message received.\n");
    }

    return 0;
}

And it gives me the following error : msgrcv: Permission denied

I also tried changing the path of ftok with : "/tmp", "/etc/passwd"

2

There are 2 answers

1
jpa On
int msqId = msgget(cle, IPC_CREAT | IPC_EXCL ) ;

The argument to msgget determines the permissions it is created with. This is a mode number, which can be specified in octal as e.g. 0600 to give read and write permissions to the current user. Alternatively the constant S_IRWXU (which equals 0700) could be used to do the same:

int msqId = msgget(cle, IPC_CREAT | IPC_EXCL | S_IRWXU ) ;

You may want to add a debug print after the msgget() call to know whether it created a new queue (using the permissions you give), or found an existing queue (which has the permissions specified when it was created).

0
TheHangel On

The problem was: IP_EXCL (and also the permission)

In order to make this code works, I replaced

int msqId = msgget(cle, IPC_CREAT | IPC_EXCL ) ;
    if (msqId == -1) {
        msqId = msgget(cle, IPC_EXCL);
        if (msqId == -1) {
            perror("msgget");
            return -1;
        }
    }

with

int msqId = msgget(cle, IPC_CREAT | 0700 ) ;
    if (msqId == -1) {
       perror("msgget");
       return -1;
    }