Dlaczego kolejka komunikatów przesyła nieprawidłową wartość? Co robię źle?

0

Wysyłam przez kolejkę liczbę 100, odbieram liczbę 0. Co robię źle? Czego nie doczytałem w manualach? Kod:

mg@mg-K54C ~/wtf $ cat kol.h
#ifndef KOL_H
#define KOL_H

#include <sys/types.h>
#include <sys/ipc.h>

typedef struct
{
  long nr;
  struct d
  {
    long liczba;
  } dane;
} msg_typKomunikatu;

#endif
mg@mg-K54C ~/wtf $ cat wysylacz.c
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stddef.h>

#include "kol.h"

int main()
{
  int kolID = msgget(ftok("./wysylacz", 1), IPC_CREAT);
  
  if(!fork())
    execlp("./odbieracz", "odbieracz", (char *)NULL);
  
  msg_typKomunikatu d; d.nr = 15; d.dane.liczba = 100;
  msgsnd(kolID, &d, sizeof(d.dane), 0);
  
  wait(NULL);
  msgctl(kolID, IPC_RMID, NULL);
}
mg@mg-K54C ~/wtf $ cat odbieracz.c
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>

#include "kol.h"

int main()
{
  int kolID = msgget(ftok("./wysylacz", 1), 0);
  
  msg_typKomunikatu d;
  msgrcv(kolID, &d, sizeof(d.dane), 0, 0);
  
  printf("%lu\n", d.dane.liczba);
}
mg@mg-K54C ~/wtf $ gcc -o wysylacz -std=gnu11 wysylacz.c
mg@mg-K54C ~/wtf $ gcc -o odbieracz -std=gnu11 odbieracz.c
mg@mg-K54C ~/wtf $ ./wysylacz
0
mg@mg-K54C ~/wtf $
1
sizeof(d.dane)

Jesteś pewien?

0

Raczej tak.

Cytując man msgop:

The msgp argument is a pointer to caller-defined structure of the fol‐
lowing general form:

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

   The  mtext  field is an array (or other structure) whose size is speci‐
   fied by msgsz, a nonnegative integer value.

EDIT: A swoją definicję struktury msg_typKomunikatu uzasadniam tym: http://tldp.org/LDP/lpg/node30.html

0
&d, sizeof(d.dane)

Nadal jesteś pewien?

0

Albo coś mnie zamroczyło, albo nie wiem.

Przecież manual pisze wyraźnie, że należy podać rozmiar nie całej struktury, ale konkretnie tej jej części, która zostanie zcastowana na mtext.

EDIT: I jeszcze z http://tldp.org/LDP/lpg/node35.html#SECTION00742400000000000000 :

The first argument to msgsnd is our queue identifier, returned by a previous call to msgget. The second argument, msgp, is a pointer to our redeclared and loaded message buffer. The msgsz argument contains the size of the message in bytes, excluding the length of the message type (4 byte long).

0

No zamroczyło Cię (i nie słuchasz @twonek):

&d, sizeof(d.dane)

Bo podajesz adres całej struktury, a rozmair tylko jej części ;)
Więc albo:

&d, sizeof(d)

albo

&d.dane, sizeof(d.dane)
0

No cóż, pozostaje debuggować, czyli sprawdzić kolID w jednym i drugim przypadku. Wyświetlić sizeof(d.dane) i to co msgrcv() zwraca.

0

MAM!!!

Należało zamienić:
int kolID = msgget(ftok("./wysylacz", 1), IPC_CREAT);

Np. na:
int kolID = msgget(ftok("./wysylacz", 1), IPC_CREAT | S_IRWXU);
(do takiego specyfikowania uprawnień potrzebne jest #include <sys/stat.h>)

Tworzyłem kolejkę, a nie dawałem sobie uprawnień do pisania do niej ani czytania z niej ;P
Dlatego zarówno msgsnd() jak i msgrcv() wywalało się ustawiając errno na Permission denied.
A struktura w odbieraczu była w ogóle niezainicjowana.

1 użytkowników online, w tym zalogowanych: 0, gości: 1