EX. NO:
DATE:
IMPLEMENTATION OF BASIC OS COMMANDS OF UNIX USING C
AIM:
To write a C program to implement the basic OS commands of UNIX such as,
ls
grep
cat
USAGE:
1.ls
ls lists the files in the current working directory. Without options, ls displays files in a bare format. The most common options to reveal this information or change the list of files are:
-l long format, displaying Unix file types, permissions, number of hard links, owner, group, size, date, and filename
-F appends a character revealing the nature of a file, for example, * for an executable, or / for a directory. Regular files have no suffix.
-a lists all files in the given directory, including those whose names start with "." (which are hidden files in Unix). By default, these files are excluded from the list.
-R recursively lists subdirectories. The command ls -R / would therefore list all files.
-d shows information about a symbolic link or directory, rather than about the link's target or listing the contents of a directory.
-t sort the list of files by modification time.
-h print sizes in human readable format.
$ls
Lists all files in the present working directory
Eg:$ ls
a.out fact.c ffs.c hi max.c one.sh rad1.c rr.c sjf.c su two.c
$ls –l
Lists the permission given to each file
Eg:$ ls -l
total 248
-rwxrwxr-x 1 it40 it40 6356 Feb 24 21:34 a.out
-rw-rw-r-- 1 it40 it40 0 Mar 10 23:31 f1
-rw-rw-r-- 1 it40 it40 193 Jan 6 21:58 fact
$ls –a
Displays all hidden files of the user
Eg:$ ls -a
.bash_logout fact ffs.c lg.c one.c rad .ragr.c.swp six.c ss two.c
a.out .bashrc fc.c four.c max.c .one.sh.swp rad.c .sf.c.swp sjf.c sum.c .viminfo
$ls –c
Lists all subdirectories of the file in columnwise fashion
Eg:$ ls -c
f1 ss fcfs.c nandy.sh lg.c five.c three.c fc.c
sjf. a.out sjf.c mat.c six.c rad two.c fact.c
$ls –d
Displays the root directory of the present directory
$ls –r
Reverses the order in which files and sundirectories are displayed
Eg:$ ls -r
two.sh sum.c sjf.c shivani rad.c priority.c nandy.sh lg.c five.c fc.c f1
$ls –R
Lists the files and subdirectories in hierarchial order
Eg:$ ls -R
a.out fact.c ffs.c hi max.c one.sh rad1.c rr.c sjf. su two.c
f1 fc.c five.c lg.c nandy.sh priority.c rad.c shivani sjf.c sum.c two.sh
$ls –t
Displays the files in the order of modification
Eg:$ ls -t
f1 ss fcfs.c nandy.sh lg.c five.c three.c fc.c
$ls –p
Displays files and subdirectories by a slash mark
Eg:$ ls -p
a.out fact.c ffs.c hi/ max.c one.sh rad1.c rr.c sjf. su two.c
$ls –i
Displays the node number of each file
2.Grep
$grep<pattern><filename>
Displays the line in which the given pattern is seen
$ grep include io.c
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
GREP AND LS:
#include<stdio.h>
main()
{
char c;
int n;
printf(“\nSIMULATION OF LS AND GREP COMMANDS\n”);
printf("1.List of files in the directory\n 2.List the lines\n ");
printf("Enter the option");
scanf("%d",&n);
switch(n)
{
case 1:
system("ls");/* The system() function executes a command supplied as an expression*/
break;
case 2:
system("grep printf stat2.c");
break;
}
}
OUTPUT:
$ vi grep.c
$ cc grep.c
$ ./a.out
1.List of files in the directory
2.List the lines
Enter the option 1
a1.c a.c f.c ls.c fact.c stat2.c ipc.c
a2.c b.c file1.c grep.c facts stat1.c ipc2.c
$ ./a.out
1.List of files in the directory
2.List the lines
Enter the option 2
printf("device %d\n",nf->st_dev);
printf("inode %d\n",nf->st_ino);
printf("user id %d\n",nf->st_uid);
printf("group id %d\n",nf->st_gid);
printf("block size :%d\n",nf->st_blksize);
printf("last access time %d\n",nf->st_atime);
printf("time of last modification %d\n",nf->st_atime);
printf("production mode %d \n",nf->st_mode);
printf("size of file %d\n",nf->st_size);
printf("number of links:%d\n",nf->st_nlink);
RESULT:
The basic OS commands of UNIX and their usage have been studied.
EX.NO:
DATE:
INTERPROCESS COMMUNICATION (SHARED MEMORY)
AIM:
To write a UNIX C program to implement interprocess communication using shared memory.
ALGORITHM:
Step 1: Start the program.
Step 2: Create the shared memory for parent process using shmget() system call.
Step 3: Attach the shared memory to the child process.
Step 4: Create child process using fork ().
Step 5: Parent process writes the content in the shared memory.
Step 6: The child process reads the content from the shared memory.
Step 7: Detach and release the shared memory.
Step 8: Stop the program.
DESCRIPTION:
A process creates a shared memory segment using shmget(). The original owner of a shared
memory segment can assign ownership to another user with shmctl(). It can also revoke this
assignment. Other processes with proper permission can perform various control functions on
the shared memory segment using shmctl(). Once created, a shared segment can be attached
to a process address space using shmat(). It can be detached using shmdt() (see shmop()). The
attaching process must have the appropriate permissions for shmat(). Once attached, the
process can read or write to the segment, as allowed by the permission requested in the attach
operation. A shared segment can be attached multiple times by the same process. A shared
memory segment is described by a control structure with a unique ID that points to an area of
physical memory. The identifier of the segment is called the shmid. The structure definition
for the shared memory segment control structures and prototypews can be found in
<sys/shm.h>. shmget() is used to obtain access to a shared memory segment.The key
argument is a access value associated with the semaphore ID. The size argument is the size in
bytes of the requested shared memory. The shmflg argument specifies the initial access
permissions and creation control flags. shmctl() is used to alter the permissions and other
characteristics of a shared memory segment. shmat() and shmdt() are used to attach and
detach shared memory segments. For our purpose, only the following two values are
important,
1. IPC_CREAT | 0666 for a server (i.e., creating and granting read and write access to the
server)
2. 0666 for any client (i.e., granting read and write access to the client)
There are three different ways of using keys, namely:
1. a specific integer value (e.g., 123456)
2. a key generated with function ftok( )
3. a uniquely generated key using IPC_PRIVATE (i.e., a private key).
If a resource is requested with IPC_PRIVATE in a place where a key is required, that process
will receive a unique key for that resource. Since that resource is identified with a unique key
unknown to the outsiders, other processes will not be able to share that resource and, as a
result, the requesting process is guaranteed that it owns and accesses that resource
exclusively.
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<fcntl.h>
main()
{
char *shmptr;
int shmid,child,i;
shmid=shmget(2041,30,IPC_CREAT|0666);
shmptr=shmat(shmid,0,0);
child=fork();
if(!child)
{
printf("------------PARENT WRITING------------\n");
for(i=0;i<26;i++)
{
shmptr[i]='a'+i;
putchar(shmptr[i]);
}
printf(“\n”);
}
else
{
wait(0);
printf("\n-----------CHILD READING-----------\n");
for(i=0;i<26;i++)
putchar(shmptr[i]);
shmdt(NULL);
shmctl(shmid,IPC_RMID,0)
}
}
OUTPUT:
$ vi iiiii.c
$ cc iiiii.c
$ ./a.out
PARENT WRITING
abcdefghijklmnopqrstuvwxyz
CHILD READING
abcdefghijklmnopqrstuvwxyz
RESULT:
Thus a UNIX C program to implement interprocess communication using shared memory is executed successfully.
EX.NO:
DATE:
INTERPROCESS COMMUNICATION (PIPES)
AIM:
To write a UNIX C program to implement interprocess communication using pipes.
DESCRIPTION:
This program illustrates the usage of pipe() system call. The pipe has two ends, one for
reading and the other for writing data. The program shows single process writing message to
the pipe and reading the same.
ALGORITHM:
Step 1: Start the program.
Step 2: Create a pipe structure using pipe() system call.Pipe() system call returns 2 file descriptors fd[0] and fd[1].fd[0] is opened for reading and fd[1] is opened for writing.
Step 3:Create a child process using fork() system call.
Step 4:Close the read end of the parent process using close().
Step 5:Write the data in the pipe using write().
Step 6:Close the write end of the child process using close().
Step 7:Read the data in the pipe using read()..
Step 8:Stop the program.
PROGRAM:
#include<stdio.h>
int main()
{
int fd[2],child;
char a[20];
printf("\nEnter the string to enter into the pipe:");
scanf("%s",a);
pipe(fd);
child=fork();
if(!child)
{
close(fd[0]);
write(fd[1],a,5);
}
else
{
close(fd[1]);
read(fd[0],a,5);
printf("\n The string retrieved from the pipe is %s\n",a);
}
return 0;
}
OUTPUT:
$ vi iiiiiiiiic.c
]$ cc iiiiiiiiic.c
$ ./a.out
Enter the string to enter into the pipe: srinivasan
The string retrieved from the pipe is:srinivasan
RESULT:
Thus a UNIX C program to implement interprocess communication using pipes is executed successfully.
EX.NO:
DATE:
INTERPROCESS COMMUNICATION (MESSAGE QUEUE)
AIM:
To write a UNIX C program to implement interprocess communication using message queue.
DESCRIPTION:
Two (or more) processes can exchange information via access to a common system message
queue. The sending process places via some (OS) message-passing module a message onto a
queue which can be read by another process. Each message is given an identification or type
so that processes can select the appropriate message. Before a process can send or receive a
message, the queue must be initialized (through the msgget function see below) Operations to
send and receive messages are performed by the msgsnd() and msgrcv() functions,
respectively. When a message is sent, its text is copied to the message queue. The msgsnd()
and msgrcv() functions can be performed as either blocking or non-blocking operations. Non-
blocking operations allow for asynchronous message transfer -- the process is not suspended
as a result of sending or receiving a message. In blocking or synchronous message passing
the sending process cannot continue until the message has been transferred or has even been
acknowledged by a receiver. IPC signal and other mechanisms can be employed to
implement such transfer.
ALGORITHM:
1. Start
2. create message queue using msgget( ) system call
3. while creating message queue it returns id into file
descriptor
4. print the message queue id
5. if successful rite into message queue using msgsnd()
system call
6. read the contents from message queue using msgrcv( )
system call
7. End.
PROGRAM:
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<string.h>
#include<stdlib.h>
int main(int argc,char* argv[])
{
int q_id,rc;
if(q_id=msgget(IPC_PRIVATE,0600)==-1)
perror("msgget”);
struct msgbuf
{
long mtype;
char mtext[20];
}* msg,* recv_msg;
printf(“message queue created %d\n”,q_id);
msg=(struct msgbuf*)malloc(sizeof(struct msgbuf) +strlen(“hello world”));
msg->mtype=1;
strcpy(msg->mtext,helloworld”);
free(msg);
printf(“message placed on queue successfully\n”);
printf(“msg:message is sent:\nmtype’%d’\n mtext’%s’\n”,msg->mtype,msg->mtext);
recv_msg=(struct msgbuf*)malloc(sizeof(struct msgbuf)+strlen(“hello world”));
if(rc==-1)
{
perror(“main:msgrcv”);
exit(1);
}
printf(“msgrcv:received message:\nmtype’%d’\nmtext’%s’\n”,recv_msg->mtype,recv_msg->mtext);
return 0;
}
OUTPUT:
message queue created 0
message placed on the queue successfully
msg: message is sent
mtype: 0
mtext: hello world
msgrcv:received message
mtype: 0
mtext: hello world
RESULT:
Thus a UNIX C program to implement interprocess communication using message queue is executed successfully.
EX.NO:
DATE:
IMPLEMENTATION OF FILE ALLOCATION TECHNIQUE
AIM:
To write a C program to implement File Allocation Techniques namely,
Indexed
Linked
Contiguous
DESCRIPTION:
The different file allocation techniques are:
Contiguous allocation.
Linked allocation.
Indexed allocation.
Contiguous Allocation:
This method requires each file to occupy a set of contiguous blocks on the disk. Disk addresses define a linear ordering on the disk. With this ordering, assuming that only one job is accessing the disk, accessing block b+1 after block b requires no head movement. When head movement is needed it is only one track. The IBM VM operating system uses contiguous allocation because it provides a good performance.
Contiguous allocation of a file is defined by the disk address and length of the first block. The directory entry for each file indicates the address of the starting block and length of area allocated for this file.
Accessing a file that has been allocated contiguously is easy. For sequential access, the file system remembers the disk address of the last block referenced and reads the next block when necessary. For direct access to block i of a file that starts at block b, we can immediately access block b + i. Both sequential and direct access can be supported by contiguous allocation.
Linked Allocation:
It solves all problems of contiguous allocation. In this method, each file is a linked list of disk blocks; the disk blocks may be scattered anywhere on the disk. The directory contains a pointer to the first and last blocks of the file. Each block contains a pointer to the next block. These pointers are not made available to the user.The drawback of this method is that it can be used effectively only for sequential access files. Another drawback is the space required for the pointers
Pointers use a smaller percentage of the file’s disk space. Another problem is reliability.
This method uses a File Allocation Table (FAT). This method is simple but efficient for disk-space allocation and it is used by MS-DOS and OS/2 operating systems. The table has one entry for each disc block and is indexed by block number. The FAT is used as a linked list. The directory entry contains the block number of the first block of the file. The table entry indexed by that block number then contains the block number of the next block in the file.
Indexed Allocation:
In the absence of FAT, the linked allocation cannot support efficient direct access, since the pointers to the blocks are scattered with the blocks themselves all over the disk and need to be retrieved in order. Indexed allocation solves this problem by bringing all pointers together in one location: the index block.
Each file has its own index block, which is an array of disk- block addresses. The ith entry in the index block points to the ith block of file. The directory contains the address of the index block. To read the ith block, we use the pointer in the ith index block entry to find and read the desired block.
(i)LINKED FILE ALLOCATION
PROGRAM:
#include<stdio.h>
struct file
{
char fname[50];
int start,size,block[10];
}f[50];
main()
{
int i,j,n;
printf("Enter no. of files:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter file name:");
scanf("%s",&f[i].fname);
printf("Enter starting block:");
scanf("%d",&f[i].start);
f[i].block[0]=f[i].start;
printf("Enter no.of blocks:");
scanf("%d",&f[i].size);
printf("Enter block numbers:");
for(j=1;j<=f[i].size;j++)
{
scanf("%d",&f[i].block[j]);
}
}
printf("\n--------------------------------------------------------");
printf("\n|File\t|\tstart\t|\tsize\t|\tblock\n");
printf("\n---------------------------------------------------------\n");
for(i=0;i<n;i++)
{
printf("%s\t\t%d\t\t%d\t",f[i].fname,f[i].start,f[i].size);
printf("%d",f[i].start);
for(j=0;j<=f[i].size-1;j++)
printf("--->%d",f[i].block[j+1]);
printf("\n");
printf("\n------------------------------------------------------------\n");
}
}
OUTPUT:
Enter no. of files:2
Enter file name:srinivasan
Enter starting block:3
Enter no.of blocks:3
Enter block numbers:1 2 4
Enter file name:seenu
Enter starting block:6
Enter no.of blocks:3
Enter block numbers:10 20 12
--------------------------------------------------------
|File | start | size | block
---------------------------------------------------------
srinivasan 3 3 3--->1--->2--->4
------------------------------------------------------------
seenu 6 3 6--->10--->20--->12
------------------------------------------------------------
(ii) INDEXED FILE ALLOCATION:
PROGRAM:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[100],ind,i,k,j,index[100],n,c,count=0,block;
char fname[50];
for(i=0;i<100;i++)
a[i]=0;
X:
printf("\nenter the parent file name\n");
scanf("%s",fname);
printf("enter the index block\n");
scanf("%d",&ind);
if(a[ind]!=1)
{
a[ind]=1;
printf("\nenter no of files on index\n");
scanf("%d",&n);
printf("\n\t----------------------------------------------------\n");
printf("\tfile name\tindex block\n");
printf("\t%s\t%d",fname,ind);
printf("\n\t------------------------------------------------------\n");
printf("\nenter the files....");
}
y:
for(i=0;i<n;i++)
{
scanf("%d",&index[i]);
}
for(i=0;i<n;i++)
{
if(a[index[i]]==0)
count++;
}
if(count==n)
{
for(j=0;j<n;j++)
if(ind<index[j]||ind>index[j])
a[index[j]]=1;
printf("\nfile is allocated");
printf("\nfile is indexed");
for(k=0;k<n;k++)
printf("\n%d---->%d:%d",ind,index[k],a[index[k]]);
}
else
{
exit(0);
}
}
OUTPUT:
enter the parent file name adess
enter the index block 14
enter no of files on index 5
----------------------------------------------------
file name index block
adess 14
------------------------------------------------------
enter the files....2 3 4 5 20
file is allocated
file is indexed
14->2:1
14->3:1
14->4:1
14->5:1
14->20:1
(ii) CONTIGUOUS FILE ALLOCATION:
PROGRAM:
#include<stdio.h>
main()
{
int n, len[20], i, j, k, block[100], st_add[20], mc=0;
printf("\nEnter the number of files: ");
scanf("%d",&n);
printf("\nEnter the length and the starting address of each file\n");
for(i=0;i<n;i++)
{
scanf("%d",&len[i]);
scanf("%d",&st_add[i]);
}
printf("\n------------------------------------------");
printf("\n|\tLENGTH\t|\tSTARTING ADDR\t|\n" );
printf("\n-------------------------------------------\n");
for(i=0;i<n;i++)
printf("|\t%d\t|\t%d\t\t|\n",len[i],st_add[i]);
printf("\n--------------------------------------------");
printf("\n\t\tCONTIGUOUS FILE ALLOCATION\t\t\n");
for(i=0;i<100;i++)
block[i]=1;
for(i=0;i<n;i++)
{
j=st_add[i];
{
if(block[j]==1)
{
for(k=j;k<(j+len[i]);k++)
{
if(block[k]==1)
mc++;
}
if(mc==len[i])
{
for(k=st_add[i];k<(st_add[i]+len[i]);k++)
{
block[k]=0;
}
printf("\nFile %d is allocated in memory from %dblock to %dblock...",i+1,st_add[i],st_add[i]+len[i]-1);
}
}
else
printf("\nFile %d is not allocated since length %d contiguous memory is not available from %d...",i+1,len[i],st_add[i]);
}
mc=0;
}
}
OUTPUT:
Enter the number of files: 2
Enter the length and the starting address of each file
2 3
3 4
------------------------------------------
| LENGTH | STARTING ADDR |
-------------------------------------------
| 2 | 3 |
| 3 | 4 |
--------------------------------------------
CONTIGUOUS FILE ALLOCATION
File 1 is allocated in memory from 3block to 4block...
File 2 is not allocated since length 3 contiguous memory is not available from 4
...................
RESULT:
Thus a UNIX C program to simulate indexed,linked,contiguous file allocation scheme is executed successfully.