CS360 Lecture notes -- Some Basic Terminology


This lecture goes over some basic terms presented to you by your operating system. It used to summarize Chapter 1 of the text book, but we no longer have a text book, so this becomes more primary reference material.

Filesystems

Definition of a ``filesystem'': A hierarchical arrangement of directories.

In Unix, the root filesystem starts with "/". However, there are other subfilesystems, that are part of the root one. To see the filesystems on your machine, type "df". You'll see something like:

UNIX> df
Filesystem            kbytes    used   avail capacity  Mounted on
/dev/sd0a              11167    5952    4099    59%    /
/dev/sd0g             140591   84016   42516    66%    /usr
/dev/sd0h             171959  141421   13343    91%    /home
-memory-               55720       0   55720     0%    /tmp
plank:(pid130)             4       4       0   100%    /amd
galoob:/export/sun4-sos4_1
                      335803  313356       0   100%    /a/galoob/export/sun4-sos4_1
cs:/var/spool/mail    221351  122607   76609    62%    /a/cs/var/spool/mail
alphard:/canary/homes
                      411687  293685   76833    79%    /a/alphard/canary/homes
UNIX>
Each line shows a different file system. The first entry on the line shows where the filesystem is, and the last shows how you access it on your machine. For example, the filesystem /dev/sd0g is a partition on one of the disks on the machine. I can get to it from the directory /usr. The filesystem alphard:/canary/homes is a filesystem that is on the machine "alphard", but has been set up (probably via Sun NFS) so that I can use it on my machine by going to /a/alphard/canary/homes. The way that filesystems work changes from year to year, but usually you can parse the output of df and figure out what is going on.

Names, Paths, Directories

When you say "ls -a", it lists all the filenames in the current directory:

UNIX> cd ~jplank/cs360/notes/Rbtree-1       # This is an ancient set of lecture notes, BTW.  Don't read them.
UNIX> ls -a
.               jh.c            makefile        mysorti.c       mysortu2.c
..              lecture         mysort.c        mysortu0.c      mysortu3.c
README          lecture.html    mysort2.c       mysortu1.c      randfile
UNIX>
(If you don't say "-a", it will not list filenames beginning with ".") Note there are two filenames that are in every directory: "." and ".."

"." is the current directory. ".." is the parent of the current directory.

The pwd command tells you the complete pathname of the current directory. The cd command moves you between directories:

UNIX> cd ~jplank/cs360/notes/Rbtree-1
UNIX> pwd
/home/plank/cs360/notes/Rbtree-1
UNIX> cd .
UNIX> pwd
/home/plank/cs360/notes/Rbtree-1
UNIX> cd ..
UNIX> pwd
/home/plank/cs360/notes
UNIX> cd ../../..
UNIX> pwd
/home
UNIX> cd ././././././.
UNIX> pwd
/home
UNIX> cd ..
UNIX> pwd
/
UNIX> cd ..
UNIX> pwd
/
UNIX> cd ..
UNIX> pwd
/
UNIX> 
Note that the parent directory of "/" is itself.

Your home directory is also the directory that you go to when you enter cd with no arguments. You can specify "~" on the Unix prompt, and it will be interpreted as your home directory. If you specify "~username", then it will be interpreted as the home directory of the given user. Finally, the "$HOME" environment variable will be set to your home directory:

The following commands were on the lab machine hydra3 in 2018. They are not exciting commands, but perhaps you haven't seen them before:

UNIX> pwd
/home/plank
UNIX> cd cs360/notes
UNIX> pwd
/home/plank/cs360/notes
UNIX> ls Chap1
bin lecture.html  makefile src
UNIX> echo $HOME
/home/plank
UNIX> cd ~bvz
UNIX> pwd
/home/bvz
UNIX> cd ~
UNIX> pwd
/home/plank
UNIX> 

Programs and processes:

Examples of programs:

When you run a program, its executing instance is called a process.

For example, suppose you type "vim /home/plank/cs360/notes/Chap1/src/ch1a.c" in one window. This executes the vim program, found in /usr/bin/vim. The executing instance is called a process. If you go to another window, and type "ps x", it will list all of the processes that you are currently executing:

UNIX> ps x
 1394 p0 IW    0:00 xclock -geometry 100x100-0-0 -update 60
 1416 p0 S     0:01 twm
 1436 p1 IW    0:00 -sh (csh)
 1427 p2 IW    0:00 -sh (csh)
 1428 p3 IW    0:00 -sh (csh)
 1443 p5 S     0:01 -sh (csh)
 2328 p5 S     0:00 vim /home/plank/cs360/notes/Chap1/src/ch1a.c
 1444 p6 IW    0:00 -sh (csh)
 2329 p6 R     0:00 ps x
UNIX>
Note that we can run more than one vim process at the same time. Go to another window and type "vim /home/plank/cs360/notes/Chap1/src/ch1b.c". Now when you type "ps x", you'll see the second process.
UNIX> ps x
 1394 p0 IW    0:00 xclock -geometry 100x100-0-0 -update 60
 1416 p0 S     0:01 twm
 1436 p1 IW    0:00 -sh (csh)
 1427 p2 S     0:00 -sh (csh)
 2330 p2 S     0:00 vim /home/plank/cs360/notes/Chap1/src/ch1b.c
 1428 p3 IW    0:00 -sh (csh)
 1443 p5 IW    0:01 -sh (csh)
 2328 p5 IW    0:00 vim /home/plank/cs360/notes/Chap1/src/ch1a.c
 1444 p6 S     0:00 -sh (csh)
 2331 p6 R     0:00 ps x
UNIX>
You should understand the distinction between process and program. The number in the first column of the ps command is the "process id".

Error Handling

Usually when an error occurs in a Unix system or library call, a special return value comes back, and a global variable "errno" is set to say what the error is. For example, suppose you try to open a file that does not exist: (This is in src/ch1a.c):

/* This program demonstrates an error and how errno/perror are used. */

#include <stdio.h>
#include <errno.h>

int main()
{
  FILE *f;

  f = fopen("/home/plank/noexist", "r");
  if (f == NULL) {
    printf("f = null.  errno = %d\n", errno);
    perror("/home/plank/noexist");
  }
  return 0;
}

ch1a.c tries to open the file /home/plank/noexist for reading. That file doesn't exist. Thus, fopen returns NULL (read the man page for fopen), and sets errno to flag the error. When you run the program, you'll see that errno was set to 2. To see what that means, you can do one of two things:

Suppose I create /home/plank/noexist, and do chmod on it so that I can't open it for reading. Then bin/ch1a will print a different error:
UNIX> echo "" > /home/plank/noexist
UNIX> chmod 0 /home/plank/noexist
UNIX> bin/ch1a
f = null.  errno = 13
/home/plank/noexist: Permission denied
UNIX> rm -f /home/plank/noexist
UNIX> bin/ch1a
f = null.  errno = 2
/home/plank/noexist: No such file or directory
UNIX> 
This is the standard Unix interface for errors. Learn to use perror.

User Identification

  • User ID: The number given to each user by the system administrator.

    There are two ways that the system deals with identification: User Id's and group id's. We won't talk much about group id's here. Your user id can be gotten by the system call "getuid()" -- read the man page.

    To print out your UID, try src/ch1b.c

    /* This program prints out your user id.  Read the man page on getuid() for more information. */
    
    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
      printf("%d\n", getuid());
      return 0;
    }
    

    As of 2021, my UID is 503 -- see what yours is.

    UNIX> bin/ch1b       # When you run this, you'll get a different number.
    503
    UNIX> 
    

    Signals

    Signals are a way for asynchronous events to occur in a program. For example, compile and run the program src/ch1c.c

    /* This program prints out a counter that increments every second.
       You stop it temporarily by typing <CNTL-Z>, which sends the SIGSTOP signal to
       the program.  You can run it again by typing fg.  Then, you can terminate the
       program with <CNTL-C>, which sends it the SIGINT signal. */
    
    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
      int i;
    
      i = 0;
      while (1) {
        i++;
        printf("%d\n", i);
        fflush(stdout);
        sleep(1);
      }
      return 0;
    }
    

    This program implements a counter that increments itself every second. Let it run for a few seconds, and then type < CNTL-Z >. This sends the "STOP" signal to the program, which stops it. You'll be back at the shell now. If you type "ps", you'll see something like:

      2483 p5 T 0:00 ch1c
    
    The "T" means that the process is not running -- it is stopped. To start it, you can type "fg", which will send it the "START" signal.

    Now, while it's running, type < CNTL-C > to kill the program -- this sends it the "INT" signal, which teminates it. Segmentation faults are also signals. You can write your programs to handle signals any way you please. This is a more advanced programming technique, which we will deal with later in the semester.