I am looking for an easy way to manage file opening and closing in x86-64 assembly on linux. I thought the easiest way would be to write a c file containing functions that I could call without having to worry about stability. So I wrote this function :
struct PORT open_port(char *filename, int mode) {
   struct PORT port;
   port.p = 0;
   if (mode) {
   if (filename == "stdout")
     port.f = stdout;
   else
     port.f = fopen(filename, "wb+");
   } else {
   if (filename == "stdin")
      port.f = stdin;
  else 
     port.f = fopen(filename, "rb");
  }
  return port;
}
And then I read the port like so:
char readchar(struct PORT *port)
{
  char r;
  if ((*port).p)
    r = (*port).p;
  else 
    r = fgetc((*port).f);
  (*port).p = 0;
  return r;
}
Where PORT.p is a char which contains the character at the current position and PORT.f a file pointer. Then I call those function in my assembler code by putting the parameters in %rdi and %rsi.
Everything works as expected when I am reading an ordinary file, but the stdin support doesn't work. I know stdin is supposed to be the value 0 and when I debug my code, I can see that the value holding the file pointer is indeed 0, but when the code gets to the fgetc() call, it seg faults. If I write plainly fgetc(0); in my function, there is also a segmentation fault. I don't get how the fgetc() function can tell the difference between the stdin and a normal 0. 
How can I read stdin using this (or a very similar pattern)? Or if it's all wrong, what should I do to open files in x64 assembly? There is certainly something I am not getting regarding how it works, help would be greatly appreciated.
(For those who are wondering what's the point of this all: it's to be able to read the next character without [in appearance] moving the file pointer, so there is a peekchar function that sets PORT.p if it's unset, so p can hold the value until it's read)
