DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING TABLE OF CONTENTS
2.
3.
4.
List of Experiments for USP: Write a C/C++ POSIX compliant program to check the following limits: (i) No. of clock ticks (ii) Max. no. of child processes (iii) Max. path length (iv) Max. no. of characters in a file name (v) Max. no. of open files/ process Write a C/C++ POSIX compliant program that prints the POSIX defined configuration options supported on any given system using feature test macros. Consider the last 100 bytes as a region. Write a C/C++ program to check whether the region is locked or not. If the region is locked, print pid of the process which has locked. If the region is not locked, lock the region with an exclusive lock, read the last 50 bytes and unlock the region. Write a C/C++ program which demonstrates interprocess communication between a reader process and a writer process. Use mkfifo, open, read, write and close APIs in your program.
PAGE NO 7-15
16-23 24-30
31-38
5.
a) Write a C/C++ program that outputs the contents of its Environment list. b) Write a C / C++ program to emulate the unix ln command.
39-46
6.
Write a C/C++ program to illustrate the race condition.
47-57
7.
Write a C/C++ program that creates a zombie and then calls system to execute the ps command to verify that the process is zombie. Write a C/C++ program to avoid zombie process by forking twice. Write a C/C++ program to implement the system function.
58-65
Write a C/C++ program to set up a real-time clock interval timer using the alarm API. List of Experiments for Compiler Design: Write a C program to implement the syntax-directed definition of “if E then S1” and “if E then S1 else S2”.
79-84
Write a yacc program that accepts a regular expression as input and produce its parse tree as output.
91-99
8. 9. 10. 11.
12.
66-72 73-78
85-90
1
1.
PROGRAMS
Page
S. NO
Program 1: Aim: Write a C/C++ POSIX compliant program to check the following limits: (i) No. of clock ticks (ii) Max. no. of child processes (iii) Max. path length (iv) Max. no. of characters in a file name (v) Max. no. of open files/ process Description: Program illustrates the use of sysconf, pathconf to display the run time limits. These limits are defined in unistd.h. It is used query general system –wide, file related configuration limits. Program: #define _POSIX_SOURCE #define _POSIX_C_SOURCE 199309L #include
#include int main() { int res; if((res=sysconf(_SC_CLK_TCK))==-1) printf("error"); else printf("no. of clock ticks %d \n",res);
if((res=sysconf(_SC_CHILD_MAX))==-1) printf("error");
Page
printf("no. of child processes %d\n",res);
2
else
if((res=pathconf("/",_PC_PATH_MAX))==-1) printf("error"); else printf("Max. no. of characters in a pathname:%d\n",res);
if((res=pathconf("/",_PC_NAME_MAX))==-1) printf("error"); else printf(" Max. no. of characters in a filename:%d\n",res);
if((res=sysconf(_SC_OPEN_MAX))==-1) printf("error"); else printf("Max. no. of open files:%d\n",res); return 0; }
Page
3
Result :
Program 2 Aim: Write a C/C++ POSIX compliant program that prints the POSIX defined configuration options supported on any given system using feature test macros. Description: Program prints the POSIX defined configuration options supported on any given system. UNIX features are implemented on a POSIX conforming system. Thus, POSIX.1 defines a set of feature test macros, which, if defined on a system, System has implemented the corresponding features. These test macros, if defined, found in header. Program: #define _POSIX_SOURCE #define _POSIX_C_SOURCE 199309L #include #include int main() { #ifdef _POSIX_JOB_CONTROL printf("system supports job control\n"); #else printf("system does not support job control\n"); #endif #ifdef _POSIX_SAVED_IDS printf("system supports saved ids\n"); #else printf("system does not supports saved ids \n"); #endif #ifdef _POSIX_CHOWN_RESTRICTED printf("system supports chown restricted\n");
#endif
Page
printf("system does not support chown restricted \n");
4
#else
#ifdef _POSIX_NO_TRUNC printf("system supports no_trunc\n"); #else printf("system does not support no_trunc \n"); #endif #ifdef _POSIX_VDISABLE printf("system supports vdisable \n"); #else printf("system does not support vdisable \n"); #endif return 0; }
Page
5
Result:
Program 3 Aim: Consider the last 100 bytes as a region. Write a C/C++ program to check whether the region is locked or not. If the region is locked, print pid of the process which has locked. If the region is not locked, lock the region with an exclusive lock, read the last 50 bytes and unlock the region. Description: Program illustrates the use of fcntl for file locking. We can set the shared lock/exclusive lock to the specified region. File locking is applicable for regular files. It allows us to impose a lock on a file so that other processes cannot modify the file until it is unlocked by the process.
Program: #include #include #include #include #include #include using namespace std; int main(int argc,char* argv[]) { struct flock fvar; char buffer[100]; int fdesc; while(--argc>0){ if((fdesc=open(*++argv,O_RDWR))==-1){ printf("error\n"); continue;
fvar.l_whence=SEEK_END;
Page
fvar.l_type=F_WRLCK;
6
}
fvar.l_start=-100; fvar.l_len=100; int flag=1;
printf("\nENTER any key to getlock\n"); while(getchar()=='y');
/* Attempt to set an exclusive lock on the entire file*/ while(fcntl(fdesc,F_SETLK,&fvar)==-1){ if(fcntl(fdesc,F_GETLK,&fvar)!=-1 &&fvar.l_type!=F_UNLCK&& flag==1 && fvar.l_pid ){ cout<<*argv<<" locked by "<
fvar.l_len=100;
Page
fvar.l_start=-100;
7
fvar.l_whence=SEEK_END;
if(fcntl(fdesc,F_SETLKW,&fvar)==-1) {printf("fcntl\n");} else printf(“Unlocked\n”); } return(0); }/* main*/ Result: Terminal 1
Page
8
Terminal 2
Program 4 Aim: Write a C/C++ program which demonstrates inter-process communication between a reader process and a writer process. Use mkfifo, open, read, write and close APIs in your program. Description: Fifo files are known as named pipes.They are special pipe device files used for inter process communication.Specifically any process can attach to pipes to read,write,or readwrite data. Data written to a file are stored in a fixed size (PIPE_BUF) buffer are retrieved in a first in first out (FIFO) order. Program: #include #include #include #include #include #include #include #include using namespace std; int main(int argc, char * argv[]) { int fd; char buf[256];
if(argc!=2 &&argc!=3) { cout<<"Usage:" < []\n"; return 0; }
{
Page
if(argc==2)
9
(void)mkfifo(argv[1],S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO);
fd=open(argv[1],O_RDONLY); while(read(fd,buf,sizeof(buf))>0) cout<
}
Result: Terminal 1
Page
10
Terminal 2
Program 5 (a) Aim: Write a C/C++ program that outputs the contents of its Environment list. Description: Each program is also passed an environment list. This program illustrates how to display the value of environment variables defined in the system. Program: #include #include #include using namespace std; extern char** environ; int main () { char** var; for (var = environ; *var != NULL; ++var) printf (“%s\n”, *var); return 0; }
Page
11
Result:
Page
12
Program 5(b) Aim: 5 b) Write a C / C++ program to emulate the unix ln command Description: A hard link is a UNIX path name for a file. Most unix files have only one hardlink. However, user may create additional hard link for files via the ln command.Symbolic links can be created in the same manner as hard links,except that you must specify the –s option to the ln command. Program: #include #include #include #include using namespace std; int main(int argc,char* argv[]) { if((argc<3||argc>4)||(argc==4 &&strcmp(argv[1],"-s"))!=0) { cout<<"Error usage:"<\n"; return 0; } else if(argc==3){ if(link(argv[1],argv[2])==-1) { cout<<"error in linking\n"; return 1; } } else if(symlink(argv[2],argv[3])==-1){ cout<<"symbolic link error\n"; return 1;
}
Page
return 0;
13
}
Page
14
Result:
Page
15
PROGRAM 6 Aim: Write a C/C++ program to illustrate the race condition. Description: The goal in this program is to allow the kernel to switch between the two processes as often as possible to demonstrate the race condition.. Program:
#include #include #include #include #include using namespace std; static void charatatime(char*);
int main(void) { pid_t pid; if ((pid=fork( ))< 0) { cout<<"fork error\n"; } else if(pid==0) { charatatime("Output from child\n"); } else { charatatime("Output from parent\n"); }
static void charatatime(char *str)
Page
}
16
exit(0);
{ char *ptr; int c; setbuf(stdout,NULL);
/* set unbuffered*/
for(ptr=str;(c=*ptr++)!=0;) { sleep(1); putc(c,stdout); } }
Page
17
Result:
Program 7 Aim: Write a C/C++ program that creates a zombie and then calls system to execute the ps command to verify that the process is zombie. Description: In UNIX System terminology, a process that has terminated, but whose parent has not yet waited for it, is called a zombie. The ps command prints the state of a zombie process as Z
Program: #include #include #include #include using namespace std; int main() { pid_t child_pid; /* Create a child process. */ child_pid = fork (); if (child_pid > 0) { cout<<"This is the parent process:"<
}
Page
return 0;
18
system("ps -e -o pid,ppid,stat,cmd");
Page
19
Result
Program 8 Aim: Write a C/C++ program to avoid zombie process by forking twice. Description: Program illustrates the creation of zombie process,how to avoid it by forking twice. Program: #include #include #include #include #include #include using namespace std; int main() { pid_t pid; if ((pid=fork())< 0) { cout<<"Fork error"; } else if( pid==0) { cout<<"first child pid="< 0) cout<<"\nsecond child pid ="<
Page
if (waitpid(pid, NULL, 0)!=pid)
20
}
}
Page
21
Result:
Program 9 Aim: Write a C/C++ program to implement the system function. Description: This program demonstrates how System function reads the unix commands and displays the corresponding ouput. Program: #include #include #include #include #include using namespace std;
int main(int argc,char *argv[]) { const char *cmdstring=argv[1]; pid_t pid; int status; if (cmdstring==NULL) { cout<<"usage : %s\n"<
} else
Page
_exit(127);
22
execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
{ while(waitpid(pid, &status, 0) < 0) { if(errno!=EINTR) { status= -1; break; } } } return (status); }
Page
23
Result:
Program 10 Aim: Write a C/C++ program to set up a real-time clock interval timer using the alarm API. Description: Program illustrates to set up a real time clock interval using alarm() API. Program: #include #include #include #include using namespace std; #define INTERVAL 5 void callme(int sig_no) { alarm(INTERVAL); cout<<"\n alarm executed"; } int main( ) { struct sigaction action; sigemptyset(&action.sa_mask); action.sa_handler=(void (*)(int)) callme; action.sa_flags=SA_RESTART; int i=0; if(sigaction(SIGALRM,&action,0)==-1) { perror("sigaction"); return 1; } if(alarm(INTERVAL)==-1)
24
perror("alarm"); Page
else while(1) {cout<<"\n value="<
i++; sleep(1);
} return 0; }
Page
25
Result:
Program 11 Aim: Write a C program to implement the syntax-directed definition of “if E then S1” and “if E then S1 else S2”. Description: Program checks the if –else- construct is in proper format through grammar. Program: /* Input to the program is assumed to be syntactically correct. The expression of „if‟ statement, statement for true condition and statement for false condition are enclosed in parenthesis */ #include #include #include #include int parsecondition(char[],int,char*,int); void gen(char [],char [],char[],int); int main() { int counter = 0,stlen =0,elseflag=0; char stmt[60]; // contains the input statement char strB[54]; // holds the expression for 'if' condition char strS1[50]; // holds the statement for true condition char strS2[45]; // holds the statement for false condition clrscr(); printf("Format of „if‟ statement \n Example ...\n"); printf("if (a
gets(stmt);
Page
printf("Enter the statement \n");
26
printf("if (a
stlen = strlen(stmt); counter = counter + 2; // increment over 'if' counter = parsecondition(stmt,counter,strB,stlen); if(stmt[counter]==')') counter++; counter = counter + 3; // increment over 'then' counter = parsecondition(stmt,counter,strS1,stlen); if(stmt[counter+1]==';') { // reached end of statement, generate the output printf("\n Parsing the input statement...."); gen(strB,strS1,strS2,elseflag); getch(); return 0; }
if(stmt[counter]==')') counter++; // increment over ')' counter = counter + 3; // increment over 'else'
counter = parsecondition(stmt,counter,strS2,stlen); counter = counter + 2; // move to the end of statement if(counter == stlen) { //generate the output elseflag = 1;
getch();
Page
gen(strB,strS1,strS2,elseflag);
27
printf("\n Parsing the input statement....");
return 0; } return 0; }
/* Function : parsecondition Description : This function parses the statement from the given index to get the statement enclosed in () Input : Statement, index to begin search, string to store the condition, total string length Output : Returns 0 on failure, Non zero counter value on success */
int parsecondition(char input[],int cntr,char *dest,int totallen) { int index = 0,pos = 0; while(input[cntr]!= '(' && cntr <= totallen) cntr++; if(cntr >= totallen) return 0; index = cntr; while (input[cntr]!=')') cntr++; if(cntr >= totallen) return 0;
dest[pos]='\0'; //null terminate the string return cntr; //non zero value
Page
dest[pos++] = input[index++];
28
while(index<=cntr)
}
/* Function : gen () Description : This function generates three address code Input : Expression, statement for true condition, statement for false condition, flag to denote if the 'else' part is present in the statement output :Three address code */ void gen(char B[],char S1[],char S2[],int elsepart) { int Bt =101,Bf = 102,Sn =103; printf("\n\tIf %s goto %d",B,Bt); printf("\n\tgoto %d",Bf); printf("\n%d: ",Bt); printf("%s",S1); if(!elsepart) printf("\n%d: ",Bf); else { printf("\n\tgoto %d",Sn); printf("\n%d: %s",Bf,S2); printf("\n%d:",Sn); }
Page
29
}
Page
30
Result:
Program 12 Aim: Write a yacc program that accepts a regular expression as input and produce its parse tree as output. Description: Program it takes Regular expression as input and produce its parse tree Using syntax directed definition method.Syntax Directed Definition(SDD) is a context free grammar together with attributes and values. Program: %{ #include char str[20]; int i=0; %} %token id %left '+''/''*''-' %% E:S
{infix_postfix(str);}
S:S'+'T |S'-'T |T T:T'*'F| T'/'F |F F:id |'('S')' ; %%
{
Page
main()
31
#include
printf("\nEnter an identifier:"); yyparse(); }
yyerror() { printf("invalid"); } yylex(){ char ch=' '; while(ch!='\n'){ ch=getchar(); str[i++]=ch; if(isalpha(ch)) return id; if(ch=='+'||ch=='*'|| ch=='-'||ch=='/') return ch;} str[--i]='\0'; return(0); exit(0); }
void push(char stack[],int *top,char ch) { stack[++(*top)]=ch; }
{ return(stack[(*top)--]);
Page
32
char pop(char stack[],int *top)
}
int prec(char ch) {
switch(ch) { case '/': case '*': return 2; case '+': case '-': return 1; case '(': return 0; default: return -1; }
}
void infix_postfix(char infix[]) { int top=-1,iptr=-1,pptr=-1; char postfix[20],stack[20],stksymb,cursymb; push(stack,&top,'\0'); while((cursymb=infix[++iptr])!='\0') { switch(cursymb) case '(': push(stack,&top,cursymb); break;
while(stksymb!='(') {
33
case ')': stksymb=pop(stack,&top);
Page
{
postfix[++pptr]=stksymb; stksymb=pop(stack,&top); } break; case '*': case '/': case '+': case '-': while(prec(stack[top])>=prec(cursymb)) postfix[++pptr]=pop(stack,&top); push(stack,&top,cursymb);break; default: if(isalnum(cursymb)==0) {printf("Error in input!"); exit(0);} postfix[++pptr]=cursymb; } } while(top!=-1) postfix[++pptr]=pop(stack,&top); printf("%s\n",postfix); }
Page
34
Result:
Page
35