You are on page 1of 34

ADVANCE LINUX PROGRAMMING:

RESOURCE MANAGEMENT

UNAME:

NAME
uname - get name and information about current kernel

SYNOPSIS
#include <sys/utsname.h>

int uname(struct utsname *buf);

DESCRIPTION
uname() returns system information in the structure pointed to by buf. The
utsname struct is defined in
<sys/utsname.h>:
struct utsname {
char sysname[];
char nodename[];
char release[];
char version[];
char machine[];
#ifdef _GNU_SOURCE
char domainname[];
#endif
};
The length of the arrays in a struct utsname is unspecified; the fields are
terminated by a null byte
(’’ ’).

RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set
appropriately.

//Program on uname

#include<stdio.h>
#include<string.h>
#include<sys/utsname.h>
#include<errno.h>
main()
{
struct utsname buf;

printf("Status: %d\n",uname(&buf));
printf("Status from errno=%d\n",errno);
printf("Description:%s\n",strerror(errno));

//perror("Description:");
printf("System name=%s\n",buf.sysname);
printf("Node name=%s\n",buf.nodename);
printf("Release=%s\n",buf.release);
printf("Version=%s\n",buf.version);
printf("Machine=%s\n",buf.machine);
}
output:

Status: 0
Status from errno=0
Description:Success
System name=Linux
Node name=Sandya
Release=2.6.18-8.el5
Version=#1 SMP Fri Jan 26 14:15:21 EST 2007
Machine=i686

output
------
Status: 0
Description:: Success
System name=Linux
Node name=Sandya
Release=2.6.18-8.el5
Version=#1 SMP Fri Jan 26 14:15:21 EST 2007
Machine=i686

CTIME:

NAME
asctime, ctime, gmtime, localtime, mktime, asctime_r, ctime_r, gmtime_r,
localtime_r - transform date and time to broken-down time or ASCII

SYNOPSIS
#include <time.h>

char *asctime(const struct tm *tm);


char *asctime_r(const struct tm *tm, char *buf);

char *ctime(const time_t *timep);


char *ctime_r(const time_t *timep, char *buf);

struct tm *gmtime(const time_t *timep);


struct tm *gmtime_r(const time_t *timep, struct tm *result);

struct tm *localtime(const time_t *timep);


struct tm *localtime_r(const time_t *timep, struct tm *result);

time_t mktime(struct tm *tm);

DESCRIPTION
The ctime(), gmtime() and localtime() functions all take an argument of data
type time_t which represents
calendar time. When interpreted as an absolute time value, it represents the
number of seconds elapsed
since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).

The asctime() and mktime() functions both take an argument representing


broken-down time which is a repre-
sentation separated into year, month, day, etc.

Broken-down time is stored in the structure tm which is defined in <time.h> as


follows:

struct tm {
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
int tm_wday; /* day of the week */
int tm_yday; /* day in the year */
int tm_isdst; /* daylight saving time */
};

The members of the tm structure are:

tm_sec The number of seconds after the minute, normally in the range 0 to 59,
but can be up to 60 to allow for leap seconds.

tm_min The number of minutes after the hour, in the range 0 to 59.
tm_hour
The number of hours past midnight, in the range 0 to 23.

tm_mday
The day of the month, in the range 1 to 31.

tm_mon The number of months since January, in the range 0 to 11.

tm_year
The number of years since 1900.

tm_wday
The number of days since Sunday, in the range 0 to 6.

tm_yday
The number of days since January 1, in the range 0 to 365.

tm_isdst
A flag that indicates whether daylight saving time is in effect at the time
described. The value is positive if daylight saving time is in effect, zero if it is not,
and negative if the information is not available.

The call ctime(t) is equivalent to asctime(localtime(t)). It converts the calendar


time t into a string of the form
"Wed Jun 30 21:49:08 1993\n"

The return value points to a statically allocated string which might be


overwritten by subsequent calls to any of the date and time functions. The function
also sets the external variable tzname (see tzset(3)) with information about the
current time zone. The re-entrant version ctime_r() does the same, but stores the
string in a user-supplied buffer of length at least 26. It need not set tzname.
The gmtime() function converts the calendar time timep to broken-down time
representation, expressed in Coordinated Universal Time (UTC). It may return
NULL when the year does not fit into an integer. The return value points to a
statically allocated struct which might be overwritten by subsequent calls to any
of the date and time functions. The gmtime_r() function does the same, but stores
the data in a user-supplied struct.
The localtime() function converts the calendar time timep to broken-time
representation, expressed relative to the user’s specified time zone. The
function acts as if it called tzset(3) and sets the external variables tzname with
information about the current time zone, timezone with the difference between
Coordinated Universal Time (UTC) and local standard time in seconds, and daylight
to a non-zero value if daylight savings time rules apply during some part of the year.
The return value points to a statically allocated struct which might be
overwritten by subsequent calls to any of the date and time functions.
The localtime_r() function does the same, but stores the data in a user-supplied
struct. It need not set tzname.

The asctime() function converts the broken-down time value tm into a


string with the same format as ctime(). The return value points to a statically
allocated string which might be overwritten by subsequent calls to any of the date
and time functions. The asctime_r() function does the same, but stores the
string in a user-supplied buffer of length at least 26.

The mktime() function converts a broken-down time structure, expressed as


local time, to calendar time representation. The function ignores the specified
contents of the structure members tm_wday and tm_yday and recomputes them
from the other information in the broken-down time structure. If structure members
are outside their legal interval, they will be normalized (so that, e.g., 40 October
is changed into 9 November). Calling mktime() also sets the external variable
tzname with information about the current time zone. If the specified broken-
down time cannot be represented as calendar time (seconds since the epoch),
mktime() returns a value of (time_t)(-1) and does not alter the tm_wday and
tm_yday members of the broken-down time structure.

RETURN VALUE
Each of these functions returns the value described, or NULL (-1 in case of
mktime()) in case an error was detected.

NOTES
The four functions asctime(), ctime(), gmtime() and localtime() return a pointer
to static data and hence are not thread-safe. Thread-safe versions asctime_r(),
ctime_r(), gmtime_r() and localtime_r() are specified by SUSv2, and available since
libc 5.2.5.

//Program on time
#include<stdio.h>
#include<time.h>
main()
{
time_t p;
struct tm *t;

time(&p);
t=localtime(&p);

printf("Seconds=%d\n",t->tm_sec);
printf("Minutes=%d\n",t->tm_min);
printf("Hours=%d\n",t->tm_hour);
printf("Day of the month=%d\n",t->tm_mday);
printf("Month=%d\n",t->tm_mon+1);
printf("Year=%d\n",t->tm_year+1900);
printf("Week day=%d\n",t->tm_wday);
printf("Day in the year=%d\n",t->tm_yday+1);
}

output

Seconds=39
Minutes=16
Hours=1
Day of the month=13
Month=8
Year=2010
Week day=5
Day in the year=225

//Program to find week day of given date

#include<stdio.h>
#include<time.h>
main()
{
time_t p;
struct tm *t;

//Accept date
int d,m,y;

printf("Enter date(dd-mm-yyyy):\n");
scanf("%d-%d-%d",&d,&m,&y);

//Convert seconds obtained using time() into tm structure


time(&p);
t=localtime(&p);

//Make changes in tm structure


t->tm_mday=d;
t->tm_mon=m-1;
t->tm_year=y+1900;

//Convert the modified time into seconds


p=mktime(t);
t=localtime(&p);

//Check for the week day and display


switch(t->tm_wday)
{
case 0:printf("Sunday\n");break;
case 1:printf("Monday\n");break;
case 2:printf("Tuesday\n");break;
case 3:printf("Wednesday\n");break;
case 4:printf("Thursday\n");break;
case 5:printf("Friday\n");break;
case 6:printf("Saturday\n");break;
}
}

output

Enter date(dd-mm-yyyy):
12-08-2010
Thursday

GETHOSTNAME,SETHOSTNAME:

NAME
gethostname, sethostname - get/set host name

SYNOPSIS
#include <unistd.h>

int gethostname(char *name, size_t len);


int sethostname(const char *name, size_t len);

DESCRIPTION
These system calls are used to access or to change the host name of the
current processor. The gethostname() system call returns a null-terminated
hostname (set earlier by sethostname()) in the array name that has a length of
len bytes. In case the null-terminated hostname does not fit, no error is returned,
but the hostname is truncated. It is unspecified whether the truncated hostname will
be null-terminated.

RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set
appropriately.

//Program to get hostname and set hostname

#include<stdio.h>
#include<unistd.h>
#include<string.h>
main()
{
char data[50];

gethostname(data,50);
printf("Host name is: %s\n",data);

printf("Enter new host name:\n");


__fpurge(stdin);
gets(data);

sethostname(data,strlen(data));
}

output:

Host name is: Sandy


Enter new host name:
Sandya

GETPWNAME,GETPWUID:

NAME
getpwnam, getpwnam_r, getpwuid, getpwuid_r - get password file entry

SYNOPSIS
#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwnam(const char *name);

struct passwd *getpwuid(uid_t uid);

int getpwnam_r(const char *name, struct passwd *pwbuf,


char *buf, size_t buflen, struct passwd **pwbufp);

int getpwuid_r(uid_t uid, struct passwd *pwbuf,


char *buf, size_t buflen, struct passwd **pwbufp);

DESCRIPTION
The getpwnam() function returns a pointer to a structure containing the broken-
out fields of the record in the password database (e.g., the local password file
/etc/passwd, NIS, and LDAP) that matches the username name.

The getpwuid() function returns a pointer to a structure containing the broken-


out fields of the record in the password database that matches the user ID uid.

The getpwnam_r() and getpwuid_r() functions obtain the same information, but
store the retrieved passwd structure in the space pointed to by pwbuf. This
passwd structure contains pointers to strings, and these strings are stored in the
buffer buf of size buflen. A pointer to the result (in case of success) or NULL (in case
no entry was found or an error occurred) is stored in *pwbufp.
The passwd structure is defined in <pwd.h> as follows:

struct passwd {
char *pw_name; /* user name */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* real name */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};

The maximum needed size for buf can be found using sysconf(3) with the
_SC_GETPW_R_SIZE_MAX parameter.

RETURN VALUE
The getpwnam() and getpwuid() functions return a pointer to a passwd
structure, or NULL if the matching entry is not found or an error occurs. If an error
occurs, errno is set appropriately. If one wants to check errno after the call, it should
be set to zero before the call.

The return value may point to static area, and may be overwritten by
subsequent calls to getpwent(), getpwnam(), or getpwuid().

The getpwnam_r() and getpwuid_r() functions return zero on success. In case


of error, an error number is returned.

//Program to get password entry file using username nd userid

#include<stdio.h>
#include<sys/types.h>
#include<string.h>
#include<pwd.h>
main()
{
struct passwd *p;
char name[20];

printf("Enter user name:\n");


__fpurge(stdin);
gets(name);

p=getpwnam(name);
/*
int id;
printf("Enter user id:\n");
__fpurge(stdin);
scanf("%d",&id);
p=getpwuid);
*/

if(p==NULL)
printf("User not available\n");
else
{
printf("Username:%s\n",p->pw_name);
printf("Password:%s\n",p->pw_passwd);
printf("User id:%d\n",p->pw_uid);
printf("Group id:%d\n",p->pw_gid);
printf("Real name:%s\n",p->pw_gecos);
printf("Directory:%s\n",p->pw_dir);
printf("Shell:%s\n",p->pw_shell);
}
}

output:

Enter user name:


root
Username:root
Password:x
User id:0
Group id:0
Real name:root
Directory:/root
Shell:/bin/bash

GETPWENT:

NAME
getpwent, setpwent, endpwent - get password file entry

SYNOPSIS
#include <sys/types.h>
#include <pwd.h>

struct passwd *getpwent(void);

void setpwent(void);

void endpwent(void);

DESCRIPTION
The getpwent() function returns a pointer to a structure containing the broken-
out fields of a record from the password database (e.g., the local password file
/etc/passwd, NIS, and LDAP). The first time it is called it returns the first entry;
thereafter, it returns successive entries.

The setpwent() function rewinds to the beginning of the password database.

The endpwent() function is used to close the password database after all
processing has been performed.

The passwd structure is defined in <pwd.h> as follows:

struct passwd {
char *pw_name; /* user name */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* real name */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};

RETURN VALUE
The getpwent() function returns a pointer to a passwd structure, or NULL if
there are no more entries or an error occurs. If an error occurs, errno is set
appropriately. If one wants to check errno after the call, it should be set to zero
before the call.

//Program to get password file entries of all users

#include<stdio.h>
#include<sys/types.h>
#include<pwd.h>
main()
{

struct passwd *p;

while((p=getpwent())!=NULL)
{
printf("%s:%s:%d:%d:%s:%s:%s\n",p->pw_name,p->pw_passwd,p-
>pw_uid,p->pw_gid,p->pw_gecos,p->pw_dir,p->pw_shell);
}
}

output:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
|

|
sandya:x:500:500:sandya:/home/sandya:/bin/bash
oracle:x:501:501::/usr/lib/oracle/xe:/bin/bash

GETGRNAM,GETGRGID:

NAME
getgrnam, getgrnam_r, getgrgid, getgrgid_r - get group file entry

SYNOPSIS
#include <sys/types.h>
#include <grp.h>
struct group *getgrnam(const char *name);

struct group *getgrgid(gid_t gid);

int getgrnam_r(const char *name, struct group *gbuf,


char *buf, size_t buflen, struct group **gbufp);

int getgrgid_r(gid_t gid, struct group *gbuf,


char *buf, size_t buflen, struct group **gbufp);

DESCRIPTION
The getgrnam() function returns a pointer to a structure containing the broken-
out fields of the record in the group database (e.g., the local group file /etc/group,
NIS, and LDAP) that matches the group name name.

The getgrgid() function returns a pointer to a structure containing the broken-


out fields of the record in the group database that matches the group ID gid.

The getgrnam_r() and getgrgid_r() functions obtain the same information, but
store the retrieved group structure in the space pointed to by gbuf. This group
structure contains pointers to strings, and these strings are stored in the buffer buf
of size buflen. A pointer to the result (in case of success) or NULL (in case no entry
was found or an error occurred) is stored in *gbufp.

The group structure is defined in <grp.h> as follows:

struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};

The maximum needed size for buf can be found using sysconf(3) with the
_SC_GETGR_R_SIZE_MAX parameter.

RETURN VALUE
The getgrnam() and getgrgid() functions return a pointer to a group
structure, or NULL if the matching entry is not found or an error occurs. If an error
occurs, errno is set appropriately. If one wants to check errno after the call, it
should be set to zero before the call.

The return value may point to static area, and may be overwritten by
subsequent calls to getgrent(), getgrgid(), or getgrnam().

The getgrnam_r() and getgrgid_r() functions return zero on success. In case of


error, an error number is returned.

//Program to get group file info using group name and groupid

#include<stdio.h>
#include<sys/types.h>
#include<string.h>
#include<grp.h>
main()
{
struct group *g;
char name[20];
int i=0;

printf("Enter group name:\n");


__fpurge(stdin);
gets(name);

g=getgrnam(name);
/*
int id;
printf("Enter group id:\n");
__fpurge(stdin);
scanf("%d",&id);
g=getgrgid(id);
*/

if(g==NULL)
printf("Group not available\n");
else
{
printf("Group name:%s\n",g->gr_name);
printf("Password:%s\n",g->gr_passwd);
printf("Group id:%d\n",g->gr_gid);
printf("Group members are:\n");
while(*(g->gr_mem+i)!=NULL)
{
printf("%s",*(g->gr_mem+i));
i++;
}
printf("\n");
}
}

output:

Enter group name:


root
Group name:root
Password:x
Group id:0
Group members are:
root

output:

Enter group id:


0
Group name:root
Password:x
Group id:0
Group members are:
root

GETGRENT:
---------
NAME
getgrent, setgrent, endgrent - get group file entry

SYNOPSIS
#include <sys/types.h>
#include <grp.h>

struct group *getgrent(void);

void setgrent(void);

void endgrent(void);

DESCRIPTION
The getgrent() function returns a pointer to a structure containing the broken-
out fields of a record in the group database (e.g., the local group file /etc/group,
NIS, and LDAP). The first time it is called it returns the first entry; thereafter, it
returns successive entries.

The setgrent() function rewinds to the beginning of the group database, to allow
repeated scans.

The endgrent() function is used to close the group database after all processing
has been performed.

The group structure is defined in <grp.h> as follows:

struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};

RETURN VALUE
The getgrent() function returns a pointer to a group structure, or NULL if there
are no more entries or an error occurs.

Upon error, errno may be set. If one wants to check errno after the call, it
should be set to zero before the call.

PROCESS MANAGEMENT:

FORK:

NAME
fork - create a child process
SYNOPSIS
#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

DESCRIPTION
fork() creates a child process that differs from the parent process only in its
PID and PPID, and in the fact that resource utilizations are set to 0. File locks and
pending signals are not inherited.

Under Linux, fork() is implemented using copy-on-write pages, so the only


penalty that it incurs is the time and memory required to duplicate the parent’s
page tables, and to create a unique task structure for the child.

RETURN VALUE
On success, the PID of the child process is returned in the parent’s thread of
execution, and a 0 is returned in the child’s thread of execution. On failure, a -1 will
be returned in the parent’s context, no child process will be created, and errno will
be set appropriately.

//Program on fork()

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
main()
{

int i;

i=fork();

if(i==0)
printf("Child process->My process id=%d\t Parent process id=
%d\n",getpid(),getppid());

else
printf("Parent process->My process id=%d\t My Parent process id=
%d\n",getpid(),getppid());

printf("Convergence Labs\n");

__fpurge(stdin);
getchar();
}

output:
Child process->My process id=3601 Parent process id=3600
Convergence Labs
Parent process->My process id=3600 My Parent process id=2947
Convergence Labs

VFORK():

NAME
vfork - create a child process and block parent

SYNOPSIS
#include <sys/types.h>
#include <unistd.h>

pid_t vfork(void);

STANDARD DESCRIPTION
(From SUSv2 / POSIX draft.) The vfork() function has the same effect as
fork(), except that the behaviour is undefined if the process created by vfork() either
modifies any data other than a variable of type pid_t used to store the return
value from vfork(), or returns from the function in which vfork() was called, or calls
any other function before successfully calling _exit() or one of the exec() family of
functions.

LINUX DESCRIPTION
vfork(), just like fork(2), creates a child process of the calling process. For
details and return value and errors, see fork(2).
vfork() is a special case of clone(2). It is used to create new processes without
copying the page tables of the parent process. It may be useful in performance
sensitive applications where a child will be created which then immediately issues an
execve().

vfork() differs from fork() in that the parent is suspended until the child makes
a call to execve(2) or _exit(2). The child shares all memory with its parent,
including the stack, until execve() is issued by the child. The child must not return
from the current function or call exit(), but may call _exit().
Signal handlers are inherited, but not shared. Signals to the parent arrive after
the child releases the parent’s memory.

HISTORIC DESCRIPTION
Under Linux, fork() is implemented using copy-on-write pages, so the only
penalty incurred by fork() is the time and memory required to duplicate the parent’s
page tables, and to create a unique task structure for the child. However, in the
bad old days a fork() would require making a complete copy of the caller’s data
space, often needlessly, since usually immediately afterwards an exec() is done.
Thus, for greater efficiency, BSD introduced the vfork() system call, that did not
fully copy the address space of the parent process, but borrowed the parent’s
memory and thread of control until a call to execve() or an exit occurred. The
parent process was suspended while the child was using its resources. The use of
vfork() was tricky: for example, not modifying data in the parent process depended
on knowing which variables are held in a register.

BUGS
It is rather unfortunate that Linux revived this spectre from the past. The
BSD manpage states: "This system call will be eliminated when proper system
sharing mechanisms are implemented. Users should not depend on the memory
sharing semantics of vfork() as it will, in that case, be made synonymous to fork()."

Formally speaking, the standard description given above does not allow one to
use vfork() since a following exec() might fail, and then what happens is undefined.

Details of the signal handling are obscure and differ between systems. The
BSD manpage states: "To avoid a possible deadlock situation, processes that are
children in the middle of a vfork() are never sent SIGTTOU or SIGTTIN signals;
rather, output or ioctls are allowed and input attempts result in an end-of-file
indication."

Currently (Linux 2.3.25), strace(1) cannot follow vfork() and requires a kernel
patch.

//Example 1

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j;

i=fork();

if(i==0)
{
for(j=0;j<=4;j++)
{
printf("%d\n",j);
sleep(1);
}
}
else
{
for(j=4;j>=0;j--)
{
printf("%d\n",j);
sleep(1);
}
}
}

output:
-------
0
4
3
1
2
2
1
3
0
4

//Example 2
main()
{
int i,j;

i=fork();

if(i==0)
{
for(j=0;j<=4;j++) //child process becomes orphan process which is
taken care by init process
{
printf("Child\n");
sleep(1);
}
}
else
{
for(j=0;j<=2;j--)
{
printf("Parent\n");
sleep(1);
}
}
}

output:
Child
Parent
Child
Parent
Child
Parent
Child
[root@Sandya PROCMGMT]# Child

//Example 3

main()
{
int i,j;

i=fork();

if(i==0)
{
for(j=0;j<=3;j++)//child process in zombie state
{
printf("Child\n");
sleep(1);
}
}
else
{
for(j=0;j<=6;j--)
{
printf("Parent\n");
sleep(1);
}
}
}

output:
Child
Parent
Child
Parent
Child
Parent
Child
Parent
Parent
Parent
Parent

//Example 4

main()
{

int i,j;

i=vfork();

if(i==0)
{
for(j=0;j<=2;j++)
{
printf("Child\n");
sleep(1);
}
exit(0);
}
else
{
for(j=0;j<=3;j++)
{
printf("Parent\n");
sleep(1);
}
wait(NULL);
}
}

output:
Child
Child
Child
Parent
Parent
Parent
Parent

EXECV FAMILY:

NAME
execl, execlp, execle, execv, execvp - execute a file

SYNOPSIS
#include <unistd.h>

extern char **environ;

int execl(const char *path, const char *arg, ...);


int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,
..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

DESCRIPTION
The exec() family of functions replaces the current process image with a new
process image. The functions described in this manual page are front-ends for the
function execve(2). (See the manual page for execve() for detailed information
about the replacement of the current process.)

The initial argument for these functions is the pathname of a file which is to be
executed.

The const char *arg and subsequent ellipses in the execl(), execlp(), and
execle() functions can be thought of as arg0, arg1, ..., argn. Together they describe
a list of one or more pointers to null-terminated strings that represent the argument
list available to the executed program. The first argument, by convention, should
point to the filename associated with the file being executed. The list of arguments
must be terminated by a NULL pointer, and, since these are variadic functions,
this pointer must be cast (char *) NULL.

The execv() and execvp() functions provide an array of pointers to null-


terminated strings that represent the argument list available to the new program.
The first argument, by convention, should point to the filename associated with the
file being executed. The array of pointers must be terminated by a NULL
pointer.
The execle() function also specifies the environment of the executed process by
following the NULL pointer that terminates the list of arguments in the parameter list
or the pointer to the argv array with an additional parameter. This additional
parameter is an array of pointers to null-terminated strings and must be terminated
by a NULL pointer. The other functions take the environment for the new process
image from the external variable environ in the current process.

Some of these functions have special semantics.

The functions execlp() and execvp() will duplicate the actions of the shell in
searching for an executable file if the specified filename does not contain a slash (/)
character. The search path is the path specified in the environment by the PATH
variable. If this variable isn’t specified, the default path ‘:/bin:/usr/bin’ is used. In
addition, certain errors are treated specially.

If permission is denied for a file (the attempted execve() returned EACCES),


these functions will continue searching the rest of the search path. If no other
file is found, however, they will return with the global variable errno set to EACCES.

If the header of a file isn’t recognized (the attempted execve() returned


ENOEXEC), these functions will execute the shell with the path of the file as its
first argument. (If this attempt fails, no further searching is done.)

RETURN VALUE
If any of the exec() functions returns, an error will have occurred. The return
value is -1, and the global variable errno will be set to indicate the error.

//Example
sri1.c

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
main()
{
int i;

i=fork();
if(i==0)
{
printf("Press enter to replace current program\n");

__fpurge(stdin);
getchar();

char *x[]={"sri","5",NULL};

//execv("sri",x);
execl("sri","sri","5",NULL);
}
else
{
printf("I am parent process....\n");
wait(NULL);
}
}

sri.c

#include<stdio.h>
main(int argc,char *argv[])
{
int n,f=1;

n=atoi(argv[1]);

while(n>0)
f=f*n--;
printf("Factorial is %d\n",f);
}

Output:

THREADS

PTHREAD_CREATE:

NAME
pthread_create - thread creation

SYNOPSIS
#include <pthread.h>

int pthread_create(pthread_t *restrict thread,


const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);

DESCRIPTION
The pthread_create() function shall create a new thread, with attributes
specified by attr, within a process. If attr is NULL, the default attributes shall be
used. If the attributes specified by attr are modified later, the thread’s
attributes shall not be affected. Upon successful completion, pthread_create()
shall store the ID of the created thread in the location referenced by thread.

The thread is created executing start_routine with arg as its sole argument. If
the start_routine returns,the effect shall be as if there was an implicit call to
pthread_exit() using the return value of start_routine as the exit status. Note that
the thread in which main() was originally invoked differs from this. When it returns
from main(), the effect shall be as if there was an implicit call to exit() using the
return value of main() as the exit status.
The signal state of the new thread shall be initialized as follows:

* The signal mask shall be inherited from the creating thread.

* The set of signals pending for the new thread shall be empty.

The alternate stack shall not be inherited.

The floating-point environment shall be inherited from the creating thread.

If pthread_create() fails, no new thread is created and the contents of the


location referenced by thread are undefined.

If _POSIX_THREAD_CPUTIME is defined, the new thread shall have a CPU-time


clock accessible, and the initial value of this clock shall be set to zero.

RETURN VALUE
If successful, the pthread_create() function shall return zero; otherwise, an
error number shall be returned to indicate the error.

PTHREAD_JOIN:

NAME
pthread_join - wait for thread termination

SYNOPSIS
#include <pthread.h>

int pthread_join(pthread_t thread, void **value_ptr);

DESCRIPTION
The pthread_join() function shall suspend execution of the calling thread until
the target thread terminates, unless the target thread has already terminated. On
return from a successful pthread_join() call with a non-NULL value_ptr argument,
the value passed to pthread_exit() by the terminating thread shall be made available
in the location referenced by value_ptr. When a pthread_join() returns successfully,
the target thread has been terminated. The results of multiple simultaneous calls to
pthread_join() specifying the same target thread are undefined. If the thread calling
pthread_join() is canceled, then the target thread shall not be detached.

It is unspecified whether a thread that has exited but remains


unjoined counts against {PTHREAD_THREADS_MAX}.

RETURN VALUE
If successful, the pthread_join() function shall return zero; otherwise, an error
number shall be returned to indicate the error.

//Example

#include<stdio.h>
#include<pthread.h>
void banner()
{
int i;
for(i=0;i<=3;i++)
{
printf("Banner function\n");
sleep(1);
}
}

main()
{
pthread_t pd;
int i;

pthread_create(&pd,NULL,(void (*))banner,NULL);

for(i=0;i<=3;i++)
{
printf("Main function\n");
sleep(1);
}

pthread_join(pd,NULL);
}

PROCESS COMMUNICATION

I) RPC - SOCKETS:

SOCKET:

NAME
socket - create an endpoint for communication

SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

DESCRIPTION
socket() creates an endpoint for communication and returns a descriptor.

The domain parameter specifies a communication domain; this selects the


protocol family which will be used for communication. These families are defined in
<sys/socket.h>.The currently understood formats include:

Name Purpose Man page


PF_UNIX, PF_LOCAL Local communication unix(7)
PF_INET IPv4 Internet protocols ip(7)
PF_INET6 IPv6 Internet protocols
PF_IPX IPX - Novell protocols
PF_NETLINK Kernel user interface device netlink(7)
PF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
PF_AX25 Amateur radio AX.25 protocol
PF_ATMPVC Access to raw ATM PVCs
PF_APPLETALK Appletalk ddp(7)
PF_PACKET Low level packet interface packet(7)

The socket has the indicated type, which specifies the communication
semantics. Currently defined types are:

SOCK_STREAM
Provides sequenced, reliable, two-way, connection-based byte streams. An
out-of-band data transmission mechanism may be supported.

SOCK_DGRAM
Supports datagrams (connectionless, unreliable messages of a fixed
maximum length).

SOCK_SEQPACKET
Provides a sequenced, reliable, two-way connection-based data
transmission path for datagrams of fixed maximum length; a consumer is required to
read an entire packet with each read system call.

SOCK_RAW
Provides raw network protocol access.

SOCK_RDM
Provides a reliable datagram layer that does not guarantee ordering.

SOCK_PACKET
Obsolete and should not be used in new programs; see packet(7).

Some socket types may not be implemented by all protocol families; for
example, SOCK_SEQPACKET is not implemented for AF_INET.

The protocol specifies a particular protocol to be used with the socket.


Normally only a single protocol exists to support a particular socket type within a
given protocol family, in which case protocol can be specified as 0. However, it is
possible that many protocols may exist, in which case a particular protocol must be
specified in this manner. The protocol number to use is specific to the
“communication domain” in which communication is to take place; see
protocols(5). See getprotoent(3) on how to map protocol name strings to protocol
numbers.

Sockets of type SOCK_STREAM are full-duplex byte streams, similar to pipes.


They do not preserve record boundaries. A stream socket must be in a connected
state before any data may be sent or received on it. A connection to another socket
is created with a connect(2) call. Once connected, data may be transferred
using read(2) and write(2) calls or some variant of the send(2) and recv(2) calls.
When a session has been completed a close(2) may be performed. Out-of-band data
may also be transmitted as described in send(2) and received as described in
recv(2).
The communications protocols which implement a SOCK_STREAM ensure that
data is not lost or duplicated. If a piece of data for which the peer protocol has
buffer space cannot be successfully transmitted within a reasonable length of time,
then the connection is considered to be dead. When SO_KEEPALIVE is enabled on
the socket the protocol checks in a protocol-specific manner if the other end is still
alive. A SIGPIPE signal is raised if a process sends or receives on a broken stream;
this causes naive processes, which do not handle the signal, to exit.
SOCK_SEQPACKET sockets employ the same system calls as SOCK_STREAM sock-
ets. The only difference is that read(2) calls will return only the amount of data
requested, and any data remaining in the arriving packet will be discarded. Also all
message boundaries in incoming datagrams are preserved.

SOCK_DGRAM and SOCK_RAW sockets allow sending of datagrams to


correspondents named in sendto(2) calls.
Datagrams are generally received with recvfrom(2), which returns the next
datagram along with the address of its sender.

SOCK_PACKET is an obsolete socket type to receive raw packets directly


from the device driver. Use packet(7) instead.

An fcntl(2) F_SETOWN operation can be used to specify a process or process


group to receive a SIGURG signal when the out-of-band data arrives or SIGPIPE
signal when a SOCK_STREAM connection breaks unexpectedly.
This operation may also be used to set the process or process group that
receives the I/O and asynchronous notification of I/O events via SIGIO. Using
F_SETOWN is equivalent to an ioctl(2) call with the FIOSETOWN or SIOCSPGRP
argument.

When the network signals an error condition to the protocol module (e.g., using
a ICMP message for IP) the pending error flag is set for the socket. The next
operation on this socket will return the error code of the pending error. For some
protocols it is possible to enable a per-socket error queue to retrieve
detailed information about the error; see IP_RECVERR in ip(7).

The operation of sockets is controlled by socket level options. These options are
defined in <sys/socket.h>. The functions setsockopt(2) and getsockopt(2) are used
to set and get options, respectively.

RETURN VALUE
On success, a file descriptor for the new socket is returned. On error, -1 is
returned, and errno is set appropriately.

vi /etc/protocols

ip 0 IP # internet protocol, pseudo protocol number


hopopt 0 HOPOPT # hop-by-hop options for ipv6
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group management protocol
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
egp 8 EGP # exterior gateway protocol
igp 9 IGP # any private interior gateway (Cisco: for IGRP)
udp 17 UDP # user datagram protocol

BIND:

NAME
bind - bind a name to a socket

SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);

DESCRIPTION
bind() gives the socket sockfd the local address my_addr. my_addr is addrlen
bytes long. Traditionally, this is called “assigning a name to a socket.” When
a socket is created with socket(2), it exists in a name space (address family) but has
no name assigned.
It is normally necessary to assign a local address using bind() before a
SOCK_STREAM socket may receive connections (see accept(2)).

The rules used in name binding vary between address families. Consult the
manual entries in Section 7 for detailed information. For AF_INET see ip(7), for
AF_INET6 see ipv6(7), for AF_UNIX see unix(7), for AF_APPLETALK see ddp(7), for
AF_PACKET see packet(7), for AF_X25 see x25(7) and for AF_NETLINK see
netlink(7).

The actual structure passed for the my_addr argument will depend on the
address family. The sockaddr structure is defined as something like:

struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}

The only purpose of this structure is to cast the structure pointer passed in
my_addr in order to avoid compiler warnings. The following example shows how this
is done when binding a socket in the Unix (AF_UNIX) domain:

#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdlio.h>

#define MY_SOCK_PATH "/somepath"

int
main(int argc, char *argv[])
{
int sfd;
struct sockaddr_un addr;
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}

memset(&addr, 0, sizeof(struct sockaddr_un));


/* Clear structure */
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, MY_SOCK_PATH,
sizeof(addr.sun_path) - 1);

if (bind(sfd, (struct sockaddr *) &addr,


sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
...
}

RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set
appropriately.

LISTEN:

NAME
listen - listen for connections on a socket

SYNOPSIS
#include <sys/socket.h>

int listen(int sockfd, int backlog);

DESCRIPTION
To accept connections, a socket is first created with socket(2), a willingness to
accept incoming connections and a queue limit for incoming connections are specified
with listen(), and then the connections are accepted with accept(2). The listen() call
applies only to sockets of type SOCK_STREAM or SOCK_SEQPACKET.
The backlog parameter defines the maximum length the queue of pending
connections may grow to. If a connection request arrives with the queue full the
client may receive an error with an indication of ECONNREFUSED or, if the underlying
protocol supports retransmission, the request may be ignored so that retries
succeed.

NOTES
The behaviour of the backlog parameter on TCP sockets changed with Linux 2.2.
Now it specifies the queue length for completely established sockets waiting to be
accepted, instead of the number of incomplete connection requests. The maximum
length of the queue for incomplete sockets can be set using the
tcp_max_syn_backlog sysctl. When syncookies are enabled there is no logical
maximum length and this sysctl setting is ignored. See tcp(7) for more information.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set
appropriately.

CONNECT:

NAME
connect - initiate a connection on a socket

SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

DESCRIPTION
The connect() system call connects the socket referred to by the file
descriptor sockfd to the address specified by serv_addr. The addrlen argument
specifies the size of serv_addr. The format of the address in serv_addr is
determined by the address space of the socket sockfd; see socket(2) for further
details.

If the socket sockfd is of type SOCK_DGRAM then serv_addr is the address to


which datagrams are sent by default, and the only address from which datagrams
are received. If the socket is of type SOCK_STREAM or SOCK_SEQPACKET, this call
attempts to make a connection to the socket that is bound to the address specified
by serv_addr.

Generally, connection-based protocol sockets may successfully connect() only


once; connectionless protocol sockets may use connect() multiple times to change
their association. Connectionless sockets may dissolve the association by connecting
to an address with the sa_family member of sockaddr set to AF_UNSPEC.

RETURN VALUE
If the connection or binding succeeds, zero is returned. On error, -1 is
returned, and errno is set appropriately.

ACCEPT:

NAME
accept - accept a connection on a socket

SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

DESCRIPTION
The accept() system call is used with connection-based socket types
(SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection request on the
queue of pending connections, creates a new connected socket, and returns a new
file descriptor referring to that socket. The newly created socket is not in the
listening state. The original socket sockfd is unaffected by this call.

The argument sockfd is a socket that has been created with socket(2), bound to
a local address with bind(2), and is listening for connections after a listen(2).

The argument addr is a pointer to a sockaddr structure. This structure is filled


in with the address of the peer socket, as known to the communications layer. The
exact format of the address returned addr is determined by the socket’s address
family (see socket(2) and the respective protocol man pages). The addrlen
argument is a value-result argument: it should initially contain the size of the
structure pointed to by addr; on return it will contain the actual length (in bytes) of
the address returned. When addr is NULL nothing is filled in.

If no pending connections are present on the queue, and the socket is not
marked as non-blocking, accept() blocks the caller until a connection is present. If
the socket is marked non-blocking and no pending connections are present on the
queue, accept() fails with the error EAGAIN.

In order to be notified of incoming connections on a socket, you can use


select(2) or poll(2). A readable event will be delivered when a new connection is
attempted and you may then call accept() to get a socket for that connection.
Alternatively, you can set the socket to deliver SIGIO when activity occurs on a
socket; see socket(7) for details.

For certain protocols which require an explicit confirmation, such as DECNet,


accept() can be thought of as merely dequeuing the next connection request and
not implying confirmation. Confirmation can be implied by a normal read or write on
the new file descriptor, and rejection can be implied by closing the new socket.
Currently only DECNet has these semantics on Linux.

NOTES
There may not always be a connection waiting after a SIGIO is delivered or
select(2) or poll(2) return a readability event because the connection might have
been removed by an asynchronous network error or another thread before accept()
is called. If this happens then the call will block waiting for the next connection to
arrive. To ensure that accept() never blocks, the passed socket sockfd needs to
have the O_NONBLOCK flag set (see socket(7)).

RETURN VALUE
On success, accept() returns a non-negative integer that is a descriptor for the
accepted socket. On error, -1 is returned, and errno is set appropriately.

SEND:

NAME
send, sendto, sendmsg - send a message on a socket

SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int s, const void *buf, size_t len, int flags);


ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr
*to, socklen_t tolen);
ssize_t sendmsg(int s, const struct msghdr *msg, int flags);

DESCRIPTION
The system calls send(), sendto(), and sendmsg() are used to transmit a
message to another socket.

The send() call may be used only when the socket is in a connected state (so
that the intended recipient is known). The only difference between send() and
write() is the presence of flags. With zero flags parameter, send() is equivalent
to write(). Also, send(s,buf,len,flags) is equivalent to sendto(s,buf,len,flags,NULL,0).

The parameter s is the file descriptor of the sending socket.

If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)


socket, the parameters to and tolen are ignored (and the error EISCONN may be
returned when they are not NULL and 0), and the error ENOTCONN is returned when
the socket was not actually connected.
Otherwise, the address of the target is given by to with tolen specifying its size.
For sendmsg(), the address of the target is given by msg.msg_name, with
msg.msg_namelen specifying its size.

For send() and sendto(), the message is found in buf and has length len. For
sendmsg(), the message is pointed to by the elements of the array msg.msg_iov.
The sendmsg() call also allows sending ancillary data (also known as control
information).

If the message is too long to pass atomically through the underlying protocol,
the error EMSGSIZE is returned, and the message is not transmitted.

No indication of failure to deliver is implicit in a send(). Locally detected errors


are indicated by a return value of -1.

When the message does not fit into the send buffer of the socket, send()
normally blocks, unless the socket has been placed in non-blocking I/O mode. In
non-blocking mode it would return EAGAIN in this case. The select(2) call may be
used to determine when it is possible to send more data.

The flags parameter is the bitwise OR of zero or more of the following flags.

MSG_CONFIRM (Linux 2.3+ only)


Tell the link layer that forward progress happened: you got a successful
reply from the other side. If the link layer doesn’t get this it will regularly
reprobe the neighbour (e.g. via a unicast ARP). Only valid on SOCK_DGRAM and
SOCK_RAW sockets and currently only implemented for IPv4 and IPv6. See arp(7)
for details.

MSG_DONTROUTE
Don’t use a gateway to send out the packet, only send to hosts on directly
connected networks. This is usually used only by diagnostic or routing programs.
This is only defined for protocol families that route; packet sockets don’t.
MSG_DONTWAIT
Enables non-blocking operation; if the operation would block, EAGAIN is
returned (this can also be enabled using the O_NONBLOCK with the F_SETFL
fcntl(2)).

MSG_EOR
Terminates a record (when this notion is supported, as for sockets of type
SOCK_SEQPACKET).

MSG_MORE (Since Linux 2.4.4)


The caller has more data to send. This flag is used with TCP sockets to
obtain the same effect as the TCP_CORK socket option (see tcp(7)), with the
difference that this flag can be set on a per-call basis.

Since Linux 2.6, this flag is also supported for UDP sockets, and informs
the kernel to package all of the data sent in calls with this flag set into a single
datagram which is only transmitted when a call is performed that does not specify
this flag. (See also the UDP_CORK socket option described in udp(7).)

MSG_NOSIGNAL
Requests not to send SIGPIPE on errors on stream oriented sockets when
the other end breaks the connection. The EPIPE error is still returned.

MSG_OOB
Sends out-of-band data on sockets that support this notion (e.g. of type
SOCK_STREAM); the underlying protocol must also support out-of-band data.

The definition of the msghdr structure follows. See recv(2) and below for an
exact description of its fields.

struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};

You may send control information using the msg_control and msg_controllen
members. The maximum control buffer length the kernel can process is limited per
socket by the net.core.optmem_max sysctl; see socket(7).

RETURN VALUE
On success, these calls return the number of characters sent. On error, -1 is
returned, and errno is set appropriately.

RECV:

NAME
recv, recvfrom, recvmsg - receive a message from a socket
SYNOPSIS
#include <sys/types.h>
#include <sys/socket.h>

ssize_t recv(int s, void *buf, size_t len, int flags);

ssize_t recvfrom(int s, void *buf, size_t len, int flags,


struct sockaddr *from, socklen_t *fromlen);

ssize_t recvmsg(int s, struct msghdr *msg, int flags);

DESCRIPTION
The recvfrom() and recvmsg() calls are used to receive messages from a
socket, and may be used to receive data on a socket whether or not it is connection-
oriented.

If from is not NULL, and the underlying protocol provides the source address,
this source address is filled in. The argument fromlen is a value-result parameter,
initialized to the size of the buffer associated with from, and modified on return to
indicate the actual size of the address stored there.

The recv() call is normally used only on a connected socket (see connect(2))
and is identical to recvfrom() with a NULL from parameter.

All three routines return the length of the message on successful completion. If
a message is too long to fit in the supplied buffer,excess bytes may be discarded
depending on the type of socket the message is received from.

If no messages are available at the socket, the receive calls wait for a message
to arrive, unless the socket is nonblocking (see fcntl(2)), in which case the
value -1 is returned and the external variable errno set to EAGAIN. The receive calls
normally return any data available, up to the requested amount, rather than waiting
for receipt of the full amount requested.

The select(2) or poll(2) call may be used to determine when more data arrives.

The flags argument to a recv() call is formed by OR’ing one or more of the
following values:

MSG_DONTWAIT
Enables non-blocking operation; if the operation would block, EAGAIN is
returned (this can also be enabled using the O_NONBLOCK with the F_SETFL
fcntl(2)).

MSG_ERRQUEUE
This flag specifies that queued errors should be received from the socket
error queue. The error is passed in an ancillary message with a type dependent on
the protocol (for IPv4 IP_RECVERR). The user should supply a buffer of sufficient
size. The payload of the original packet that caused the error is passed as normal
data via msg_iovec. The original destination address of the datagram that caused
the error is supplied via msg_name.
For local errors, no address is passed (this can be checked with the
cmsg_len member of the cmsghdr). For error receives, the MSG_ERRQUEUE is set
in the msghdr. After an error has been passed, the pending socket error is
regenerated based on the next queued error and will be passed on the next socket
operation.

MSG_OOB
This flag requests receipt of out-of-band data that would not be received in
the normal data stream. Some protocols place expedited data at the head of the
normal data queue, and thus this flag cannot be used with such protocols.

MSG_PEEK
This flag causes the receive operation to return data from the beginning
of the receive queue without removing that data from the queue. Thus, a
subsequent receive call will return the same data.

MSG_TRUNC
Return the real length of the packet, even when it was longer than the
passed buffer. Only valid for packet sockets.

MSG_WAITALL
This flag requests that the operation block until the full request is satisfied.
However, the call may still return less data than requested if a signal is caught,
an error or disconnect occurs, or the next data to be received is of a different type
than that returned.

As an example, Linux uses this auxiliary data mechanism to pass extended


errors, IP options or file descriptors over Unix sockets.

The msg_flags field in the msghdr is set on return of recvmsg(). It can contain
several flags:

MSG_EOR
indicates end-of-record; the data returned completed a record (generally
used with sockets of type SOCK_SEQPACKET).

MSG_TRUNC
indicates that the trailing portion of a datagram was discarded because the
datagram was larger than the buffer supplied.

MSG_CTRUNC
indicates that some control data were discarded due to lack of space in the
buffer for ancillary data.

MSG_OOB
is returned to indicate that expedited or out-of-band data were received.

MSG_ERRQUEUE
indicates that no data was received but an extended error from the socket
error queue.

RETURN VALUE
These calls return the number of bytes received, or -1 if an error occurred. The
return value will be 0 when the peer has performed an orderly shutdown.

CLOSE:

NAME
close - close a file descriptor

SYNOPSIS
#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. Any record locks (see fcntl(2)) held on the file it was associated with, and
owned by the process, are removed (regardless of the file descriptor that was used
to obtain the lock).

If fd is the last copy of a particular file descriptor the resources associated with
it are freed; if the descriptor was the last reference to a file which has been removed
using unlink(2) the file is deleted.

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

You might also like