CS110: Principles of Computer Systems

Spring 2021
Instructors Roz Cyrus and Jerry Cain

PDF

Introduction to UNIX Filesystems

  • You should already be familiar with the Linux filesystem as a user. The filesystem uses a tree-based model to store files and directories of files. You can get details of a file in a particular directory with the ls command
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ls
alphabet.txt  copy.c  Makefile	open.c	search.c  t.c  umask.c	vowels.txt
  • You can get a more detailed listing  with the ls -al command:
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ls -la
total 16
drwx------ 2 troccoli operator 2048 Mar 29 07:22 .
drwxr-xr-x 5 poohbear root     2048 Mar 28 17:06 ..
-rw------- 1 troccoli operator   27 Mar 29 07:26 alphabet.txt
-rw------- 1 troccoli operator 1882 Mar 29 07:26 copy.c
-rw------- 1 troccoli operator  634 Mar 29 07:26 Makefile
-rw------- 1 troccoli operator  988 Mar 29 07:26 open.c
-rw------- 1 troccoli operator 2302 Mar 29 07:26 search.c
-rw------- 1 troccoli operator 1321 Mar 29 07:26 t.c
-rw------- 1 troccoli operator  393 Mar 29 07:26 umask.c
-rw------- 1 troccoli operator    6 Mar 29 07:26 vowels.txt
  • There are two files listed as directories (d), "." and "..".  These stand for:
    • "." is the current directory
    • ".." is the parent directory
  • The "rwx------" designates the permissions for a file or directory, with "r" for read
    permission, "w" for write permission, and "x" for execute permission.

Introduction to UNIX Filesystems

  

poohbear@myth53:~/cs110/lecture-examples/filesystems$ ls -la search
-rwxr-xr-x 1 poohbear operator 22344 Mar 29 07:32 search
  • There are actually three parts to the permissions line, each with the three permission types available:
    • rwx r-x r-x

 owner

          group 

                     other

In this case, the owner has read, write, and execute permissions, the group has only read and execute permissions, and the user also has only read and execute permissions.

  • Because each individual set of permissions can be either r, w, or x, there are three bits of information per permission field. We can therefore, use base 8 to designate a particular permission set. Let's see how this would work for the above example:
    • permissions: rwx r-x r-x
    • bits (base 2): 111 101 101
    • base 8:               7   5   5        
  • So, the permissions for the file would be recorded internally as 755.

Introduction to UNIX Filesystems

  

  • In C, a file can be created using the open system call, and you can set the permissions at that time, as well. We will discuss the idea of system calls soon, but for now, simply think of them as a function that can do systemsy stuff. The open function comes with the following signatures (and this works in C, even though C does not support function overloading! How, you ask? See here.)
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
  • There are many flags (see man 2 open for a list of them), and they can be bitwise or'd together. You must include exactly one of the following flags:

    • O_RDONLY: read only

    • O_WRONLY: write only

    • O_RDWR: read and write

  • We employ one of the following flags when creating a file in either O_WRONLY or O_RDWR mode:
    • O_CREAT: create the file if it doesn't exist
    • O_EXCL: mandate the file be created from scratch, fail if file already exists

Introduction to UNIX Filesystems

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
  • When creating a file, the third argument, in part, determines the file's permissions.
  • The reason it is in part is because there is a default permissions mask, called umask, that imposes limits on what the permissions can be. The value of umask is also a three-digit octal, although if a bit is set in the umask, then any attempt to set that bit via the mode parameter is simply ignored. The umask can be set with the following system call:
mode_t umask(mode_t mask); // see "man 2 umask" for details
  • The return value is the old mask (the umask value prior to the call).
  • If you want to check the umask value, you must call the function twice, as with:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[]) {
    mode_t old_mask = umask(0); get old mask as return value
    umask(old_mask); // restore to original
    printf("umask is set to %03o\n",old_mask);
    return 0;
}
poohbear@myth53:~/cs110/lecture-examples/filesystems$ gcc umask.c -o umask
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ./umask
umask is set to 022
  • That 022 means all permission bits can be set, except for the group's and other's individual write bits.

Introduction to UNIX Filesystems

  • Today's lecture examples reside within /usr/class/cs110/lecture-examples/filesystems.
    • The /usr/class/cs110/lecture-examples directory is a git repository that will be updated with additional examples as the quarter progresses.
    • To get started, type git clone /usr/class/cs110/lecture-examples lecture-examples at the command prompt to create your own local copy.
    • Each time I mention there are new examples (or whenever you think to), descend into your local copy and type git pull. Doing so will update your local copy to match whatever the primary has become.

Introduction to UNIX Filesystems

  • You can override umask if you need to set the permissions a particular way.
  • The program below creates an "empty" file, setting its permissions to 0644:
#include <fcntl.h>    // for open
#include <unistd.h>   // for read, close
#include <stdio.h>
#include <sys/types.h> // for umask
#include <sys/stat.h>  // for umask
#include <errno.h>

const char *kFilename = "empty";
const int kFileExistsErr = 17; 
int main() {
    umask(0); // set to 0 to enable all permissions to be set
    int fd = open(kFilename, O_WRONLY | O_CREAT | O_EXCL, 0644);
    if (fd == -1) {
        printf("There was a problem creating '%s'!\n", kFilename);
        if (errno == kFileExistsErr) {
            printf("The file already exists.\n");
        } else {
            printf("Unknown errorno: %d\n", errno);
        }
        return -1;
    }
    printf("Successfully opened the file called \"%s\", and about to close it.\n", kFilename);
    close(fd); // close is the companion to open, file session equivavent to free
    return 0;
}
poohbear@myth53:~/cs110/lecture-examples/filesystems$ make open
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ./open
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ./open 
Successfully opened the file called "empty", and about to close it.
poohbear@myth53:~/cs110/lecture-examples/filesystems$ ls -la empty 
-rw-r--r-- 1 poohbear operator 0 Mar 29 08:43 empty
Made with Slides.com