0

First I have following macro

#define MSG_UPDATE_DATA 70

Then open a pipe with popen

SensServer = popen("./SensServer", "w") ;

In the following code that uses the putc(...) function to write to pipe, the function makes the program block and the lines of code following do not execute

void requestTempAndPress(int pid) {
    printf("Temp and presure requested. msg_type: %d\n", MSG_UPDATE_DATA);
    int n = putc(MSG_UPDATE_DATA, SensServer);

    printf("Data sent: %d\n", MSG_UPDATE_DATA);
}

It outputs Temp and presure requested. msg_type: 70 fine. But not the "Data sent..." line.

HedgepigMatt
  • 190
  • 3
  • 16

3 Answers3

0

As per the man page,

  • pipe is a fd, type int.
  • putc() needs a FILE* stream as argument.

So, most possibly, in your code, you are supplying the wrong type of argument to putc(), creating the issue.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Given the information (and lack of a sample program), this sounds like a question asking how to make pipes non-blocking. This has been discussed before, usually for nonblocking reads, e.g.,

The first link mentions fcntl and the O_NONBLOCK flag which the manual page says can be applied to both reads and writes.

However, using popen makes the pipe using buffered I/O, while the operations addressed by fcntl are non-buffered read and write (you really cannot mix the two). If the program were changed to use the low-level pipe (as in the example for the first link), and consistently used the non-buffered I/O, it would give the intended behavior.

Here are links to more general discussion on the topic:

On the other hand (noting comments), if the program fragment is for example part of some larger system doing handshaking (expecting a timely response back from the server), that will run into problems. The fragment is writing a single character across the pipe. However, popen opens a (block-)buffered stream. Nothing will be sent directly to the server as single-character writes unless some help is provided. For instance, one could flush the output stream after each putc, e.g.,

fflush(SensServer);

Alternatively, one could make the stream unbuffered by changing it immediately after the successful call to popen, e.g., using setvbuf:

setvbuf(SensServer, NULL, _IONBF, 0);

Here are links for further reading about buffering in pipes:

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • Just a side note: We were dealing with a process that didn't flush to stdout or print newline at all, so we piped the process to [stdbuf(1)](http://linux.die.net/man/1/stdbuf) and read from it, to see if we have a problem with buffering (we did have a problem with buffering :) ) – holgac Apr 20 '15 at 13:16
0

The problem was due to the fact I initialised the variable SensServer in the parent process but not the child. Which meant the pointer was 0 or I guess a random memory location.

HedgepigMatt
  • 190
  • 3
  • 16