Files, I/O and File Systems
I/O
In C code, there are two ways to do I/O, via the C library functions, or directly via system calls (which the C library functions use). Here's an example of using the C library functions to create a file called hello.txt that contains the text Hello, World!:
#include <stdio.h>
int main() {
FILE *fp = fopen("hello.txt", "w");
if (fp == NULL) {
perror("fopen");
return 1;
}
fprintf(fp, "Hello, World!\n");
fclose(fp);
return 0;
}
Notice that fopen returns a FILE* pointer, which is a C library structure that represents a file. The fprintf function is used to write to the file, and fclose is used to close the file.
If we trace the system calls this code makes, we see
brk(NULL) = 0x56abe2786000
brk(0x56abe27a7000) = 0x56abe27a7000
openat(AT_FDCWD, "hello.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
write(3, "Hello, World!\n", 14) = 14
close(3) = 0
exit_group(0) = ?
We can write a version that uses the system calls directly:
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd = open("hello.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror("open");
return 1;
}
write(fd, "Hello, World!\n", 14);
close(fd);
return 0;
}
Notice that in this case, fd is an integer (a file descriptor) that represents the file. Data about what is going on in the file is not stored in a way directly accessible to us; that information is stored in the kernel. We use the write system call to write to the file, and the close system call to close the file.
(When logged in, completion status appears here.)