y: ld [fp+12] -> %r0 ld [r0] -> %r0 mv #4 -> %r1 add %r0, %r1 -> %r0 ld [r0] -> %r0 ret | read10: push #4 // s is at [fp] mov #10 -> %r0 // s = (char *) malloc(10) st %r0 -> [sp]-- jsr malloc pop #4 st %r0 -> [fp] mov #10 -> %r0 // read(0, s, 10) st %r0 -> [sp]-- ld [fp] -> %r0 st %r0 -> [sp]-- st %g0 -> [sp]-- jsr read pop #12 ld [fp] -> %r0 // return s ret |
read10: Allocating s: 1 point
Buffering is useful because it eliminates the need to make small read() and write() system calls, which are expensive. In essence, the system call overhead is amortized by using memory.
Programs that perform small reads and writes are helped the most by buffering:
#include <stdio.h> main() { while (getchar() != EOF) ; } |
Programs that perform large reads and writes are not helped by buffering:
#include <stdio.h> main() { char buffer[10000]; while (fread(buffer, 1, 10000, stdin) > 0) ; } |
A few of you said that cat is helped by buffering. I was in a kindly mood, so I didn't take off for it. If I write cat as follows:
main() { char buffer[10000]; int j; while (1) { j = read(0, buffer, 10000); if (j == 0) exit(0); write(1, buffer, j); } } |
It is going to work correctly, doesn't do buffering, and will run very quickly.
/* Started: Wed Mar 23 14:21:23 EDT 2011 */ /* Finished: Wed Mar 23 14:27:38 EDT 2011 */ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <string.h> #include <dirent.h> #include "dllist.h" void findjim(char *dir) { DIR *d; struct dirent *de; char *fname; Dllist l, tmp; struct stat buf; fname = (char *) malloc(strlen(dir)+300); l = new_dllist(); d = opendir(dir); for (de = readdir(d); de != NULL; de = readdir(d)) { if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { sprintf(fname, "%s/%s", dir, de->d_name); if (strstr(de->d_name, "jim") != NULL) printf("%s\n", fname); stat(fname, &buf); if (S_ISDIR(buf.st_mode)) dll_append(l, new_jval_s(strdup(fname))); } } closedir(d); dll_traverse(tmp, l) { findjim(tmp->val.s); free(tmp->val.s); } free_dllist(l); free(fname); } int main() { findjim("."); } |
One of you tried system("grep jim *"), which gave me a laugh. The proper call is either system("find . -print | grep jim") or more properly system("find . -print | grep jim'[^/]*$").
It takes three arguments:
Scenario A: Since you've specified O_EXCL, the file is not created or opened. Nothing happens to the file: UNIX> ls -l f1.txt -rw-r--r-- 1 plank staff 7 Mar 23 14:10 f1.txt UNIX> q5 xca 666 27 -rw-r--r-- 1 plank staff 7 --- -- ----- f1.txt Shaft! |
Scenario B: The open call is made with only O_WRONLY. However, since the file exists and is writable, the open will succeed and XXX will overwrite the first four bytes of f1.txt: UNIX> ls -l f1.txt -rw-r--r-- 1 plank staff 7 Mar 23 14:10 f1.txt UNIX> q5 - 777 0 -rw-r--r-- 1 plank staff 7 --- -- ----- f1.txt XXX t! |
Scenario C: The file will be created, and since we're calling umask(644), it will turn off protection bits 644. Thus, it will be created with 000 as permissions: UNIX> ls -l f1.txt ls: f1.txt: No such file or directory UNIX> q5 ca 644 644 ---------- 1 plank staff 4 --- -- ----- f1.txt XXX |
Scenario D: I don't own the file and can't write it, but I can read it. Thus it will be unchanged. UNIX> ls -l f1.txt -rwxr--r-- 1 binky elves 7 Mar 23 14:10 f1.txt UNIX> q5 a 755 272 -rwxr--r-- 1 binky elves 7 Mar 23 14:10 f1.txt Shaft! |
Scenario E: Since the file doesn't exist, it will be created with mode 755: UNIX> ls -l f1.txt ls: f1.txt: No such file or directory UNIX> q5 cx 777 22 -rwxr-xr-x 1 plank staff 4 --- -- ----- f1.txt XXX |
Scenario F: I don't own the file, but I do have write permissions on it, so it will be truncated before writing XXX: UNIX> ls -l f1.txt -rwxrwxrwx 1 binky elves 7 Mar 23 14:10 f1.txt UNIX> q5 ct 644 70 -rwxrwxrwx 1 binky elves 4 --- -- ----- f1.txt XXX |
Scenario G: It will open the file and append XXX to it: UNIX> ls -l f1.txt -rw-r--r-- 1 plank staff 7 Mar 23 14:10 f1.txt UNIX> q5 ac 752 0 -rw-r--r-- 1 plank staff 11 --- -- ----- f1.txt Shaft! XXX |
Scenario H: I don't own the file and can't write it or read it: UNIX> ls -l f1.txt -rw------- 1 binky elves 7 Mar 23 14:10 f1.txt UNIX> q5 a 666 22 -rw------- 1 binky elves 7 Mar 23 14:10 f1.txt cat: f1.txt: Permission denied |
Scenario I: The file will be opened and truncated: UNIX> ls -l f1.txt -rw-r--r-- 1 plank staff 7 Mar 23 14:10 f1.txt UNIX> q5 ct 706 0 -rw-r--r-- 1 plank staff 4 --- -- ----- f1.txt XXX |
Scenario J: I did not specify O_CREAT, so nothing will happen: UNIX> ls -l f1.txt ls: f1.txt: No such file or directory UNIX> q5 - 666 0 ls: f1.txt: No such file or directory cat: f1.txt: No such file or directory |
Scenario K: It will create f1.txt with 0504 permissions: UNIX> ls -l f1.txt ls: f1.txt: No such file or directory UNIX> q5 ct 504 0 -r-x---r-- 1 plank staff 4 --- -- ----- f1.txt XXX |
Scenario L: I can't open the file, so it will remain unchanged: UNIX> ls -l f1.txt ----r----- 1 plank staff 7 Mar 23 14:10 f1.txt UNIX> q5 t 766 22 ----r----- 1 plank staff 7 Mar 23 14:10 f1.txt Shaft! |