- Implemented first time functions.
[planlOS.git] / programs / libc / stdio.c
blob8c7c3656fdce7df884775a06abcf4fc239453be3
1 /*
2 Copyright (C) 2008 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <string.h>
25 #include <stdlib.h>
27 #define ERROR_EOF 1
28 #define ERROR_ERROR 2
30 struct FILE
32 int fd;
33 int append;
34 int error;
37 FILE *stderr = 0;
38 FILE *stdout = 0;
39 FILE *stdin = 0;
41 FILE *fopen(const char *filename, const char *mode)
43 // Open file
44 int openmode = 0;
45 if (strchr(mode, 'r')) openmode = O_RDONLY;
46 else if (strchr(mode, 'w')) openmode = O_WRONLY | O_CREAT;
47 else if (strchr(mode, 'a')) openmode = O_WRONLY | O_CREAT;
48 if (strchr(mode, '+')) openmode = (openmode & ~O_ACCMODE) | O_RDWR;
49 int fd = open(filename, openmode);
50 if (fd == -1) return 0;
51 // Return file structure
52 FILE *file = malloc(sizeof(FILE));
53 memset(file, 0, sizeof(FILE));
54 file->fd = fd;
55 if (strchr(mode, 'a')) file->append = 1;
56 return file;
58 int fclose(FILE *file)
60 if (!file) return EOF;
61 close(file->fd);
62 free(file);
63 return 0;
65 FILE *freopen(const char *filename, const char *mode, FILE *file)
67 if (fclose(file) == EOF) return 0;
68 return fopen(filename, mode);
70 int feof(FILE *file)
72 return (file->error & ERROR_EOF) != 0;
74 int ferror(FILE *file)
76 return (file->error & ERROR_ERROR) != 0;
78 int fseek(FILE *file, long int offset, int origin)
80 if (!file) return EOF;
81 file->error = 0;
82 if (lseek(file->fd, offset, origin) == (off_t)-1) return EOF;
83 return 0;
85 long int ftell(FILE *file)
87 if (!file) return EOF;
88 long int pos = lseek(file->fd, 0, SEEK_CUR);
89 return pos;
91 void rewind(FILE *file)
93 fseek(file, 0, SEEK_SET);
95 void clearerr(FILE *file)
97 file->error = 0;
100 int fgetpos(FILE *file, fpos_t *pos)
102 if (!file || !pos) return EOF;
104 long int position = lseek(file->fd, 0, SEEK_CUR);
105 if (position == -1)
107 *pos = 0;
108 return EOF;
110 *pos = position;
111 return 0;
113 int fsetpos(FILE *file, const fpos_t *pos)
115 if (!file || !pos) return EOF;
116 file->error = 0;
117 if (lseek(file->fd, *pos, SEEK_SET) == (off_t)-1) return -1;
118 return 0;
121 int fgetc(FILE *file)
123 if (!file) return EOF;
124 char c = 0;
125 int size = read(file->fd, &c, 1);
126 if (size == 0)
128 file->error = ERROR_EOF;
129 return EOF;
131 else if (size == -1)
133 file->error = ERROR_ERROR;
134 return EOF;
136 return c;
138 char *fgets(char *str, int num, FILE *file)
140 int n = 0;
141 while (n < num)
143 char c = fgetc(file);
144 if ((c == EOF) && ferror(file)) return 0;
145 if ((c == EOF) && (n == 0))
147 return 0;
149 else if ((c == EOF) || (c == '\n') || (c == 0))
151 str[n] = 0;
152 return str;
154 else
156 str[n] = c;
158 n++;
160 str[n - 1] = 0;
161 return str;
163 int fscanf(FILE *file, const char *fmt, ...)
165 return -1;
167 size_t fread(void *ptr, size_t size, size_t count, FILE *file)
169 if (!file) return 0;
170 int bytecount = read(file->fd, ptr, size * count);
171 if (bytecount == -1)
173 file->error = ERROR_ERROR;
174 return 0;
176 if (bytecount != (int)(size * count))
178 file->error = ERROR_EOF;
180 return bytecount;
183 int fputc(int c, FILE *file)
185 if (!file) return EOF;
186 if (file->append) lseek(file->fd, 0, SEEK_END);
187 int size = write(file->fd, &c, 1);
188 if (size == 0)
190 file->error = ERROR_EOF;
191 return EOF;
193 else if (size == -1)
195 file->error = ERROR_ERROR;
196 return EOF;
198 return c;
200 int fputs(const char *s, FILE *file)
202 if (!file) return EOF;
203 if (file->append) lseek(file->fd, 0, SEEK_END);
204 int size = write(file->fd, s, strlen(s));
205 if (size == -1)
207 file->error = ERROR_ERROR;
208 return EOF;
210 return size;
212 int vfprintf(FILE *file, const char *fmt, va_list args)
214 if (!file) return EOF;
215 if (file->append) lseek(file->fd, 0, SEEK_END);
216 // FIXME: Greater length?
217 char buffer[1024];
218 vsnprintf(buffer, 1024, fmt, args);
220 int written = write(file->fd, buffer, strlen(buffer));
221 if (written == -1)
223 file->error = ERROR_ERROR;
224 return EOF;
226 return written;
228 int fprintf(FILE *file, const char *fmt, ...)
230 if (!file) return EOF;
231 if (file->append) lseek(file->fd, 0, SEEK_END);
232 // FIXME: Greater length?
233 char buffer[1024];
234 va_list args;
235 va_start(args, fmt);
236 vsnprintf(buffer, 1024, fmt, args);
237 va_end(args);
239 int written = write(file->fd, buffer, strlen(buffer));
240 if (written == -1)
242 file->error = ERROR_ERROR;
243 return EOF;
245 return written;
247 size_t fwrite(const void *ptr, size_t size, size_t count, FILE *file)
249 if (!file) return EOF;
250 if (file->append) lseek(file->fd, 0, SEEK_END);
251 int written = write(file->fd, ptr, size * count);
252 if (written == -1) return EOF;
253 return written;
256 int fileno(FILE *file)
258 if (!file) return -1;
259 return file->fd;
262 FILE *tmpfile(void)
264 // TODO
265 return 0;
267 char *tmpnam(char *s)
269 // TODO
270 return s;
273 int ungetc(int character, FILE *file)
275 return EOF;
278 int rename(const char *oldname, const char *newname)
280 return -1;
282 int remove(const char *filename)
284 return -1;
287 int printf(const char *fmt, ...)
289 va_list args;
290 va_start(args, fmt);
291 int status = vfprintf(stdout, fmt, args);
292 va_end(args);
293 return status;
295 int puts(const char *s)
297 printf("%s\n", s);
298 return 0;
300 int putc(int c, FILE *file)
302 return fputc(c, file);
304 int putchar(int c)
306 return fputc(c, stdout);
308 int getchar(void)
310 return fgetc(stdin);
313 void perror(const char *str)
315 printf("%s\n", str);
318 int fflush(FILE *file)
320 return 0;
323 int setvbuf(FILE *file, char *buf, int type, size_t size)
325 return 0;
328 int scanf(const char *format, ... )
330 return -1;
332 int sscanf(const char *s, const char *format, ... )
334 return -1;