System Programming & Operating System: A Laboratory Manual FOR
System Programming & Operating System: A Laboratory Manual FOR
A LABORATORY MANUAL
FOR
SYSTEM PROGRAMMING & OPERATING
SYSTEM
LABORATORY MANUAL
Prepared By
Prof. Faraz Bagwan
(Subject Teacher)
_______________________________________________________________________________________________________________________
SPOS Lab (TE EnTC, 2015 Course) A.Y. 2020-21 Laboratory Manual
______________________________________________________________________________________________________________________
Course Objectives:
• To understand system software concepts, like the use and implementation of assembler, macros,
linker, loaders and compiler.
• To get acquainted with software tools for program development.
• To explore memory allocation methods, input output devices and file system w. r. t. various
operating system.
• To study and implement various processes scheduling techniques and dead lock avoidance schemes
in operating system.
Course Outcomes:
CO1: On completion of the course, student will be able to
CO2: Demonstrate the knowledge of Systems Programming and Operating Systems
CO3: Formulate the Problem and develop the solution for same.
CO4: Compare and analyse the different implementation approach of system programming
operating system abstractions.
CO5: Interpret various OS functions used in Linux / Ubuntu
_______________________________________________________________________________________________________________________
Department of EnTC Engineering (SE) Dr. D. Y. Patil School of Engineering, Lohegaon, Pune
Programming & Problem Solving (FE, 2015 Course), A.Y. 2018-19 Laboratory Manual
______________________________________________________________________________________________________________________
INDEX
Exp. Title of Experiment DoP DoA Remark/ Sign
No. Marks
1 a. Study of Basic Linux Commands 2-2-21 5-2-21
b. Write a shell scripting on LINUX OS
2 Write C Program to implement Lexical 16-2-21 19-2-21
Analyzer for simple arithmetic operation
3 Design of PASS I & Pass II assembler for 8-3-21 12-3-21
pseudo machine code.
4 Design of a MACRO PASS-I 23-3-21 26-3-21
5 Implement Job scheduling algorithms: FCFS, 5-4-21 9-4-21
SJF
6 Implement Bankers Algorithm for deadlock 19-4-21 23-4-21
detection and avoidance
7 Implementation of page replacement 10-5-21 14-5-21
algorithm: FIFO
8.a Study of System calls to list files, directories 8-6-21 11-6-21
8.b Study of System calls to handles process 24-5-21 28-5-21
CERTIFICATE
Class: TE EnTC Roll No. ________ University Exam Seat No. _________________________ has
completed all the practical work satisfactorily in the subject of Sys Prog. & OS Lab as
THEORY:
Note:
• Directories are denoted in blue color.
• Files are denoted in white.
• You will find similar color schemes in different flavors of Linux.
As soon as you insert this command and hit enter, the files are concatenated, but you do not
see a result. This is because Bash Shell (Terminal) is silent type. Shell Commands will
never give you a confirmation message like "OK" or "Command Successfully Executed". It will
only show a message when something goes wrong or when an error has occurred.
To view the new combo file "sample" use the command
cat sample
Note: Only text files can be displayed and combined using this command.
Creating Directories
Directories can be created on a Linux operating system using the following command
This command will create a subdirectory in your present working directory, which is usually
your "Home Directory".
CONCLUSION:
Thus, we have successfully implemented basic Linux commands.
EXPERIMENT NO: 1.b
TITLE: Write C Program to implement Lexical Analyzer for simple arithmetic operation
which creates output tables (Uniform Symbol Table or a. Identifier Table b. Literal Table
c. Symbol Table)
THEORY:
A shell script is a computer program designed to be run by the Unix/Linux shell which could
be one of the following:
• The Bourne Shell
• The C Shell
• The Korn Shell
• The GNU Bourne-Again Shell
A shell is a command-line interpreter and typical operations performed by shell scripts include
file manipulation, program execution, and printing text.
ALGORITHM:
1. Get a number
2. Use for loop or while loop to compute the factorial by using the below formula
3. fact(n) = n * n-1 * n-2 * .. 1
4. Display the result.
OUTPUT:
CONCLUSION:
Thus, we have successfully implemented a shell script for calculating factorial of a number.
EXPERIMENT NO: 2
TITLE: Write C Program to implement Lexical Analyzer for simple arithmetic operation
which creates output tables (Uniform Symbol Table or a. Identifier Table b. Literal Table
c. Symbol Table)
THEORY:
Compiler is responsible for converting high level language in machine language. There are
several phases involved in this and lexical analysis is the first phase.
Lexical analyzer reads the characters from source code and convert it into tokens.
Token Type
c identifier
= operator
a identifier
+ operator
b identifier
; separator
SOURCE CODE:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int main(){
char ch, buffer[15], operators[] = "+-*/%=";
FILE *fp;
int i,j=0;
fp = fopen("program.txt","r");
if(fp == NULL){
printf("error while opening the file\n");
exit(0);
}
while((ch = fgetc(fp)) != EOF){
for(i = 0; i < 6; ++i){
if(ch == operators[i])
printf("%c is operator\n", ch);
}
if(isalnum(ch)){
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0)){
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
printf("%s is keyword\n", buffer);
else
printf("%s is indentifier\n", buffer);
}
}
fclose(fp);
//system("PAUSE");
return 0;
}
OUTPUT:
CONCLUSION:
THEORY:
## What is an Assembler?
Assembler is a program for converting instructions that are written in low-level assembly code
into relocatable machine code and generating information along, for the loader.
It is an assembler that generates the object code directly in memory for immediate execution.
It passes through your source code only once and then it’s done. It generates instructions
by evaluating the mnemonics in operation field and finds the value of symbol and literals to
produce machine code.
When an assembler divides its tasks in two passes, it is called a Two-pass assembler.
- Pass-1:
1. Defines symbols and literals and remembers them in symbolic table form and literal
table form respectively.
2. Keep track of location counter.
3. Process pseudo-operations.
- Pass-2:
1. Generate object code by converting symbolic op-code into corresponding numeric op-
code.
2. Generate data for literals and look for values of symbols.
One-pass assembler cannot resolve issues of forward references of data symbols. It requires
all data symbols to be defined before they are being used. A Two-pass assembler solves this
confusion by devoting one pass exclusively to resolve all issues of forward referencing and
then generates object code with no chaos in the next pass.
# Algorithm Design
In our design of a Two-pass assembler, we are interested in generating machine codes from a
given set of assembly language codes. Tasks performed by the assembler in the two passes
are:
Pass 1: Define symbols and literals.
The second pass reads the program again from the beginning. Each instruction is translated
into the appropriate binary machine code. Translation includes the following operations:
After studying the tasks classification for the two passes, it is necessary to establish a
database that will work with our assembler.
Pass 1 Database
Pass 2 Database
SOURCE CODE:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Symbol *head=NULL;
reverseArray(d,0,4);
for(s=0;s<5;s++)
{
printf("%d",d[s]);
str[s] = d[s] + '0';
}
printf("\n");
printf("%s",str);
return str;
}
/*******************************************************************
HASH TABLE IS USED TO STORE THE OPCODES BEING READ
*******************************************************************/
int getHashIndex(char name[])
{
int sum=0,i=0;
while(name[i]!='\0')
{
sum+=name[i++];
}
return sum%13;
}
void insertAtIndex(Opcode *Node,int index)
{
if(hash_table[index] == NULL) //boundary condition
{
hash_table[index] = Node;
Node->next = NULL;
}
else
{
Opcode* temp = hash_table[index];
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = Node;
Node->next=NULL;
}
}
void insertIntoHashMap(Opcode *Node)
{
int index = getHashIndex(Node->name);
insertAtIndex(Node,index);
}
int *getAddressCode(char* temp)
{
Symbol * t = head;
int * val;
int num;
while(t != NULL)
{
if(!strcmp(temp,t->name))
{
num = t->add;
break;
}
t = t->next;
}
val = conBin(num);
return val;
}
char * getRegisterCode(char* temp)
{
char *s;
if (strcmp(temp,"R0") == 0)
{
s = "00000";
}
else if (strcmp(temp,"R1") == 0)
s = "00001";
else if (strcmp(temp,"R2") == 0)
s = "00010";
else if (strcmp(temp,"R3") == 0)
s = "00011";
else if (strcmp(temp,"R4") == 0)
s = "00100";
else if (strcmp(temp,"R5") == 0)
s = "00101";
else if (strcmp(temp,"R6") == 0)
s = "00110";
else if (strcmp(temp,"R7") == 0)
s = "00111";
else if (strcmp(temp,"R8") == 0)
s = "01000";
else if (strcmp(temp,"R9") == 0)
s = "01001";
else if (strcmp(temp,"R10") == 0)
s = "01010";
else if (strcmp(temp,"R11") == 0)
s = "01011";
else if (strcmp(temp,"R12") == 0)
s = "01100";
else if (strcmp(temp,"R13") == 0)
s = "01101";
else if (strcmp(temp,"R14") == 0)
s = "01110";
else if (strcmp(temp,"R15") == 0)
s = "01111";
else if (strcmp(temp,"A1") == 0)
s = "10000";
else if (strcmp(temp,"A2") == 0)
s = "10001";
else if (strcmp(temp,"A3") == 0)
s = "10010";
else if (strcmp(temp,"A4") == 0)
s = "10011";
else if (strcmp(temp,"port0") == 0)
s = "10100";
else if (strcmp(temp,"port1") == 0)
s = "10101";
return s;
}
char *getConstantCode(int temp)
{
return convertTo5BitBinaryString(temp);
}
struct Opcode* getOpcodeNode(char *op)
{
Opcode* temp = NULL;
int index = getHashIndex(op); //get hash-index for the opcode in
the hash table
if(hash_table[index] == NULL)
{
printf("Wrong Opcode");
return NULL;
}
else
{
temp = hash_table[index];
while(strcmp(temp->name,op)!=0 && temp!=NULL) //loop until
the opcode is not found or the temp pointer not pointing to NULL
{
temp = temp->next;
}
if(temp == NULL)
{
printf("Opcode not found!");
return NULL;
}
else
{
return temp;
}
}
}
char * getOpcodeFormat(Opcode* temp)
{
return temp->format;
}
int main()
{
FILE *input_opcode;
FILE *output_machine_code;
FILE *input_instructions;
int ilc=0; //Instruction Location Counter
int base = 0;
char c,c2,c3,temp;
char opcode[100];
char machine_code[100];
char format[5];
strcpy(Node->name,opcode);
//Name of the opcode is fed
strcpy(Node->code,machine_code);
//Machine code of the opcode is fed
strcpy(Node->format,format);
//Format of the opcode is fed
// printf("BEFORE INSERTING NAME:: %s ,CODE:: %s and
format",Node->name,Node->code,Node->format);
insertIntoHashMap(Node);
if(hash_table[i]!=NULL)
{
while(temp!=NULL)
{
printf("NAME:: %s and CODE:: %s and format:: %s
\n",temp->name,temp->code,temp->format);
temp = temp->next;
}
}
}
printf("Now reading Opcodes and Converting them to machine
codes\n");
input_instructions = fopen("input_instructions.txt","r+");
output_machine_code = fopen("output_machine_code.txt","w+");
char k;
char op[100];
/********************************************************************
***************************/
/*First pass for generation of symbol table*/
while(op[l+1]!='\0')
{
if(op[l]==':') //Its a label
{
Symbol *t;
struct Symbol *temp = (struct Symbol*)
malloc(sizeof(Symbol)); //dynamic memory allocation for a node of
symbol
int i=0;
for(;i<l;i++)
temp->name[i] = op[i];
temp->name[i] = '\0';
temp->add = ilc + 1 + base;
temp->next = NULL;
if(head == NULL) //boundary condition for implementing
symbol table using linked list
head = temp;
else //adding new symbol node to existing table of nodes
{
t = head;
while(t->next!=NULL)
t= t->next;
t->next = temp;
}
//handle label
}
l++;
}
ilc++;
}
fclose(input_instructions);
/********************************************************************
***************************/
/*Second pass for generation of binary codes*/
input_instructions = fopen("input_instructions.txt","r+");
int * binary;
char test[100];
int count;
do
{
k=fscanf(input_instructions,"%s",op);
printf("WORD SCANNED IS %s \n",op);
/*check if opcode or label*/
int l=0;
while(op[l+1]!='\0')
{
l++;
}
if(op[l]==':') //Its a label
{
printf("Label Found!\n");
fprintf(output_machine_code,"\n");
//handle label
}
else
{
char temp[100];
char temp2[100];
char temp3[100];
int temp4;
//handle opcode and print corresponding machine code
Opcode* current_node = getOpcodeNode(op);
fprintf(output_machine_code,"%s",current_node-
>code);//print machine code of the opcode
if (strcmp("z",getOpcodeFormat(current_node))==0)
//ZERO OPERAND INSTRUCTION
{
fprintf(output_machine_code,"\n");//Do nothing
}
else if(strcmp("r",getOpcodeFormat(current_node))==0)
//ONE OPERAND REGISTER OPERAND INSTRUCTION
{
k = fscanf(input_instructions,"%s",temp); //read
corresponding register code
fprintf(output_machine_code,"%s",getRegisterCode(temp)); //write
corresponding register code in binary
fprintf(output_machine_code,"\n");
}
else if(strcmp("a",getOpcodeFormat(current_node))==0)
//ONE OPERAND ADDRESS OPERAND INSTRUCTION
{
k = fscanf(input_instructions,"%s",temp);
binary = getAddressCode(temp); //write corresponding
address in binary
for(count=0;count<10;count++)
{
fprintf(output_machine_code,"%d",binary[count]);
}
fprintf(output_machine_code,"\n");
}
else if(strcmp("rr",getOpcodeFormat(current_node))==0)
//TWO OPERAND REGISTER REGISTER OPERAND INSTRUCTION
{
//printf("inside two");
k = fscanf(input_instructions,"%s",temp);
k = fscanf(input_instructions,"%s",temp2);
fprintf(output_machine_code,"%s",getRegisterCode(temp));
fprintf(output_machine_code,"%s",getRegisterCode(temp2));
fprintf(output_machine_code,"\n");
}
else if(strcmp("ri",getOpcodeFormat(current_node))==0)
//TWO OPERAND REGISTER CONSTANT INSTRUCTION
{
k = fscanf(input_instructions,"%s",temp);
k = fscanf(input_instructions,"%d",&temp4);
fprintf(output_machine_code,"%s",getRegisterCode(temp));
//
fprintf(output_machine_code,"%s",getConstantCode(temp4));
binary = conBin(temp4);
for(count=0;count<10;count++)
{
fprintf(output_machine_code,"%d",binary[count]);
}
fprintf(output_machine_code,"\n");
}
else if(strcmp("rrr",getOpcodeFormat(current_node))==0)
//THREE OPERAND REGISTER-REGISTER-REGISTER INSTRUCTION
{
k = fscanf(input_instructions,"%s",temp);
k = fscanf(input_instructions,"%s",temp2);
k = fscanf(input_instructions,"%s",temp3);
fprintf(output_machine_code,"%s",getRegisterCode(temp));
fprintf(output_machine_code,"%s",getRegisterCode(temp2));
fprintf(output_machine_code,"%s",getRegisterCode(temp3));
fprintf(output_machine_code,"\n");
}
else if(strcmp("rri",getOpcodeFormat(current_node))==0)
//THREE OPERAND REGISTER-REGISTER-INTERMEDIATE INSTRUCTION
{
k = fscanf(input_instructions,"%s",temp);
k = fscanf(input_instructions,"%s",temp2);
k = fscanf(input_instructions,"%d",&temp4);
fprintf(output_machine_code,"%s",getRegisterCode(temp));
fprintf(output_machine_code,"%s",getRegisterCode(temp2));
binary = conBin(temp4);
for(count=0;count<10;count++)
{
fprintf(output_machine_code,"%d",binary[count]);
}
fprintf(output_machine_code,"\n");
}
}
OUTPUT:
CONCLUSION:
THEORY:
A macro processor is a program that copies a stream of text from one place to another,
making a systematic set of replacements as it does so. Macro processors are often
embedded in other programs, such as assemblers and compilers. Sometimes they are
standalone programs that can be used to process any kind of text.
Macro processors have been used for language expansion (defining new language constructs
that can be expressed in terms of existing language components), for systematic text
replacements that require decision making, and for text reformatting (e.g. conditional
extraction of material from an HTML file).
ALGORITHM
1. Start.
2. Start the program execution.
3. Macro instructions are included in a separate file.
4. The instructions with ‘macro’,’mend’,’call’ on them should not be printed in the
output.
5. Print all other instructions such as start,load,store,add,sub etc with their values.
6. Stop the program execution.
7. End
SOURCE CODE:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
void main()
{ char n1,n,c1,i;
char fn[10][10],ilab[20],iopd[20],m[20][3],oper[20],opd[20];
FILE *fp1,*fp2,*p[5];
clrscr();
n=0;
fp1=fopen("z:\macin.txt","r");
while(!feof(fp1))
{
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
if(strcmp(iopd,"macro")==0)
n++;
}
printf("no.of macros=%d\n",n);
n1=n;
printf("enter the text filename \n");
for(i=0;i<n;i++)
{s
canf("%s",fn[i]);
p[i]=fopen(fn[i],"w");
}
n=0;
rewind(fp1);
while(!feof(fp1))
{
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
if(strcmp(iopd,"macro")==0)
{s
trcpy(m[n],oper);
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
while(strcmp(iopd,"mend")!=0)
{
fprintf(p[n],"%s%s%s\n",ilab,iopd,oper);
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
}
fclose(p[n]);
n++;
}}
for(i=0;i<n1;i++)
p[i]=fopen(fn[i],"r");
fp2=fopen("z:\outm.txt","w");
rewind(fp1);
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
while(!feof(fp1))
{ if(strcmp(iopd,"call")==0)
{
for(i=0;i<n1;i++)
{ if(strcmp(m[i],oper)==0)
{
rewind(p[i]);
fscanf(p[i],"%s%s%s",ilab,iopd,oper);
while(!feof(p[i]))
{
fprintf(fp2,"%s%s%s",ilab,iopd,oper);
c1=1;
fscanf(p[i],"%s%s%s",ilab,iopd,oper);
}
break;
}}} if(c1!=1)
fprintf(fp2,"%s%s%s\n",ilab,iopd,oper);
c1=0;
fscanf(fp1,"%s%s%s",ilab,iopd,oper);
}
fprintf(fp2,"%s%s%s\n",ilab,iopd,oper);
}
OUTPUT:
CONCLUSION:
THEORY:
First Come First Serve is a scheduling algorithm used by the CPU to schedule jobs. It is a
Non-Preemptive Algorithm. Priority is given according to which they are requested by the
processor. Let’s understand the concept in the following order:
The process that requests the services of CPU first, get the CPU first. This is the philosophy
used by the first come first serve algorithm.
Important Points
• It is non-preemptive
• Average waiting time is not optimal
• Cannot utilize resources in parallel
#include<stdio.h>
int main()
{
int n,bt[20],wt[20],tat[20],avwt=0,avtat=0,i,j;
printf("Enter total number of processes(maximum 20):");
scanf("%d",&n);
wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
}
for(i=0;i<n;i++)
{
tat[i]=bt[i]+wt[i];
avwt+=wt[i];
avtat+=tat[i];
printf("\nP[%d]\t\t%d\t\t%d\t\t%d",i+1,bt[i],wt[i],tat[i]);
}
avwt/=i;
avtat/=i;
printf("\n\nAverage Waiting Time:%d",avwt);
printf("\nAverage Turnaround Time:%d",avtat);
return 0;
}
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],i,j,n,total=0,pos,temp;
float avg_wt,avg_tat;
printf("Enter number of process:");
scanf("%d",&n);
temp=bt[i];
bt[i]=bt[pos];
bt[pos]=temp;
temp=p[i];
p[i]=p[pos];
p[pos]=temp;
}
wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=0;
for(j=0;j<i;j++)
wt[i]+=bt[j];
total+=wt[i];
}
avg_wt=(float)total/n;
total=0;
avg_tat=(float)total/n;
printf("\n\nAverage Waiting Time=%f",avg_wt);
printf("\nAverage Turnaround Time=%f\n",avg_tat);
}
OUTPUT: (FCFS)
OUTPUT: (SJF)
CONCLUSION:
Thus we have successfully implemented fcfs and sjf Job Scheduling Algorithm
EXPERIMENT NO: 6
THEORY:
The banker’s algorithm which is also known as avoidance algorithm is a deadlock detection
algorithm. It was developed by Edsger Dijkstra. It is designed to check the safe state
whenever a resource is requested. It takes analogy of bank, where customer request to
withdraw cash. Based on some data the cash is lent to the customer. The banker can’t give
more cash than what the customer has requested for, and the total available cash. As this
algorithm uses bank analogy so named as banker’s algorithm
The basic data structures used to implement this algorithm are given below.
Let n be the total number of processes and m be the total number of resource types in the
system.
Available: A vector of length m. It shows number of available resources of each type. If
Available[i] = k, then k instances of resource Ri are available.
Max: An n×m matrix that contain maximum demand of each process. If Max[i,j] = k, then
process Pi can request maximum k instances of resource type Rj.
Allocation: An n×m matrix that contain number of resources of each type currently allocated
to each process. If Allocation[i,j] = k, then Pi is currently allocated k instances of resource type
Rj.
Need: An n×m matrix that shows the remaining resource need of each process. If Need[i,j] =
k, then process Pi may need k more instances of resource type Rj to complete the task.
SOURCE CODE:
#include <stdio.h>
printf("\nAllocated resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", allocation[i]);
}
printf("\nAvailable resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", available[i]);
}
printf("\n");
while (counter != 0)
{
safe = 0;
for (i = 0; i < processes; i++)
{
if (running[i])
{
exec = 1;
for (j = 0; j < resources; j++)
{
if (maximum_claim[i][j] - current[i][j] >
available[j])
{
exec = 0;
break;
}
}
if (exec)
{
printf("\nProcess%d is executing\n", i + 1);
running[i] = 0;
counter--;
safe = 1;
printf("\n");
}
}
return 0;
}
OUTPUT:
CONCLUSION:
THEORY:
In an operating system that uses paging for memory management, a page replacement
algorithm is needed to decide which page needs to be replaced when new page comes in.
Page Fault – A page fault happens when a running program accesses a memory page that is
mapped into the virtual address space, but not loaded in physical memory.
Since actual physical memory is much smaller than virtual memory, page faults happen. In
case of page fault, Operating System might have to replace one of the existing pages with the
newly needed page. Different page replacement algorithms suggest different ways to decide
which page to replace. The target for all algorithms is to reduce the number of page faults.
ALGORITHM
4. Check the need of replacement from old page to new page in memory
SOURCE CODE:
#include<stdio.h>
int main()
{
int i,j,n,a[50],frame[10],no,k,avail,count=0;
printf("\n ENTER THE NUMBER OF PAGES:\n");
scanf("%d",&n);
printf("\n ENTER THE PAGE NUMBER :\n");
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("\n ENTER THE NUMBER OF FRAMES :");
scanf("%d",&no);
for(i=0;i<no;i++)
frame[i]= -1;
j=0;
printf("\tref string\t page frames\n");
for(i=1;i<=n;i++)
{
printf("%d\t\t",a[i]);
avail=0;
for(k=0;k<no;k++)
if(frame[k]==a[i])
avail=1;
if (avail==0)
{
frame[j]=a[i];
j=(j+1)%no;
count++;
for(k=0;k<no;k++)
printf("%d\t",frame[k]);
}
printf("\n");
}
printf("Page Fault Is %d",count);
return 0;
}
OUTPUT:
CONCLUSION:
THEORY:
A system call is a mechanism that provides the interface between a process and the operating
system. It is a programmatic method in which a computer program requests a service from the
kernel of the OS.
System call offers the services of the operating system to the user programs via API
(Application Programming Interface). System calls are the only entry points for the kernel
system.
SOURCE CODE:
#include <sys/types.h>
#include<stdio.h>
#include <sys/stat.h>
#include<stdlib.h>
#include <dirent.h>
DIR* dir;
char name[1000];
dir = opendir(dirName);
if (dir == 0) {
perror ("File opening error");
exit(1);
while ((dirEntry=readdir(dir)) != 0) {
sprintf(name,"%s/%s",dirName,dirEntry->d_name);
if (S_ISDIR(inode.st_mode))
printf("directory ");
else if (S_ISREG(inode.st_mode))
else
if (S_ISLNK(inode.st_mode))
else;
if (argc != 2) {
exit(0);
}
printf("\nThe content of the directory is:\n\n");
listDir(argv[1]);
OUTPUT:
CONCLUSION:
THEORY:
A system call is a mechanism that provides the interface between a process and the operating
system. It is a programmatic method in which a computer program requests a service from the
kernel of the OS.
System call offers the services of the operating system to the user programs via API
(Application Programming Interface). System calls are the only entry points for the kernel
system.
SOURCE CODE:
int main()
{
pid_t childpid; /* variable to store the child's pid */
int status; /* parent process: child's exit status */
}
else /* fork() returns new pid to the parent process */
{
printf("PARENT: I am the parent process!\n");
printf("PARENT: Here's my PID: %d\n", getpid());
printf("PARENT: The value of my copy of childpid is
%d\n", childpid);
printf("PARENT: I will now wait for my child to
exit.\n");
wait(&status); /* wait for child to exit, and store
its status */
printf("PARENT: Child's exit code is: %d\n",
WEXITSTATUS(status));
printf("PARENT: Goodbye!\n");
exit(0); /* parent exits */
}
}
else /* fork returns -1 on failure */
{
perror("fork"); /* display error message */
exit(0);
}
}
OUTPUT:
CONCLUSION: