Programming Assignment 5
1 Summary
zmedia has decided that, while they
  like the zplayer you wrote for PA4, it needs some additional functionality.
  Specifically, they want the user to be able to pause the player, 
  change its speed, and change what is playing.
  
 
2 Documents
  zmedia has provided you with the following use case descriptions and
  statemachine diagram for the new version of zplayer.
    
  Note that zmedia considered several different statemachine diagrams before
  deciding on the one they gave you. Note, in particular, that this version
  does not consider the speed of the system a defining attribute. Hence,
  it does not include states with multiple speeds.
  
 
3 Additional Specifications/Constraints
  In addition to conforming to the documents provided by zmedia (and
  all related course policies), the system must satisfy the following
  additional specifications/constraints.
    
3.1 Processes
    The system must satisfy the following requirements related to
    processes.
    
- 
    There must be only one running process when the system is in the
    On, Loading, and Ready states.
    
 
- 
    In general, there must be two running processes when the system is
    in the Playing and Paused states. The only exception to this requirement
    is whem the system is in the Playing state and the bookz_player has 
    terminated, in which case there will be only one running process.
    
 
- 
    There must be no running processes when the system exits the Off state.
    
 
 
3.2 Slowing the Display
    The system must satisfy the following requirements related to the
    "reading speed" (i.e., the delay between lines).
    
- 
    The default delat between lines must be 1 second.
    
 
- 
    Pressing the ? must not change the delay between lines
    in any way.
    
 
- 
    Pressing the + and/or - keys must not 
    artificially shorten the current delay between
    lines. In other words, though the user expects those keys to 
    change the delay, if the system has just started to "sleep"
    when one of them is pressed it must "resume sleeping" after 
    it responds to the event and "sleep" the appropriate amount of time.
    
 
 
 
4 Submission
  The 
.zip file you submit must be named 
pa5.zip.
  
  In addition to the source code and makefile, the .zip
  file must contain four screenshots of the output from
  ps. Specifically, it must contain: one
  (named before.png) that shows the relevant current
  processes before you run zplayer, one (named ready.png)
  that shows the relevant running processes when zplayer is in the
  Ready state, one (named playing.png) that shows the
  relevant current processes when zplayer is in the Playing state, and
  one (named after.png) that shows the relevant current
  processes after zplayer has terminated.
  
  You must not submit any data files.
  
 
5 Help and Hints
  You may find the following hints helpful. 
    
5.1 Choosing Signals
    The only user-defined signals you may use are 
    SIGUSR1 and SIGUSR2. Hence, you will
    have to use some system-defined signals to satisfy some of the
    requirements. (There are some obvious alternatives to consider.)
    
5.2 Sending Signals
    Since the parent process will need to send signals to the child process
    it will need to store the child's PID in a variable. Since signals
    may need to be sent while the system is in different states, the
    variable will need to be declared/defined appropriately.
    
5.3 Sleeping
    v1 of the 
bookz_player used the 
    
sleep() function. Unfortunately, this function has a
    resolution of a second, which is insufficient for the current
    version. Instead, you must use the 
nanosleep() 
    function.
    
    #define _POSIX_C_SOURCE 199309
    #include <time.h>
    /**
     * Suspend execution for the given amount of time.
     *
     * @param request   The amount of time
     * @param remain    The remaining time (if interrupted)
     * @return          0 normally; -1 on error or if interrupted
     */
    int 
    nanosleep(const struct timespec *request, struct timespec *remain);
    
    This function uses the following timespec structure.
    
    struct timespec {
      time_t tv_sec;   /** Seconds     */
      long   tv_nsec;  /** Nanoseconds */
    }
    
    (Self Test: You should understand why request is
    const and remain is not.)
    
    As discussed in the additional requirements above, you must
    account for the fact that nanosleep() may be
    interrupted. You can use the parameter remain for this
    purpose.
    
 
5.4 The Length of the Delay
    You will need to be careful when you declare/define the variable that 
    holds the current delay (e.g., think about its storage duration, 
    whether the compiler should be able to store it in a register,
    and whether it needs to be atomic with respect to signal handlers).
    
5.5 Signal Handlers
    You will certainly need a signal handler for 
SIGUSR1
    and/or 
SIGUSR2 if you use them. You should probably
    use one signale handler for changing the speed (whether it is
    slower or faster).
    
    You will want to ensure that the code that changes the speed
    can't be interrupted (i.e., is treated as "critical").
    
 
5.6 Testing
    Obviously, you should carefully test all of the new transitions
    (being especially careful about the bye transitions).  Don't just
    include the obvious tests, however, make sure you also include
    tests like the following.
    
- 
      Pressing + many times.
      
 
- 
      Pressing + and - after transitioning
      from paused to playing.
      
 
- 
      Pressing l after transitioning from paused to playing.
      
 
- 
      Transitioning between playing and paused many times.
      
 
- 
      Pressing 
? after a second or third bookz has been
      loaded.
       
- 
      Pressing 
b after a second or third bookz has been
      loaded.
       
- 
      Transitioning between playing and paused many times after
      loading a second/third bookz.