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

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

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:

HOSTNAMEIt gives the name the host computer i.e., user computer name.

SHELL It gives the location of the shell in server.

SSH_CLIENTIt 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.

PATHIt 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]);

}

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=40;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;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;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:*.jar=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:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=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:*.aac=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/qt-3.3/bin:/usr/lib/ccache:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/11695A0510/bin

PWD=/home/11695A0510/UnixLab

LANG=en_US.UTF-8

KDE_IS_PRELINKED=1

KDEDIRS=/usr

SELINUX_LEVEL_REQUESTED=

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

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.

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

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_RDWROpen 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);

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_RDWROpen 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 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:

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_RDWROpen 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>

#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);

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:

rorrb

Open file for reading.

worwb

Truncate to zero length or create file for writing.

aorab

Append; open or create file for writing at end-of-file.

r+orrb+orr+b

Open file for update (reading and writing).

w+orwb+orw+b

Truncate to zero length or create file for update.

a+orab+ora+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

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

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*.