0

I have written a basic C++ program as such:

#include <sstream>
#include <unistd.h>
#include <cstdio>
#include <iostream>

int main(void)
{
  int foo;
  std::cin >> foo;
  FILE* fd = fopen("./output", "a+");
  std::stringstream ss;
  ss << getpid() << std::endl;
  fputs(ss.str().c_str(), fd);
}

The code simply expects input from standard input, and appends its process id to an output file. After successful compilation, I execute the binary as background process ./my_binary&, check its pid with jobs -l, and try to pass a dummy integer to it either with printf "6\0" >/proc/<pid>/fd/0 or echo -e "6\n" >/proc/<pid>/fd/0. The process does not write in output file and exit as I expect it to. What am I doing wrong here? I can see the 0 descriptor in the process' proc directory but does it get somehow blocked when the process it thrown in the background?

Note that in contrast, I can exhibit the expected behaviour by fg <n>ing and manually entering an integer.

Edit: As per Kusalananda's comment, I have realized that a SIGTTIN signal is being emitted for processes which have been backgrounded while expecting input from tty.

Edit: Failing to find a way to mitigate SIGTTINT issue, I decided to use a named pipe instead of stdin. The code has been changed so (also I switched to C, having realized I ended up using pure C anyway):

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(void)
{
  char input[3]; 
  read(7, input, 2);
  int num = atoi(input);
  char output[256];
  memset(output, 0, 256);
  sprintf(output, "%d : %d\n", getpid(), num);
  write(13, output, strlen(output));

  return 0;
}

I created a pipe: mkfifo input_pipe, and called the process as ./process 7<input_pipe 13>>output, passing the arguments into input_pipe.

  • 1
    What is the status of the process after you try to write to it? Most programs that read from the terminal as its standard input enters a "stopped" state when put into the background, since it blocks on the read until a terminal is present. Try e.g. ( read thing ) & in the shell. – Kusalananda Dec 12 '18 at 12:00
  • Great, this has been a good starting point. The process is indeed being stopped, and it is also rejecting kill -SIGCONT <pid> continue signals. I have looked further into it and seen that a SIGTTIN signal is being emitted for processes which have been backgrounded while expecting input from tty. I'll see if I can trap and ignore this signal, or get input from some other file than stdin. I will keep here posted. – corsel Dec 12 '18 at 13:09
  • 2
    If your intent is to have the process act like a daemon that can accept input from some unrelated process, the time-tested way of doing this is to have it read from a named pipe. – Mark Plotnick Dec 12 '18 at 14:45
  • Thanks for the tip, I ended up doing that and edited the question accordingly. I have a few of these bckground jobs and once one pulls the input data out of the pipe, others starve. Do you know of any ways to deal with this more elegant than perhaps giving each process a different pipe, and copying the data to each of them, or appending n numbers of repeated input? – corsel Dec 12 '18 at 15:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.