0% found this document useful (0 votes)
64 views

Unix and Advance Topics in C Programming: A Simple C Program

This document discusses C programming and Unix commands. It provides examples of simple C programs, compiling and running programs in Unix, using library functions, command line arguments, and running Unix commands from C programs. It focuses on common file system calls like open, create, close, read, write, and lseek. The goals are to familiarize readers with Unix C syntax, writing programs that use command line arguments, and interfacing C programs with the Unix operating system.

Uploaded by

khizar malik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views

Unix and Advance Topics in C Programming: A Simple C Program

This document discusses C programming and Unix commands. It provides examples of simple C programs, compiling and running programs in Unix, using library functions, command line arguments, and running Unix commands from C programs. It focuses on common file system calls like open, create, close, read, write, and lseek. The goals are to familiarize readers with Unix C syntax, writing programs that use command line arguments, and interfacing C programs with the Unix operating system.

Uploaded by

khizar malik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

UNIX AND ADVANCE TOPICS IN C

PROGRAMMING

Objectives

 Be familiar with syntax of Unix C-Program.


 Gain knowledge of how to create, compile, and execute a C program under Unix System.
 Find out how to write C-Program using command line arguments.
 Running UNIX Commands from C.

A SIMPLE C PROGRAM

Example#1:

Assume we have the following program stored in a file called file.c.


>vi file.c
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[])
{
printf (”Hello World!\n”);
exit (0);
}

 #include <stdio.h> is a directive to the c preprocessor to include the file stdio.h that will
tell the program how to input and output data.

 #include <stdlib.h> is to be able to use the exit function that tells us if the program ran
successfully or not.

COMPILE AND EXECUTE A C PROGRAM UNDER UNIX SYSTEM

gcc [-o FileName] fileName.c


To compile C program
 The gcc is assumed to be your GNU c compiler. Otherwise you would compile the
program using the standard cc compiler.

 The ’-o’ option indicates that the compile file should be stored in a file called ’FileName’
instead of the default ’a.out’.

Con’t Example#1:

Compile the program in example #1 without using –o option


> gcc file.c
Run the program

59 | P a g e
> ./a.out
Or you can compile the program in example #1 using –o option
gcc -o file file.c
Run the program
> ./file

UNIX LIBRARY FUNCTIONS

The UNIX system provides a large number of C functions as libraries. Some of these implement
frequently used operations, while others are very specialized in their application. Do Not
Reinvent Wheels: It is wise for programmers to check whether a library function is available to
perform a task before writing their own version. This will reduce program development time.
The library functions have been tested, so they are more likely to be correct than any function
which the programmer might write. This will save time when debugging the program.

Finding Information about Library Functions

The UNIX manual has an entry for all available functions. Function documentation is stored in
section 3 of the manual, and there are many other useful system calls in section 2. If you already
know the name of the function you want, you can read the page by typing (to find about sqrt):

man 3 sqrt

If you don’t know the name of the function, a full list is included in the introductory page for
section 3 of the manual. To read this, type

man 3 intro

There are approximately 700 functions described here. This number tends to increase with each
upgrade of the system.

Example#2

The file sqrt1.c contains c code prints the square roots of the numbers from 0 to 25.
Notice that we converted the integer i to a double using the typcast operation.
#include <stdio.h>
#include <math.h>
int main()
{
int i;
double number;
for (i = 0; i <= 25; i++) {
number = sqrt((double) i);
printf(“The square root of %d is %f\n”,i,number);
}
}

60 | P a g e
To compile program that used c library: gcc -o sqrt1 sqrt1.c -lm

To execute the program: ./sqrt1 Example#3:

This example generates random numbers that range from a minimum value of 3 and a
maximum value of 12. Notice that we used the modulo operator % to ensure maximum
value of our random numbers is less than 10.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i, number, min value;
min value = 3;
for (i = 0; i < 15; i++)
{
number = min value + (rand() % 10);
printf(”Random number is %d \”);
}
}

C FUNCTIONS

C uses “function” to package blocks of code. A function has a name, a list of arguments and the
block of code it executes.

Example #4:

The following example shows a function that converts speed from miles/hour to
kilometers/hour.
#include <stdio.h>
float mphtokph(float speed)
{
return(speed*1.60934);
}
int main()
{
float mph, kph;
printf("Enter speed (miles/hour): ");
scanf("%f", &mph);
kph = mphtokph(mph);

61 | P a g e
printf("\n speed of %3.1f miles/hour equals %3.1f
kilometers/hour \n\n",mph, kph);
}

COMMAND LINE ARGUMENTS IN C

The arguments for main( int argc, char *argv[] ) are argc(argument count) and argv(argument
vector). The argument argc is an integer that contains the number of arguments being passed to main ;
argv is an array of strings. Each string is an argument. The computer is able to count the number of
arguments and assign the value to argc. The array argv[1] contains the first argument, argv[2]
contains the second argument and so on . The program’s name is stored in argv[0].

Example#5:

For a program named prog1 which is invoked with the command line: The value of argc is
4, the value of argv[0] is "prog1", the value of argv[1] is "add", the value of argv[2] is
"12", and the value of argv[3] is "5".
>prog1 add 12 5
Example#6:

Try to run the program with and without argument and see the result.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int i;
for (i = 0; i < argc ; i++) // scan al entries of argv[i]
{
/* print all the arguments */
printf(“arg %d: %s \n”, i, argv[i]);
}
exit (0);
}
Example#7:

Note: atoi( ) function is used to convert string into integer.


#include<stdio.h>
#include<stdlib.h>
main(int argc, char *argv[])
{
int sum;
if(argc<=3)
{

62 | P a g e
printf("You must input three numbers as command line inputs.\n");
exit(0);
}
sum=atoi(argv[1])+atoi(argv[2])+atoi(argv[3]);
printf("The sum of three values is = %d\n",sum);
}

RUNNING UNIX COMMANDS FROM C

We can run commands from a C program just as if they were from the UNIX command line by
using the system( ) function.

int system ( char *string ) where string can be the name of a UNIX utility, an executable shell
script or a user program. System returns the exit status of the shell.

System is prototyped in <stdlib.h>

system is a call that is made up of 3 other system calls: execl( ), wait( ) and fork( ) (which are
prototyped in <unistd>)

Example#8:

Calling a UNIX command


main( )
{ printf(``Files in Directory are:\n'');
system(``ls -l'');
}
Example#9:

Calling a shell script


main( )
{ printf(``Files in Directory are:\n'');
system(“./sh'');
}

63 | P a g e
LABORATORY8: MAJOR FILE STRUCTURE RELATED SYSTEM CALLS

Objective

1. Understand system calls.


2. Identify the use of system calls.
3. Learn Major File Structure Related System Calls(open, create, close, read, write, and lseek).

WHAT IS A SYSTEM CALL?

A system call is a request for the operating system to do something on behalf of the user's
program. The system calls are functions used in the kernel itself. To the programmer, the
system call appears as a normal C function call. However since a system call executes code in
the kernel, there must be a mechanism to change the mode of a process from user mode to
kernel mode.

USE OF SYSTEM CALLS

 UNIX system calls are used to:

1. manage the file system,


2. control processes,
3. and to provide interprocess communication.
 Major System Calls:

1. The UNIX system interface consists of about 80 system calls (as UNIX evolves
this number will increase). The table below lists about 40 of the most important
system call.

2. The file structure related system calls in UNIX let you create, open, and close
files, read and write files, randomly access files, alias and remove files, get
information about files, check the accessibility of files, change protections,
owner, and group of files, and control devices.

64 | P a g e

File Structure Related Calls


SPECIFIC CLASS SYSTEM
CALL
Creating a Channel creat( )
open( )
close( )
Input/Output read( )
write( )
Random Access lseek( )
Channel Duplication dup( )
Aliasing and Removing Files link( )
Aliasing and Removing Files unlink( )
File Status stat( )
fstat( )
Access Control access( )
chmod( )
chown( )
umask( )
Device Control ioctl( )
Change Working Directory chdir( )

Process Related Calls

SPECIFIC CLASS SYSTEM CALL


Process Related Calls
Process Creation and exec( ) SPECIFIC CLASS SYSTEM CALL
termination
Pipelines pipe( )
fork( )
Messages msgget( )
wait( )
msgsnd( )
exit( )
msgrcv( )
Process Owner and Group getuid( )
msgctl( )
getgid( )
Semaphores semget( )
getegid( )
semop( )
Process Identity getpid( )
Shared Memory shmget( )
getppid( )
shmat( )
Process Control signal( )
shmdt( )
kill( )
alarm( )

65 | P a g e
 System call operations either use a character string that defines the absolute or relative
path name of a file, or a small integer called a file descriptor that identifies the I/O
channel.

 A channel is a connection between a process and a file that appears to the process as an
unformatted stream of bytes.

 File descriptors 0, 1, and 2 refer to standard input, standard output, and standard error
files respectively.

 File descriptor 0 is a channel to your terminal's keyboard and file descriptors 1 and 2
are channels to your terminal's

CREAT( ) SYSTEM CALL

int creat(char *file_name, int mode)


It returns either a non-negative file descriptor or –1 on error.
creat( ), creates an empty file with the specified mode permissions, if the file named by
file_name does not exist. However, if the file does exist, its contents are discarded and the
mode value is ignored. The permissions of the existing file are retained.

The mode is usually specified as an octal number such as 0666 that would mean read/write
permission for owner, group, and others or the mode may also be entered using manifest
constants defined in the "/usr/include/sys/stat.h" file. e.g. S_IREAD,S_IWRITE

Header files needed for this system call in which the actual prototype appears, & in which
useful constants are defined are:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
All input and output operations start by opening a file using either the "creat( )" or "open( )"
system calls. These calls return a file descriptor that identifies the I/O channel. Recall that
file descriptors 0, 1, and 2 refer to standard input, standard output, and standard error files
respectively, and that file descriptor 0 is a channel to your terminal's keyboard and file
descriptors 1 and 2 are channels to your terminal's display screen.

Example#1:

Create a file newfile with read & write permission to owner and read only for the group
and others.
fd = creat(“/tmp/newfile”, 0644);

66 | P a g e
Example#2:

After running the example check whether, the file datafile.dat exist in your current folder
or not.
#include <stdio.h>
#include <sys/types.h> /* defines types used by sys/stat.h */
#include <sys/stat.h> /* defines S_IREAD & S_IWRITE */
int main( )
{
int fd;
fd = creat("datafile.dat", S_IREAD | S_IWRITE);
if (fd == -1)
printf("Error in creating datafile.dat\n");
else
{
printf("datafile.dat created for read/write access\n");
printf("datafile.dat is currently empty\n"); }

close(fd);
exit (0); /*exit() terminates the calling process , exit(0) for successful &
exit(1) for error, exit() is defined in #include<stdlib.h> */
}

int open(char *file_name, int option_flags, [int mode])


It returns either a non-negative file descriptor or –1 on error.
 open( ), It opens a file for reading or writing, or creates an empty file.

 file_name is a pointer to the character string that names the file,

 option_flags represent the type of channel, and

 mode defines the file's access permissions if the file is being created. It is only
used with the O_CREAT option_flag and it is concerned with the security
permissions.

 Header files needed for this system call in which the actual prototype appears, & in
which useful constants are defined are:

 #include<sys/types.h>
 #include<sys/stat.h>
 #include<fcntl.h>

67 | P a g e
The allowable option flags as defined in "/usr/include/fcntl.h" or #include<fcntl.h> are:
Option flag Description

#define O_RDONLY 0 Open the file for reading only

#define O_WRONLY 1 Open the file for writing only

#define O_RDWR 2 Open the file for both reading and writing

#define O_APPEND 010 append (writes guaranteed at the end)

#define O_CREAT 00400 If file doesn’t exist , create the file, set the owner ID to the process’s
effective UID, and set the group id to the group id of the directory in
which the file is created.

#define O_TRUNC 01000 If file exists, it is truncated to length zero

#define O_EXCL 02000 Exclusive open(i. e If O_CREAT is set and the file exists, then open() fails.

Multiple values are combined using the | operator (i.e. bitwise OR). Note: some combinations
are mutually exclusive such as: O_RDONLY | O_WRONLY and will cause open( ) to fail. If the
O_CREAT flag is used, then a mode argument is required. The mode argument may be
specified in the same manner as in the creat( ) system call.

Example#3:

This causes the file data, in the current working directory, to be opened as read only for the
use by the program.
fd = open(“data”, O_RDONLY);
Example#4:

The open call can also be used to create a file from scratch, as follows:
fd = open (“/tmp/newfile”, O_WRONLY | O_CREAT, 0644);
Example#5:

means, if file lock does not exist, then create it with permission 0644. If it does exist, then
fail open call, returning –1 in fd.
fd = open(“lock”, O_WRONLY | O_CREAT | O_EXCL, 0644);
Example#6:

O_TRUNC when used with O_CREAT it will force a file to be truncated to zero bytes if it
exists and its access permissions allow.
fd = open(“file”, O_WRONLY | O_CREAT | O_TRUNC, 0644);
Example#7:

#include<stdlib.h>

68 | P a g e
#include<fcntl.h>
#define PERMS 0644 /* Permission for open with O_CREAT */
char *filename = "newfile";
main()
{
int fd;
if((fd=open(filename, O_RDWR | O_CREAT, PERMS)) == -1)
{
printf("Couldn't create %s\n",filename);
exit(1); /*error, so exit */
}
printf(“The file is opened and ready for read and write operation“)
/* rest of program follows */
exit(0); /*normal successful exit */
}

CLOSE( ) SYSTEM CALL

int close(int file_descriptor)


The close system calls returns 0 if successful, -1 on error (which can
happen if the integer argument is not a valid file descriptor).
close( ) system call to close a previously opened file. It is defined in header file
#include<unistd.h>. file_descriptor identifies a currently open file. close( ) fails if
file_descriptor does not identify a currently open file.

READ() WRITE()SYSTEM CALLS

int read( int file_descriptor, char *buffer_pointer, unsigned transfer_size) int


write(int file_descriptor, char *buffer_pointer, unsigned transfer_size)
return the number of bytes transferred if successful & -1 if error
 file_descriptor is a file descriptor which has been obtained from a previous call to either
open or creat,

 buffer_pointer points to the area in memory (or is a pointer to an array or structure


into which data will be copied, in many cases it is simply name of array itself ) where the
data is stored for a read( ) or where the data is taken for a write( ), and

 transfer_size defines the maximum number of characters transferred between the file
and the buffer (or number of bytes) . There is no limit on transfer_size, but you must
make sure it's safe to copy transfer_size bytes to or from the memory pointed to by
buffer_pointer. A transfer_size of 1 is used to transfer a byte at a time for so-called

69 | P a g e
"unbuffered" input/output. The most efficient value for transfer_size is the size of the
largest physical record the I/O channel is likely to have to handle.

Example#8:

#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define BUFSIZE 512
int main()
{ char buffer[BUFSIZE];
int fd;
int nread;
long total = 0;
if(( fd = open("myfile", O_RDONLY)) == -1) /* open "myfile" read only */
{ printf("Error in opening myfile\n");
exit(1);
}
while( (nread = read(fd,buffer, BUFSIZE)) >0) /* loops until EOL, shown by
return value of 0 */
{ total += nread; /* increment total */
}
printf("Total chars in my file : %ld\n",total);
exit(0);
}

LSEEK() SYSTEM CALL

long lseek(int file_descriptor, long offset, int whence)


returns a long integer that defines the new file pointer value measured in
bytes from the beginning of the file. If unsuccessful (it returns –1), the
file position does not change.
whence new position

0 (SEEK_SET) offset bytes into the file (The offset is measured from the beginning of the file;
usual actual integer value=0)

1 (SEEK_CUR) current position in the file plus offset (The offset is measured from the
current position of the file pointer; usual value =1 )

2 (SEEK_END) current end-of-file position plus offset (The offset is measured from the end
of the file; usual value =2)

70 | P a g e
The UNIX system file system treats an ordinary file as a sequence of bytes. No internal
structure is imposed on a file by the operating system. Generally, a file is read or written
sequentially -- that is, from beginning to the end of the file. Sometimes sequential reading
and writing is not appropriate. It may be inefficient, for instance, to read an entire file just to
move to the end of the file to add characters. Fortunately, the UNIX system lets you read and
write anywhere in the file. Known as "random access", this capability is made possible with
the lseek( ) system call. During file I/O, the UNIX system uses a long integer, also called a File
Pointer, to keep track of the next byte to read or write. This long integer represents the
number of bytes from the beginning of the file to that next character. Random access I/O is
achieved by changing the value of this file pointer using the lseek( ) system call. lseek()
enables random access into a file. To use it we need header files
#include<sys/types.h> and #include<unistd.h> .

Example#9:

a program fragment gives a position 16 bytes before the end of the file. From this example
it is clear that offset can be negative i.e it is possible to move backwards from the starting
point indicated by whence.
newpos = lseek(fd, -16, SEEK_END)
Example#10:

a program fragment that will append to the end of an existing file by opening the file,
moving to the end with lseek, and starting to write.
fd = open(filename, O_RDWR);
lseek(fd, 0, SEEK_END);
write(fd, outbuf, OBSIZE);
Example#11:

#include <fcntl.h> /* defines options flags */


#include <sys/types.h> /* defines types used by sys/stat.h */
#include <sys/stat.h> /* defines S_IREAD & S_IWRITE */
static char message[] = "Hello, world";
int main( )
{
int fd;
char buffer[80];
/* open datafile.dat for read/write access (O_RDWR)
create datafile.dat if it does not exist (O_CREAT)
return error if datafile already exists (O_EXCL)
permit read/write access to file (S_IWRITE | S_IREAD)
*/
fd = open("datafile.dat",O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
if (fd != -1)

71 | P a g e
{
printf("datafile.dat opened for read/write access\n");
write(fd, message, sizeof(message));
lseek(fd, 0, 0); /* go back to the beginning of the file */ if (read(fd, buffer,
sizeof(message)) == sizeof(message)) printf("\"%s\" was written to datafile.dat\n",
buffer);
else
printf("*** error reading datafile.dat ***\n");
close (fd);
}
else
printf("*** datafile.dat already exists ***\n");
exit (0);
}

EXCERSICES

1. Update the code in example#8 to get the file name from the command line argument.

You might also like