Input-output system calls in C | Create, Open, Close, Read, Write

Input-output system calls in C | Create, Open, Close, Read, Write

Input-output system calls in C | Create, Open, Close, Read, Write

System calls in C are requests made by a program to the operating system kernel for services it can’t access directly. These services go beyond input and output devices and include functions like process control, file management, memory management, and inter-process communication. In C programming, various functions, such as create, open, read, and write, are used for input/output system calls.

Important Terminology

What is the File Descriptor?

The file descriptor is basically an integer that would identify an open file of the process.

A file descriptor table is a collection of integer array indices where each index corresponds to a file descriptor. Each element in this table is a pointer to a file table entry. In an operating system, there is one unique file descriptor table for each process.

A file table entry is an in-memory structure representing an open file. It is created when a program requests to open a file. These entries maintain information about the file, including the current file position.

Standard File Descriptors: When a process starts, it automatically has three standard file descriptors open: 0, 1, and 2. These are often referred to as stdin (0), stdout (1), and stderr (2). By default, each of these descriptors points to a file table entry for a file named /dev/tty .

/dev/tty: This is an in-memory surrogate for the terminal. In other words, it’s a representation in the computer’s memory that stands for the terminal device. The terminal, in this context, is a combination of a keyboard and a video screen where the user interacts with the system.

  1. Read from stdin (fd 0):
    When you type on the keyboard, the program reads from standard input (stdin), linked to file descriptor 0, and saves it from the file named /dev/tty .
  2. Write to stdout (fd 1):
    Output you see on the screen is written to standard output (stdout), associated with file descriptor 1, and comes from the file named /dev/tty .
  3. Write to stderr (fd 2):
    Error messages you see on the screen are written to standard error (stderr), linked to file descriptor 2, and also come from the file named /dev/tty .

Input/Output System Calls

There are 5 Input/Output system calls.

1. Create

The creat() function in C is used to create a new empty file. It allows us to specify the permissions and the name of the file we want to create. This function is defined in the header file, and the flags used as arguments are defined in the header file. The creat() function is a system call for file creation in C programming.

Syntax of create() in C

int create(char *filename, mode_t mode); 

Return Value

When creating or opening a file, the first unused file descriptor is often returned, starting with 3 (as 0, 1, and 2 are typically reserved for stdin, stdout, and stderr). If there’s an error, the function returns -1.

How C create() works in OS

  1. Create a new empty file on the disk.

2.Create a file table entry.

3.Set the first unused file descriptor to point to the file table entry.

4.Return the file descriptor used, -1 upon failure.

In C, this process might involve using functions like creat() , open() , and checking the return values for success or failure.

2. C open

The open() function in C is used to open a file for reading, writing, or both. It is also capable of creating the file if it does not exist. This function is defined in the header file, and the flags passed as arguments are defined in the header file. When using open() , you can specify flags to control the file opening mode, and it’s important to note that additional flags are needed to create a file if it doesn’t exist.

Syntax of open() in C

int open (const char* Path, int flags); 

FlagsDescription
O_RDONLYIt will Open the file in read-only mode.
O_WRONLYIt will Open the file in write-only mode.
O_RDWRIt will Open the file in read and write mode.
O_CREATIt can Create a file if it doesn’t exist.
O_EXCLIt can Prevent creation if it already exists.
O_ APPENDIt will Open the file and places the cursor at the end of the contents.
O_ASYNCIt will Enable input and output control by signal.
O_CLOEXEC
It will Enable close-on-exec mode on the open file.

How C open() works in OS

  1. Find the existing file on the disk.

2.Create a file table entry.

3.Set the first unused file descriptor to point to the file table entry.

4.Return the file descriptor used, -1 upon failure.

Example of C open()

/ C program to illustrate // open system call #include #include #include #include extern int errno; int main() < // if file does not have in directory // then file foo.txt is created. int fd = open("foo.txt", O_RDONLY | O_CREAT); printf("fd = %d\n", fd); if (fd == -1) < // print which type of error have in a code printf("Error Number % d\n", errno); // print program detail "Success or failure" perror("Program"); >return 0; >

Output

fd = 3 

3. C close

The close() function in C is used to inform the operating system that you have finished using a file descriptor and want to close the associated file. This function is defined in the header file.

Syntax of close() in C

int close(int fd); 

How C close() works in the OS

  1. Destroy file table entry referenced by element fd:
  2. Set element fd of the file descriptor table to NULL:

Example 1: close() in C

// C program to illustrate close system Call #include #include #include int main() < int fd1 = open("foo.txt", O_RDONLY); if (fd1 < 0) < perror("c1"); exit(1); >printf("opened the fd = % d\n", fd1); // Using close system Call if (close(fd1) < 0) < perror("c1"); exit(1); >printf("closed the fd.\n"); >
opened the fd = 3 closed the fd. 

Example 2

// C program to illustrate close system Call #include #include int main() < // assume that foo.txt is already created int fd1 = open("foo.txt", O_RDONLY, 0); close(fd1); // assume that baz.tzt is already created int fd2 = open("baz.txt", O_RDONLY, 0); printf("fd2 = % d\n", fd2); exit(0); >
fd2 = 3 

When the program starts, file descriptors 0, 1, and 2 are already used. So, the first available file descriptor is 3. After closing and setting them to NULL, the next open() gets file descriptor 3. That’s why the output of this program is 3.

4. C read

The read() function in C reads a specified number of bytes ( cnt ) from the file associated with the file descriptor ( fd ) into the memory area pointed to by buf . A successful read() also updates the access time for the file. This function is defined in the header file.

Syntax of read() in C

size_t read (int fd, void* buf, size_t cnt); 

Parameters

#include int main() < int fd, sz; char* c = (char*)calloc(100, sizeof(char)); fd = open("foo.txt", O_RDONLY); if (fd < 0) < perror("r1"); exit(1); >sz = read(fd, c, 10); printf("called read(% d, c, 10). returned that" " %d bytes were read.\n", fd, sz); c[sz] = '\0'; printf("Those bytes are as follows: % s\n", c); return 0; >
called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo.

5. C write

Writes cnt bytes from buf to the file or socket associated with fd. cnt should not be greater than INT_MAX (defined in the limits.h header file). If cnt is zero, write() simply returns 0 without attempting any other action. The write() is also defined inside header file.

Syntax of write() in C

size_t write (int fd, void* buf, size_t cnt); 

Parameters

Return Value

Important Points about C write