Week 09 Tutorial Questions

Objectives

Tutorial Questions

  1. Write a C program, print_cwd.c, that prints the current working directory to the terminal.

    Your program should:

    • Use the getcwd(3) function to retrieve the current working directory.
    • Print the result to stdout.
    • Use perror(3) to print an appropriate error message if getcwd fails (e.g., if the buffer is too small or permissions prevent access).

    You may assume the current working directory path will not exceed 1024 characters.

    For example:
    pwd
    /home/student/lab01
    dcc print_cwd.c -o print_cwd
    ./print_cwd
    Current directory: /home/student/lab01
    
  2. Write a C program, change_dir.c, that changes the current working directory to a directory specified as a command-line argument.

    Your program should:

    • Use the chdir(2) system call to change the working directory.
    • Print a message like Moving to /some/path if the change is successful.
    • If chdir fails (e.g., due to a non-existent directory or permission issue), print an error message using perror(3) and fprintf.

    If no directory is provided as an argument, print a usage message and exit.

    ./change_dir /tmp
    Moving to /tmp
    ./change_dir /does/not/exist
    Could not change directory.: No such file or directory
    Could not change directory.
    ./change_dir
    Usage: ./change_dir 
    
  3. The stat() and lstat() functions both take an argument which is a pointer to a struct stat object, and fill it with the meta-data for a named file.

    On Linux, a struct stat contains the following fields (among others, which have omitted for simplicity):

    struct stat {
        ino_t st_ino;         /* inode number */
        mode_t st_mode;       /* protection */
        uid_t st_uid;         /* user ID of owner */
        gid_t st_gid;         /* group ID of owner */
        off_t st_size;        /* total size, in bytes */
        blksize_t st_blksize; /* blocksize for filesystem I/O */
        blkcnt_t st_blocks;   /* number of 512B blocks allocated */
        time_t st_atime;      /* time of last access */
        time_t st_mtime;      /* time of last modification */
        time_t st_ctime;      /* time of last status change */
    };
    

    Explain what each of the fields represents (in more detail than given in the comment!) and give a typical value for a regular file which appears as follows:

    ls -ls stat.c
    8 -rw-r--r--  1 jas  cs1521  1855  Sep  9 14:24 stat.c
    

    Assume that jas has user id 516, and the cs1521 group has group id 36820.

  4. Consider the following (edited) output from the command ls -l ~cs1521:

    drwxr-x--- 11 cs1521 cs1521 4096 Aug 27 11:59 17s2.work
    drwxr-xr-x  2 cs1521 cs1521 4096 Aug 20 13:20 bin
    -rw-r-----  1 cs1521 cs1521   38 Jul 20 14:28 give.spec
    drwxr-xr-x  3 cs1521 cs1521 4096 Aug 20 13:20 lib
    drwxr-x--x  3 cs1521 cs1521 4096 Jul 20 10:58 public_html
    drwxr-xr-x 12 cs1521 cs1521 4096 Aug 13 17:31 spim
    drwxr-x---  2 cs1521 cs1521 4096 Sep  4 15:18 tmp
    lrwxrwxrwx  1 cs1521 cs1521   11 Jul 16 18:33 web -> public_html
    
    1. Who can access the 17s2.work directory?

    2. What operations can a typical user perform on the public_html directory?

    3. What is the file web?

    4. What is the difference between stat("web", &info) and lstat("web", &info)?
      (where info is an object of type (struct stat))

  5. Write a C program, chmod_if_public_write.c, which is given 1+ command-line arguments which are the pathnames of files or directories

    If the file or directory is publically-writeable, it should change it to be not publically-writeable, leaving other permissions unchanged.

    It also should print a line to stdout as in the example below

    dcc chmod_if_public_write.c -o chmod_if_public_write
    ls -ld file_modes.c file_modes file_sizes.c file_sizes
    -rwxr-xrwx 1 z5555555 z5555555 116744 Nov  2 13:00 file_sizes
    -rw-r--r-- 1 z5555555 z5555555    604 Nov  2 12:58 file_sizes.c
    -rwxr-xr-x 1 z5555555 z5555555 222672 Nov  2 13:00 file_modes
    -rw-r--rw- 1 z5555555 z5555555   2934 Nov  2 12:59 file_modes.c
    ./file_modes file_modes file_modes.c file_sizes file_sizes.c
    removing public write from file_sizes
    file_sizes.c is not publically writable
    file_modes is not publically writable
    removing public write from file_modes.c
    ls -ld file_modes.c file_modes file_sizes.c file_sizes
    -rwxr-xr-x 1 z5555555 z5555555 116744 Nov  2 13:00 file_sizes
    -rw-r--r-- 1 z5555555 z5555555    604 Nov  2 12:58 file_sizes.c
    -rwxr-xr-x 1 z5555555 z5555555 222672 Nov  2 13:00 file_modes
    -rw-r--r-- 1 z5555555 z5555555   2934 Nov  2 12:59 file_modes.c
    
    Make sure you handle errors.
  6. Write a C program, file_permissions.c, that uses the `stat(2)` system call to extract and print the permissions of a file named test_file.

    Your program should:

    • Use stat to retrieve information about test_file.
    • Print the permission bits (user/group/other) in binary format (e.g., 110110100).
    • Then, convert and print the same permissions in the human-readable format (e.g., rw-rw-r--).

    Use perror to print appropriate error messages if stat fails (e.g., if the file does not exist).

    For example, your output might look like:
    ls -l test_file
    -rw-r--r-- 1 user user 0 Jul  3 10:00 test_file
    dcc file_permissions.c -o file_permissions
    ./file_permissions
    Binary permissions: 110100100
    Symbolic permissions: rw-r--r--
    

    You should use bitwise operations to extract and format the permission bits.

  7. Write a C program, list_dir.c, which opens a directory named "test_dir" and lists its contents.

    You should use opendir(3) in your answer and use perror to print error messages for example if the directory does not exist or if you do not have permission to list its contents.

    For example:

    ls -a test_dir
    .  ..  f  g
    dcc list_dir.c -o list_dir
    ./list_dir
    .
    ..
    f
    g
    chmod 310 list_dir
    ./list_dir
    test_dir: Permission denied
    rm -r test_dir
    ./list_dir
    test_dir: No such file or directory
    

    What are the first two entries that are listed ie . and .. ?

  8. Write a C program, count_files.c, that opens a directory named "test_dir" and counts the number of regular files in it (excluding . and ..).

    You should use opendir(3) and readdir(3) in your answer and use perror to print error messages if the directory does not exist or if you do not have permission to list its contents.

    For example, it should output something similar to the following:
    ls -a test_dir
    .  ..  file1  file2  dir1
    dcc count_files.c -o count_files
    ./count_files
    Number of files: 2
    chmod 310 test_dir
    ./count_files
    test_dir: Permission denied
    
    Make sure you handle errors. In particular make sure you are able to handle permission errors.
  9. Write a C program, list_files_by_extension.c, that opens a directory named "test_dir" and lists all files with a specific extension (e.g., .txt). The extension should be passed as a command-line argument.

    You should use opendir(3) and readdir(3) in your answer and use perror to print error messages if the directory does not exist or if you do not have permission to list its contents.

    For example, it should output something similar to the following:
    ls test_dir
    file1.txt  file2.c  file3.txt  file4.h
    dcc list_files_by_extension.c -o list_files_by_extension
    ./list_files_by_extension .txt
    file1.txt
    file3.txt
    ./list_files_by_extension .c
    file2.c
    ./list_files_by_extension .txt
    file2.txt
    
    Make sure you handle errors. In particular make sure you are able to handle permission errors.

Revision questions

The following questions are primarily intended for revision, either this week or later in session.
Your tutor may still choose to cover some of these questions, time permitting.