UNIX API Module-3 Open and creat
UNIX API Module-3 Open and creat
open
This is used to establish a connection between a process and a file i.e. it is used to open an existing file for
data transfer function or else it may be also be used to create a new file.
The returned value of the open system call is the file descriptor (row number of the file table), which
contains the inode information.
The prototype of open function is
#include<sys/types.h>
#include<sys/fcntl.h>
int open(const char *pathname, int accessmode, mode_t permission);
If successful, open returns a nonnegative integer representing the open file descriptor.
If unsuccessful, open returns –1.
The first argument is the name of the file to be created or opened. This may be an absolute pathname or
relative pathname.
If the given pathname is symbolic link, the open function will resolve the symbolic link reference to a non
symbolic link file to which it refers.
The second argument is access modes, which is an integer value that specifies how actually the file should be
accessed by the calling process.
Generally the access modes are specified in <fcntl.h>. Various access modes are:
O_RDONLY - open for reading file only
O_WRONLY - open for writing file only
O_RDWR - opens for reading and writing file.
There are other access modes, which are termed as access modifier flags, and one or more of the following can be
specified by bitwise-ORing them with one of the above access mode flags to alter the access mechanism of the file.
O_APPEND - Append data to the end of file.
O_CREAT - Create the file if it doesn’t exist
O_EXCL - Generate an error if O_CREAT is also specified and the file already exists.
O_TRUNC - If file exists discard the file content and set the file size to zero bytes.
O_NONBLOCK - Specify subsequent read or write on the file should be non-blocking.
O_NOCTTY - Specify not to use terminal device file as the calling process control terminal.
To illustrate the use of the above flags, the following example statement opens a file called /usr/divya/usp for
read and write in append mode:
int fd=open(“/usr/divya/usp”,O_RDWR | O_APPEND,0);
If the file is opened in read only, then no other modifier flags can be used.
If a file is opened in write only or read write, then we are allowed to use any modifier flags along with them.
The third argument is used only when a new file is being created. The symbolic names for file permission are
given in the table in the previous page.
creat
This system call is used to create new regular files.
The prototype of creat is
#include <sys/types.h>
#include<unistd.h>
int creat(const char *pathname, mode_t mode);
Returns: file descriptor opened for write-only if OK, -1 on error.
The first argument pathname specifies name of the file to be created.
The second argument mode_t, specifies permission of a file to be accessed by owner group and others.
The creat function can be implemented using open function as:
#define creat(path_name, mode)
open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
read
The read function fetches a fixed size of block of data from a file referenced by a given file descriptor.
The prototype of read function is:
#include<sys/types.h>
#include<unistd.h>
size_t read(int fdesc, void *buf, size_t nbyte);
If successful, read returns the number of bytes actually read.
If unsuccessful, read returns –1.
The first argument is an integer, fdesc that refers to an opened file.
The second argument, buf is the address of a buffer holding any data read.
The third argument specifies how many bytes of data are to be read from the file.
The size_t data type is defined in the <sys/types.h> header and should be the same as unsigned int.
There are several cases in which the number of bytes actually read is less than the amount requested:
o When reading from a regular file, if the end of file is reached before the requested number of bytes has
been read. For example, if 30 bytes remain until the end of file and we try to read 100 bytes, read
returns 30. The next time we call read, it will return 0 (end of file).
o When reading from a terminal device. Normally, up to one line is read at a time.
o When reading from a network. Buffering within the network may cause less than the requested amount
to be returned.
o When reading from a pipe or FIFO. If the pipe contains fewer bytes than requested, read will return only
what is available.
write
The write system call is used to write data into a file.
The write function puts data to a file in the form of fixed block size referred by a given file descriptor.
The prototype of write is
#include<sys/types.h>
#include<unistd.h>
ssize_t write(int fdesc, const void *buf, size_t size);
If successful, write returns the number of bytes actually written.
If unsuccessful, write returns –1.
The first argument, fdesc is an integer that refers to an opened file.
The second argument, buf is the address of a buffer that contains data to be written.
The third argument, size specifies how many bytes of data are in the buf argument.
The return value is usually equal to the number of bytes of data successfully written to a file. (size value)
close
The close system call is used to terminate the connection to a file from a process.
The prototype of the close is
#include<unistd.h>
int close(int fdesc);
If successful, close returns 0.
If unsuccessful, close returns –1.
The argument fdesc refers to an opened file.
Close function frees the unused file descriptors so that they can be reused to reference other files. This is
important because a process may open up to OPEN_MAX files at any time and the close function allows a
process to reuse file descriptors to access more than OPEN_MAX files in the course of its execution.
The close function de-allocates system resources like file table entry and memory buffer allocated to hold
the read/write.
fcntl
The fcntl function helps a user to query or set flags and the close-on-exec flag of any file descriptor.
The prototype of fcntl is
#include<fcntl.h>
int fcntl(int fdesc, int cmd, …);
The first argument is the file descriptor.
The second argument cmd specifies what operation has to be performed.
The third argument is dependent on the actual cmd value.
The possible cmd values are defined in <fcntl.h> header.
cmd value Use
F_GETFL Returns the access control flags of a file descriptor fdesc
F_SETFL Sets or clears access control flags that are specified in the third argument to
fcntl. The allowed access control flags are O_APPEND & O_NONBLOCK
F_GETFD Returns the close-on-exec flag of a file referenced by fdesc. If a return value is
zero, the flag is off; otherwise on.
F_SETFD Sets or clears the close-on-exec flag of a fdesc. The third argument to fcntl is
an integer value, which is 0 to clear the flag, or 1 to set the flag
F_DUPFD Duplicates file descriptor fdesc with another file descriptor. The third
argument to fcntl is an integer value which specifies that the duplicated file
descriptor must be greater than or equal to that value. The return value of
fcntl is the duplicated file descriptor
The fcntl function is useful in changing the access control flag of a file descriptor.
For example: after a file is opened for blocking read-write access and the process needs to change the access
to non-blocking and in write-append mode, it can call:
int cur_flags=fcntl(fdesc,F_GETFL);
int rc=fcntl(fdesc,F_SETFL,cur_flag | O_APPEND | O_NONBLOCK);
The following example reports the close-on-exec flag of fdesc, sets it to on afterwards:
cout<<fdesc<<”close-on-exec”<<fcntl(fdesc,F_GETFD)<<endl;
(void)fcntl(fdesc,F_SETFD,1); //turn on close-on-exec flag
The following statements change the standard input og a process to a file called FOO:
int fdesc=open(“FOO”,O_RDONLY); //open FOO for read
close(0); //close standard input
if(fcntl(fdesc,F_DUPFD,0)==-1)
perror(“fcntl”); //stdin from FOO now
char buf[256];
int rc=read(0,buf,256); //read data from FOO
The dup and dup2 functions in UNIX perform the same file duplication function as fcntl.
They can be implemented using fcntl as:
lseek
The lseek function is also used to change the file offset to a different value.
Thus lseek allows a process to perform random access of data on any opened file.
The prototype of lseek is
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fdesc, off_t pos, int whence);
On success it returns new file offset, and –1 on error.
The first argument fdesc, is an integer file descriptor that refer to an opened file.
The second argument pos, specifies a byte offset to be added to a reference location in deriving the new file
offset value.
The third argument whence, is the reference location.
Whence value Reference location
SEEK_CUR Current file pointer address
SEEK_SET The beginning of a file
SEEK_END The end of a file
They are defined in the <unistd.h> header.
If an lseek call will result in a new file offset that is beyond the current end-of-file, two outcomes possible
are:
o If a file is opened for read-only, lseek will fail.
o If a file is opened for write access, lseek will succeed.
o The data between the end-of-file and the new file offset address will be initialised with NULL
characters.
link
The link function creates a new link for the existing file.
The prototype of the link function is
#include <unistd.h>
int link(const char *cur_link, const char *new_link);
If successful, the link function returns 0.
If unsuccessful, link returns –1.
The first argument cur_link, is the pathname of existing file.
The second argument new_link is a new pathname to be assigned to the same file.
If this call succeeds, the hard link count will be increased by 1.
The UNIX ln command is implemented using the link API.
/*test_ln.c*/
#include<iostream.h>
#include<stdio.h>
#include<unistd.h>
unlink
The unlink function deletes a link of an existing file.
This function decreases the hard link count attributes of the named file, and removes the file name entry of
the link from directory file.
A file is removed from the file system when its hard link count is zero and no process has any file descriptor
referencing that file.
The prototype of unlink is
#include <unistd.h>
int unlink(const char * cur_link);
If successful, the unlink function returns 0.
If unsuccessful, unlink returns –1.
The argument cur_link is a path name that references an existing file.
ANSI C defines the rename function which does the similar unlink operation.
The prototype of the rename function is:
#include<stdio.h>
int rename(const char * old_path_name,const char * new_path_name);
The UNIX mv command can be implemented using the link and unlink APIs as shown:
#include <iostream.h>
#include <unistd.h>
#include<string.h>
int main ( int argc, char *argv[ ])
{
if (argc != 3 || strcmp(argv[1],argcv[2]))
cerr<<”usage:”<<argv[0]<<””<old_link><new_link>\n”;
else if(link(argv[1],argv[2]) == 0)
return unlink(argv[1]);
return 1;
}
stat, fstat
The stat and fstat function retrieves the file attributes of a given file.
The only difference between stat and fstat is that the first argument of a stat is a file pathname, where as
the first argument of fstat is file descriptor.
The prototypes of these functions are
#include<sys/stat.h>
#include<unistd.h>
access
The access system call checks the existence and access permission of user to a named file.
The prototype of access function is:
#include<unistd.h>
int access(const char *path_name, int flag);
On success access returns 0, on failure it returns –1.
The first argument is the pathname of a file.
The second argument flag, contains one or more of the following bit flag .
Bit flag Uses
F_OK Checks whether a named file exist
R_OK Test for read permission
W_OK Test for write permission
X_OK Test for execute permission
The flag argument value to an access call is composed by bitwise-ORing one or more of the above bit flags as
shown:
int rc=access(“/usr/divya/usp.txt”,R_OK | W_OK);
if (UID == (uid_t)-1)
cerr <<“Invalid user name”;
else for (int i = 2; i < argc ; i++)
if (stat(argv[i], &statv)==0)
{
if (chown(argv[i], UID,statv.st_gid))
perror (“chown”);
else
perror (“stat”);
}
return 0;
}
utime Function
The utime function modifies the access time and the modification time stamps of a file.
The prototype of utime function is
#include<sys/types.h>
#include<unistd.h>
#include<utime.h>