Tutorial Week 2
Questions
What are some of the differences between a processor running in privileged mode (also called kernel mode) and user mode? Why are the two modes needed?
What are the two main roles of an Operating System?
-
Given a high-level understanding of file systems, explain how a
file system fulfills the two roles of an operating system?
Which of the following instructions (or instruction sequences) should only be allowed in kernel mode?
- Disable all interrupts.
- Read the time of day clock.
- Set the time of day clock.
- Change the memory map.
- Write to the hard disk controller register.
- Trigger the write of all buffered blocks associated with a file back to disk (fsync).
-
The following code contains the use of typical UNIX process management system calls: fork(), execl(), exit() and getpid(). If you are unfamiliar with their function, browse the man pages on a UNIX/Linux machine get an overview, e.g: man fork
Answer the following questions about the code below.
- What is the value of i in the parent and child after fork.
- What is the value of my_pid in a parent after a child updates it?
- What is the process id of /bin/echo?
- Why is the code after execl not expected to be reached in the normal case?
- How many times is Hello World printed when FORK_DEPTH is 3?
- How many processes are created when running the code (including the first process)?
#include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #define FORK_DEPTH 3 main() { int i, r; pid_t my_pid; my_pid = getpid(); for (i = 1; i <= FORK_DEPTH; i++) { r = fork(); if (r > 0) { /* we're in the parent process after successfully forking a child */ printf("Parent process %d forked child process %d\n",my_pid, r); } else if (r == 0) { /* We're in the child process, so update my_pid */ my_pid = getpid(); /* run /bin/echo if we are at maximum depth, otherwise continue loop */ if (i == FORK_DEPTH) { r = execl("/bin/echo","/bin/echo","Hello World",NULL); /* we never expect to get here, just bail out */ exit(1); } } else { /* r < 0 */ /* Eek, not expecting to fail, just bail ungracefully */ exit(1); } } }
-
- What does the following code do?
- In addition to O_WRONLY, what are the other 2 ways one can open a file?
- What open return in fd, what is it used for? Consider success and failure in your answer.
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char teststr[] = "The quick brown fox jumps over the lazy dog.\n"; main() { int fd; int len; ssize_t r; fd = open("testfile", O_WRONLY | O_CREAT, 0600); if (fd < 0) { /* just ungracefully bail out */ perror("File open failed"); exit(1); } len = strlen(teststr); printf("Attempting to write %d bytes\n",len); r = write(fd, teststr, len); if (r < 0) { perror("File write failed"); exit(1); } printf("Wrote %d bytes\n", (int) r); close(fd); }
-
The following code is a variation of the previous code that writes twice.
- How big is the file (in bytes) after the two writes?
- What is lseek() doing that is affecting the final file size?
- What over options are there in addition to SEEK_SET?.
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char teststr[] = "The quick brown fox jumps over the lazy dog.\n"; main() { int fd; int len; ssize_t r; off_t off; fd = open("testfile2", O_WRONLY | O_CREAT, 0600); if (fd < 0) { /* just ungracefully bail out */ perror("File open failed"); exit(1); } len = strlen(teststr); printf("Attempting to write %d bytes\n",len); r = write(fd, teststr, len); if (r < 0) { perror("File write failed"); exit(1); } printf("Wrote %d bytes\n", (int) r); off = lseek(fd, 5, SEEK_SET); if (off < 0) { perror("File lseek failed"); exit(1); } r = write(fd, teststr, len); if (r < 0) { perror("File write failed"); exit(1); } printf("Wrote %d bytes\n", (int) r); close(fd); }
-
Compile either of the previous two code fragments on a UNIX/Linux machine and run strace ./a.out and observe the output.
- What is strace doing?
- Without modifying the above code to print fd, what is the value of the file descriptor used to write to the open file?
- printf does not appear in the system call trace. What is appearing in it's place? What's happening here?
-
Compile and run the following code.
- What do the following code do?
- After the program runs, the current working directory of the shell is the same. Why?
- In what directory does /bin/ls run in? Why?
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> main() { int r; r = chdir(".."); if (r < 0) { perror("Eek!"); exit(1); } r = execl("/bin/ls","/bin/ls",NULL); perror("Double eek!"); }
-
On UNIX, which of the following are considered system calls? Why?
- read()
- printf()
- memcpy()
- open()
- strncpy()