stdlib.h: implement mkstemp()
[neatlibc.git] / stdio.c
blobde3ff4149b239668a39dd1fc782b57b963a04c9f
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
9 static char *putstr(char *d, char *s)
11 while (*s)
12 *d++ = *s++;
13 return d;
16 static int digits(unsigned long n, int base)
18 int i;
19 for (i = 0; n; i++)
20 n /= base;
21 return i ? i : 1;
24 static char *digs = "0123456789abcdef";
26 static char *putint(char *s, unsigned long n, int base, int sign)
28 int d;
29 int i;
30 if (sign && n & 0x80000000) {
31 *s++ = '-';
32 n = -n;
34 d = digits(n, base);
35 for (i = 0; i < d; i++) {
36 s[d - i - 1] = digs[n % base];
37 n /= base;
39 return s + d;
42 int vsprintf(char *dst, char *fmt, va_list ap)
44 char *d = dst;
45 char *s = fmt;
46 while (*s) {
47 int c = *s++;
48 if (c != '%') {
49 *d++ = c;
50 continue;
52 if (*s == 'l')
53 s++;
54 switch ((c = *s++)) {
55 case 'd':
56 d = putint(d, va_arg(ap, long), 10, 1);
57 break;
58 case 'u':
59 d = putint(d, va_arg(ap, long), 10, 0);
60 break;
61 case 'x':
62 case 'p':
63 d = putint(d, va_arg(ap, long), 16, 0);
64 break;
65 case 'c':
66 *d++ = va_arg(ap, int);
67 break;
68 case 's':
69 d = putstr(d, va_arg(ap, char *));
70 break;
71 case '\0':
72 s--;
73 break;
74 default:
75 *d++ = c;
78 *d = '\0';
79 return d - dst;
82 static char buf[1 << 12];
84 static FILE _stdout = {1};
85 static FILE _stderr = {2};
86 FILE *stdout = &_stdout;
87 FILE *stderr = &_stderr;
89 int printf(char *fmt, ...)
91 va_list ap;
92 int ret;
93 va_start(ap, fmt);
94 ret = vsprintf(buf, fmt, ap);
95 va_end(ap);
96 return write(1, buf, ret);
99 int fprintf(FILE *filp, char *fmt, ...)
101 va_list ap;
102 int ret;
103 va_start(ap, fmt);
104 ret = vsprintf(buf, fmt, ap);
105 va_end(ap);
106 return write(filp->fd, buf, ret);
109 int sprintf(char *dst, char *fmt, ...)
111 va_list ap;
112 int ret;
113 va_start(ap, fmt);
114 ret = vsprintf(dst, fmt, ap);
115 va_end(ap);
116 return ret;
119 void perror(char *s)
121 int idx = errno;
122 if (idx >= sys_nerr)
123 idx = 0;
124 fprintf(stderr, "%s: %s\n", s, sys_errlist[idx]);
127 FILE *fopen(char *path, char *mode)
129 FILE *fp;
130 int flags;
132 if (strchr(mode, '+'))
133 flags = O_RDWR;
134 else
135 flags = *mode == 'r' ? O_RDONLY : O_WRONLY;
136 if (*mode != 'r')
137 flags |= O_CREAT;
138 if (*mode == 'w')
139 flags |= O_TRUNC;
140 if (*mode == 'a')
141 flags |= O_APPEND;
143 fp = malloc(sizeof(*fp));
144 fp->fd = open(path, flags, 0600);
145 return fp;
148 int fclose(FILE *fp)
150 int ret = close(fp->fd);
151 free(fp);
152 return ret;
155 void setbuf(FILE *fp, char *buf)