2

While going through the standard library functions of C (glibc), I found that printf() actually calls puts() functions (_IO_puts). But I am unable to find out how the puts function actually writes to the stdout ?

Does it uses write() system call defined in unistd.h or something else ? One thing I find out that puts() actually calling _IO_xputn through _IO_putn.

Please help. Thank you.

arka
  • 418
  • 2
  • 9
  • Students in the same class: [one](https://stackoverflow.com/questions/71633306/how-do-c-output-functions-actually-work-under-the-hood), [two](https://stackoverflow.com/questions/71634992/definition-of-inbuilt-c-functions), [three](https://stackoverflow.com/questions/71634030/how-puts-standard-library-function-works-in-c). – Eric Postpischil Mar 27 '22 at 11:25
  • You can use the `strace` utility to trace the system calls which are called by a process. – fpmurphy Mar 27 '22 at 12:27

1 Answers1

1

For Unix based systems for which Linux is part, most functions in stdio library are wrappers that are one layer above the standard I/O system calls. You see, the operating system provides a set of APIs called system calls. Applications cannot directly access hardware resources and hence they usually call these "system calls" whenever they need to do any sort of privileged thing like writing to the screen or reading from the keyboard.

In Unix, everything is abstracted as a file so whenever you need to write characters to a screen, all you need to do is open some file that represents the "screen" and write those characters there. The kernel will take care of the rest. Quite simply, this is how you'd do this in C:

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUFF_SIZE 2

int main()
{

    int terminal;
    char buffer[BUFF_SIZE] = "C\n";        // This will store the character to print +  new line
    terminal = open("/dev/tty", O_WRONLY); // systemcall to open terminal
    if (terminal < 0)
        exit(1); // some error happened

    dup2(terminal, STDOUT_FILENO); // use our newly opened terminal as default Standard output

    if (write(terminal, buffer, BUFF_SIZE) != BUFF_SIZE) // systemcall to write to terminal
        exit(1);                                         // We couldn't write anything
}

This just goes to show you that everything in stdio is layered on top of the basic I/O system calls. These system calls are read, write, open, etc. If you want to learn more about system calls and some OS internals, read the book "Three Easy Pieces" by Andrea Arpaci-Dusseau

  • Is it necessary to open a `tty` ? why just write(STDOUT_FILENO, buffer, BUFF_SIZE) ? – arka Mar 27 '22 at 06:08
  • For sure you can do, STDOUT_FILENO / STDIN_FILENO / STDERR_FILENO are file descriptors too that point to /dev/tty still. I added the open() syscall just to show you what stdio library does under the hood – Clinton Kavai Mar 27 '22 at 06:17