Unix Internals Lab UNIX INTERNAL LAB PROGRAMS (JNTU SYLLABUS) - VOLUME 1 Week 1 a) To write a program to display environment variables. b) To write a program implement different types of functions of exec family Week 2 a) To write a program to implement creation of stream b) To write a program to read and write a stream in a file. c) To write a program to implement to position a stream. Week 3 a) To write a program to implement adding, modifying & deleting a record in a file b) To write a program to find the status of a file. Week 4 Write a Program that takes certain file names along the command line arguments and remove if there exists any duplicates Week5 To Write a Program to find whether the file is having read, write, execute permissions and also check whether a given name is file or directory Week 6 To create chain of processes Week 7 Write a program to (a) Create semaphores b)Set values to semaphores c)Get values from semaphores d)Remove semaphores Department of CSE,MITS,Madanapalle Page 1 Unix Internals Lab Week 8 To write a program implement message queue Week 9 Write a program to (a) Create shared memory (b) Write to shared memory (c) Read from shared memory Week 10 Write a program which takes a source file name and directory name as command line argument and print a message ‘YES’, if the file is found in the given directory Department of CSE,MITS,Madanapalle Page 2 Unix Internals Lab Week 1 a) AIM: To write a program to display environment variables. DESCRIPTION: As UNIX is a multiuser operating system which involves many users can work simultaneously on a server and server maintains all the details of each user known as “User Environment”. The environment variables give several properties of user. Some of them are: HOSTNAMEIt gives the name the host computer i.e., user computer name. SHELL It gives the location of the shell in server. SSH_CLIENTIt gives the IP address and port number with which the user(client) was connected. HIST_SIZE It gives the size of the user history which had been maintained. USER It gives the user name. MAIL It gives the mailing information of the user. PATHIt gives the absolute path of the user working directory(from root). PWD It gives the path of user’s present working directory. LOGNAME It gives the login name of the user with which the user had logined. OLDPWD It gives the directory within which the present working directory of the user presents. SOURCE CODE: //This program is to display environment variables #include<stdio.h> void main(argc,argv,envp) int argc; char *argv[]; char *envp[]; { int i; for(i=0;envp[i]!=(char*)0;i++) printf("\n%s",envp[i]); } Department of CSE,MITS,Madanapalle Page 3 Unix Internals Lab INPUT/OUTPUT: HOSTNAME=linuxsr.mits.com SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=172.16.2.18 1291 22 SELINUX_USE_CURRENT_RANGE= QTDIR=/usr/lib/qt-3.3 OLDPWD=/home/11695A0510 QTINC=/usr/lib/qt-3.3/include SSH_TTY=/dev/pts/111 USER=11695A0510 LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=4 0;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;4 4:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=0 1;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01; 31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.ja r=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01; 31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*. pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.pn g=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mp eg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:* .vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc =01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*. yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aa c=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc =01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01; 36: MAIL=/var/spool/mail/11695A0510 PATH=/usr/lib/qt3.3/bin:/usr/lib/ccache:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/11695A05 10/bin PWD=/home/11695A0510/UnixLab LANG=en_US.UTF-8 KDE_IS_PRELINKED=1 KDEDIRS=/usr SELINUX_LEVEL_REQUESTED= Department of CSE,MITS,Madanapalle Page 4 Unix Internals Lab SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass HISTCONTROL=ignoredups SHLVL=1 HOME=/home/11695A0510 LOGNAME=11695A0510 QTLIB=/usr/lib/qt-3.3/lib CVS_RSH=ssh SSH_CONNECTION=172.16.2.18 1291 172.16.0.251 22 LESSOPEN=|/usr/bin/lesspipe.sh %s G_BROKEN_FILENAMES=1 Department of CSE,MITS,Madanapalle Page 5 Unix Internals Lab Week 1 b): AIM: To write a program implement different types of functions of exec family. DESCRIPTION: The’exec’ family of functions, for executing a file as a process image. You can use these functions to make a child process execute a new program after it has been forked. They are declared in the header file’unistd.h’. execl(): int execl (const char *FILENAME, const char *ARG0, ...) This is similar to’execv', but the ARGV strings are specified individually instead of as an array. A null pointer must be passed as the last such argument. execv(): int execv (const char *FILENAME, char *const ARGV[]) The’execv’ function executes the file named by FILENAME as a new process image. The ARGV argument is an array of null-terminated strings that is used to provide a value for the ’argv’ argument to the’main’ function of the program to be executed. The last element of this array must be a null pointer. execle(): int execle (const char *FILENAME, const char *ARG0, char *const ENV[], ...) This is similar to ‘execl’, but permits you to specify the environment for the new program explicitly. The environment argument is passed following the null pointer that marks the last ARGV argument, and should be an array of strings in the same format as for the ’environ’ variable. execlp(): int execlp (const char *FILENAME, const char *ARG0, ...) This function is like ’execl’, except that it performs the same file name searching as the ’execvp’ function. execve ():int execve (const char *FILENAME, char *const ARGV[], char *const ENV[]) This is similar to ’execv’, but permits you to specify the environment for the new program explicitly as the ENV argument. This should be an array of strings in the same format as for the ’environ’ variable; execvp():int execvp (const char *FILENAME, char *const ARGV[]) The ’execvp’ function is similar to ’execv’, except that it searches the directories listed in the ’PATH’ environment variable (*note Standard Environment::) to find the full file name of a file from FILENAME if FILENAME does not contain a slash. This function is useful for executing system utility programs, because it looks for them in the places that the user has chosen. Shells use it to run the commands that user’s type. Department of CSE,MITS,Madanapalle Page 6 Unix Internals Lab SOURCE CODE: //This program is to implement different types of functions of exec family. #include<unistd.h> main(){ int r; char *cmd[]={"ls","-l",(char *)0}; char *env[]={"Home=/user/home","logname=home",(char*)0}; char *argv[]={"/bin/ls/","-r","-t","-l",(char *)0}; execl("/bin/ls","-r","-t","-l",(char*)0); execv("/bin/ls",argv); execle("/bin/ls/","ls","-l",(char*)0); r=execlp("ls","ls","-l",(char*)0); r=execve("/bin/ls",cmd,env); r=execvp("ls",cmd); } INPUT/OUTPUT: total 52 -rwxrwxr-x. 1 11695A0510 11695A0510 5410 Jan 29 15:45 a.out -rw-rw-r--. 1 11695A0510 11695A0510 938 Jan 29 15:07 msgque.c -rw-rw-r--. 1 11695A0510 11695A0510 180 Jan 8 15:56 fileoperations.dat -rw-rw-r--. 1 11695A0510 11695A0510 396 Jan 8 15:54 fileoperations -rw-rw-r--. 1 11695A0510 11695A0510 1837 Jan 8 15:53 fileoperations.c -rw-rw-r--. 1 11695A0510 11695A0510 0 Jan 8 15:51 new.txt -rw-rw-r--. 1 11695A0510 11695A0510 0 Jan 8 15:50 unix.txt -rw-rw-r--. 1 11695A0510 11695A0510 311 Jan 8 15:46 filestatus.c -rw-rw-r--. 1 11695A0510 11695A0510 591 Jan 1 16:01 readWriteStream.c -rw-rw-r--. 1 11695A0510 11695A0510 358 Jan 1 15:57 positionStream.c -rw-rw-r--. 1 11695A0510 11695A0510 340 Jan 1 14:35 createStream.c -rw-rw-r--. 1 11695A0510 11695A0510 380 Dec 18 15:59 execFamily.c -rw-rw-r--. 1 11695A0510 11695A0510 136 Dec 18 14:58 Welcome.c -rw-rw-r--. 1 11695A0510 11695A0510 143 Dec 18 14:53 dispEnv.c Department of CSE,MITS,Madanapalle Page 7 Unix Internals Lab Week 2 a) AIM: To write a program to implement creation of stream DESCRIPTION: The ’open’ and ’creat’ functions are declared in the header file ’fcntl.h’. creat(): int creat (const char *FILENAME, mode_t MODE) This function is obsolete, the call creat (FILENAME, MODE) is equivalent to open (FILENAME, O_WRONLY | O_CREAT | O_TRUNC, MODE). If on a 32 bit machine the sources are translated with ’_FILE_OFFSET_BITS == 64’ the function ’creat’ returns a file descriptor opened in the large file mode which enables the file handling functions to use files up to 2^63 in size and offset from -2^63 to 2^63. This happens transparently for the user since all of the low-level files handling functions are equally replaced. open(): int open (const char *FILENAME, int FLAGS[, mode_t MODE]) The ’open’ function creates and returns a new file descriptor for the file named by FILENAME. Initially, the file position indicator for the file is at the beginning of the file. The argument MODE is used only when a file is created, but it doesn't hurt to supply the argument in any case. The normal return value from ’open' is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. File access modes used for open() are as follows: O_RDONLY Open for reading only. O_RDWROpen for reading and writing. O_WRONLY Open for writing only. SOURCE CODE: #include<stdio.h> #include<fcntl.h> #include<stdlib.h> void main() { int fd;//fd gives file descriptor fd=creat("unix.txt",0666); if(fd==-1) printf("\nFile cannot be created"); else printf("\nFile is created"); fd=open("unix.txt", O_RDONLY); Department of CSE,MITS,Madanapalle Page 8 Unix Internals Lab if(fd==-1) printf("\nFile cannot be opened"); else printf("\nFile is opened\n"); } INPUT/OUTPUT: File is created File is opened Week 2 b) AIM: To write a program to read and write a stream in a file. DESCRIPTION: The ’open’ and ’creat’ functions are declared in the header file ’fcntl.h’. Open():int open (const char *FILENAME, int FLAGS[, mode_t MODE]) The ’open’ function creates and returns a new file descriptor for the file named by FILENAME. Initially, the file position indicator for the file is at the beginning of the file. The argument MODE is used only when a file is created, but it doesn't hurt to supply the argument in any case. The normal return value from ’open' is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. File access modes used for open() are as follows: O_RDONLY Open for reading only. O_RDWROpen for reading and writing. O_WRONLY Open for writing only. creat(): int creat (const char *FILENAME, mode_t MODE) This function is obsolete, the call creat (FILENAME, MODE) is equivalent to open (FILENAME, O_WRONLY | O_CREAT | O_TRUNC, MODE). If on a 32 bit machine the sources are translated with ’_FILE_OFFSET_BITS == 64’ the function ’creat’ returns a file descriptor opened in the large file mode which enables the file handling functions to use files up to 2^63 in size and offset from -2^63 to 2^63. This happens transparently for the user since all of the lowlevel files handling functions are equally replaced. The functions for performing primitive input and Input/Output operations on file descriptors: ’read', ’write', and ’lseek'. These functions are declared in the header file ’unistd.h'. read(): data type: ssize_t This data type is used to represent the sizes of blocks that can be read or written in a single operation. It is similar to ’size_t’, but must be a signed type. ssize_t read (int FILEDES, void *BUFFER, size_t SIZE) The ’read’ function reads up to SIZE bytes from the file with descriptor FILEDES, storing the results in the BUFFER. (This is not necessarily a character string, and no terminating null character is added.).The return value is the number of bytes actually read. This might be less than SIZE; A value of zero indicates end-of-file (except if the value of the SIZE argument is Department of CSE,MITS,Madanapalle Page 9 Unix Internals Lab also zero). If ’read’ returns at least one character, there is no way you can tell whether end-of-file was reached. But if you did reach the end, the next read will return zero. write(): ssize_t write (int FILEDES, const void *BUFFER, size_t SIZE) The ‘write’ function writes up to SIZE bytes from BUFFER to the file with descriptor FILEDES. The data in BUFFER is not necessarily a character string and a null character is Input/Output like any other character. The return value is the number of bytes actually written. This may be SIZE, but can always be smaller. Your program should always call ’write’ in a loop, iterating until all the data is written. In the case of an error, ’write’ returns -1. SOURCE CODE: #include<stdio.h> #include<fcntl.h> #include<stdlib.h> void main() { int fd1,fd2,size; fd1=open("createStream.c",O_RDONLY); if(fd1==-1) printf("\nFile createStream.c is not opened"); else printf("\nFile createStream.c is opened"); fd2=creat("new.txt",0666); if(fd2==-1) printf("\nFile new.txt is not created\n"); else { printf("\nFile new.txt is created\n"); exit(0); } size=sizeof(buffer); while((n=read(fd1,buffer,size))>=0) { write(fd2,buffer,n); printf("\nWritten %d",n); } } INPUT/OUTPUT: Department of CSE,MITS,Madanapalle Page 10 Unix Internals Lab File createStream.c is opened File new.txt is created Week 2 c) AIM: To write a program to implement to position a stream. DESCRIPTION: Open(): int open (const char *FILENAME, int FLAGS[, mode_t MODE]) The ’open’ function creates and returns a new file descriptor for the file named by FILENAME. Initially, the file position indicator for the file is at the beginning of the file. The argument MODE is used only when a file is created, but it doesn't hurt to supply the argument in any case. The normal return value from ’open' is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. File access modes used for open() are as follows: O_RDONLY Open for reading only. O_RDWROpen for reading and writing. O_WRONLY Open for writing only. read(): ssize_t read (int FILEDES, void *BUFFER, size_t SIZE) The ’read’ function reads up to SIZE bytes from the file with descriptor FILEDES, storing the results in the BUFFER. (This is not necessarily a character string, and no terminating null character is added.).The return value is the number of bytes actually read. This might be less than SIZE; a value of zero indicates end-of-file (except if the value of the SIZE argument is also zero). If ’read’ returns at least one character, there is no way you can tell whether end-of-file was reached. But if you did reach the end, the next read will return zero. lseek(): ’lseek’ specifies the position in the file for the next ’read’ or ’write’ operation. off_t lseek (int FILEDES, off_t OFFSET, int WHENCE) The ’lseek’ function is used to change the file position of the file with descriptor FILEDES. The WHENCE argument specifies how the OFFSET should be interpreted. SOURCE CODE: //This program is to implement to position a stream #include<stdio.h> Department of CSE,MITS,Madanapalle Page 11 Unix Internals Lab #include<fcntl.h> void main() { int fd,var,count=0; char c; fd=open("createStream.c",O_RDONLY); if(fd==-1) printf("\nFile createStream.c is not opened"); else printf("\nFile createStream.c is opened"); while((var=read(fd,&c,1))>0&&(count<4)) { printf("\n%c ",c); var=lseek(fd,0L,1); printf("var=%d\n",var); count++; } } INPUT/OUTPUT: File createStream.c is opened # var=1 i var=2 n var=3 c var=4 Week 3 a) AIM: To write a program to implement adding, modifying & deleting a record in a file. Description: fopen: fopen - open a stream #include <stdio.h> FILE *fopen(const char *filename, const char *mode); Department of CSE,MITS,Madanapalle Page 12 Unix Internals Lab The fopen() function opens the file whose pathname is the string pointed to by filename, and associates a stream with it. The argument mode points to a string beginning with one of the following sequences: r or rb Open file for reading. w or wb Truncate to zero length or create file for writing. a or ab Append; open or create file for writing at end-of-file. r+ or rb+ or r+b Open file for update (reading and writing). w+ or wb+ or w+b Truncate to zero length or create file for update. a+ or ab+ or a+b Append; open or create file for update, writing at end-of-file. fseek(), rewind() Position the file pointer in anticipition of the next read or write. Prototypes: #include <stdio.h> int fseek(FILE *stream, long offset, int whence); void rewind(FILE *stream); When doing reads and writes to a file, the OS keeps track of where you are in the file using a counter generically known as the file pointer. You can reposition the file pointer to a different point in the file using the fseek() call. Think of it as a way to randomly access you file. The first argument is the file in question, obviously. offset argument is the position that you want to seek to, and whence is what that offset is relative to. Of course, you probably like to think of the offset as being from the beginning of the file. I mean, "Seek to position 3490, that should be 3490 bytes from the beginning of the file." Well, it can be, but it doesn't have to be. Imagine the power you're wielding here. Try to command your enthusiasm. You can set the value of whence to one of three things: SEEK_SET Department of CSE,MITS,Madanapalle Page 13 Unix Internals Lab offset is relative to the beginning of the file. This is probably what you had in mind anyway, and is the most commonly used value for whence. SEEK_CUR offset is relative to the current file pointer position. So, in effect, you can say, "Move to my current position plus 30 bytes," or, "move to my current position minus 20 bytes." SEEK_END offset is relative to the end of the file. Just like SEEK_SET except from the other end of the file. Be sure to use negative values for offset if you want to back up from the end of the file, instead of going past the end into oblivion. Speaking of seeking off the end of the file, can you do it? Sure thing. In fact, you can seek way off the end and then write a character; the file will be expanded to a size big enough to hold a bunch of zeros way out to that character. Now that the complicated function is out of the way, what's this rewind() that I briefly mentioned? It repositions the file pointer at the beginning of the file: fseek(fp, 0, SEEK_SET); // same as rewind() rewind(fp); // same as fseek(fp, 0, SEEK_SET) Return Value For fseek(), on success zero is returned; -1 is returned on failure. The call to rewind() never fails. Example fseek(fp, 100, SEEK_SET); // seek to the 100th byte of the file fseek(fp, -30, SEEK_CUR); // seek backward 30 bytes from the current pos fseek(fp, -10, SEEK_END); // seek to the 10th byte before the end of file fseek(fp, 0, SEEK_SET); // seek to the beginning of the file rewind(fp); // seek to the beginning of the file fwrite: size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); Write block of data to stream Department of CSE,MITS,Madanapalle Page 14 Unix Internals Lab Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream. The postion indicator of the stream is advanced by the total number of bytes written. The total amount of bytes written is (size*count). Parameters: Ptr :Pointer to the array of elements to be written, converted to a const void*. Size : Size in bytes of each element to be written. size_t is an unsigned integral type. Count: Number of elements, each one with a size of size bytes. size_t is an unsigned integral type. Stream:Pointer to a FILE object that specifies an Input/Output stream. Return Value The total number of elements successfully written is returned. If this number differs from the count parameter, a writing error prevented the function from completing. In this case, the error indicator (ferror) will be set for the stream. If either size or count is zero, the function returns zero and the error indicator remains unchanged. size_t is an unsigned integral type. Fread: size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); Read block of data from stream Reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by ptr. The position indicator of the stream is advanced by the total amount of bytes read. The total amount of bytes read if successful is (size*count). Department of CSE,MITS,Madanapalle Page 15 Unix Internals Lab Parameters: ptr Pointer to a block of memory with a size of at least (size*count) bytes, converted to a void*. size Size, in bytes, of each element to be read. size_t is an unsigned integral type. count Number of elements, each one with a size of size bytes. size_t is an unsigned integral type. stream Pointer to a FILE object that specifies an input stream. Return Value: The total number of elements successfully read is returned. If this number differs from the count parameter, either a reading error occurred or the end-of-file was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror and feof, respectively. If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged.size_t is an unsigned integral type. SOURCE CODE: //This program is to perform adding, modifying & deleting a record in a file #include<stdio.h> #include<stdlib.h> #include<fcntl.h> struct employee{ char name[30]; int age; }emp; Department of CSE,MITS,Madanapalle Page 16 Unix Internals Lab void main() { char ch,c,sn[30],filename[30]; FILE *ft,*fp; printf("Enter the file to be opened:"); scanf("%s",&filename); fp=fopen(filename,"rb+"); if(fp==NULL) fp=fopen(filename,"wb+"); while(1){ printf("\n1.Add\n2.List\n3.Modify\n4.Delete\n5.Exit\n"); printf("Enter your choice:"); ch=getchar(); switch(ch){ case’1': fseek(fp,0,SEEK_END); c='y'; while(c=='y'){ printf("\nEnter the name and age:"); scanf("%s%d",&emp.name,&emp.age); fwrite(&emp,sizeof(emp),1,fp); c=getchar(); } break; case’2': rewind(fp); printf("\nThe list is:"); while((fread(&emp,sizeof(emp),1,fp))==1) printf("\n%s%d",emp.name,emp.age); break; case’3': c='y'; while(c=='y') { printf("Enter name to be modified:"); scanf("%s",&sn); rewind(fp); while((fread(&emp,sizeof(emp),1,fp))==1) Department of CSE,MITS,Madanapalle Page 17 Unix Internals Lab if(strcmp(emp.name,sn)==0){ printf("Enter the name and age:"); scanf("%s%d",&emp.name,&emp.age); fseek(fp,sizeof(emp),SEEK_CUR); fwrite(&emp,sizeof(emp),1,fp); } c=getchar(); } break; case’4': c='y'; while(c=='y'){ printf("\nEnter name to be deleted:"); scanf("%s",&sn); ft=fopen("temp.dat","wb+"); rewind(fp); while(fread(&emp,sizeof(emp),1,fp)==1) if(strcmp(emp.name,sn)!=0) fwrite(&emp,sizeof(emp),1,ft); fclose(fp); fclose(ft); remove(filename); rename("temp.dat",filename); fp=fopen(filename,"rb+"); c=getchar(); } break; case’5': fclose(fp); exit(0); default: printf("Enter the valid number!"); } } getch(); } INPUT/OUTPUT: 1.Add Department of CSE,MITS,Madanapalle Page 18 Unix Internals Lab 2.List 3.Modify 4.Delete 5.Exit Enter your choice:1 Enter the name and age:chiru 58 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:1 Enter the name and age:balu 49 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:1 Enter the name and age:sky 27 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:2 The list is: Chiru 58 Balu 49 Sky 27 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:3 Enter name to be modified:chiru Department of CSE,MITS,Madanapalle Page 19 Unix Internals Lab Enter the name and age:ramcharan 28 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:4 Enter name to be deleted:sky1 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:2 The list is: Chiru 58 Balu 49 1.Add 2.List 3.Modify 4.Delete 5.Exit Enter your choice:5 Week 3 b) AIM: To write a program to find the status of a file. SOURCE CODE: //This program is tofind the status of a file #include<stdio.h> #include<fcntl.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> void main(){ int fd; struct stat s; fd=open("new.txt",O_RDONLY); if(stat("new.txt",&s)==-1) Department of CSE,MITS,Madanapalle Page 20 Unix Internals Lab printf("Error!"); printf("File Status:%o",s.st_mode); close(fd); } INPUT/OUTPUT: File Status: 100664 Week 4: AIM: Write a Program that takes certain file names along the command line arguments and remove if there exists any duplicates DESCRIPTION: Files can be deleted from the file system by using the unlink() function. The unlink() function takes the file name to be removed as an argument removes the file from the file system. The unlink() function is defined in unistd.h header file. int unlink(const char *pathname); unlink() deletes a name from the file system. If that name was the last link to a file and no processes have the file open the file is deleted and the space it was using is made available for reuse. On success, zero is returned. On error, -1 is returned, and errno is set appropriately. Department of CSE,MITS,Madanapalle Page 21 Unix Internals Lab SOURCE CODE: #include <stdio.h> #include <unistd.h> #include <sys/stat.h> int main(int argc, char *argv[]){ struct stat s; int i; if(argc<2){ printf("Arguments missing!"); return 1; } for(i=1;i<argc;i++){ if(stat(argv[i],&s)==0){ if(unlink(argv[i])==0) printf("\nFile \"%s\" found and deleted.",argv[i]); else printf("\nFile \"%s\" canot be deleted.",argv[i]); } else printf("\nNo duplicates exist for file \"%s\".",argv[i]); } return 0; } Input/Output: [usr@linuxsr labcode]$ ./week4.out sample.c File "sample.c" found and deleted. Week5 Aim: To Write a Program to find whether the file is having read, write, execute permissions and also check whether a given name is file or directory Description NAME: access - check user's permissions for a file #include <unistd.h> int access(const char *pathname, int mode); access checks whether the process would be allowed to read, write or test for existence of the file (or other file system object) whose name is pathname. If pathname is a symbolic link permissions of the file referred to by this symbolic link are tested. Department of CSE,MITS,Madanapalle Page 22 Unix Internals Lab mode is a mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK, W_OK and X_OK request checking whether the file exists and has read, write and execute permissions, respectively. F_OK just requests checking for the existence of the file. RETURN VALUE On success (all requested permissions granted), zero is returned. On error (at least one bit in mode asked for a permission that is denied, or some other error occurred), -1 is returned, and errno is set appropriately. NAME: stat, fstat, lstat - get file status #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int stat(const char *file_name, struct stat *buf); int fstat(int filedes, struct stat *buf); int lstat(const char *file_name, struct stat *buf); These functions return information about the specified file. You do not need any access rights to the file to get this information but you need search rights to all directories named in the path leading to the file. stat stats the file pointed to by file_name and fills in buf. lstat is identical to stat, except in the case of a symbolic link, where the link itself is stat-ed, not the file that it refers to. fstat is identical to stat, only the open file pointed to by filedes (as returned by open(2)) is stat-ed in place of file_name. They all return a stat structure, which contains the following fields: struct stat { dev_t ino_t mode_t nlink_t uid_t gid_t dev_t off_t st_dev; /* device */ st_ino; /* inode */ st_mode; /* protection */ st_nlink; /* number of hard links */ st_uid; /* user ID of owner */ st_gid; /* group ID of owner */ st_rdev; /* device type (if inode device) */ st_size; /* total size, in bytes */ Department of CSE,MITS,Madanapalle Page 23 Unix Internals Lab blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last change */ }; The value st_size gives the size of the file (if it is a regular file or a symlink) in bytes. The size of a symlink is the length of the pathname it contains, without trailing NUL. The following POSIX macros are defined to check the file type: S_ISREG(m)is it a regular file? S_ISDIR(m)directory? S_ISCHR(m)character device? S_ISBLK(m)block device? S_ISFIFO(m)fifo? S_ISLNK(m)symbolic link? (Not in POSIX.1-1996.) S_ISSOCK(m)socket? (Not in POSIX.1-1996.) Source Code: #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<dirent.h> int main(int argc,char *argv[]) { int count; struct stat statbuf; if(argc<2) { printf("\n need some more arguments"); exit(1); } for(count=1;count<argc;count++) { if(access(argv[count],F_OK)==-1) { printf("\n %s this file or directory not found in pwd\n",argv[count]); continue; Department of CSE,MITS,Madanapalle Page 24 Unix Internals Lab } stat(argv[count],&statbuf); if(S_ISDIR(statbuf.st_ino)) printf("\n %s is a directory and its permissions are \n",argv[count]); else printf("|n %s is a file and its permissions are \n ",argv[count]); if(access(argv[count],R_OK)==0) printf("read permission \n"); if(access(argv[count],W_OK)==0) printf("write permission \n"); if(access(argv[count],X_OK)==0) printf("execute permission \n"); } exit(0); } INPUT/OUTPUT: [sudhakar.n@linuxsr ~]$ vi week5_file.c [sudhakar.n@linuxsr ~]$ cc week5_file.c [sudhakar.n@linuxsr ~]$ ./a.out test unix test is a directory and its permissions are read permission write permission execute permission unix is a directory and its permissions are read permission write permission execute permission [sudhakar.n@linuxsr ~]$ ./a.out test unix sdkf test is a directory and its permissions are read permission Department of CSE,MITS,Madanapalle Page 25 Unix Internals Lab write permission execute permission unix is a directory and its permissions are read permission write permission execute permission sdkf this file or directory not found in pwd Week 6 Aim: To create chain of processes Description: fork() System call: System call fork() is used to create processes. It takes no arguments and returns a process ID. The purpose of fork() is to create a new process, which becomes the child process of the caller. After a new child process is created, both processes will execute the next instruction following the fork() system call. Therefore, we have to distinguish the parent from the child. This can be done by testing the returned value of fork(): If fork() returns a negative value, the creation of a child process was unsuccessful. fork() returns a zero to the newly created child process. fork() returns a positive value, the process ID of the child process, to the parent. The returned process ID is of type pid_t defined in sys/types.h. Normally, the process ID is an integer. Moreover, a process can use function getpid() to retrieve the process ID assigned to this process. Department of CSE,MITS,Madanapalle Page 26 Unix Internals Lab Therefore, after the system call to fork(), a simple test can tell which process is the child. Please note that Unix will make an exact copy of the parent's address space and give it to the child. Therefore, the parent and child processes have separate address spaces. getppid and getppid System Calls: #include <sys/types.h> #include <unistd.h> pid_t getpid(void) pid_t getppid(void) Getpid() returns the process ID of the calling process. The ID is guaranteed to be unique and is useful for constructing temporary file names. Getppid() returns the process ID of the parent of the calling process. The getpid() and getppid() functions are always successful, and no return value is reserved to indicate an error. Source code: #include<fcntl.h> #include<stdio.h> int main() { if(fork()==0) { printf("%d \t %d\n",getpid(),getppid()); if(fork()==0) { printf("%d \t %d\n",getpid(),getppid()); if(fork()==0) Department of CSE,MITS,Madanapalle Page 27 Unix Internals Lab printf("%d \t %d\t hello \n",getpid(),getppid()); } } return 0; } Input/Output: [sudhakar.n@linuxsr ~]$ vi week6process.c [sudhakar.n@linuxsr ~]$ cc week6process.c [sudhakar.n@linuxsr ~]$ ./a.out 13924 13923 13925 13924 13926 13925 he Week-7 Aim: Write a program to (a) Create semaphores (b) Set values to semaphores (c) Get values from semaphores (d) Remove semaphores Description: A semaphore in UNIX is a variable that acts as a counter. A semaphore is used to control access to a resource when two or more processes try to access it at the same time. The value of the semaphore is initialized by the first process when the resource is in access by it. When the second process tries to access the resource it checks the value of the semaphore and if it finds the Department of CSE,MITS,Madanapalle Page 28 Unix Internals Lab value as initialized it does not access the resource. After the first process is completed it reinitializes the semaphore value and now the second process uses it. UNIX provides a set of functions for performing operations on semaphores. These functions are defined in sys/sem.h header file. int semctl(int semid, int semnum, int cmd, ...); The function semctl performs the control operation specified by cmd on the semaphore set identified by semid, or on the semnum-th semaphore of that set. (Semaphores are numbered starting at 0.) int semget(key_t key, int nsems, int semflg); The semget system call returns the semaphore set identifier associated with the argument key. A new set of nsems semaphores is created if key has the value IPC_PRIVATE or if no existing semaphore set is associated with key and IPC_CREAT is specified in semflg. If semflg specifies both IPC_CREAT and IPC_EXCL and a semaphore set already exists for key, then semget() fails with errno set to EEXIST. int semop(int semid, struct sembuf *sops, unsigned nsops); semop performs operations on selected semaphores in the set indicated by semid. Each of the nsops elements in the array pointed to by sops specifies an operation to be performed on a single semaphore. Source Code: #include<stdio.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/sem.h> #include<sys/ipc.h> Department of CSE,MITS,Madanapalle Page 29 Unix Internals Lab #define SEMKEY 75 int semid; unsigned int count; struct sembuf psembuf,vsembuf; main(argc,argv) int argc; char *argv[]; { int i,first,second; short initarray[2],outarray[2]; extern cleanup(); if(argc==1) { for(i=0;i<20;i++) signal(i,cleanup); semid=semget(SEMKEY,2,0777|IPC_CREAT); initarray[0]=initarray[1]=1; semctl(semid,2,SETALL,initarray); semctl(semid,2,GETALL,outarray); printf("Sem init vals %d %d \n",outarray[0],outarray[1]); pause(); } else if(argv[1][0]=='a') Department of CSE,MITS,Madanapalle Page 30 Unix Internals Lab { first=0; second=1; } else { first=1; second=0; } semid=semget(SEMKEY,2,0777); psembuf.sem_op=-1; psembuf.sem_flg=SEM_UNDO; vsembuf.sem_op=1; vsembuf.sem_flg=SEM_UNDO; for(count=0; ;count++) { psembuf.sem_num=first; semop(semid,&psembuf,1); psembuf.sem_num=second; semop(semid,&psembuf,1); printf("Proc %d count %d \n",getpid(),count); vsembuf.sem_num=second; semop(semid,&vsembuf,1); Department of CSE,MITS,Madanapalle Page 31 Unix Internals Lab vsembuf.sem_num=first; semop(semid,&vsembuf,1); if(count>1) break; } } cleanup() { semctl(semid,2,IPC_RMID,0); exit(0); } INPUT/OUTPUT:: [09BF1A0551@localhost ~]$ ./a.out a Proc 18161 count 0 Proc 18161 count 1 Proc 18161 count 2 Proc 18247 count 2 Week 8 AIM::To write a program implement message queue Description: Two (or more) processes can exchange information via access to a common system message queue. Before a process can send or receive a message, the queue must be initialized (through the msgget) Operations to send and receive messages are performed by the msgsnd() and msgrcv() functions, respectively. Department of CSE,MITS,Madanapalle Page 32 Unix Internals Lab msgget(): The msgget() function returns the message queue identifier associated with key. #include <sys/msg.h> int msgget(key_t key, int msgflg) If successful, msgget() returns a message queue identifier. On failure, msgget() returns a value of -1 and sets errno to indicate the error msgctl(): This function performs the control operation specified by cmd on the message queue with identifier msqid. #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf); On success, the return value will be 0, otherwise -1 with errno indicating the error. msgget() & msgrcv() #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg); ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg); On a failure both functions return -1 with errno indicating the error, otherwise msgsnd returns 0 and msgrvc returns the number of bytes actually copied into the mtext array. To send or receive a message, the calling process allocates a structure of the following general form: struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[1]; }; Source Code: /* message data */ #include<stdio.h> #include<time.h> #include<string.h> #include<sys/ipc.h> #include<sys/msg.h> #include<sys/wait.h> #include<sys/errno.h> Department of CSE,MITS,Madanapalle Page 33 Unix Internals Lab extern int err; #define mp 0600 #define ml 128 int msgqid,rc,done; struct msg_buf { long int mtype; char mtext[ml]; }msg; int main(int argc,char **argv) { int msgqid=msgget(IPC_PRIVATE,mp|IPC_CREAT); if(msgqid<0) { printf("Error"); return; } printf("mq %d created\n",msgqid); printf("\nTrying to send message"); msg.mtype=1; sprintf(msg.mtext,"%s","Welcome"); rc=msgsnd(msgqid,&msg,sizeof(msg.mtext),0); if(rc<0) { printf("Error"); return 1; } rc=msgrcv(msgqid,&msg,sizeof(msg.mtext),1,0); if(rc<0) { printf("Error"); return 1; } printf("\nRecieved msg:%s\n",msg.mtext); rc=msgctl(msgqid,IPC_RMID,NULL); if(rc<0) { printf("Error"); return 1; } printf("\nmsgqid %d is removed \n",msgqid); return 0; } Department of CSE,MITS,Madanapalle Page 34 Unix Internals Lab INPUT/OUTPUT::: [09BF1A0551@localhost ~]$ gcc msgque.c [09BF1A0551@localhost ~]$ ./a.out mq 786434 created Trying to send message Recieved msg:a.textmsg.... msgqid 786434 is removed Week 9 Aim: Write a program to (d) Create shared memory (e) Write to shared memory (f) Read from shared memory Department of CSE,MITS,Madanapalle Page 35 Unix Internals Lab Description: There are various ways for inter-process communication. Shared memory is the fastest and most flexible of the techniques. In this technique, information is shared by reading and writing from a common segment of memory. 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 prototypes are found in sys/shm.h header file. shmget() is used to obtain access to a shared memory segment. int shmget(key_t key, size_t size, int shmflg); The key argument is an 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. 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 cmd argument is one of following control commands: SHM_LOCK -- Lock the specified shared memory segment in memory. SHM_UNLOCK -- Unlock the shared memory segment. IPC_STAT -- Return the status information contained in the control structure and place it in the buffer pointed to by buf. IPC_SET -- Set the effective user and group identification and access permissions. IPC_RMID -- Remove the shared memory segment. shmat() and shmdt() are used to attach and detach shared memory segments. void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr); Department of CSE,MITS,Madanapalle Page 36 Unix Internals Lab 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. Source Code: #include<stdio.h> #include<sys/ipc.h> #include<sys/shm.h> #include<sys/types.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #define segsize 100 int main(int argc,char *argv[]) { int shmid,cntr; key_t key; char *segptr; char buff[]="hello world"; key=ftok(".",'s'); if(shmid=shmget(key,segsize,IPC_CREAT|IPC_EXCL|0666)==-1) { if((shmid=shmget(key,segsize,0))==-1) { printf("\nError"); Department of CSE,MITS,Madanapalle Page 37 Unix Internals Lab exit(1); } } else { printf("\nCreating a new shmid\n"); printf("\nshmid %d",shmid); } system("ipcs -m"); if((segptr=shmat(shmid,0,0))==(char *)-1) { printf("\nError"); exit(1); } printf("\nwriting data to shm....\n"); strcpy(segptr,buff); printf("\nDone\n"); printf("\nReading data from shm....\n"); printf("\nDATA %s \n",segptr); printf("\nDone\n"); printf("\nRemaining shmseg....\n"); if(shmctl(shmid,IPC_RMID,0)==-1) printf("\nCant remove shmreg.....\n"); Department of CSE,MITS,Madanapalle Page 38 Unix Internals Lab else printf("\nRemoved successfully"); } INPUT/OUTPUT:: [09BF1A0551@localhost ~]$ gcc sharedmemory.c [09BF1A0551@localhost ~]$ ./a.out ------ Shared Memory Segments -------key shmid owner perms bytes nattch status 0x7300019d 1048578 09BF1A0554666 100 0 0x53000135 327683 09BF1A0540666 100 0 0xbfbea638 393221 09BF1A0538666 100 0 0xbff39188 425990 09BF1A0538666 100 0 0xffffffff 458759 09BF1A0551666 0x00619ff4 491528 0x5300013d 524297 09BF1A0538666 100 0 100 0 09BF1A0541666 100 0 0x7300018d 1081354 09BF1A0551666 100 0 writing data to shm.... Done Reading data from shm.... DATA hello world Done Remaining shmseg.... Removed successfully Department of CSE,MITS,Madanapalle Page 39 Unix Internals Lab Week 10 Aim: Write a program which takes a source file name and directory name as command line argument and print a message ‘YES’, if the file is found in the given directory Description: The existence of a file can be determined using the access() function with the F_OK mode. If the file exists, the function returns 0 else, it returns 1. The full pathname of the file should be provided as an argument for the access() function. Department of CSE,MITS,Madanapalle Page 40 Unix Internals Lab access() checks whether the calling process can access the file pathname. The mode specifies the accessibility check(s) to be performed. The mode may be F_OK – tests for the existence of the file. Source code: #include<stdio.h> #include<unistd.h> #include<string.h> main(int argc, char *argv[]){ char *filename, *path; if(argc<2){ printf("Arguments missing!\n"); printf("Usage: FILE DIRECTORY"); return 1; } filename=argv[1]; path=argv[2]; if(path[strlen(path)-1]!='/') path=strcat(path,"/"); filename=strcat(path,filename); printf("Filename: %s",filename); if(access(filename,F_OK)==0) printf("\nYES"); else printf("\nNO"); return 0; } Input/Output: [usr@linuxsr labcode]$ ./week10.out week1a.c /home/usr/labcode Filename: /home/usr/labcode/week1a.c File present. Department of CSE,MITS,Madanapalle Page 41 Unix Internals Lab [usr@linuxsr labcode]$ ./week10.out ser.c /home/usr/labcode Filename: /home/usr/labcode/ser.c File not present! TEXT BOOKS: 1. The Design of the Unix Operating System, Maurice J. Bach, Prentice Hall of India, 1991. REFERENCES: 1. William Stallings, Operating Systems: Internals and Design Principles, Fifth Edition, Prentice Hall, 2005. 2. Understanding the LINUX Kernel, Daniel P. Bovet and Marco cesati, O’REILLY Publications, 2005 Department of CSE,MITS,Madanapalle Page 42 Unix Internals Lab Web Sites: 1. www.ugu.com 2. http://www.wikipedia.com 3. www.unix.org Department of CSE,MITS,Madanapalle Page 43