Omar Sheikh
Karapet Shaginyan
CS111 Lecture 5
Professor Eggert
10/8/09 10:00AM
Orthogonality
-decisions on each axis are independent, and (ideally) result in a useful design. This is out goal in OS design.
- Example: making changes in the file system should not result in having to rewrite the way processes are handled.
-
In OS design, our three main issues are files, processes, and memory.
You can think of these as the labels on the axes of a 3-D plane and
the orthogonality analogy should make sense.
How to model O.S. resources in a
user program. (mechanism)
O.S. data structure
(process descriptor)
(file
descriptor)
Struct pte {int pid; int vid; ______;};
O.S. struct pte *p = return (struct pte foolya*) ~ (int) p;
struct foolya; |
3) an int (very common)
OS table
table itself is in memory
application sees the table
memory is invisible to application
Passing out ints is a very common approach in Unix, here are some examples:
pid_t, fd(int), uid_t, gid_t, IP
ports, ino_t, dev_t
The drawback of this method: ints
are easily forged. Anyone can guess a number.
int main (void) {
kill (1, SIG_KILL);
}
We get around this drawback by forcing
out OS to check if an application has authority of certain ints.
int main (void) {
char buf[512];
read(27, buf, sizeof(buf));
}
returns EBADF - bad file descriptors
int main(int argc, char **argv) {
kill(atoi(argv[1]), SIGTERM));
return 0;
}
how to kill yourself in shell
$ kill $$
kill(getpid(), SIGTERM);
Files and Processes
creating/destroying file descriptors
int
open(char const *filename, int flags[, mode_t mode]);
If a syscall fails (returns with
-1, you can examine the variable errno to get more information about
the failure. On a successful syscall, errno is garbage. Errno is special
because it is a thread local variable.
When opening a file use one either
O_RDONLY, O_WRONLY, O_RDWR for either read-only, write-only, or read-and-write
respectively. Use O_CREAT if you want the OS to create the file if it
doesn't already exist.
Example: open(“/tmp/foo”, O_RDONLY|O_CREAT,
0666)
0666 specifies the permissions. These
are 9 bits that are used to specifiy the owner's, group's, and other's
permissions for a file or directory. The first 3 bits represent the
permissions for the owner, the next 3 bits for the group, and the final
3 bits for others. In each category, if the first bit is on, then read
permissions are available. If the second second bit is on, it represents
write permissions, if the third bit is on, it represents execute permissions.
a side note on permissions:
101 | 111 | 110 | 100 |
5 | 7 | 6 | 4 |
sticky bit | user | group | other |
arg to open for a created file
=> mask it with the process’s
umask (in process descriptor)
m&~u is file’s actual mode
program: open(“foo”, O_WRONLY, 0666);
users says umask 022
0666
0022
0644
Too much orthogonality? 167 --x rw-
rwx is possible. This means others can read, write, execute, but the
owner can only execute. This is strange, but allowable.
creating/destroying fds fd= open(--)
creating/destroying processes. pid_t fork(void);
clone process
parent are identical except
multiple versions of exit:
int or void exit(int(exit status)); <--C library cleanup
void _exit(int); <--syscall
int printdate(void){ ---char args [2] = {“date”, NULL};
pid_t p=fork();
switch(p){
case -1: return -1;
case 0: execup(“/usr/bin/date”, args);
default: int status;
if (waitpid(p, &status, 0 <0) return -1;
return status;
int execup(char const *filename, char *const *args);
change program to filename, run it’s main function
always returns -1 (if it returns)
settings errno
date.c
int main(int argc, char **argv){
decode_options(
gettimeofday(-);
int n = printf(---);
int o = fflush(stdout);
if (ok(n,o)) return 0;
else return 1;
}
O.S. does this:
exit(main(argc,
argv));
race conditions
behavior goes bad if processes are scheduled in a certain way:
does waitpid get called in parent before or after -exit is called in child?
zombie processes: child has died,
but parent hasn’t waited on it yet, preserve the exit status in the
case that the parents requests it.
open
exit => closes all open fds
fd = open (“foo”, o_RDWR, _ )
remove(“foo”);
read(fd, _) a nameless file: sticks around, until file is closed.
write(___)
while (exists(n)) n = n+ “x”;
p1: open(n, O_RDWR, O_CREAT, 0666);
p2: