]> mj.ucw.cz Git - moe.git/blob - judge/io.c
68c299248ee158e58e2413ad907e6ec5df6b8caa
[moe.git] / judge / io.c
1 /*
2  *      I/O functions for judges
3  *
4  *      (c) 2007 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11
12 #include "judge.h"
13
14 #define BUFSIZE 65536
15
16 struct stream *sopen_fd(char *name, int fd)
17 {
18   struct stream *s = xmalloc(sizeof(*s) + BUFSIZE + strlen(name) + 1);
19   s->fd = fd;
20   s->pos = s->stop = s->buf;
21   s->end = s->buf + BUFSIZE;
22   s->name = s->end;
23   strcpy(s->name, name);
24   s->flags = 0;
25   return s;
26 }
27
28 struct stream *sopen_read(char *name)
29 {
30   int fd = open(name, O_RDONLY);
31   if (fd < 0)
32     die("Unable to open %s for reading: %m", name);
33   return sopen_fd(name, fd);
34 }
35
36 struct stream *sopen_write(char *name)
37 {
38   int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
39   if (fd < 0)
40     die("Unable to open %s for writing: %m", name);
41   return sopen_fd(name, fd);
42 }
43
44 void sflush(struct stream *s)
45 {
46   if (s->pos > s->stop)
47     {
48       char *p = s->buf;
49       int len = s->pos - s->buf;
50       while (len > 0)
51         {
52           int c = write(s->fd, p, len);
53           if (c <= 0)
54             die("Error writing %s: %m", s->name);
55           p += c;
56           len -= c;
57         }
58     }
59   s->pos = s->stop = s->buf;
60 }
61
62 void sclose(struct stream *s)
63 {
64   sflush(s);
65   close(s->fd);
66   free(s);
67 }
68
69 static int srefill(struct stream *s)
70 {
71   int len = read(s->fd, s->buf, BUFSIZE);
72   if (len < 0)
73     die("Error reading %s: %m", s->name);
74   s->pos = s->buf;
75   s->stop = s->buf + len;
76   return len;
77 }
78
79 int sgetc_slow(struct stream *s)
80 {
81   return (srefill(s) ? *s->pos++ : -1);
82 }
83
84 int speekc_slow(struct stream *s)
85 {
86   return (srefill(s) ? *s->pos : -1);
87 }