Fairy
Fairy

Reputation: 111

Invalid argument and Identifier removed error in message queues

I am new to message queues. Basically what I am trying to do here is, I fork and make a user processes. After the fork() I send a message to the user process and wait for a message back from user message. In the actual program I am using while(1) to loop like this with 100 user processes. To make sure I send message and receive message only from one particular user process at a time I used user process PID as the 4th argument in message receive and I make the message type =getpid() when I send the message. I am getting an invalid argument error. I tried to change the permission bits to 0666 but when I do this the program goes in an infinite loop. When the permission is 0777 I get the following result. Here is the minimal working code of what I did. Please excuse the long list of headers.

oss.c

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <sys/wait.h>

//global variables
int shmid;
int msgid;
key_t shmkey;

int currentprocessPID;
int key= 11223344;
void startprocess();

struct mesg_buffer {
    long mesg_type;
    int mesg_text[4];
} message;
/*mesg.text[0]-Stores PID
mesg.text[1]-stores CPU time used by process seconds
mesg.text[2]= stores CPU time used by process nanoseconds
*/

int main(int argc, char **argv)
{
    if((msgid = msgget(key, 0777 | IPC_CREAT))==-1)
        perror("error in msg get");
    printf("going to fork");
                    pid_t pID = fork();
                    if (pID < 0)
                    {
                        perror("Failed to fork:");
                        exit(EXIT_FAILURE);
                    }

                    else if (pID == 0)
                    {
                        static char *args[]={"./user",NULL};
                        int status;
                        if(( status= (execv(args[0], args)))==-1)
                        {
                            perror("oss:failed to execv");
                            exit(EXIT_FAILURE);
                        }
                        else
                            printf("\n message sent to user sucessfully");
                    }

                    currentprocessPID=pID;

                    message.mesg_type = currentprocessPID;
                    if( msgsnd(msgid, &message, sizeof(message), 0)==-1)
                        perror("error in sending message to user process");
                    else
                    {
                        printf("\nmessage sent to process %d",currentprocessPID);

                    }


                if(msgrcv(msgid, &message, sizeof(message), currentprocessPID, 0)==-1)
                    perror("error in recieving message from user process");
                else
                {
                    int corpse,status;
                        while ((corpse = waitpid(message.mesg_text[0], &status, 0)) != message.mesg_text[0] && corpse != -1)
                        {
                            char pmsg[64];
                            snprintf(pmsg, sizeof(pmsg), "logParse: PID %d exited with status 0x%.4X", corpse, status);
                            perror(pmsg);
                        }

                    printf("\n%d process is done with its work",message.mesg_text[0]);
                }

    return 0;
    exit(0);
}

user.c

//copy same headers as above

int shmid;
int key= 11223344;
struct mesg_buffer {
    long mesg_type;
    int mesg_text[4];
} message;
void main()
{
        int pid=getpid();
        printf("\n\nhello from %d",getpid());
        int times=0,timen=0,zero=0,randomnum,timelimit,n=0,sum,i,locals=0,localn=0;

        int msgid = msgget(key, 0666 | IPC_CREAT);
        if(msgid==-1)
            {
            perror("User:error in message get");
            exit(0);
            }
                if(msgrcv(msgid, &message, sizeof(message), pid, 0)==-1)
                {
                    perror("User: Error in receieving message from OSS");
                    exit(0);
                }
                else
                {
                    printf("\nIn User: Data received ");

                        message.mesg_type = pid;
                        message.mesg_text[0]=pid;
                        message.mesg_text[1] = locals;
                        message.mesg_text[2]=localn;
                        message.mesg_text[3]=1;

                        if( msgsnd(msgid, &message, sizeof(message), 0)==-1)
                            perror("error in sending message back to OSS");
                        exit(0);

                }
    exit(0);

}

This is the output that I get:

error in msg get: Permission denied
error in sending message to user process: Invalid argument
error in recieving message from user process: Invalid argument
going to fork

In the actual program which is like 500 lines, I used permission bits 0666. In that program I get a identifier removed error when the user process tries to receive message from oss.

Upvotes: 1

Views: 459

Answers (2)

Fairy
Fairy

Reputation: 111

So after suffering for more than a day (researching for answers) My professor pointed out that I was sending the message to user process before it even had the message queues setup. All I had to do was add sleep(1); after message was sent from oss.

Upvotes: 0

Thomas Padron-McCarthy
Thomas Padron-McCarthy

Reputation: 27632

You probably ran an earlier version of the program where you gave the wrong permissions with IPC_CREAT, or where you forgot to add any permissions at all (making them all zero), and that message queue is still there, with those permissions. I have done this myself a few times. This will give a "Permission denied" error in msgget, and later "Invalid argument" in msgsnd and msgrcv. Try another key.

Remember that a message queue is a permanent thing, similar to a file. Once you have created it, it stays there on your computer until you remove it (or reboot the computer), even after your program has exited.

And another thing: Remember that standard output is line buffered, meaning it doesn't actually print anything until it gets a newline to print, and my advice is to replace all your printf("\nWhatever") with printf("Whatever\n"), otherwise you might not see the output when you expect to see it.

Upvotes: 1

Related Questions