2

I'm calling iperf3 from via popen and read from its output into a string.

#include <stdio.h>
#include <iostream>

using namespace std;

int main() {
  string peer_ip = "localhost";

  string iperf_cmd = "iperf3 -c " + peer_ip + " -t 1" + " -R 2>&1";
  string iperf_out;
  char iperf_buff[2];

  FILE *iperf_d = popen(iperf_cmd.c_str(), "r");
  while (fgets(iperf_buff, 2, iperf_d) != nullptr)
    iperf_out += iperf_buff;
  pclose(iperf_d);

  cout << iperf_out << "\n";
}

This works most of the time.

However, when the network is is very slow, my fgets gets stuck and program never prints the output from iperf3. Why is that?

From man fgets(3):

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.

Note that my buffer is 2 bytes long.

foki
  • 8,624
  • 6
  • 33
  • 32
  • Are you sure that it's `fgets` that is stuck, and not the `iperf3`? – Vlad Feinstein Jun 01 '22 at 00:56
  • @VladFeinstein How would you check that in this program? I mean, I can forcibly interrupt `iperf3` by adding `timeout 2` in front of `iperf_cmd`. That will "unstuck" `iperf3`, but what if I cannot come up with any reasonable timeout for determining that `iperf3` is stuck? – foki Jun 01 '22 at 01:33
  • what happens if you simply run that `iperf3 -c localhost -t 1 -R` on that slow network? – Vlad Feinstein Jun 01 '22 at 02:40
  • @VladFeinstein Well, it all runs repeatedly on a real network with significant real-time variations. Unfortunately, I don't have an emulator in which I could reproduce the network conditions. What I know for sure is that the program gets stuck (from my logs). My point is that there is no (easy) way for me to tell whether `fgets` or the process itself gets stuck using the `popen` and `fgets` API that Linux exposes. Or, am I wrong? – foki Jun 01 '22 at 23:46

0 Answers0