next up previous contents Back to Operating Systems Home Page
Next: Moving inside a file Up: Block-oriented I/O in UNIX Previous: File creation

Opening files

The use of creat()has become somewhat obsolete, since an unique system call, open(), can be used both to create and to open files. This also solves possible concurrency problems that can occur if multiple processes try to open or create the same file (more on this later).

This routine is declared as follows:

int open(char *path, int flags, mode_t auth)
and takes three arguments, the last of which is optionalgif:

The only thing that needs be explained is then how to specify the opening mode by the flags argument. This argument is constructed as the bitwise OR of some integer constants, which are pre-defined in system headers. The most used of them are:

In the following example a file is opened for writing, or created in rw-r-r- mode it it does not exist, and a second is open for reading.

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
...
int fildes1, fildes2;
...
fildes1=open("myfile1", O_WRONLY|O_CREAT, 0644);
fildes2=open("myfile2", O_READ);

if (fildes1==-1 || fildes2 == -1 )
{
    perror("opening's messed up");
    exit(1);
}
...

Now there's a problem. Suppose that a process X wants to write a file, or create it if it doesn't exist. It then calls open() with O_WRONLY, O_TRUNC and O_CREAT flags. Suppose it doesn't find it, and hence sets about creating it but it's suspended just before it does (this is likely to happen: creating a file is a ``slow'' I/O operation, after all). Since Dr. Murphy and his Law are always ready to screw things up, a process Y arrives that can either create the same file, or kindly append data to it, if it's already there. Since it's not there yet, it opts for creation, then writes some data on it and goes away. Now X wakes up, and happily resumes the ``creation'' of the same file, with the net result of blowing away Y's hard work.

Problems like this are typical of a multiprogramming environment, and we'll deal with them in greater detail soon, when we'll talk about concurrency. For now it will sufice to recognize that the problem is solved if we can somehow be guaranteed that the sequence of checking for existence and then creating is atomic, i.e. indivisible, with respect to other processes calling open() with the same file name in the same directory. UNIX offers this option if the flag O_EXECL is specified along with O_CREAT.


next up previous contents Back to Operating Systems Home Page
Next: Moving inside a file Up: Block-oriented I/O in UNIX Previous: File creation

Franco Callari