12 static char _ibuf
[BUFSZ
], _obuf
[BUFSZ
], _ebuf
[BUFSZ
];
13 static FILE _stdin
= {0, EOF
, _ibuf
, NULL
, BUFSZ
, 0};
14 static FILE _stdout
= {1, EOF
, NULL
, _obuf
, 0, BUFSZ
};
15 static FILE _stderr
= {2, EOF
, NULL
, _ebuf
, 0, 1};
16 FILE *stdin
= &_stdin
;
17 FILE *stdout
= &_stdout
;
18 FILE *stderr
= &_stderr
;
20 FILE *fopen(char *path
, char *mode
)
25 if (strchr(mode
, '+'))
28 flags
= *mode
== 'r' ? O_RDONLY
: O_WRONLY
;
36 fp
= malloc(sizeof(*fp
));
37 memset(fp
, 0, sizeof(*fp
));
38 fp
->fd
= open(path
, flags
, 0600);
44 fp
->ibuf
= malloc(BUFSZ
);
45 fp
->obuf
= malloc(BUFSZ
);
55 int ret
= close(fp
->fd
);
68 if (write(fp
->fd
, fp
->obuf
, fp
->olen
) != fp
->olen
)
74 int fputc(int c
, FILE *fp
)
76 if (fp
->olen
< fp
->osize
) {
77 fp
->obuf
[fp
->olen
++] = c
;
80 if (c
== '\n' || fp
->olen
== fp
->osize
)
88 return fputc(c
, stdout
);
91 static void ostr(FILE *fp
, char *s
, int wid
, int left
)
93 int fill
= wid
- strlen(s
);
98 fputc((unsigned char) *s
++, fp
);
104 static int digits(unsigned long n
, int base
)
112 static char *digs
= "0123456789abcdef";
113 static char *digs_uc
= "0123456789ABCDEF";
115 #define FMT_LEFT 0001 /* flag '-' */
116 #define FMT_PLUS 0002 /* flag '+' */
117 #define FMT_BLANK 0004 /* flag ' ' */
118 #define FMT_ALT 0010 /* flag '#' */
119 #define FMT_ZERO 0020 /* flag '0' */
120 #define FMT_SIGNED 0040 /* is the conversion signed? */
121 #define FMT_UCASE 0100 /* uppercase hex digits? */
123 static void oint(FILE *fp
, unsigned long n
, int base
,
124 int wid
, int bytes
, int flags
)
131 int left
= flags
& FMT_LEFT
;
132 int alt_form
= flags
& FMT_ALT
;
133 int ucase
= flags
& FMT_UCASE
;
134 int prefix_len
= 0; /* length of sign or base prefix */
137 if (flags
& FMT_SIGNED
) {
138 if ((signed long) n
< 0) {
143 if (flags
& FMT_PLUS
)
145 else if (flags
& FMT_BLANK
)
149 } else if (n
> 0 && alt_form
) {
150 prefix_len
= base
== 16 ? 2 : 1;
159 for (i
= 0; i
< d
; i
++) {
160 s
[d
- i
- 1] = ucase
? digs_uc
[n
% base
] : digs
[n
% base
];
164 fill
= (flags
& FMT_ZERO
) ? '0' : ' ';
166 if (fill
== ' ' && !left
)
171 } else if (prefix_len
) {
174 fputc(ucase
? 'X' : 'x', fp
);
176 if (fill
== '0' && !left
)
185 static char *fmt_flags
= "-+ #0";
187 int vfprintf(FILE *fp
, char *fmt
, va_list ap
)
192 int c
= (unsigned char) *s
++;
194 int bytes
= sizeof(int);
202 while ((f
= strchr(fmt_flags
, *s
))) {
203 flags
|= 1 << (f
- fmt_flags
);
206 left
= flags
& FMT_LEFT
;
208 wid
= va_arg(ap
, int);
215 while (isdigit(*s
)) {
221 bytes
= sizeof(long);
225 bytes
= bytes
< sizeof(int) ? sizeof(char) : sizeof(short);
228 switch ((c
= *s
++)) {
231 oint(fp
, va_arg(ap
, long), 10, wid
, bytes
, flags
);
235 oint(fp
, va_arg(ap
, long), 10, wid
, bytes
, flags
);
238 oint(fp
, va_arg(ap
, long), 8, wid
, bytes
, flags
);
243 oint(fp
, va_arg(ap
, long), 16, wid
, bytes
, flags
);
247 oint(fp
, va_arg(ap
, long), 16, wid
, bytes
, flags
);
251 fputc(va_arg(ap
, int), fp
);
255 fputc(va_arg(ap
, int), fp
);
258 ostr(fp
, va_arg(ap
, char *), wid
, left
);
261 *va_arg(ap
, int *) = fp
->ostat
- beg
;
270 return fp
->ostat
- beg
;
279 fprintf(stderr
, "%s: %s\n", s
, sys_errlist
[idx
]);
281 fprintf(stderr
, "%s\n", sys_errlist
[idx
]);
284 int vsnprintf(char *dst
, int sz
, char *fmt
, va_list ap
)
290 ret
= vfprintf(&f
, fmt
, ap
);
295 int vsprintf(char *dst
, char *fmt
, va_list ap
)
297 return vsnprintf(dst
, 1 << 20, fmt
, ap
);
300 int printf(char *fmt
, ...)
305 ret
= vfprintf(stdout
, fmt
, ap
);
310 int vprintf(char *fmt
, va_list ap
)
312 return vfprintf(stdout
, fmt
, ap
);
315 int fprintf(FILE *fp
, char *fmt
, ...)
320 ret
= vfprintf(fp
, fmt
, ap
);
325 int sprintf(char *dst
, char *fmt
, ...)
330 ret
= vsprintf(dst
, fmt
, ap
);
335 int snprintf(char *dst
, int sz
, char *fmt
, ...)
340 ret
= vsnprintf(dst
, sz
, fmt
, ap
);
345 int fputs(char *s
, FILE *fp
)
348 fputc((unsigned char) *s
++, fp
);
354 int ret
= fputs(s
, stdout
);
360 long fwrite(void *v
, long sz
, long n
, FILE *fp
)
362 unsigned char *s
= v
;
365 if (fputc(*s
++, fp
) == EOF
)
366 return n
* sz
- i
- 1;