stdio.h: add fopen() and fclose()
[neatlibc.git] / stdio.c
blob62ef94adeb7f0cb31f09a5f280abea2aa23cd4d5
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <unistd.h>
7 static char *putstr(char *d, char *s)
9 while (*s)
10 *d++ = *s++;
11 return d;
14 static int digits(unsigned long n, int base)
16 int i;
17 for (i = 0; n; i++)
18 n /= base;
19 return i ? i : 1;
22 static char *digs = "0123456789abcdef";
24 static char *putint(char *s, unsigned long n, int base, int sign)
26 int d;
27 int i;
28 if (sign && n & 0x80000000) {
29 *s++ = '-';
30 n = -n;
32 d = digits(n, base);
33 for (i = 0; i < d; i++) {
34 s[d - i - 1] = digs[n % base];
35 n /= base;
37 return s + d;
40 int vsprintf(char *dst, char *fmt, va_list ap)
42 char *d = dst;
43 char *s = fmt;
44 while (*s) {
45 int c = *s++;
46 if (c != '%') {
47 *d++ = c;
48 continue;
50 if (*s == 'l')
51 s++;
52 switch ((c = *s++)) {
53 case 'd':
54 d = putint(d, va_arg(ap, long), 10, 1);
55 break;
56 case 'u':
57 d = putint(d, va_arg(ap, long), 10, 0);
58 break;
59 case 'x':
60 case 'p':
61 d = putint(d, va_arg(ap, long), 16, 0);
62 break;
63 case 'c':
64 *d++ = va_arg(ap, int);
65 break;
66 case 's':
67 d = putstr(d, va_arg(ap, char *));
68 break;
69 case '\0':
70 s--;
71 break;
72 default:
73 *d++ = c;
76 *d = '\0';
77 return d - dst;
80 static char buf[1 << 12];
82 static FILE _stdout = {1};
83 static FILE _stderr = {2};
84 FILE *stdout = &_stdout;
85 FILE *stderr = &_stderr;
87 int printf(char *fmt, ...)
89 va_list ap;
90 int ret;
91 va_start(ap, fmt);
92 ret = vsprintf(buf, fmt, ap);
93 va_end(ap);
94 return write(1, buf, ret);
97 int fprintf(FILE *filp, char *fmt, ...)
99 va_list ap;
100 int ret;
101 va_start(ap, fmt);
102 ret = vsprintf(buf, fmt, ap);
103 va_end(ap);
104 return write(filp->fd, buf, ret);
107 int sprintf(char *dst, char *fmt, ...)
109 va_list ap;
110 int ret;
111 va_start(ap, fmt);
112 ret = vsprintf(dst, fmt, ap);
113 va_end(ap);
114 return ret;
117 void perror(char *s)
119 int idx = errno;
120 if (idx >= sys_nerr)
121 idx = 0;
122 fprintf(stderr, "%s: %s\n", s, sys_errlist[idx]);
125 FILE *fopen(char *path, char *mode)
127 FILE *fp;
128 int flags;
130 if (strchr(mode, '+'))
131 flags = O_RDWR;
132 else
133 flags = *mode == 'r' ? O_RDONLY : O_WRONLY;
134 if (*mode != 'r')
135 flags |= O_CREAT;
136 if (*mode == 'w')
137 flags |= O_TRUNC;
138 if (*mode == 'a')
139 flags |= O_APPEND;
141 fp = malloc(sizeof(*fp));
142 fp->fd = open(path, flags, 0600);
143 return fp;
146 int fclose(FILE *fp)
148 int ret = close(fp);
149 free(fp);
150 return ret;
153 void setbuf(FILE *fp, char *buf)