CSE 120: File System Examples

In lecture we discussed the nature of various peculiar behaviors of file systems. This page shows the example programs we used in lecture to demonstrate them.

File Corruption

When multiple processes are writing to the same file at the same time without any coordination, you should assume that the file will become corrupted. This situation is a race condition similar to multiple threads accessing a shared data structure in memory at the same time. The program corrupt.c demonstrates this scenario with four processes writing to the same file:

int
main (int argc, char *argv[])
{
    int i, fd;

    fd = open ("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
    if (fd < 0)
	printf ("Failed to open output file\n");

    fork();
    fork();
    
    for (i = 0; i < 4; i++) {
	char *ptr, *str = "4 processes writing to the same file\n";

	for (ptr = str; *ptr; ptr++) {
	    if (write (fd, ptr, 1) < 0) {
		printf ("Failed to write to output file\n");
		return -1;
	    }
	}
    }
    
    close (fd);
    return 0;
}

Compiling and running the program shows corrupted data written to the file file.out:

% gcc corrupt.c
% ./a.out
% cat file.out
4 processes writing to the same file
4 p4rocess4 proc processes writing to the same file
4 processes writing to the same file
4 processes writing toes wri4 proctesses writing to the same file
4 processes writing to the same file
4 processes writing to the same file
4 processes writing to the same file
esses writing to the same fi le
4 processes writing tothe same fi thle saemie file
4
4 pr processes writing to the same file
4 processes writing to the same file
ng to the same file
4 processes writing to the same file
4 processes writing to the same file
ocesses writing to the same file

"Hidden" Deleted Files

File systems do not free up blocks storing file data until all processes using a file have closed it. As a result, removing a file can remove the directory entry for the file (i.e., it no longer shows up in a directory listing) but the file itself still exists (i.e., processes using the file can still read and write data in the file). The program hidden.c demonstrates this situation:

int
main (int argc, char *argv[])
{
    char buff[256];
    int r, fd;

    fd = open ("file.in", O_RDONLY);
    if (fd < 0) {
	printf ("Failed to open input file\n"); return -1;
    }
    printf ("Opened file.in for reading\n");

    printf ("Type enter:\n");
    if (read (STDIN_FILENO, buff, 256) <= 0) {
	printf ("Failed to read from stdin\n"); return -1;
    }

    // suspend and delete file

    printf ("Reading from file.in\n");
    r = read (fd, buff, 16);
    if (r <= 0) {
	printf ("Failed to read from input file\n"); return -1;
    }

    buff[r] = '\0';
    printf ("%s\n", buff);

    return 0;
}

Compiling and running the program shows that the process can still read the data in the file even though we have deleted it after the process has opened it:

% cp hidden.c file.in
% gcc hidden.c
% ./a.out
Opened file.in for reading
Type enter:
^Z
[1]+  Stopped                 ./a.out
% rm file.in
% ls file.in
ls: cannot access file.in: No such file or directory
% fg
./a.out

Reading from file.in
#include &stdio.