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

Study of Linux Introduction To Linux

The document provides an overview of Linux and its file system structure. It discusses: 1) Linux is an open-source operating system based on the Linux kernel and comprises components like Apache HTTP Server and the X Window System. Studies show Linux's market share and revenue are growing rapidly. 2) The Linux file system uses inodes, data blocks, and directories to organize files. It has a single hierarchical structure with everything starting from the root directory. 3) Important directories include /bin, /sbin, /boot, /dev, /etc, and /home. Special directories are /proc and /tmp. It then briefly describes the fork() and exec() system calls used to create processes

Uploaded by

Find out
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)
63 views

Study of Linux Introduction To Linux

The document provides an overview of Linux and its file system structure. It discusses: 1) Linux is an open-source operating system based on the Linux kernel and comprises components like Apache HTTP Server and the X Window System. Studies show Linux's market share and revenue are growing rapidly. 2) The Linux file system uses inodes, data blocks, and directories to organize files. It has a single hierarchical structure with everything starting from the root directory. 3) Important directories include /bin, /sbin, /boot, /dev, /etc, and /home. Special directories are /proc and /tmp. It then briefly describes the fork() and exec() system calls used to create processes

Uploaded by

Find out
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/ 10

STUDY OF LINUX

INTRODUCTION TO LINUX
Linux is a generic term referring to Unix-like computer operating systems based on the Linux
kernel. Their development is one of the most prominent examples of free and open source
software collaboration; typically all the underlying source code can be used, freely modified,
and redistributed by anyone.
The name "Linux" comes from the Linux kernel, originally written in 1991 by Linus Torvalds.
The rest of the system usually comprises components such as the Apache HTTP Server, the X
Window System, the K Desktop Environment, and utilities and libraries from the GNU
operating system (announced in 1983 by Richard Stallman).
Many quantitative studies of free / open source software focus on topics including market share
and reliability, with numerous studies specifically examining Linux. The Linux market is
growing rapidly, and the revenue of servers, desktops, and packaged software running Linux
was expected to exceed $35.7 billion by 2008.
LINUX FILE SYSTEM
A file system is the methods and data structures that an operating system uses to keep track of
files on a disk or partition; that is, the way the files are organized on the disk. The word is also
used to refer to a partition or disk that is used to store the files or the type of the file system.
The difference between a disk or partition and the file system it contains is important. A few
programs (including, reasonably enough, programs that create file systems) operate directly on
the raw sectors of a disk or partition; if there is an existing file system there it will be destroyed
or seriously corrupted. Most programs operate on a file system, and therefore won't work on a
partition that doesn't contain one (or that contains one of the wrong type). Before a partition or
disk can be used as a file system, it needs to be initialized, and the bookkeeping data structures
need to be written to the disk. This process is called making a file system.
Most UNIX file system types have a similar general structure, although the exact details vary
quite a bit. The central concepts are superblock, inode, data block, directory block, and
indirection block. The superblock contains information about the file system as a whole, such
as its size (the exact information here depends on the file system). An inode contains all
information about a file, except its name. The name is stored in the directory, together with the
number of the inode. A directory entry consists of a filename and the number of the inode
which represents the file. The inode contains the numbers of several data blocks, which are
used to store the data in the file. There is space only for a few data block numbers in the inode,
however, and if more are needed, more space for pointers to the data blocks is allocated
dynamically. These dynamically allocated blocks are indirect blocks; the name indicates that
in order to find the data block, one has to find its number in the indirect block first.
Like UNIX, Linux chooses to have a single hierarchical directory structure. Everything starts
from the root directory, represented by /, and then expands into sub-directories instead of
having so-called 'drives'. In the Windows environment, one may put one's files almost
anywhere: on C drive, D drive, E drive etc. Such a file system is called a hierarchical structure
and is managed by the programs themselves (program directories), not by the operating system.
On the other hand, Linux sorts directories descending from the root directory / according to
their importance to the boot process.
Linux, like Unix also chooses to be case sensitive. What this means is that the case, whether in
capitals or not, of the characters becomes very important. This feature accounts for a fairly
large proportion of problems for new users especially during file transfer operations whether it
may be via removable disk media such as floppy disk or over the wire by way of FTP.
The following bin/ dev/ home/ lost+found/ proc/ sbin/ usr/ boot/ etc/ lib/ mnt/ root/ tmp/ var/
are explained in detail.
/sbin - This directory contains all the binaries that are essential to the working of the system.
These include system administration as well as maintenance and hardware configuration
programs.
/bin - In contrast to /sbin, the bin directory contains several useful commands that are used by
both the system administrator as well as nonprivileged users.
/boot - This directory contains the system.map file as well as the Linux kernel. Lilo places the
boot sector backups in this directory.
/dev - This is a very interesting directory that highlights one important characteristic of the
Linux filesystem - everything is a file or a directory. Look through this directory and you should
see hda1, hda2 etc, which represent the various partitions on the first master drive of the system.
/dev/cdrom and /dev/fd0 represent your CDROM drive and your floppy drive.
/etc - This directory contains all the configuration files for your system. Your lilo.conf file lies
in this directory as does hosts, resolv.conf and fstab. /home –These are the user home
directories, which can be found under /home/username.
/lib - This contains all the shared libraries that are required by system programs. Windows
equivalent to a shared library would be a DLL file.
/lost+found - Linux should always go through a proper shutdown. Sometimes your system
might crash or a power failure might take the machine down. Either way, at the next boot, a
lengthy filesystem check using fsck will be done. Fsck will go through the system and try to
recover any corrupt files that it finds. The result of this recovery operation will be placed in
this directory.
/mnt - This directory usually contains mount points or sub-directories where you mount your
floppy and your CD.
/opt - This directory contains all the software and add-on packages that are not part of the
default installation.
/proc - This is a special directory on your system.
/root - We talked about user home directories earlier and well this one is the home directory of
the user root.
/tmp - This directory contains mostly files that are required temporarily.
/usr - This is one of the most important directories in the system as it contains all the user
binaries.
/usr/src/linux contains the source code for the Linux kernel.
/var - This directory contains spooling data like mail and also the output from the printer
daemon. The above content briefs about Linux and the file system of Linux

UNIX SYSTEM CALLS


fork() & getpid() 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.
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.
Execution
Parent and children execute concurrently
Parent waits until children terminate
The following is a simple example of fork()
1.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ printf("Hello \n");
fork();
printf("bye\n");
return 0; }
2.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
Void main() {
Pid_t pid;
fork();
pid=getpid();
if(pid == -1)
printf(“\n Error in creating process “);
else if(pid == 0)
printf("\nExecuting in child process, pid=%d and its parent pid = %d ", getpid(),getppid());
else printf("\nExecuting in parent process,pid=%d \n",getpid());
}
exec() System Call
The exec functions of Unix-like operating systems are a collection of functions that causes the
running process to be completely replaced by the program passed as argument to the function.
As a new process is not created, the process ID (PID) does not change across an execute, but
the data, heap and stack of the calling process are replaced by those of the new process.

Fork-exec is a commonly used technique in Unix whereby an executing process spawns a new
program. fork() is the name of the system call that the parent process uses to "divide" itself
("fork") into two identical processes. After calling fork(), the created child process is actually
an exact copy of the parent - which would probably be of limited use - so it replaces itself with
another process using the system call exec().

The parent process can either continue execution or wait for the child process to complete. The
child, after discovering that it is the child, replaces itself completely with another program, so
that the code and address space of the original program are lost.
If the parent chooses to wait for the child to die, then the parent will receive the exit code of
the program that the child executed. Otherwise, the parent can ignore the child process and
continue executing as it normally would; to prevent the child becoming a zombie it should wait
on children at intervals or on SIGCHLD.

When the child process calls exec(), all data in the original program is lost, and replaced with
a running copy of the new program. This is known as overlaying. Although all data is replaced,
the file descriptors that were open in the parent are closed only if the program has explicitly
marked them close-on-exec. This allows for the common practice of the parent creating a pipe
prior to calling fork() and using it to communicate with the executed program.

Example:
/* using execvp to execute the contents of argv */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
execvp(argv[1], &argv[1]);
perror("exec failure");
exit(1);
}

wait() System Call


_ A parent process usually needs to synchronize its actions by waiting until the child process
has either stopped or terminated its actions.
_ The wait() system call allows the parent process to suspend its activities until one of these
actions has occurred.
_ The wait() system call accepts a single argument, which is a pointer to an integer and returns
a value defined as type pid_t.
_ If the calling process does not have any child associated with it, wait will return immediately
with a value of -1.
_ If any child processes are still active, the calling process will suspend its activity until a child
process terminates.

Example of wait():
#include <sys/types.h>
#include <sys/wait.h>
Void main()
{
int status;
pid_t pid;
pid = fork();
if(pid == -1)
printf(“\nERROR child not created “);
else if (pid == 0) /* child process */
{
printf("\n I'm the child!");
exit(0);
}
else /* parent process */
{
wait(&status);
printf("\n I'm the parent!")
printf("\n Child returned: %d\n", status)
}
}

A few notes on this program:


wait(&status) causes the parent to sleep until the child process is finished execution .The exit
status of the child is returned to the parent.
stat() System Call
There are a number of system calls that a process can use to obtain file information. The most
useful one is "stat" system call.
The stat() system call is used to obtain file information. Its prototype is like this:
int stat(const char *file_name, struct stat *buf)
The stat structure is a pre-defined structure, which contains the following fields:
struct stat
{
dev_t st_dev; /* device */
ino_t st_ino; /* inode */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device type (if inode device) */
off_t st_size; /* total size, in bytes */
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 */
};

Here is a small program which use the stat call:


#include <iostream>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
const int N_BITS = 3;
int main(int argc, char *argv[ ])
{
unsigned int mask = 0700;
struct stat buff;
static char *perm[] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
if (argc > 1) {
if ((stat(argv[1], &buff) != -1))
{
cout << "Permissions for " << argv[1] << " ";
for (int i=3; i; --i)
{
cout << perm[(buff.st_mode & mask) >> (i-1)*N_BITS];
mask >>= N_BITS;
}
cout << endl;
}
else
{
perror(argv[1]);
return 1;
}
}
else
{
cerr << "Usage: " << argv[0] << " file_name\n";
return 2;
}
return 0;
}

close() System Call


The close() system call is used to close a file descriptor.

#include <unistd.h>
int close(int fd);

DESCRIPTION
close() closes a file descriptor, so that it no longer refers to any file and may be reused. If fd is
the last copy of a particular file descriptor the resources associated with it are freed;

RETURN VALUE
close() returns zero on success. On error, -1 is returned, and errno is set appropriately.

readdir() System Call


NAME
Readdir() –To read a directory

#include <sys/types.h>
#include <dirent.h>
struct dirent *readdir(DIR *dir);

DESCRIPTION
The readdir() function returns a pointer to a dirent structure representing the next directory
entry in the directory stream pointed to by dir. It returns NULL on reaching the end-of-file or
if an error occurred.
On Linux, the dirent structure is defined as follows:
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file */
char d_name[256]; /* filename */
};
The data returned by readdir() may be overwritten by subsequent calls to readdir() for the same
directory stream.

RETURN VALUE
The readdir() function returns a pointer to a dirent structure, or NULL if an error occurs or end-
of-file is reached. On error, errno is set appropriately.
opendir() System Call
NAME
Opendir() – To open a directory

#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
DESCRIPTION
The opendir() function opens a directory stream corresponding to the directory name, and
returns a pointer to the directory stream. The stream is positioned at the first entry in the
directory.

RETURN VALUE
The opendir() function returns a pointer to the directory stream. On error, NULL is returned,
and errno is set appropriately.
ERRORS
EACCES Permission denied.
EMFILE Too many file descriptors in use by process.
ENFILE Too many files are currently open in the system.
ENOENT Directory does not exist, or name is an empty string.
ENOMEM Insufficient memory to complete the operation.
ENOTDIR name is not a directory.

exit() System Call


This system call is used to terminate(normal/abnormal) the current running program.

I/O SYSTEM CALLS


File-I/O through system calls is simpler and operates at a lower level than making calls to the
C file-I/O library. There are seven fundamental file-I/O system calls:
creat() Create a file for reading or writing.
open() Open a file for reading or writing.
close() Close a file after reading or writing.
unlink() Delete a file.
write() Write bytes to file.
read() Read bytes from file.
These calls were devised for the UNIX operating system and are not part of the ANSI C spec.
Use of these system calls requires a header file named
"fcntl.h":

creat() Sytem Call


The "creat()" system call, of course, creates a file. It has the syntax:
int fp; /* fp is the file descriptor variable */
fp = creat( <filename>, <protection bits> );
Ex: fp=creat(“students.dat”,RD_WR);
This system call returns an integer, called a "file descriptor", which is a number that identifies
the file generated by "creat()". This number is used by other system calls in the program to
access the file. Should the "creat()" call encounter an error, it will return a file descriptor value
of -1.
The "filename" parameter gives the desired filename for the new file. The "permission bits"
give the "access rights" to the file. A file has three "permissions" associated with it:

1. Write permission - Allows data to be written to the file.


2. Read permission - Allows data to be read from the file.
3. Execute permission - Designates that the file is a program that can be run.

These permissions can be set for three different levels:


User level: Permissions apply to individual user.
Group level: Permissions apply to members of user's defined "group".
System level: Permissions apply to everyone on the system.

open() Sytem Call


The "open()" system call opens an existing file for reading or writing. It has the syntax:
<file descriptor variable> = open( <filename>, <access mode> );
The "open()" call is similar to the "creat()" call in that it returns a file descriptor for the given
file, and returns a file descriptor of -1 if it encounters an error. However, the second parameter
is an "access mode", not a permission code. There are three modes (defined in the "fcntl.h"
header file):
O_RDONLY Open for reading only.
O_WRONLY Open for writing only.
O_RDWR Open for reading and writing.
For example, to open "data" for writing, assuming that the file had been created by another
program, the following statements would be used:
int fd;
fd = open( "students.dat", O_WRONLY );
A few additional comments before proceeding:
A "creat()" call implies an "open()". There is no need to "creat()" a file and then "open()" it.

close() Sytem Call


The "close()" system call is very simple. All it does is "close()" an open file when there is no
further need to access it. The "close()" system call has the syntax:
close( <file descriptor> );
The "close()" call returns a value of 0 if it succeeds, and returns -1 if it encounters an error.

unlink() Sytem Call


The "unlink()" system call deletes a file. It has the syntax:
unlink( <file_name_string> );
It returns 0 on success and -1 on failure.

write() Sytem Call


The "write()" system call writes data to an open file. It has the syntax:
write( <file descriptor>, <buffer>, <buffer length> );

The file descriptor is returned by a "creat()" or "open()" system call. The "buffer" is a pointer
to a variable or an array that contains the data; and the "buffer length" gives the number of
bytes to be written into the file. While different data types may have different byte lengths on
different systems, the "sizeof()" statement can be used to provide the proper buffer length in
bytes. A "write()" call could be specified as follows:
float array[10];
write( fd, array, sizeof( array ) );
The "write()" function returns the number of bytes it actually writes. It will return -1 on an
error.

read() Sytem Call


The "read()" system call reads data from a open file. Its syntax is exactly the same as that of
the "write()" call:
read( <file descriptor>, <buffer>, <buffer length> );
The "read()" function returns the number of bytes it actually returns. At the end of file it returns
0, or returns -1 on error.

Example:
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
main(int argc,char *argv[])
{
int fd,i;
char ch[1];
if (argc<2)
{ printf("Usage: mycat filename\n");
exit(0);
}
fd=open(argv[1],O_RDONLY);
if(fd==-1)
printf("%s is not exist",argv[1]);
else
{
printf("Contents of the file %s is : \n",argv[1]);
while(read(fd,ch,1)>0)
printf("%c",ch[0]);
close(fd);
}

You might also like