Week 09 Tutorial Questions

Objectives

  1. Write a C program, print_diary.c, which prints the contents of the file $HOME/.diary to stdout

    The lecture example getstatus.c shows how to get the value of an environment variable.

    snprintf is a convenient function for constructing the pathname of the diary file.

  2. 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.

  3. 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))

  4. 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.
  5. Write a C program, print_file_bits.c, which given as a command line arguments the name of a file contain 32-bit hexadecimal numbers, one per line, prints the low (least significant) bytes of each number as a signed decimal number (-128..127).
  6. The following code will compile with

    gcc   void-pointer.c -o void-pointer
    clang void-pointer.c -o void-pointer
    dcc   void-pointer.c -o void-pointer
    

    It will even compile with

    gcc   -Werror -Wall -Wextra void-pointer.c -o void-pointer
    clang -Werror -Wall -Wextra void-pointer.c -o void-pointer
    dcc   -Werror -Wall -Wextra void-pointer.c -o void-pointer
    

    But it wont compile with

    gcc   -Werror -Wall -Wextra              -Wpedantic void-pointer.c -o void-pointer
    clang -Werror -Wall -Wextra -Weverything -Wpedantic void-pointer.c -o void-pointer
    dcc   -Werror -Wall -Wextra              -Wpedantic void-pointer.c -o void-pointer
    

    How can the code be modified to compile with the -Wpedantic option?

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    static uint16_t a;
    
    int main(void)
    {
        uint16_t b;
    
        uint16_t *pa = &a;
        uint16_t *pb = &b;
        uint16_t *pc = malloc(sizeof(uint16_t));
    
        *pa = 0xAAAA;
        *pb = 0xBBBB;
        *pc = 0xCCCC;
    
        printf("a:\n\tvalue: 0x%X\n\taddress: %16p\n", *pa, pa);
        printf("b:\n\tvalue: 0x%X\n\taddress: %16p\n", *pb, pb);
        printf("c:\n\tvalue: 0x%X\n\taddress: %16p\n", *pc, pc);
    }
    
  7. The following code will compile with

    gcc   pointer-arithmetic.c -o pointer-arithmetic
    clang pointer-arithmetic.c -o pointer-arithmetic
    dcc   pointer-arithmetic.c -o pointer-arithmetic
    

    It will even compile with

    gcc   -Werror -Wall -Wextra pointer-arithmetic.c -o pointer-arithmetic
    clang -Werror -Wall -Wextra pointer-arithmetic.c -o pointer-arithmetic
    dcc   -Werror -Wall -Wextra pointer-arithmetic.c -o pointer-arithmetic
    

    But it wont compile with

    gcc   -Werror -Wall -Wextra              -Wpedantic pointer-arithmetic.c -o pointer-arithmetic
    clang -Werror -Wall -Wextra -Weverything -Wpedantic pointer-arithmetic.c -o pointer-arithmetic
    dcc   -Werror -Wall -Wextra              -Wpedantic pointer-arithmetic.c -o pointer-arithmetic
    

    How can the code be modified to compile with the -Wpedantic option?

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    void *next_byte(void *byte){
        return byte + 1;
    }
    
    int main(void)
    {
        uint8_t  chars[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        uint32_t ints[10]  = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
        printf("%16p - %16p\n", (void *)&chars[0], (void *)next_byte(&chars[0]));
        printf("%16p - %16p\n", (void *)&ints[0],  (void *)next_byte(&ints[0]));
    }
    

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.