You are on page 1of 42

11. Implement in C the following UNIX commands using System calls A. cat B. ls C. mv 12.

Write a program that takes one or more file/directory names as command line input and reports the following information on the file. A. File type. B. Number of links. C. Time of last access. D. Read, Write and Execute permissions. AIM: Implement in C the cat Unix command using system calls #include<fcntl.h> #include<sys/stat.h> #define BUFSIZE 1 int main(int argc, char **argv) { int fd1; int n; char buf; fd1=open(argv[1],O_RDONLY); printf("Welcome to AEC\n"); while((n=read(fd1,&buf,1))>0) { printf("%c",buf); /* or write(1,&buf,1); */ } return (0); } AIM: Implement in C the following ls Unix command using system calls Algorithm: 1. Start. 2. open directory using opendir( ) system call. 3. read the directory using readdir( ) system call. 4. print dp.name and dp.inode . 5. repeat above step until end of directory. 6. End #include <sys/types.h> #include <sys/dir.h> #include <sys/param.h> #include <stdio.h>

#define FALSE 0 #define TRUE 1 extern int alphasort(); char pathname[MAXPATHLEN]; main() { int count,i; struct dirent **files; int file_select(); if (getwd(pathname) == NULL ) { printf("Error getting pathn"); exit(0); } printf("Current Working Directory = %sn",pathname); count = scandir(pathname, &files, file_select, alphasort); if (count <= 0) { printf("No files in this directoryn"); exit(0); } printf("Number of files = %dn",count); for (i=1;i<count+1;++i) printf("%s \n",files[i-1]->d_name); } int file_select(struct direct *entry) { if ((strcmp(entry->d_name, ".") == 0) ||(strcmp(entry->d_name, "..") == 0)) return (FALSE); else return (TRUE); }

AIM: Implement in C the Unix command mv using system calls Algorithm: 1. Start 2. open an existed file and one new open file using open() system call 3. read the contents from existed file using read( ) system call 4. write these contents into new file using write system call using write( ) system call 5. repeat above 2 steps until eof 6. close 2 file using fclose( ) system call 7. delete existed file using using unlink( ) system 8. End.

b) mv

#include<sys/types.h> #include<sys/stat.h> #include<stdio.h> #include<fcntl.h> main( int argc,char *argv[] ) { int i,fd1,fd2; char *file1,*file2,buf[2]; file1=argv[1]; file2=argv[2]; printf("file1=%s file2=%s",file1,file2); fd1=open(file1,O_RDONLY,0777); fd2=creat(file2,0777); while(i=read(fd1,buf,1)>0) write(fd2,buf,1); remove(file1); close(fd1); close(fd2); }

$awk $2==computer && &3>1000{print}sales.txt.

13. Write a C program to emulate the UNIX ls l command. ALGORITHM : Step 1: Include necessary header files for manipulating directory. Step 2: Declare and initialize required objects. Step 3: Read the directory name form the user. Step 4: Open the directory using opendir() system call and report error if the directory is not available. Step 5: Read the entry available in the directory. Step 6: Display the directory entry ie., name of the file or sub directory. Step 7: Repeat the step 6 and 7 until all the entries were read. /* 1. Simulation of ls command */ #include<fcntl.h> #include<stdio.h> #include<unistd.h> #include<sys/stat.h> main() { char dirname[10]; DIR *p; struct dirent *d; printf("Enter directory name "); scanf("%s",dirname); p=opendir(dirname); if(p==NULL) { perror("Cannot find dir."); exit(-1); } while(d=readdir(p)) printf("%s\n",d->d_name); } SAMPLE OUTPUT: enter directory name iii.. f2

1. Write a program to display processid and groupid.

#include<stdio.h> main() { printf(pid=%d pgrp=%d,getpid(),getpgrp(0)); }

Output:pid=4267 pgrp=4267

3. Write program to display userid, groupid, processid and parent processid.

#include<stdio.h> #include<sys/types.h> #include<unistd.h> main() { printf(processid: pid=%d,getpid()); printf(parent processid: ppid=%d,getppid()); printf(userid : uid=%d,getuid());

printf(user groupid=%d,getgid()); }

Output:processid: pid=4574 parent processid: ppid=3263 processid: pid=500 user groupid=500

4. Write program to display process status before and after forking.

#include<stdio.h> main() { int fpid; printf(before forking fpid=%d,fpid); system(ps); fpid=fork(); system(ps); printf(after forking fpid=%d,fpid); }

Output:Pid tty time cmd

3263 pts/11 4865 pts/11

00:00:00 00:00:00

bash a.out

5. Write a program to create processid, parent processid and

child processid before and after forking.

#include<stdio.h> #include<sys/types.h> #include<unistd.h> main() { int fpid; printf(before forking fpid=%d pid=%d ppid= %d\n,fpid,getpid(),getppid()); fpid=fork(); if(fpid==0) { printf(child process fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); } else {

printf(parent process fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); } printf(after forking fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); }

Output:before forking fpid=13725684 pid=3753 ppid=3062 child process fpid=0 pid=3754 ppid=3753 after forking fpid=0 pid=3754 ppid=3753 parent process fpid=3754 pid=3753 ppid=3062 after forking fpid=3754 pid=3753 ppid=3062

6. Write program to demonstrate wait() system call.

#include<stdio.h> #include<sys/types.h> #include<unistd.h> main() { int fpid,status; printf(before forking fpid=%d pid=%d ppid= %d\n,fpid,getpid(),getppid());

fpid=fork(); if(fpid==0) { printf(child process fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); } else { printf(parent process fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); } Wait(status); printf(after forking fpid=%d pid=%d ppid=%d\n, fpid,getpid(),getppid()); }

Output:before forking fpid=-1081197880 pid=4004 ppid=3062 child process fpid=0 pid=4005 ppid=4004 after forking fpid=0 pid=4005 ppid=4004 parent process fpid=4005 pid=4004 ppid=3062 after forking fpid=4005 pid=4004 ppid=3062

7. Write a program to explain waiting chain of processes.

#include<stdio.h> #include<unistd.h> main() { If(fork()==0) { printf(pid=%d\t ppid=%d,getpid(),getppid()); If(fork()==0) { printf(pid=%d\t ppid=%d,getpid(),getppid()); If(fork()==0) printf(pid=%d\t ppid=%d,getpid(),getppid()); }}}

Output:pid=4311 ppid=4310 pid=4311 ppid=4312 pid=4312 ppid=4313 pid=4311 ppid=4314

8. Write a program to implement pipe() system call.

#include<stdio.h>

#include<unistd.h> main() { int pipefd[2],n; char buff[100]; if(pipe(pipefd)<0) perror(pipe error); printf(read fd=%d,write fd=%d\n,pipefd[1],pipefd[2]); if(write(pipefd[1],hello world\n,12)!=12) perror(write error); if(n=read(pipefd[0],buff,sizeof(buff)<=0)) perror(read error); write(1,buff,n); }

Output:readfd=3 writefd=4

. Write a program to create related processes (parent/child) through pipes. #include<stdio.h> #include<unistd.h> main()

{ int pid,fd[2]; char buff[10]={}; pipe(fd); pid=fork(); if(pid==0) { close(fd[0]); printf(is the child\n); write(fd[1],hello,5); } else { close(fd[1]); printf(is the parent); read(fd[0],buff,5); printf(%s,buff); }}

Output:is the child is the paent hello

10. Write a program to demonstrate the open() system call. #include<stdio.h> #include<unistd.h> #include<fctnl.h> main() { int fd1,fd2,fd3; printf(before open); fd1=open(/etc/passwd,0_RDONLY); fd2=open(/etc/passwd,0_WRONLY); fd3=open(/etc/passwd,0_RDONLY); printf(fd1=%d fd2=%d fd3=%d fd1,fd2,fd3); }

Output:before open fd1=3 fd2=-1 fd3=4

Write a program to demonstrate the read() system call. #include<stdio.h> #include<unistd.h> #include<fctnl.h> main() { int fd1; char buf1[20],buf2[20]; buf1[19]=\0; buf2[19]=\0; printf(****************\n); fd1=open(/etc/passwd,O_RDONLY); read(fd1,buf1,19); printf(fd1=%d buf1=%s\n,fd1,buf1); read(fd1,buf2,19); printf(fd1=%d buf2=%s\n,fd1,buf2); printf(*************\n); } Output:*************************** fd1=3 buf1=root:*:0:0:root:/00

fd1=4 buf2=root:*:0:0:root:/00 *************************** Write a program to demonstrate the read() system call reading two files. #include<stdio.h> #include<unistd.h> #include<fctnl.h> main() { int fd1,fd2,fd3; char buf1[20],buf2[20]; buf1[19]=\0; buf2[19]=\0; printf(****************\n); fd1=open(/etc/passwd,O_RDONLY); fd2=open(/etc/passwd,O_RDONLY); read(fd1,buf1,19); printf(fd1=%d buf1=%s\n,fd1,buf1); read(fd2,buf2,19); printf(fd2=%d buf2=%s\n,fd2,buf2); printf(*************\n); }

Output:***************

fd1=-1 buf1=8t fd2=-1 buf2=8t putty

Write a program to demonstrate the creat(), write() and close() system calls. #include<stdio.h> #include<unistd.h> #include<fctnl.h> main() { int fd1; char *buf1=I am a string; char *buf1=I am second string; printf(****************\n); fd1=creat(./testcreat.txt,O_WRONLY); write(fd1,buf1,20); write(fd1,buf2,30); printf(fd1=%d buf1=%s\n,fd1,buf1); close(fd1); chmod(./testcreat.txt,0666); printf(****************\n); }

Output:******************** fd1=3 buf1=i am a string ********************

19. Write a C program that illustrates how to execute two commands concurrently with a command pipe. Ex: - ls l | sort AIM: Implementing Pipes DESCRIPTION: A pipe is created by calling a pipe() function. int pipe(int filedesc[2]); It returns a pair of file descriptors filedesc[0] is open for reading and filedesc[1] is open for writing. This function returns a 0 if ok & -1 on error. ALGORITHM: The following is the simple algorithm for creating, writing to and reading from a pipe. 1) Create a pipe through a pipe() function call. 2) Use write() function to write the data into the pipe. The syntax is as follows write(int [],ip_string,size); int [] filedescriptor variable, in this case if int filedesc[2] is the variable, then use the filedesc[1] as the first parameter. ip_string The string to be written in the pipe. Size buffer size for storing the input 3) Use read() function to read the data that has been written to the pipe. The syntax is as follows

read(int [], char,size); PROGRAM: #include<stdio.h> #include<string.h> main() { int pipe1[2],pipe2[2],childpid; if(pipe(pipe1)<0 || pipe(pipe2) < 0) printf("pipe creation error"); if (( childpid=fork())<0) { printf("cannot fork"); } else if(childpid >0) { close(pipe1[0]); close(pipe2[1]); client(pipe2[0],pipe1[1]); while (wait((int *) 0 ) !=childpid); close(pipe1[1]); close(pipe2[0]); exit(0); } else { close(pipe1[1]); close(pipe2[0]); server(pipe1[0],pipe2[1]); close(pipe1[0]); close(pipe2[1]); exit(0); } } client(int readfd,int writefd) { int n; char buff[1024];

if(fgets(buff,1024,stdin)==NULL) printf("file name read error"); n=strlen(buff); if(buff[n-1]=='\n') n--; if(write(writefd,buff,n)!=n) printf("file name write error"); while((n=read(readfd,buff,1024))>0) if(write(1,buff,n)!=n) printf("data write error"); if(n<0) printf("data error"); } server(int readfd,int writefd) { char buff[1024],errmsg[50]; int n,fd; n=read(readfd,buff,1024); buff[n]='\0'; if((fd=open(buff,0))<0) { sprintf(buff,"file does nit exist"); write(writefd,buff,1024); } else { while((n=read(fd,buff,1024))>0) write(writefd,buff,n); } } 20. Write C programs that illustrate communication between two unrelated processes using named pipe. AIM: Implementing IPC using a FIFO (or) named pipe. DESCRIPTION: Another kind of IPC is FIFO(First in First Out) is sometimes also called as named pipe.It is like a pipe, except that it has a name.Here the name is that of a file that multiple

processes can open(), read and write to. A FIFO is created using the mknod() system call. The syntax is as follows int mknod(char *pathname, int mode, int dev); The pathname is a normal Unix pathname, and this is the name of the FIFO. The mode argument specifies the file mode access mode.The dev value is ignored for a FIFO. Once a FIFO is created, it must be opened for reading (or) writing using either the open system call, or one of the standard I/O open functions-fopen, or freopen. ALGORITHM: The following is the simple algorithm for creating, writing to and reading from a FIFO. 1) 2) Create a fifo through mknod() function call. Use write() function to write the data into the fifo. The syntax is as follows write(int [],ip_string,size); int [] filedescriptor variable, in this case if int filedesc[2] is the variable, then use the filedesc[1] as the first parameter.

ip_string The string to be written in the fifo.

Size buffer size for storing the input 3) Use read() function to read the data that has been written to the fifo. The syntax is as follows read(int [], char,size); PROGRAM: #define FIFO1 "Fifo1" #define FIFO2 "Fifo2" #include<stdio.h> #include<string.h> #include<sys/types.h> #include<fcntl.h>

#include<sys/stat.h> main() { int childpid,wfd,rfd; mknod(FIFO1,0666|S_IFIFO,0); mknod(FIFO2,0666|S_IFIFO,0); if (( childpid=fork())==-1) { printf("cannot fork"); } else if(childpid >0) { wfd=open(FIFO1,1); rfd=open(FIFO2,0); client(rfd,wfd); while (wait((int *) 0 ) !=childpid); close(rfd); close(wfd); unlink(FIFO1); unlink(FIFO2); } else { rfd=open(FIFO1,0); wfd=open(FIFO2,1); server(rfd,wfd); close(rfd); close(wfd); } } client(int readfd,int writefd) { int n; char buff[1024]; printf ("enter s file name"); if(fgets(buff,1024,stdin)==NULL) printf("file name read error"); n=strlen(buff); if(buff[n-1]=='\n') n--;

if(write(writefd,buff,n)!=n) printf("file name write error"); while((n=read(readfd,buff,1024))>0) if(write(1,buff,n)!=n) printf("data write error"); if(n<0) printf("data error"); } server(int readfd,int writefd) { char buff[1024],errmsg[50]; int n,fd; n=read(readfd,buff,1024); buff[n]='\0'; if((fd=open(buff,0))<0) { sprintf(buff,"file does nit exist"); write(writefd,buff,1024); } else { while((n=read(fd,buff,1024))>0) write(writefd,buff,n); } } 21. Write a C program to create a message queue with read and write permissions to write 3 messages to it with different priority numbers. 22. Write a C program that receives the messages (from the above message queue as specified in (21)) and displays them. Aim: To create a message queue DESCRIPTION: Message passing between processes are part of operating system, which are done through a message queue. Where messages are stored in kernel and are associated with message queue identifier (msqid). Processes read and write messages to an arbitrary queue in a way such that a process writes a message to a queue, exits and other process reads it at later time. ALGORITHM:

Before defining a structure ipc_perm structure should be defined which is done by including following file. #include <sys/types.h> #include <sys/ipc.h> A structure of information is maintained by kernel, it should contain following. struct msqid_ds{ struct ipc_perm msg_perm; /*operation permission*/ struct msg *msg_first; /*ptr to first msg on queue*/ struct msg *msg_last; /*ptr to last msg on queue*/ ushort msg_cbytes; /*current bytes on queue*/ ushort msg_qnum; /*current no of msgs on queue*/ ushort msg_qbytes; /*max no of bytes on queue*/ ushort msg_lspid; /*pid o flast msg send*/ ushort msg_lrpid; /*pid of last msgrecvd*/ time_t msg_stime; /*time of last msg snd*/ time_t msg_rtime; /*time of last msg rcv*/ time_t msg_ctime; /*time of last msg ctl*/ }; To create new message queue or access existing message queue msgget() function is used Syntax: int msgget(key_t key ,int msgflag); Msg flag values Num val Symb value desc 0400 MSG_R Read by owner 0200 MSG_w Write by owner 0040 MSG_R >>3 Read by group 0020 MSG_W>>3 Write by group

Exp Prog:--Write a C program that illustrates the following. a) Creating a message queue. b) Writing to a message queue. c) Reading from a message queue.

#include <stdio.h> #include <sys/ipc.h> #include <fcntl.h> #define MAX 255

struct mesg { long type; char mtext[MAX]; } *mesg; char buff[MAX]; main() { int mid,fd,n,count=0;; if((mid=msgget(1006,IPC_CREAT | 0666))<0) { printf(\n Cant create Message Q); exit(1); } printf(\n Queue id:%d, mid); mesg=(struct mesg *)malloc(sizeof(struct mesg)); mesg ->type=6; fd=open(fact,O_RDONLY); while(read(fd,buff,25)>0) { strcpy(mesg ->mtext,buff); if(msgsnd(mid,mesg,strlen(mesg ->mtext),0)== -1) printf(\n Message Write Error); } if((mid=msgget(1006,0))<0) { printf(\n Cant create Message Q); exit(1); } while((n=msgrcv(mid,&mesg,MAX,6,IPC_NOWAIT))>0) write(1,mesg.mtext,n); count++; if((n= = -1)&(count= =0)) printf(\n No Message Queue on Queue:%d,mid); } Msgget returns msqid, or -1 if error 1. To put message on queue msgsnd() function is used.

Syntax: int msgsnd(int msqid , struct msgbuf *ptr,int length, int flag); msqid is message queue id, a unique id msgbuf is actual content to send, a pointer to structure which contain following struct msgbuf { Long mtype; /*message type >0 */ Char mtext[1]; /*data*/ }; length is the size of message in bytes flag is - IPC_NOWAIT which allows sys call to return immediately when no room on queue, when this is specified msgsnd will return -1 if no room on queue. Else flag can be specified as 0 2. To receive Message msgrcv() function is used Syntax: Int msgrcv(int msqid , struct msgbuf *ptr, int length, long msgtype, int flag); *ptr is pointer to structure where message received is to be stored Length is size to be received and stored in pointer area Flag has MSG_NOERROR , it returns an error if length is not large enough to receive msg, if data portion is greater than msg length it truncates and returns. 3. Variety of control operations on msg can be done through msgctl() function Int msgctl(int msqid, int cmd, struct msqid_ds *buff); IPC_RMID in cmd is given to remove a message queue from the system. Let us create a header file msgq.h with following in it #include <sys/type.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/errno.h> extern int errno; #define MKEY1 1234L #define MKEY2 2345L #define PERMS 0666

Server operation algorithm: #include msgq.h main() { Int readid, writeid; If((readid = msgget(MSGKEY1, PERMS |IPC_CREAT))<0) err_sys(Server: cant get message queue 1); If((writeid= msgget(MKEY@, PERMS | IPC_CREAT))<0) err_sys(Server : cant get message queue 2); server(readid,writeid); exit(0); }

Client process: #include msgq.h main() { int readid, writeid; /* open queues which server has already created it */ If ( (wirteid =msgget(MKEY1,0))<0) err_sys(client : cant access msgget message queue 1); if((readid=msgget(MKEY2,0))<0) err_sys(client : cant msgget messages queue 2): client(readid,writeid); /*delete msg queuu */ If (msgctl(readid, IPC_RMID,( struct msqid_ds *)0)<0) err_sys(Client: cant RMID message queue1); if(msgctl(writeid, IPC_RMID, (struct msqid_ds *) 0) <0) err_sys(Client: cant RMID message queue 2); exit(0); }

23. Write a C program to allow cooperating processes to lock a resource for exclusive use, using a) Semaphores b) flock or lockf system calls.

23. a) AIM: C program that illustrate file locking using semaphores PROGRAM: #include<stdio.h> #include<stdlib.h> #include<error.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> int main(void) { key_t key; int semid; union semun arg; if((key==ftok("sem demo.c","j"))== -1) { perror("ftok"); exit(1); } if(semid=semget(key,1,0666|IPC_CREAT))== -1) { perror("semget"): exit(1); } arg.val=1; if(semctl(semid,0,SETVAL,arg)== -1) { perror("smctl"); exit(1); } return 0; } OUTPUT: semget smctl

25. Write a C program that implements a producer-consumer system with two processes. (using Semaphores). Algorithm: 1. Start 2. create semaphore using semget( ) system call 3. if successful it returns positive value 4. create two new processes 5. first process will produce 6. until first process produces second process cannot consume 7. End. Source code: #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #include<unistd.h> #define num_loops 2 int main(int argc,char* argv[]) { int sem_set_id; int child_pid,i,sem_val; struct sembuf sem_op; int rc; struct timespec delay; clrscr(); sem_set_id=semget(ipc_private,2,0600); if(sem_set_id==-1) { perror(main:semget); exit(1); } printf(semaphore set created,semaphore setid%d\n , sem_set_id); child_pid=fork();

switch(child_pid) { case -1: perror(fork); exit(1); case 0: for(i=0;i<num_loops;i++) { sem_op.sem_num=0; sem_op.sem_op=-1; sem_op.sem_flg=0; semop(sem_set_id,&sem_op,1); printf(producer:%d\n,i); fflush(stdout); } break; default: for(i=0;i<num_loops;i++) { printf(consumer:%d\n,i); fflush(stdout); sem_op.sem_num=0; sem_op.sem_op=1; sem_op.sem_flg=0; semop(sem_set_id,&sem_op,1); if(rand()>3*(rano_max14)); { delay.tv_sec=0; delay.tv_nsec=10; nanosleep(&delay,null); } } break; } return 0; }

Output: semaphore set created

semaphore set id 327690 producer: 0 consumer:0 producer:1 consumer:1 26. Write client and server programs (using c) for interaction between server and client processes using Unix Domain sockets. /* Program For Connectionless Echo Client */ /* ************* clec.c ************ */ #include<stdio.h> #include<netinet/in.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<stdlib.h> main(int argc,char *argv[]) { int i,j,sfd,al; char to[80]; char from[1024]; struct sockaddr_in server,client; if ((sfd=socket(AF_INET,SOCK_DGRAM,0))<0) { perror("socket err"); exit(1); } //bzero((char*)&client,sizeof(client)); client.sin_family=AF_INET; client.sin_port=htons(5522); client.sin_addr.s_addr=htonl(0); if (bind(sfd,(struct sockaddr *)&client,sizeof(client))<0) { perror("bind error"); exit(1); }

write(1,"Enter Message : ",sizeof("Enter Mesage : ")); if ((i=read(0,to,sizeof(to)))<0) { perror("read error"); exit(1); } to[i-1]='\0';

//bzero((char*)&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(5000); server.sin_addr.s_addr=inet_addr("192.168.100.101"); al=sizeof(server); if ((j=sendto(sfd,to,i,0,(struct sockaddr *)&server,al))<0) { perror("sendto error"); exit(1); }

if ((i=recvfrom(sfd,from,sizeof(from),0,(struct sockaddr *)&server,&al))<0) { perror("recvfrom error"); exit(1); } from[i-1]='\0'; printf("Server Message : %s\n",from); close(sfd); }

/* Program For Connectionless Echo Server */

/* ************* cles.c ************* */ #include<stdio.h> #include<netinet/in.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<stdlib.h> main(int argc,char *argv[]) { int i,j,sfd,al; char buf[1024]; struct sockaddr_in server,client;

if ( (sfd=socket(AF_INET,SOCK_DGRAM,0))<0) { perror("socket error"); exit(1); }

//bzero((char*)&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(5000); server.sin_addr.s_addr=htonl(INADDR_ANY);

if ( bind(sfd,(struct sockaddr*)&server,sizeof(server))<0) { perror("bind error"); exit(1); } al=sizeof(client);

if ( (i=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&client,&al))<0) { perror("recvfrom error"); exit(1); } buf[i-1]='\0'; printf("Client Message : %s\n",buf);

if ( (j=sendto(sfd,buf,i,0,(struct sockaddr *)&client,al))!=i) { perror("sendto error"); exit(0); } close(sfd); }

27. Write client and server programs (using c) for interaction between server and client processes using Internet Domain sockets. /* Program For Connection Oriented Chat Client */ /* ************ cochatclient.c ************ */ #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> main() { char to[80],from[80]; char smsg[]="\nServer Message : "; char msg[]="\nEnter Your Message : ";

int sfd,i,j; struct sockaddr_in server;

if ( (sfd=socket(AF_INET,SOCK_STREAM,0))<0) { perror("socket error..."); exit(1); } bzero((char*)&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(3333); server.sin_addr.s_addr=inet_addr("192.168.100.101"); if ( connect(sfd,(struct sockaddr *)&server,sizeof(server)) < 0) { perror("connect error.."); exit(1); } for (;;) { write(0,msg,sizeof(msg)); i=read(0,to,sizeof(to)); to[i-1]='\0'; j=write(sfd,to,i); i=read(sfd,from,sizeof(from)); from[i-1]='\0'; write(1,smsg,sizeof(smsg)); write(1,from,i); } close(sfd);

/* Program For Connection Oriented Chat Server */ /* ************ cochatserver.c *********** */ #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> main() { char from[80],to[80]; char cmsg[]="\nClient Message : "; char msg[]="\nEnter Your Mesage...."; int sfd,nsfd,i,j; struct sockaddr_in server; if ( (sfd=socket(AF_INET,SOCK_STREAM,0))<0) { perror("Scoket error"); exit(1); }

bzero((char*)&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(3333); server.sin_addr.s_addr=htonl(0L);

if ( bind(sfd,(struct sockaddr *)&server,sizeof(server))<0) { perror("bind error..."); exit(1); } if (listen(sfd,5)<0) {

perror("listen error.."); exit(1); }

if ( (nsfd=accept(sfd,0,0))<0) { perror("accept error"); exit(1); } for (;;) { i=read(nsfd,from,sizeof(from)); from[i-1]='\0'; write(1,cmsg,sizeof(cmsg)); write(1,from,i); write(1,msg,sizeof(msg)); j=read(0,to,sizeof(to)); to[j-1]='\0'; write(nsfd,to,j); } close(sfd); }

28. Write a C program that illustrates two processes communicating using shared memory. DESCRIPTION:

Shared Memory is an efficeint means of passing data between programs. One program will create a memory portion which other processes (if permitted) can access. The problem with the pipes, FIFOs and message queues is that for two processes to exchange information, the information has to go through the kernel. Shared memory provides a way around this by letting two or more processes share a memory segment. In shared memory concept if one process is reading into some shared memory, for example, other processes must wait for the read to finish before processing the data. 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. It is prottyped by: int shmget(key_t key, size_t size, int shmflg); 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. When the call succeeds, it returns the shared memory segment ID. This call is also used to get the ID of an existing shared segment (from a process requesting sharing of some existing memory portion). The following code illustrates shmget(): #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ... key_t key; /* key to be passed to shmget() */ int shmflg; /* shmflg to be passed to shmget() */ int shmid; /* return value from shmget() */

int size; /* size to be passed to shmget() */ ... key = ... size = ... shmflg) = ... if ((shmid = shmget (key, size, shmflg)) == -1) { perror("shmget: shmget failed"); exit(1); } else { (void) fprintf(stderr, "shmget: shmget returned %d\n", shmid); exit(0); } ... Controlling a Shared Memory Segment shmctl() is used to alter the permissions and other characteristics of a shared memory segment. It is prototyped as follows: int shmctl(int shmid, int cmd, struct shmid_ds *buf); The process must have an effective shmid of owner, creator or superuser to perform this command. The cmd argument is one of following control commands: SHM_LOCK -- Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command. SHM_UNLOCK -- Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command. IPC_STAT -- Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command. IPC_SET -- Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command. IPC_RMID -- Remove the shared memory segment. The buf is a sructure of type struct shmid_ds which is defined in <sys/shm.h> The following code illustrates shmctl(): #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>

... int cmd; /* command code for shmctl() */ int shmid; /* segment ID */ struct shmid_ds shmid_ds; /* shared memory data structure to hold results */ ... shmid = ... cmd = ... if ((rtrn = shmctl(shmid, cmd, shmid_ds)) == -1) { perror("shmctl: shmctl failed"); exit(1); } .. Attaching and Detaching a Shared Memory Segment shmat() and shmdt() are used to attach and detach shared memory segments. They are prototypes as follows: void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr); shmat() returns a pointer, shmaddr, to the head of the shared segment associated with a valid shmid. shmdt() detaches the shared memory segment located at the address indicated by shmaddr . The following code illustrates calls to shmat() and shmdt(): #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> static struct state { /* Internal record of attached segments. */ int shmid; /* shmid of attached segment */ char *shmaddr; /* attach point */ int shmflg; /* flags used on attach */ } ap[MAXnap]; /* State of current attached segments. */ int nap; /* Number of currently attached segments. */ ... char *addr; /* address work variable */ register int i; /* work area */ register struct state *p; /* ptr to current state entry */ ... p = &ap[nap++]; p->shmid = ... p->shmaddr = ... p->shmflg = ... p->shmaddr = shmat(p->shmid, p->shmaddr, p->shmflg); if(p->shmaddr == (char *)-1) {

perror("shmop: shmat failed"); nap--; } else (void) fprintf(stderr, "shmop: shmat returned %#8.8x\n", p->shmaddr); ... i = shmdt(addr); if(i == -1) { perror("shmop: shmdt failed"); } else { (void) fprintf(stderr, "shmop: shmdt returned %d\n", i); for (p = ap, i = nap; i--; p++) if (p->shmaddr == addr) *p = ap[--nap]; } ... Algorithm: 1. Start 2. create shared memory using shmget( ) system call 3. if success full it returns positive value 4. attach the created shared memory using shmat( ) system call 5. write to shared memory using shmsnd( ) system call 6. read the contents from shared memory using shmrcv( ) system call 7. End .

Source Code: #include<stdio.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/types.h> #include<string.h> #include<sys/shm.h> #define shm_size 1024 int main(int argc,char * argv[]) { key_t key; int shmid; char *data;

int mode; if(argc>2) { fprintf(stderr,usage:stdemo[data_to_writte]\n); exit(1); } if((shmid=shmget(key,shm_size,0644/ipc_creat))==-1) { perror(shmget); exit(1); } data=shmat(shmid,(void *)0,0); if(data==(char *)(-1)) { perror(shmat); exit(1); } if(argc==2) printf(writing to segment:\%s\\n,data); if(shmdt(data)==-1) { perror(shmdt); exit(1); } return 0; } Input: #./a.out suresh Output: writing to segment suresh

You might also like