Newsgroup: it.comp.os.linux.development
Titolo: [help] memcpy

Nella man page di ipq_get_packet si legge:
       typedef struct ipq_packet_msg {
         ...
       	 size_t data_len;
	 ...
       } ipq_packet_msg_t;
       Each of these fields may be read by the  application.   If
       the  queue  mode is IPQ_COPY_PACKET and the data_len value
       is greater than zero, the packet payload contents may  be
       accessed  in  the  memory  following  the ipq_packet_msg_t
       structure to a range of data_len.
Non ho capito bene come fare per accedere al payload del pacchetto
io faccio:
size_t len=packet_msg->data_len;
if (len > 0) {
	payload=malloc(len);
	payload=memcpy(payload,packet_msg+sizeof(ipq_packet_msg_t),len);
	//Segfault in memcpy
packet_msg e` un puntatore (valido) ad una struttura ipq_packet_msg_t, 
che contiene i metadati del pacchetto
e` corretto il metodo che uso per accedere al payload?
ciao
Kronos
-- 
Home: 
http://kronoz.tsx.org
"I've seen things you people wouldn't believe...
 Attack Ships on fire off the shores of Orion.
 I've watched C-beams glitter in the dark off of Tanhauser Gate.
 All those moments will be lost in time...like tears, in rain.
 Time to die." -- Roy Batty (played by Rutger Hauer)

Nella man page di ipq_get_packet si legge:
       typedef struct ipq_packet_msg {
         ...
       	 size_t data_len;
	 ...
       } ipq_packet_msg_t;
       Each of these fields may be read by the  application.   If
       the  queue  mode is IPQ_COPY_PACKET and the data_len value
       is greater than zero, the packet payload contents may  be
       accessed  in  the  memory  following  the ipq_packet_msg_t
       structure to a range of data_len.
Non ho capito bene come fare per accedere al payload del pacchetto
io faccio:
size_t len=packet_msg->data_len;
if (len > 0) {
	payload=malloc(len);
	pointer=memcpy(payload,packet_msg+sizeof(ipq_packet_msg_t),len);


 e` corretto il metodo che uso per accedere al payload?
Non ho la documentazione in questione sotto mano, ma sospetto che l'ultimo
campo della struct sia qualcosa come:
   char data[0]
 
Se č cosě, il modo giusto per accedere ai dati č quello di utilizzare
l'indirizzo effettivo di quel campo, quindi:
 
   memcpy( payload, &packet_msg->data[0], len );
O piů semplicemente: 
  memcpy( payload, packet_msg->data, len );
che č equivalente.
Infatti, sempre assumendo l'esistenza del campo 'data', non č
necessariamente vero che
    &packet_msg->data[0] == packet_msg + sizeof(ipq_get_packet)
anche se 'data' č l'ultimo campo e sizeof(char[0]) == 0.
Confronta ad esempio le seguenti due struct:
 struct S1 {
  int len;
  char	data[0];	
 } ;
 struct S2 {
  int len;
  char p;
  char	data[0];	
 } ;
 
Nel primo caso l'offset di 'data' č pari a sizeof(struct S1),
mentre nel secondo č inferiore.
 
 printf("%d %d\n", sizeof(struct S1), &((struct S1*)(0))->data );		
 printf("%d %d\n", sizeof(struct S2), &((struct S2*)(0))->data );
 
Max	
 

che contiene i metadati del pacchetto
E non ti da' un errore in compilazione? Mi pare che dovrebbe essere
	pointer = memcpy(payload, ((unsigned char *)packet_msg) + ...
Leonardo
-- 
".signature": bad command or file name

  printf("%d %d\n", sizeof(struct S2), &((struct S2*)(0))->data );
questo l'ho verificato ma non l'ho capito...
dipende forse da come il compilatore pone i dati in memoria?
ciao
Kronos
-- 
Home: 
http://kronoz.tsx.org
Porc i' mond che cio' sott i piedi!
V. Catozzo

         pointer = memcpy(payload, ((unsigned char *)packet_msg) + ...
no, nessun errore ne` warning (anche con Wall)
con gcc version 2.95.2 19991024 (release)
poi la man page di memcpy mi da questo prototipo:
void *memcpy(void *dest, const void *src, size_t n);
la conversione da void* a qualcosa* e viceversa e` implicita
ciao
Kronos
-- 
Home: 
http://kronoz.tsx.org
Il dottore mi ha detto di smettere di fare cene intime per quattro.
A meno che non ci siamo altre tre persone.