4

I have a simple program (working example):

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

int main() {
  pid_t my_pid = getpid();
  char str[30];

  sprintf(str, "/proc/%d/fd", my_pid);
  printf("hello, I am gonna print out: %s", str);

  execvp( "ls", (char *[]) { "ls", str, NULL } );

  return 0;
}

compiled with gcc on a Linux VM. My question is why the output sent to printf is never printing.

I understand that printf buffers its output and only flushes on \n. I am wondering why it is that it doesn't print in this case. I read that output streams are flushed on program exit. printf is buffering outputs in a malloc'd piece of memory (I confirmed this in my implementation).

My questions about this (more details are welcome):

  • Why does commenting out the call to execvp cause the output to be printed on stdout, but it is not printed as is? My thought is, wouldn't it still be considered program exit even after ls cannibalizes the process?
  • Would printf's in-memory buffer be considered an output stream?
  • A completely unrelated detail to this question is I am wondering why the file descriptor 10 on zsh and 255 on bash are not inherited by my process.
anatolyg
  • 26,506
  • 9
  • 60
  • 134
user129393192
  • 797
  • 1
  • 8
  • Or in other words: the buffered data is stored in memory local to the old process – but as this one is replaced entirely by a new one the former ceases to exist – before it could flush the buffer. The memory of it is either discarded or re-used (overwritten) by the new process. – Aconcagua Apr 18 '23 at 06:32
  • "wouldn't it still be considered program exit" No. – n. m. could be an AI Apr 18 '23 at 09:23

1 Answers1

5

execvp replaces the old process with a new process. Any open file descriptors remain open, but the data buffered by the C stdio library is not preserved. The C startup code will attach a new FILE pointer to the STDOUT file descriptor. The key point is that a file descriptor is an OS object, whereas a FILE pointer is a C library object. Only the OS object is preserved.

user3386109
  • 34,287
  • 7
  • 49
  • 68
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • Does a `FILE*` correspond to the buffered memory (as in `printf`)? Why is it necessary to have both a `FILE*` and a file descriptor? If I close file descriptor `STDOUT_FILENO`, should I expect `FILE* stdout` to stop working? – user129393192 May 11 '23 at 05:02