1 |
#include "stdio.h" |
#include "stdio.h" |
2 |
|
#include "malloc.h" |
3 |
#include "string.h" |
#include "string.h" |
4 |
#include "syscalls.h" |
#include "unistd.h" |
5 |
#include <stdbool.h> |
#include <stdbool.h> |
6 |
|
|
|
#define STDOUT_FILENO 1 |
|
|
#define STDERR_FILENO 2 |
|
|
|
|
7 |
enum printf_size |
enum printf_size |
8 |
{ |
{ |
9 |
PS_DEFAULT, |
PS_DEFAULT, |
293 |
putchar (int c) |
putchar (int c) |
294 |
{ |
{ |
295 |
return write (STDOUT_FILENO, &c, 1); |
return write (STDOUT_FILENO, &c, 1); |
296 |
|
} |
297 |
|
|
298 |
|
#define FBUFSIZ 1024 |
299 |
|
|
300 |
|
static int |
301 |
|
fmode_to_flags (const char *mode) |
302 |
|
{ |
303 |
|
int flags = 0; |
304 |
|
|
305 |
|
if (mode[0] == 'r') |
306 |
|
flags = O_RDONLY; |
307 |
|
else if (mode[0] == 'w') |
308 |
|
flags = O_WRONLY | O_CREAT | O_TRUNC; |
309 |
|
else if (mode[0] == 'a') |
310 |
|
flags = O_WRONLY | O_CREAT | O_APPEND; |
311 |
|
else |
312 |
|
return -1; |
313 |
|
|
314 |
|
if (mode[1] == '+') |
315 |
|
{ |
316 |
|
flags &= ~(O_RDONLY | O_WRONLY); |
317 |
|
flags |= O_RDWR; |
318 |
|
} |
319 |
|
|
320 |
|
return flags; |
321 |
|
} |
322 |
|
|
323 |
|
FILE * |
324 |
|
fopen (const char *pathname, const char *mode) |
325 |
|
{ |
326 |
|
int flags = fmode_to_flags (mode); |
327 |
|
|
328 |
|
if (flags == -1) |
329 |
|
return NULL; |
330 |
|
|
331 |
|
int fd = open (pathname, flags); |
332 |
|
|
333 |
|
if (fd < 0) |
334 |
|
return NULL; |
335 |
|
|
336 |
|
FILE *file = malloc (sizeof (FILE)); |
337 |
|
|
338 |
|
if (file == NULL) |
339 |
|
{ |
340 |
|
close (fd); |
341 |
|
return NULL; |
342 |
|
} |
343 |
|
|
344 |
|
file->fd = fd; |
345 |
|
file->buf = malloc (FBUFSIZ); |
346 |
|
file->buf_size = 0; |
347 |
|
file->mode = flags; |
348 |
|
|
349 |
|
return file; |
350 |
|
} |
351 |
|
|
352 |
|
int |
353 |
|
fclose (FILE *file) |
354 |
|
{ |
355 |
|
fflush (file); |
356 |
|
|
357 |
|
int ret = close (file->fd); |
358 |
|
|
359 |
|
if (ret < 0) |
360 |
|
return ret; |
361 |
|
|
362 |
|
free (file->buf); |
363 |
|
free (file); |
364 |
|
|
365 |
|
return 0; |
366 |
|
} |
367 |
|
|
368 |
|
size_t |
369 |
|
fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) |
370 |
|
{ |
371 |
|
size_t total = size * nmemb; |
372 |
|
size_t written = 0; |
373 |
|
char buf[FBUFSIZ]; |
374 |
|
|
375 |
|
while (total) |
376 |
|
{ |
377 |
|
size_t to_write = total; |
378 |
|
|
379 |
|
if (to_write > FBUFSIZ) |
380 |
|
to_write = FBUFSIZ; |
381 |
|
|
382 |
|
memcpy (buf, ptr, to_write); |
383 |
|
|
384 |
|
int ret = write (stream->fd, buf, to_write); |
385 |
|
|
386 |
|
if (ret < 0) |
387 |
|
return ret; |
388 |
|
|
389 |
|
total -= to_write; |
390 |
|
written += to_write; |
391 |
|
} |
392 |
|
|
393 |
|
return written; |
394 |
|
} |
395 |
|
|
396 |
|
int |
397 |
|
fputs (const char *str, FILE *stream) |
398 |
|
{ |
399 |
|
while (*str) |
400 |
|
{ |
401 |
|
((unsigned char *) stream->buf)[stream->buf_size++] = *str; |
402 |
|
|
403 |
|
if (stream->buf_size >= FBUFSIZ || *str == '\n') |
404 |
|
{ |
405 |
|
int ret = fwrite (stream->buf, 1, stream->buf_size, stream); |
406 |
|
|
407 |
|
if (ret < 0) |
408 |
|
return ret; |
409 |
|
|
410 |
|
stream->buf_size = 0; |
411 |
|
} |
412 |
|
|
413 |
|
str++; |
414 |
|
} |
415 |
|
|
416 |
|
return 0; |
417 |
|
} |
418 |
|
|
419 |
|
int |
420 |
|
fflush (FILE *stream) |
421 |
|
{ |
422 |
|
if (stream->buf_size == 0) |
423 |
|
return 0; |
424 |
|
|
425 |
|
return fwrite (stream->buf, 1, stream->buf_size, stream); |
426 |
|
} |
427 |
|
|
428 |
|
FILE * |
429 |
|
fdopen (int fd, const char *mode) |
430 |
|
{ |
431 |
|
int flags = fmode_to_flags (mode); |
432 |
|
|
433 |
|
if (flags == -1) |
434 |
|
return NULL; |
435 |
|
|
436 |
|
FILE *file = malloc (sizeof (FILE)); |
437 |
|
|
438 |
|
if (file == NULL) |
439 |
|
return NULL; |
440 |
|
|
441 |
|
file->fd = fd; |
442 |
|
file->buf = malloc (FBUFSIZ); |
443 |
|
file->buf_size = 0; |
444 |
|
file->mode = flags; |
445 |
|
|
446 |
|
return file; |
447 |
} |
} |