UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Lab 04
SYSTEM CALLS
Objective
➢ Understand system calls.
➢ Identify the use of system calls.
➢ Learn Major System Calls of file system(write, read, open)
Date:
Name:
Reg#: Group:
Marks: Signature:
Page 1 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Introduction:
A system call is a request for the operating system to do something on behalf of the user's
program. The system calls are functions used in the kernel itself. To the programmer, the system
call appears as a normal C function call. However since a system call executes code inthe kernel,
there must be a mechanism to change the mode of a process from user mode to kernel mode.
Use of System calls
UNIX system calls are used to:
➢ Manage the file system
➢ Control processes
➢ And to provide inter process communication
Types of System Calls
System calls are classified into the following categories:
File System Operations
1: Write()
write() system call is used to write to a file descriptor. In other words write() can be used to write to
any file (all hardware are also referred as file in Linux) in the system but rather than specifying the
file name, you need to specify its file descriptor.
Page 2 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Syntax:
#include<unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
The first parameter (fd) is the file descriptor where you want to write. The data that is to be written
is specified in the second parameter. Finally, the third parameter is the total bytes that are to be
written.
To understand better let’s look at the first program below:
Program1: To write some data on the standard output device (by default – monitor)
//Name the program file as “write.c”
#include<unistd.h>
Int main()
write(1,"hello\n",6); //1 is the file descriptor, "hello\n" is the data, 6 is the count of characters in data
How it works?
The write() system call takes three parameters: “1” which is the file descriptor of the file where we
want to write. Since we want to write on standard output device which is the screen, hence the file
descriptor, in this case, is ‘1’, which is fixed (0 is the file descriptor for standard input device (e.g.
keyboard) and 2 is for standard error device)).
Next thing is what we want to write on the screen. In this case its “hello\n” i.e. hello and
newline(\n), so a total of 6 characters, which becomes the third parameter. The third parameter is
how much you want to write, which may be less than the data specified in the second parameter.
You can play around and see the change in output.
Output:
Once you compile and run this, the output on the screen will be the word “hello”, as shown below
Page 3 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
On success, the write() system call returns the ‘number of bytes written’ i.e. the count of how many
bytes it could write. This you can save in an integer variable and checked. The write() system call
on failure returns -1.
Note: students get confused by thinking that write() return the data that is written. Remember, it
returns the count of characters written. Refer to the program below.
Program 2
#include<stdio.h>
#include<unistd.h>
int main()
int count;
count=write(1,"hello\n",6);
printf("Total bytes written: %d\n",count);
How it Works?
The program is similar to the previous one except that this time it also explicitly prints the count of
bytes that write() system call was able to write on file descriptor 1.
Page 4 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Output:
Variations
Try making the changes as shown in the codes below and observe the output to understand the
working of the write() system call in detail.
Program 3:
#include<unistd.h>
int main()
write(1,"hello\n",60); //the bytes to be printed (third parameter) are more than the data specified in
2nd parameter
Program4:
#include<unistd.h>
int main()
write(1,"hello\n",3);//the bytes to be printed (third parameter) are less than the data specified in 2nd
parameter
Page 5 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Program5:
#include<unistd.h>
#include<stdio.h>
int main()
int count;
count=write(3,"hello\n",6); //the file descriptor is not one of the pre-specified ones i.e., 0, 1 or 2
printf("Total bytes written: %d\n",count);
Will this call to write() be successful? If not then what will it return?
2. read()
The use of read() system call is to read from a file descriptor. The working is same as write(), the
only difference is read() will read the data from file pointed to by file descriptor.
Syntax:
#include<unistd.h>
ssize_t read(int fd, const void *buf, size_t count);
The first parameter is the file descriptor. The second parameter is the buffer where the read data will
be saved. Lastly, the third parameter is the number of bytes that you want to read.
Think of the buffer as a temporary storing area. As you are reading from this page and before typing
the program on your system you temporarily store it in your brain. So your brain is the buffer.
Although this page contains a lot of data, you might want to read only 20 characters. Hence, the
third parameter (count) tells, how much you want to read?
Page 6 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Program 6: To read data from the standard input device and write it on the screen
//read.c
#include<unistd.h>
int main()
char buff[20];
read(0,buff,10);//read 10 bytes from standard input device(keyboard), store in buffer (buff)
write(1,buff,10);//print 10 bytes from the buffer on the screen
How it works?
The read() system call reads the input typed by the user via the keyboard (file descriptor 0) and
stores it in the buffer (buff) which is nothing but a character array. It will read a maximum of 10
bytes (because of the third parameter). This can be less than or equal to the buffer size. No matter
how much the user types only first 10 characters will be read.
Finally, the data is printed on the screen using the write() system call. It prints the same 10 bytes
from the buffer (buff) on the screen (file descriptor 1).
Output:
Page 7 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Variations: you can try different values of the third parameter in read and write to understand the
working better.
The read() system call returns -1 on failure and “the count of bytes read” on success.
Important:
A common question that comes to our mind is that as a programmer you cannot guarantee how much the user
will type as an input. Hence, you can not specify the correct bytes in write() systemc all’s 3rd parameter.
Hence, the output may vary from what you expect.
Now, remember what read() returns on success! the number of bytes read, and that’s the key as demonstrated
below.
Program 7: To read data from the standard input device and write it on the screen
//read.c
#include<unistd.h>
int main()
int nread;
char buff[20];
nread=read(0,buff,10);//read 10 bytes from standard input device(keyboard), store in buffer (buff)
write(1,buff,nread);//print 10 bytes from the buffer on the screen
How it works?
This time we store the count of bytes read by read() in nread variable and then use variable in the
write() to print exactly the same number of bytes on the screen.
Page 8 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Practice Programs on write()/read() system call
Q1. Write a program to read a maximum of 15 characters from the user and print them on the
screen.
Q2. Write a program to print the count of characters read by the read() system call.
3. Open()
In the previous section on read/write system call we learned how to read from the standard input
device and how to write to a standard output device. But, normally we would either read from a user-
created file or write to a user-created file. Hence, the question comes that how do know the file
descriptor of these files because to read or to write the first parameter in the read()/write() system
calls is the file descriptor. We can use the open() system call to get the file descriptor of any file.
Syntax
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
The open() system call has two syntax. We discuss the first one here:
int open(const char *pathname, int flags);
The first parameter is the name of the file that you want to open for reading/writing. The second
parameter is the mode in which to open the file i.e., for reading or for writing. For reading from a
file, the flag used is O_RDONLY, for writing O_WRONLY and for both reading and writing
Page 9 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
O_RDWR.
Other commonly used flags are given in below table
Value Meaning
O_RDONLY Open the file so that it is read only.
O_WRONLY Open the file so that it is write only.
O_RDWR Open the file so that it can be read from and written to.
O_APPEND Append new information to the end of the file.
O_TRUNC Initially clear all data from the file.
O_CREAT If the file does not exist, create it. If the O_CREAT option is used, then you
mustinclude the third parameter.
O_EXCL Combined with the O_CREAT option, it ensures that the caller must create
the file.If the file already exists, the call will fail.
On success, the open() system call return the file descriptor of the file. This descriptor now can be
used in read()/write() system call for further processing. The value of the file descriptor will always
be a positive number greater than 2. Whereas on failure it returns -1.
Program 1: Write a program using open() system call to read the first 10 characters of an existing
file “test.txt” and print them on screen.
//open.c
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
Page 10 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
#include<fcntl.h>
int main()
int n,fd;
char buff[50];
fd=open("test.txt",O_RDONLY); //opens test.txt in read mode and the file descriptor is saved in
integer fd.
printf("The file descriptor of the file is: %d\n,fd); // the value of the file descriptor is printed.
n=read(fd,buff,10);//read 10 characters from the file pointed to by file descriptor fd and save them in
buffer (buff)
write(1,buff,n); //write on the screen from the buffer
How it works?
First, create a file “test.txt” and write some content into it(more than 10 characters). The open() system
call opens the file test.txt in read-only mode and returns the file descriptor. This file descriptor is
saved in variable ‘fd’. You can print it to check the value of file descriptor of the file. next, use read()
to read 10 characters from the file into the buffer. Finally, the buffer values are printed on the screen.
The file descriptor used here is ‘0’ which is the file descriptor for standard output device.
Output
Step1: create the file test.txt and write “1234567890abcdefghij54321” into it
$nano test.txt
Step2: compile the program
$gcc open.c
Step3: run
$./a.out
Page 11 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Syntax 2:
The second syntax is used when the file involved does not already exist in the system and you want
to create it on the go.
int open(const char *pathname, int flags, mode_t mode);
The first parameter is the file name. The second parameter is the mode (read/write). In this case
apart from writing O_RDONLY, O_WRONLY and O_RDWR you also need to write O_CREAT,
to create the file. The third parameter specifies the permissions on the created file
(read/write/execute).
Note: O_RDONLY and O_WRONLY flags are different from read and write permission in the
manner that even if a file has write permission on it it will not open in write mode until you specify
the O_WRONLY mode.
Now, we extend Program 1 to read from file text.txt and write the contents into a existing file
“towrite.txt”
Program2: To read 10 characters from file “test.txt” and write them into non-existing file
“towrite.txt”
//open2.c
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
Page 12 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
{
int n,fd,fd1;
char buff[50];
fd=open("test.txt",O_RDONLY);
n=read(fd,buff,10);
fd1=open("towrite.txt",O_WRONLY|O_CREAT,0642);//use the pipe symbol (|) to separate
O_WRONLY and O_CREAT. 6 for user, 4 is for group and 2 is write for others.
write(fd1,buff,n);
How it works?
In this we open the “towrite.txt” in write mode and also use O_CREAT to create it with read and
write permission for user, read for the group and write for others. The data is read from test.txt using
file descriptor fd and stored in buff. It is then written from buff array into file towrite.txt using file
descriptor fd1.
Output
Page 13 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
[ Practice Tasks ]
Task-1. Program to Open a File
This program opens a file and checks if it was opened successfully.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDONLY); // Open file in read-only mode
if (fd == -1) {
perror("Error opening file");
return 1;
}
printf("File opened successfully with file descriptor: %d\n", fd);
close(fd); // Close the file
return 0;
}
Explanation:
• open("example.txt", O_RDONLY): Opens example.txt in read-only mode.
• If the file is opened successfully, it prints the file descriptor; otherwise, it shows an error.
Task-2. Program to Write to a File
This program opens a file and writes some text into it.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_WRONLY | O_CREAT, 0644); // Open for writing,
create if doesn't exist
if (fd == -1) {
perror("Error opening file");
return 1;
}
const char *text = "Hello, World!\n";
ssize_t bytes_written = write(fd, text, 13); // Write data to file
Page 14 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
if (bytes_written == -1) {
perror("Error writing to file");
close(fd);
return 1;
}
printf("Successfully wrote %ld bytes to the file\n", bytes_written);
close(fd); // Close the file
return 0;
}
Explanation:
• open("example.txt", O_WRONLY | O_CREAT, 0644): Opens example.txt for writing,
creating it with permissions 0644 if it doesn’t exist.
• write(fd, text, 13): Writes "Hello, World!\n" to the file.
Task-3. Program to Read from a File
This program opens a file and reads content from it.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd = open("example.txt", O_RDONLY); // Open file in read-only mode
if (fd == -1) {
perror("Error opening file");
return 1;
}
char buffer[100];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1); // Read up to 99
bytes
if (bytes_read == -1) {
perror("Error reading from file");
close(fd);
return 1;
}
buffer[bytes_read] = '\0'; // Null-terminate the buffer for printing
printf("Data read from file:\n%s\n", buffer);
close(fd); // Close the file
return 0;
}
Page 15 of 16
UNIVERSITY OF CHAKWAL
DEPARTMENT OF COMPUTER SCIENCE
& INFORMATION TECHNOLOGY
(Operating Systems)
Explanation:
• read(fd, buffer, sizeof(buffer) - 1): Reads up to 99 bytes into buffer.
• buffer[bytes_read] = '\0': Adds a null terminator to print the string.
Home Tasks
Q1. Write a program to read the contents of file F1 into file F2. The contents of file F2 should not
get deleted or overwritten.
hint: use O_APPEND flag
Q2. Write a program using open() system call to copy the contents of one file into another file.
Page 16 of 16