fix O_RDWR bug.
[mit-jos.git] / lib / fprintf.c
blob23f89246318f5458692e83b630aad700d08de906
1 #include <inc/lib.h>
3 // Collect up to 256 characters into a buffer
4 // and perform ONE system call to print all of them,
5 // in order to make the lines output to the console atomic
6 // and prevent interrupts from causing context switches
7 // in the middle of a console output line and such.
8 struct printbuf {
9 int fd; // file descriptor
10 int idx; // current buffer index
11 ssize_t result; // accumulated results from write
12 int error; // first error that occurred
13 char buf[256];
17 static void
18 writebuf(struct printbuf *b)
20 if (b->error > 0) {
21 ssize_t result = write(b->fd, b->buf, b->idx);
22 if (result > 0)
23 b->result += result;
24 if (result != b->idx) // error, or wrote less than supplied
25 b->error = (result < 0 ? result : 0);
29 static void
30 putch(int ch, void *thunk)
32 struct printbuf *b = (struct printbuf *) thunk;
33 b->buf[b->idx++] = ch;
34 if (b->idx == 256) {
35 writebuf(b);
36 b->idx = 0;
40 int
41 vfprintf(int fd, const char *fmt, va_list ap)
43 struct printbuf b;
45 b.fd = fd;
46 b.idx = 0;
47 b.result = 0;
48 b.error = 1;
49 vprintfmt(putch, &b, fmt, ap);
50 if (b.idx > 0)
51 writebuf(&b);
53 return (b.result ? b.result : b.error);
56 int
57 fprintf(int fd, const char *fmt, ...)
59 va_list ap;
60 int cnt;
62 va_start(ap, fmt);
63 cnt = vfprintf(fd, fmt, ap);
64 va_end(ap);
66 return cnt;
69 int
70 printf(const char *fmt, ...)
72 va_list ap;
73 int cnt;
75 va_start(ap, fmt);
76 cnt = vfprintf(1, fmt, ap);
77 va_end(ap);
79 return cnt;