omg i need help so bad. I've been working on a school project for what seems like an eternity and i'm close to deadline. Using FIFO's (i ahve to) to communicate between parent and child proc's. Right now I'm stuck on a read/write.

fifomsg is a struct with int length and char[16] message fields. This is what I'm trying to send between the processes.

child code:

fdw = Open("syscallfifo", O_WRONLY);

fifomsg msg1;        
strcpy(msg1.message, (char*)pid);
msg1.length = sizeof(msg1);

write(fdw, &msg1, sizeof(msg1));
close(fdw);

parent code:

fdr = Open("syscallfifo", O_RDWR);
	
fifomsg msg1;
	
read(fdr, &msg1.length, sizeof(msg1.length));
read(fdr, &msg1.message, sizeof(msg1) - sizeof(msg1.length));
close(fdr);

At this point in execution, the process halts and I have to suspend/kill. I'm begging for help. As soon as possible would be ideal.

If I can't get the struct data to work, I'm going to have to resort to a fixed-sized character array to pass to the FIFO. I'm working on this as a backup because I can't progress any further with my msg struct. I'm getting a freeze when I use strcat.

int MSGSIZE = 16;
char* msgbuf;
msgbuf = (char*)malloc(MSGSIZE+1);
sprintf(msgbuf, "systemcall");
strcat(msgbuf, (char*)pid);

int fdw = Open("syscallfifo", O_WRONLY);
int written = write(fdw, msgbuf, sizeof(msgbuf));

I'm desperate. Thank anyone for any consideration.

also I wanted to mention I searched through the forum and couldn't find a similar problem.

Dani AI

Generated

Most likely causes of the "hang" seen in the snippets: casting a pid to char * (undefined behavior), using sizeof on a pointer instead of the string length, not checking return values from open/read/write, and blocking behavior of FIFOs (open/read can wait indefinitely). already pointed out the pid cast; 's idea to include a numeric pid field in the struct is also a solid, simpler solution.

Recommended practical fixes and checks:

  • Store the pid as an integer member in the struct (portable and avoids string conversion), or convert safely with snprintf() into a fixed-size buffer and always bound-check the result.
  • When writing strings, pass the actual byte count (e.g. strlen(buf) or strlen(buf)+1 to include the NUL), not sizeof of a char *.
  • Always check return values from open, read, and write and print errno (use perror) so any blocking/ENXIO/EPIPE conditions are visible.

Robust I/O helpers (use these to avoid partial read/write hangs):

ssize_t write_all(int fd, const void *buf, size_t count) {
  const char *p = buf;
  while (count) {
    ssize_t n = write(fd, p, count);
    if (n <= 0) return -1;
    p += n; count -= n;
  }
  return 0;
}

ssize_t read_all(int fd, void *buf, size_t count) {
  char *p = buf;
  while (count) {
    ssize_t n = read(fd, p, count);
    if (n <= 0) return n;
    p += n; count -= n;
  }
  return 0;
}

Notes on FIFO ordering and debugging:

  • open(..., O_WRONLY) blocks until a reader exists; open(..., O_RDONLY) blocks until a writer exists. To avoid deadlock, arrange open order (reader first) or open one side with O_NONBLOCK and handle errors, or keep a dummy fd open. Use strace/ltrace or print errno for immediate diagnosis.

Checklist: stop casting integers to pointers, use bounded conversion (snprintf), send the correct byte count, use the *_all() helpers above, and check errors. This will eliminate the common causes of the freeze described by .

Recommended Answers

All 5 Replies

>>strcat(msgbuf, (char*)pid);
If you have to cast to char * then chances are good you're doing something wrong. ;) What type is pid? I'm guessing it's an int, and that would be a problem because typecasting doesn't make an integer into a string.

pid is a pid_t, pretty much like an int, just holds the process id, is there any other way to add this onto the end of my message?

by the way, thanks for the fast reply, i will be checking for response about every 10 minutes or so.

if msg is a struct, why not just have an an int inside the struct to hold the pid and set it equal?

ya i guess i could add another int field, but wouldn't make a difference right now I can't get the message struct to send anyway. my main problem is with read/write.

pid_t is integral, so you need to actually convert it to a string. Type casting doesn't cut it, but sprintf is a good easy fix:

sprintf(msg1.message, "%lu", (unsigned long)pid);

This is assuming that message is an array or pointer with memory allocated to it and sized enough to hold the value. If it's just a pointer, you need to allocate some memory:

msg1.message = malloc(ENOUGH_FOR_AN_INT + 1);

if (msg1.message == NULL)
  error("malloc failure");

sprintf(msg1.message, "%lu", (unsigned long)pid);

The same goes with your alternate solution:

sprintf(msgbuf, "systemcall%lu", (unsigned long)pid);
/* strcat(msgbuf, (char*)pid); */
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.