How puts standard library function works in C? [duplicate] - c

This question already has answers here:
Where can I find the source code for all the C standard libraries?
(4 answers)
Closed 11 months ago.
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.

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

Related

How do C output functions actually work under the hood? [duplicate]

This question already has answers here:
Where can I find the source code for all the C standard libraries?
(4 answers)
Closed 11 months ago.
I am trying to learn some C, but I am finding some of the standard functions a bit opaque.
Take putc or putchar as an example. I am trying to work out what drives this at the most basic level. I have tried to follow their definitions back through the GNU compiler source but it just ends up in this enormous tree of source files.
Is there a primitive "print this character" function that all the others are built from? I had assumed that it was just a write() system call, but an answer to a related question said that this is completely implementation specific. So how else can it actually produce the output if not a system call?
So how else can it actually produce the output if not a system call?
It does use a system call, but the specific system call is implementation-dependent.
Unix implementations use the write() system call. Implementations for other operating systems will use whatever is analogous to this.
There could also be standalone implementations that run directly on hardware without an operating system. These "unhosted" implementations might omit the stdio library, or they could implement its features by accessing the hardware directly. In this case there's no system call, the I/O is done by the stdio library itself.
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

what is the different of using fflush(stdout) and not using it

#include <stdio.h>
int main()
{
printf("Hello");
fflush(stdout);
return 0;
}
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
I'm trying to understand the use of fflush(stdout) and what is the difference between the 2 programs above?
In a normal C program running on a modern OS, file access is buffered twice (or more when you count buffers like the buffer in your drive). One buffer is implemented in the FILE structure and the other is implemented in the kernel.
Often, the FILE structure buffers the content in a buffer inside of your program. When you write something to a buffered file, the content is keep in the buffer, inside of the running program. It is written to the OS when the buffer is full and, when the buffering mode is line buffered, at the end of a line. This data is written to the OS by a syscall, for example write().
The buffer is there because a syscall requires a context switch from the user program to the kernel, this is relatively expensive (slow), the buffer is here to reduce the number of syscalls. You could also use the syscalls from your program directly without the stdio functions, however, this functions are less portable and more complex to handle.
A fflush(stdout) checks if there are any data in the buffer that should be written and if so, the underlying syscall is used to write the data to the OS.
When the syscall returns, the data is in your kernel. But modern operating systems buffer this data as well. This is used to reduce the number of disk writes, reduce latency and other things. This buffer is completely independent of the FILE buffer inside your program.
Note that this does not apply to all systems. For example microcontroller environments may provide some stdio.h functions that write directly to a UART, without any buffer, neither inside FILE nor any (probably non-existent) OS.
To see what fflush() does to a running program, compare this programs:
int main(void)
{
fputs("s",stdout);
fputs("e",stderr);
}
and
int main(void)
{
fputs("s",stdout);
fflush(stdout);
fputs("e",stderr);
}
On Linux, stderr is not buffered by default, so fputs("e",stderr); will print the data immediately. On the other hand, fputs("s",stdout); is line buffered by default on Linux so the data is not printed immediately. This causes the first program to output es and not se, but the second one outputs se.
You can change the buffer modes with setvbuf()
When stdout points to a tty, it is, by default, line-buffered. This means the output is buffered inside the computer internals until a full line is received (and output).
Your programs do not send a full line to the computer internals.
In the case of using fflush() you are telling the computer internals to send the current data in the buffer to the device; without fflush() you are relying on the computer internals to do that for you at program termination.
By computer internals I mean the combination of the C library, Operating System, hardware interface, (automatic) buffers between the various interfaces, ...

Read a txt file line by line without using fopen()

I need to read a text file line by line.
The problem is that in my code I cannot use fopen() and then fgets() to read the content of each line, because fopen() fails when I use a lot of threads (it seems that it gets overload because it is being opend so many times).
Most operating systems have limits on how many files a particular process can open at the same time. Since fopen() is "just" a wrapper on top of open(), it won't help to use a lower-level interface if this is your problem.
You can verify that this is indeed your problem by checking errno when fopen() fails, i.e. if it returns NULL. You sound as if you've already done this, but you weren't very specific. I would expect EMFILE if you're running into the per-process limit (see the open() manual page).
You need to investigate what your particular limits are and see if you can change them, or re-design your program so that you don't open as many files in parallel.
You can use open (man open (2)) and read (man read(2)).
What is the real problem with fopen()?
If open/read works and fopen/fread doesn't work, this may be because you're running out of lock structures. Using unlocked_getc in a loop (reading until you get a newline) might be the easiest option.
you can use getline()
You would need to specify the delimiter and a while or for loop to stop when reach EOF.
EDIT: you said you dont want to use fopen() and fgets() and so :
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
if (line = something)
{
// read next line and print it... but how?
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
Some folks recommended you to use open(2) and read(2) as replacements of fopen(3) and fgets(3), but since they are Unix (Linux and OS X) API, you cannot use them with Borland on Windows. What corresponds to open(2) and read(2) on Windows are Win32 APIs CreateFile and ReadFile
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467.aspx
But I really doubt this is the way to go for you... You're trying to solve a problem which should never happen on a normal program. You need to find the root cause of your problem.

System Calls Function for prompting and getting user input

Ok, so I am writing a C program for my class, but I am only allowed to use system calls. Basically our program is making our on cp command, where we are taking two files as inputs from the command line and copying the first file and putting it into a second file. It is relatively simple and I have most of the code right or just about right with maybe some small fixes. However, one part of the program is if the destination file already exits, we need to prompt the user to ask if it should be overwritten or not, so I need to know how to get user input using a system call function, aka I can't use scanf, fgets, gets etc. The only function I can use from the standard library is printf basically. So I need to know what the system calls function is to get a user prompt. This part of the code is suppose to work like cp -i , if that helps anyone. Thank you in advance.
You could use system call read. To read from standard input, fd (file descriptor) is 0.
$ man read
READ(2)
Linux Programmer's Manual (2)
NAME
read - read from a file descriptor
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
DESCRIPTION
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
If count is zero, read() returns zero and has no other results. If count is greater than SSIZE_MAX, the result is unspecified.

What is the equivalent to Posix popen() in the Win32 API?

Is there a rough equivalent to the Linux/Unix stdio.h popen() function in the Win32 API? If so, where can I find it?
Edit: I need to know this to patch an omission in the D standard library. Any answer must use only standard Win32 API, no MSVC-specific functions. Also, I'd prefer something that's not horribly low-level, if it exists.
MSDN explains how you do what popen does using the Windows API in Pipe Handle Inheritance . Here it provides a well-documented example. It's way more low-level than the _popen function found in the runtime library linked by Jason, but uses the Win32 API exclusively.
You can call _popen if you're writing a console application. For more information, see the documentation on the MSDN site: http://msdn.microsoft.com/en-us/library/96ayss4b(VS.80).aspx
Sadly it's not particularly easy.
You need to create a pipe using the win32 function (CreatePipe), then typically you need to duplicate the end of the pipe (DuplicateHandle) that you're giving to the subprocess to allow it to be inherited, otherwise it won't be and hence can't be used.
Then you need to create a process using CreateProcess (which takes lots of structure pointers, including a STARTUPINFO), and pass in the STARTUPINFO the handle that you've duplicated as its stdout.
Then you can read from the reading end of the pipe (ReadFile etc) until you reach eof, then you need to clean up by closing all the various win32 handles.
Digging up an old thread ...
Reacting to Jason Coco's reply above, and contrary to what the linked MSDN page claims, it is apparently possible nowadays to call _popen() from non-console apps. I call it from a QuickTime importer component, basically a DLL in disguise. It opens a console window but otherwise shows the expected behaviour. Compiling a standard console tool with mingw32's -mwindows option to make it a GUI app, _popen continues to work correctly (but a console window opens even when running the tool from another console.
This is an old post, but I also had a need several years ago to use a popen() like call in a Windows environment. As several of the comments in the answer here have noted, using the Windows API to implement anything close to the classic POSIX popen() is interesting.
I created an implementation which I submitted to Code Review . This implementation uses pipes to stdin and from stdout, as well as Windows methods for CreateProcess(...).
The linked code is designed to be built into a dll with a very small API.
int __declspec(dllexport) cmd_rsp(const char *command, char **chunk, unsigned int size);
Simple example of usage:
#include "cmd_rsp.h"
int main(void)
{
char *buf = {0};
buf = calloc(100, 1);
if(!buf)return 0;
cmd_rsp("dir /s", &buf, 100);
printf("%s", buf);
free(buf);
//or a custom exe
char *buf2 = {0};
buf2 = calloc(100, 1);
cmd_rsp("some_custom_program.exe arg_1 arg_2 arg_n", &buf2, 100);
printf("%s", buf2);
free(buf2);
return 0;
}
It takes any command that can be for example issued from stdin, creates a separate process to execute the command, then returns all response content (If there is any) to a buffer, and does this without displaying the CMD window popup. The buffer grows as needed to accommodate size of response.

Resources