J. G.
J. G.

Reputation: 57

problems with messages queue

this program should create a fixed number of childs (30), and these threads should communicate each other for purposes that maybe I can explain after. occurs the error 22: invalid arguments both on msgsnd and msgrcv lines. sorry this is the first time I try to use the messages queues in C

for now I want that the father first send to child a message about a preference number, every child should receive it and write in the array called vettorestudenti this info. before starting do other things I have to fix this

there is a test code at the beginning in the define area:



there are some structs:
 struct dati{
        pid_t sender;
        int preferenza;// the father writes a preference number in a queue that should be read by children threads
    };
    struct msgbuf {
            long mtype; //pid destinatario 
            struct dati msglist;

        };
 struct tipostudente { //array that contains info about child process

    int matricola; // ID
    int voto_AdE; //student mark
    int numeroinviti; //number of invitations
    int preferenzaGruppo; // preference
    };
    pid_t *studenti;
//FOLLOW UPDATED CODE
 struct msgbuf coda[POP_SIZE];
    int queue_id = msgget(MY_KEY, IPC_CREAT | IPC_EXCL| 0666);
    if(queue_id==-1)
    { perror("error msgget"); }

many rows after
 /* vector of kids PIDs */
    studenti = malloc(POP_SIZE*sizeof(*studenti));
for(int u=0; u<POP_SIZE; u++)
        {
            coda[u].mtype=studenti[u];// qui il pid del destinatario
            coda[u].msglist.preferenza= funzionesceltaGrp();
            printf("funzpref22 %d  and studenti[u]= %lu \n",coda[u].msglist.preferenza, coda[u].mtype);
            if (msgsnd(queue_id, &coda[u], sizeof(coda[u])-sizeof(long), 0) == -1) 
            {

                perror("error msgsnd"); //INVALID ARGUMENT ERROR HERE

            }

        }


    for (i=0; i<POP_SIZE; i++) {//POP_SIZE volte esegue la fork
        switch (studenti[i] = fork()) {
        case -1:
            /* Handle error */
            fprintf(stderr, "%s, %d: Errore (%d) nella fork\n",
                __FILE__, __LINE__, errno);
            exit(EXIT_FAILURE);
        case 0: 
            srand(getpid());
            vettorestudenti[i].matricola=rand()%999999; 

            if (msgrcv(queue_id, &coda[i], sizeof(coda[i])-sizeof(long),0, 0) == -1) 
            {

                perror("error msgrcv"); //INVALID ARGUMENT ERROR HERE
            }
            printf("messaggio ricevuto, sono lo studente %d \n",vettorestudenti[i].matricola);




            free(studenti); 
            exit(0); 

            break; //FINE CODICE STUDENTE
        default:
            //codice del padre 


            break;  

        }
    }

Upvotes: 0

Views: 522

Answers (1)

Andrew Henle
Andrew Henle

Reputation: 1

You are misusing errno. You are assuming if it has a non-zero value it indicates an error, which is not true. errno merely indicates what the error was after an actual error condition was returned from a library function. In the absence of positive error indication by other means, the value of errno itself is meaningless.

See 7.5 Errors , paragraph 4 of the C standard:

The value of errno in the initial thread is zero at program startup (the initial value of errno in other threads is an indeterminate value), but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.

For example:

int queue_id = msgget(MY_KEY, IPC_CREAT | IPC_EXCL| 0666);
TEST_ERROR;

That code assumes a non-zero value for errno indicates an error. It does not. Per the POSIX msgget() documentation:

RETURN VALUE

Upon successful completion, msgget() shall return a non-negative integer, namely a message queue identifier. Otherwise, it shall return -1 and set errno to indicate the error.

errno's only use after msgget() is to indicate what error happened if and only if msgget() has already returned -1.

Upvotes: 5

Related Questions