Question 3 - write_ints()

It's too slow because of system call overhead, and system calls are slow. It is writing 4 bytes at a time, so, for example, when write_ints should be writing 1000 bytes overall, it is doing so with 250 system calls rather than one.

bit_set is a simple program with bit arithmetic. In typical C fashion, we don't test to see if index is a bad value. We just do what we're told.

int bit_set(const unsigned char *to_include, int index)
{
  int word, bit;

  word = index/8;
  bit = index%8;
  
  if (to_include[word] & (1 << bit)) return 1;
  return 0;
}

write_ints needs to have a buffer. Since our boss is allowing a global variable with 1024 bytes, that's what we'll use. We need to fill the buffer, and when it gets full, we write it. At the end of the procedure, if it's not empty, we have to write the remainder.

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int BUF[256];

void write_ints(int fd, int size, const int *ints, const unsigned char *to_include)
{
  int i;
  int elts;

  elts = 0;
 
  for (i = 0; i < size; i++) {
    if (bit_set(to_include, i)) {
      BUF[elts] = ints[i];
      elts++;
      if (elts == 256) {        /* I know I should use #defines and sizeof(int), but it's a test. */
        write(fd, BUF, 1024);
        elts = 0;
      }
    }
  }
  if (elts != 0) write(fd, BUF, elts * sizeof(int));
}

Grading


Question 4

Obviously, these can come in any order:

Grading

3 points per part. I gave partial credit to some other answers.


Question 5

This question comes from the lecture entitled "Files, Links and Inodes": http://web.eecs.utk.edu/~jplank/plank/classes/cs360/360/notes/Links/lecture.html. In the beginning of this lecture it says:

When you create a file in Unix, there are quite a few things that happen. In this lecture, we are going to focus on three components of a file in Unix:
  • The bytes of the file itself.
  • The metadata of the file.
  • The links to the file that are relative to a directory.
I then show what happens when you do:
UNIX> echo "This is f1.txt" > f1.txt

Here, we're doing the same thing, only we're doing:

UNIX> echo "My name is Harvey" > f1.txt
This changes the following three things on disk:
  1. It has put the bytes "My name is Harvey\n" into the contents of the file.
  2. It has created the file f1.txt, and as such, puts a mapping of the name f1.txt to its inode into the "d1" directory.
  3. It has created the metadata for the file and stored it onto an inode on disk.

Grading

I meant for this question to be a free 9 points for everyone. This is the main takeaway from the "Links" lecture. As it turns out, since I hadn't asked a question like this on an exam, a lot of students didn't "study" it.

Three points per part.


Question 6

This came from a bank. I'm answering with the command line:

UNIX> ./a.out staph rust bo

Line 2: The memcpy copies the bytes "staph" with no null character. The answer is 01234staph012345.

Line 3: The memcpy copies the bytes "rust" with the null character. Since it uses ip+1, it starts at the fourth byte. The answer is 0123rust.

Line 4: This is printing the string "8901" as an integer, so little endian: 0x31303938.

Line 5: i is '5', which is 0x35 and j is '2', which is 0x32. So: 0x3532.

Line 6: i is '7'. If you view it as an array of four characters, then it is "7***", where the asterisks are the null character. The strcat() will simply put "bo" at the end, and there's still a null character: "7bo*" - the answer is 7bo.

Grading

3 points per question. I did give partial credit.


Question 7

2 points per question. I did give partial credit.