Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
In computing, a system call is the programmatic way in which a computer program requests a
service from the kernel of the operating system it is executed on. A system call is a way for
programs to interact with the operating system. A computer program makes a system call when it
makes a request to the operating system’s kernel. System call provides the services of the operating
system to the user programs via Application Program Interface(API). It provides an interface
between a process and operating system to allow user-level processes to request services of the
operating system. System calls are the only entry points into the kernel system. All programs
needing resources must use system calls.
A system call is just what its name implies -- 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 in the kernel, there must be a mechanism to change the
mode of a process from user mode to kernel mode.
The C compiler uses a predefined library of functions (the C library) that have the names of the
system calls. The library functions
typically invoke an instruction that changes the process execution mode to kernel mode and causes
the kernel to start executing code for systemcalls. The instruction that causes the mode change is
often referred to as an "operating system trap" which is a software generated interrupt.
The library routines execute in user mode, but the system call interface is a special case of an
interrupt handler.
The library functions pass the kernel a unique number per system call in a machine dependent way
--either as a parameter to the operating system trap, in a particular
register, or on the stack -- and the kernel thus determines the specific system call the user is
invoking. In handling the operating system trap, the kernel looks up the system call number in a
table to find the address of the appropriate kernel routine that is the entry point for the system call
and to find the number of parameters the system call expects. The kernel calculates the (user)
address of the first parameter to the system call by adding (or subtracting, depending on the
direction of stack growth) an offset to the user stack pointer, corresponding to the number of the
parameters to the system call. Finally, it copies the user parameters to the "u area" and call the
appropriate system call routine.
After executing the code for the system call, the kernel determines whether there was an error. If
so, it adjusts register locations in the saved user register context, typically setting the "carry" bit for
the PS (processor status) register and copying the error number into register 0 location. If there
were no errors in the execution of the system call, the kernel clears the "carry" bit in the PS register
and copies the appropriate return values from the system call into the locations for registers 0 and 1
in the saved user register context. When the kernel returns from the operating system trap to user
mode, it returns to the library instruction after the trap instruction. The library interprets the return
values from the kernel and returns a value to the user program.
UNIX system calls are used to manage the file system, control processes, and to provide
interprocess communication. The UNIX system interface consists of about 80 system calls (as
UNIX evolves this number will increase). The following table lists about 40 of the more important
system call:
File Descriptor table: File descriptor table is the collection of integer array indices that are file
descriptors in which elements are pointers to file table entries. One unique file
descriptors table is provided in operating system for each process.
File Table Entry: File table entries is a structure In-memory surrogate for an open file, which is
created when process request to opens file and these entries maintains file position.
Standard File Descriptors: When any process starts, then that process file descriptors table’s fd(file
descriptor) 0, 1, 2 open automatically, (By default) each of these 3 fd references file table entry for a
file named /dev/tty
/dev/tty: In-memory surrogate for the terminal
Terminal: Combination keyboard/video screen
Read from stdin => read from fd 0 : Whenever we write any character from keyboard, it read
from stdin through fd 0 and save to file named /dev/tty.
Write to stdout => write to fd 1 : Whenever we see any output to the video screen, it’s from the
file named /dev/tty and written to stdout in screen through fd 1.
Write to stderr => write to fd 2 : We see any error to the video screen, it is also from that file write
to stderr in screen through fd 2.
I/O System calls
Create() : Used to create a new empty file.
Syntax in C language:
int create(char *filename, mode_t mode)
Parameter :
filename : name of the file which you want to create
mode : indicates permissions of new file.
Returns :
return first unused file descriptor (generally 3 when first creat use in process beacuse 0, 1,
2 fd are reserved)
return -1 when error
How it work in OS
Create new empty file on disk
Create file table entry
Set first unused file descriptor to point to file table entry
Return file descriptor used, -1 upon failure
Example:
When a system call returns successfully, it returns something other than -1, but it does not clear
"errno". "errno" only has meaning directly after a system call that returns an error.
When you use system calls in your programs, you should check the value returned by those system
calls. Furthermore, when a system call discovers an error, you should use the "perror()" subroutine
to print a diagnostic message on the standard error file that describes why the system call failed.
The syntax for "perror()" is:
void perror(string)
char string;
"perror()" displays the argument string, a colon, and then the error message, as directed by "errno",
followed by a newline. The output of "perror()" is displayed on "standard error". Typically, the
argument give to "perror()" is the name of the program that incurred the error,argv[0]. However,
when using subroutines and system calls on files, the related file name might be passed to
"perror()".
There are occasions where you the programmer might wish to maintain more control over the
printing of error messages than "perror()" provides -- such as with a formatted screen where the
newline printed by "perror()" would destroy the formatting. In this case, you can directly access the
same system external (global) variables that "perror()" uses. They are:
Example:
int main()
{
int i;
extern int errno, sys_nerr;
How it works in OS
Find existing file on disk
Create file table entry
Set first unused file descriptor to point to file table entry
Return file descriptor used, -1 upon failure
Example
C program for open system call
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
extern int errno;
int main()
{
// if file does not have in directory
// then file foo.txt is created.
int fd = open("abc.txt",O_WRONLY);
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;
}
close();
Tells the operating system you are done with a file descriptor and Close the file which pointed by
fd.
Syntax in C language
#include <fcntl.h>
int close(int fd);
Parameter
fd :file descriptor
Return
0 on success.
-1 on error.
How it works in the OS
Destroy file table entry referenced by element fd of file descriptor table
– As long as no other process is pointing to it!
Set element fd of file descriptor table to NULL
Example
C program for close system call
#include<stdio.h>
#include <fcntl.h>
int main()
{
int fd1 = open("abc.txt", O_RDONLY);
if (fd1 < 0)
{
perror("c1");
exit(1);
}
printf("opened the fd = % d\n", fd1);
read();
From the file indicated by the file descriptor fd, the read() function reads cnt bytes of input into the
memory area indicated by buf. A successful read() updates the access time for the file.
Syntax in C language
size_t read (int fd, void* buf, size_t cnt);
Parameters
fd: file descripter
buf: buffer to read data from
cnt: length of buffer
Returns: How many bytes were actually read
return Number of bytes read on success
return 0 on reaching end of file
return -1 on error
return -1 on signal interrupt
Important points
buf needs to point to a valid memory location with length not smaller than the specified size
because of overflow.
fd should be a valid file descriptor returned from open() to perform read operation because
if fd is NULL then read should generate error.
cnt is the requested number of bytes read, while the return value is the actual number of
bytes read. Also, some times read system call should read less bytes than cnt.
Example
C program for read system call
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
fd1=open(argv[1],O_RDWR);
if(fd1==-1)
{
perror("Error");
printf("unalbe to open file\n");
}
else
{
printf("file opend sucessfully..\n");
}
fd2=open(argv[2],O_RDWR);
if(fd2==-1)
{
perror("Error");
printf("unalbe to open file\n");
}
else
{
printf("file opend sucessfully..\n");
}
while ((n = read(fd1, buf, 10)) > 0)
write(fd2, buf, n);
return 0;
}
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.
#include <fcntl.h>
size_t write (int fd, void* buf, size_t cnt);
Parameters
fd: file descripter
buf: buffer to write data to
cnt: length of buffer
Important points
The file needs to be opened for write operations
buf needs to be at least as long as specified by cnt because if buf size less than the cnt then
buf will lead to the overflow condition.
cnt is the requested number of bytes to write, while the return value is the actual number of
bytes written. This happens when fd have a less number of bytes to write than cnt.
If write() is interrupted by a signal, the effect is one of the following:
-If write() has not written any data yet, it returns -1 and sets errno to EINTR.
-If write() has successfully written some data, it returns the number of bytes it wrote
before it was interrupted.
Example
C program for write system call
#include<stdio.h>
#include<sys/stat.h>
#include<errno.h>
#include <fcntl.h>
main()
{
int sz;
close(fd);
}
(or)
fd[0] = open("tfile",O_RDWR);
fd[1] = open("tfile",O_RDWR);
write(fd[0],buf1,strlen(buf1));
write(1, buf2, read(fd[1],buf2,12));
close(fd[0]);
close(fd[1]);
return 0;
}
rename();
C program for rename system call (mv command)
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<errno.h>
{
int fd1,fd2;
char buf[1024];
long int n;
fd1=open("new.txt",O_RDWR);
if(fd1==-1){
perror("Error:");
printf("unable to open file");
exit(1);
}
else
{
printf("file opened sucessfully with fd=%d",fd1);
}
fd2=creat("new6.txt",S_IRWXU|S_IRGRP|S_IROTH);
if(fd2==-1)
{
perror("Error:");
printf("unable to create file");
exit(2);
}
else
{
printf("file created sucessfully with fd=%d",fd2);
}
while((n=read(fd1,buf,1024))>0){
if(write(fd2,buf,n)!=n){
perror("Error");
printf("unable to write data in to second file");
}
}
return 0;
}
#include <stdio.h>
#include <fcntl.h>
int main()
{
int fd;
long position;
fd = open("datafile.dat", O_RDONLY);
if ( fd != -1)
{
position = lseek(fd, 0L, 2); /* seek 0 bytes from end-of-file */
if (position != -1)
printf("The length of datafile.dat is %ld bytes.\n", position);
else
perror("lseek error");
}
else
printf("can't open datafile.dat\n");
close(fd);
}
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
close(fd[0]);
close(fd[1]);
return 0;
}
int fd = link(argv[1],argv[2]);
if (fd ==-1)
{
// print which type of error have in a code
printf("Error Number % d\n", errno);
Output:
aditya@CSE-WEB:~$ ./a.out x2 x1
fd = 0/naditya@CSE-WEB:~$ ls -li x2 x1
19011963 -rw-rw-r-- 2 aditya aditya 6 Sep 7 14:44 x1
19011963 -rw-rw-r-- 2 aditya aditya 6 Sep 7 14:44 x2
if (fd ==-1)
{
// print which type of error have in a code
printf("Error Number % d\n", errno);