0

I Need to write the following struct to a fifo:

struct msg_t {
   int length;
   char* msg;
};

I malloc the struct and the char* inside it and I write like this: (let's assume msg is the variable name) write(fifo_fd, &msg, sizeof(msg_t));

The length is read from the other end just fine. The string isn't.. How can I write those two fields with a single write? If not, are two separate writes good?

Thank you.

dlvhdr
  • 482
  • 4
  • 19

2 Answers2

2

you will just be writing the length and the pointer address, which I doubt is what you will want at the other end. My guess is what you actually want is something like this:

struct msg_t msg;
// Initialise msg
write( fifo_fd, &(msg.length), sizeof(int) );
write( fifo_fd, msg.msg, msg.length );
Sodved
  • 8,428
  • 2
  • 31
  • 43
  • Thank you.. That's what I thought of but, I thought there was a way to do this in one write. I guess this is the most correct way :) – dlvhdr Dec 23 '13 at 07:35
  • @dlv There *are* ways to do it in one write, but it takes some prep-work on the data storage side. Honestly, it isn't work the hassle if this is all you want done. This answer will do what you need. (+1, btw). – WhozCraig Dec 23 '13 at 07:47
1

Did you consider using flexible array members (also explained here)? See this... So declare

struct msg_t {
    unsigned length;
    char msg[];
};

allocate it with e.g.

struct msg_t* make_msg(unsigned l) {
  // one extra byte for the terminating null char
  struct msg_t* m = malloc(sizeof(struct msg_t)+l+1; 
  if (!m) { perror("malloc m"); exit(EXIT_FAILURE); };
  memset(m, 0, sizeof(struct msg_t)+l+1);
  m->length = l;
  return m;
}

then write it with e.g.

fwrite(m, sizeof(struct msg_t)+m->length+1, 1, fil);

or if you use write do the buffering yourself (since a write can be partial!) e.g.

void write_msg(int fd, struct msg_t *m) {
   assert(m != NULL);
   char* b = m;
   unsigned siz = sizeof(struct msg_t)+m->length+1);
   while (siz>0) {
      int cnt=write (fd, b, siz);
      if (cnt<0) { perror("write"); exit(EXIT_FAILURE); };
      b += cnt;
      siz -= cnt;
   }
}
Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547