aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/include/nolibc/stdio.h95
1 files changed, 89 insertions, 6 deletions
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 4c6af3016e2e..149c5ca59aad 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -18,40 +18,123 @@
#define EOF (-1)
#endif
+/* just define FILE as a non-empty type */
+typedef struct FILE {
+ char dummy[1];
+} FILE;
+
+/* We define the 3 common stdio files as constant invalid pointers that
+ * are easily recognized.
+ */
+static __attribute__((unused)) FILE* const stdin = (FILE*)-3;
+static __attribute__((unused)) FILE* const stdout = (FILE*)-2;
+static __attribute__((unused)) FILE* const stderr = (FILE*)-1;
+
+/* getc(), fgetc(), getchar() */
+
+#define getc(stream) fgetc(stream)
+
static __attribute__((unused))
-int getchar(void)
+int fgetc(FILE* stream)
{
unsigned char ch;
+ int fd;
- if (read(0, &ch, 1) <= 0)
+ if (stream < stdin || stream > stderr)
+ return EOF;
+
+ fd = 3 + (long)stream;
+
+ if (read(fd, &ch, 1) <= 0)
return EOF;
return ch;
}
static __attribute__((unused))
-int putchar(int c)
+int getchar(void)
+{
+ return fgetc(stdin);
+}
+
+
+/* putc(), fputc(), putchar() */
+
+#define putc(c, stream) fputc(c, stream)
+
+static __attribute__((unused))
+int fputc(int c, FILE* stream)
{
unsigned char ch = c;
+ int fd;
- if (write(1, &ch, 1) <= 0)
+ if (stream < stdin || stream > stderr)
+ return EOF;
+
+ fd = 3 + (long)stream;
+
+ if (write(fd, &ch, 1) <= 0)
return EOF;
return ch;
}
static __attribute__((unused))
-int puts(const char *s)
+int putchar(int c)
+{
+ return fputc(c, stdout);
+}
+
+
+/* puts(), fputs(). Note that puts() emits '\n' but not fputs(). */
+
+static __attribute__((unused))
+int fputs(const char *s, FILE *stream)
{
size_t len = strlen(s);
ssize_t ret;
+ int fd;
+
+ if (stream < stdin || stream > stderr)
+ return EOF;
+
+ fd = 3 + (long)stream;
while (len > 0) {
- ret = write(1, s, len);
+ ret = write(fd, s, len);
if (ret <= 0)
return EOF;
s += ret;
len -= ret;
}
+ return 0;
+}
+
+static __attribute__((unused))
+int puts(const char *s)
+{
+ if (fputs(s, stdout) == EOF)
+ return EOF;
return putchar('\n');
}
+
+/* fgets() */
+static __attribute__((unused))
+char *fgets(char *s, int size, FILE *stream)
+{
+ int ofs;
+ int c;
+
+ for (ofs = 0; ofs + 1 < size;) {
+ c = fgetc(stream);
+ if (c == EOF)
+ break;
+ s[ofs++] = c;
+ if (c == '\n')
+ break;
+ }
+ if (ofs < size)
+ s[ofs] = 0;
+ return ofs ? s : NULL;
+}
+
#endif /* _NOLIBC_STDIO_H */