Commit 5df28c15 authored by Thomas Weißschuh's avatar Thomas Weißschuh Committed by Paul E. McKenney

tools/nolibc: implement fd-based FILE streams

This enables the usage of the stream APIs with arbitrary filedescriptors.

It will be used by a future testcase.
Signed-off-by: default avatarThomas Weißschuh <linux@weissschuh.net>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
parent e8842cf0
...@@ -21,17 +21,75 @@ ...@@ -21,17 +21,75 @@
#define EOF (-1) #define EOF (-1)
#endif #endif
/* just define FILE as a non-empty type */ /* just define FILE as a non-empty type. The value of the pointer gives
* the FD: FILE=~fd for fd>=0 or NULL for fd<0. This way positive FILE
* are immediately identified as abnormal entries (i.e. possible copies
* of valid pointers to something else).
*/
typedef struct FILE { typedef struct FILE {
char dummy[1]; char dummy[1];
} FILE; } FILE;
/* We define the 3 common stdio files as constant invalid pointers that static __attribute__((unused)) FILE* const stdin = (FILE*)(intptr_t)~STDIN_FILENO;
* are easily recognized. static __attribute__((unused)) FILE* const stdout = (FILE*)(intptr_t)~STDOUT_FILENO;
*/ static __attribute__((unused)) FILE* const stderr = (FILE*)(intptr_t)~STDERR_FILENO;
static __attribute__((unused)) FILE* const stdin = (FILE*)-3;
static __attribute__((unused)) FILE* const stdout = (FILE*)-2; /* provides a FILE* equivalent of fd. The mode is ignored. */
static __attribute__((unused)) FILE* const stderr = (FILE*)-1; static __attribute__((unused))
FILE *fdopen(int fd, const char *mode __attribute__((unused)))
{
if (fd < 0) {
SET_ERRNO(EBADF);
return NULL;
}
return (FILE*)(intptr_t)~fd;
}
/* provides the fd of stream. */
static __attribute__((unused))
int fileno(FILE *stream)
{
intptr_t i = (intptr_t)stream;
if (i >= 0) {
SET_ERRNO(EBADF);
return -1;
}
return ~i;
}
/* flush a stream. */
static __attribute__((unused))
int fflush(FILE *stream)
{
intptr_t i = (intptr_t)stream;
/* NULL is valid here. */
if (i > 0) {
SET_ERRNO(EBADF);
return -1;
}
/* Don't do anything, nolibc does not support buffering. */
return 0;
}
/* flush a stream. */
static __attribute__((unused))
int fclose(FILE *stream)
{
intptr_t i = (intptr_t)stream;
if (i >= 0) {
SET_ERRNO(EBADF);
return -1;
}
if (close(~i))
return EOF;
return 0;
}
/* getc(), fgetc(), getchar() */ /* getc(), fgetc(), getchar() */
...@@ -41,14 +99,8 @@ static __attribute__((unused)) ...@@ -41,14 +99,8 @@ static __attribute__((unused))
int fgetc(FILE* stream) int fgetc(FILE* stream)
{ {
unsigned char ch; unsigned char ch;
int fd;
if (stream < stdin || stream > stderr) if (read(fileno(stream), &ch, 1) <= 0)
return EOF;
fd = 3 + (long)stream;
if (read(fd, &ch, 1) <= 0)
return EOF; return EOF;
return ch; return ch;
} }
...@@ -68,14 +120,8 @@ static __attribute__((unused)) ...@@ -68,14 +120,8 @@ static __attribute__((unused))
int fputc(int c, FILE* stream) int fputc(int c, FILE* stream)
{ {
unsigned char ch = c; unsigned char ch = c;
int fd;
if (stream < stdin || stream > stderr)
return EOF;
fd = 3 + (long)stream;
if (write(fd, &ch, 1) <= 0) if (write(fileno(stream), &ch, 1) <= 0)
return EOF; return EOF;
return ch; return ch;
} }
...@@ -96,12 +142,7 @@ static __attribute__((unused)) ...@@ -96,12 +142,7 @@ static __attribute__((unused))
int _fwrite(const void *buf, size_t size, FILE *stream) int _fwrite(const void *buf, size_t size, FILE *stream)
{ {
ssize_t ret; ssize_t ret;
int fd; int fd = fileno(stream);
if (stream < stdin || stream > stderr)
return EOF;
fd = 3 + (long)stream;
while (size) { while (size) {
ret = write(fd, buf, size); ret = write(fd, buf, size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment