summaryrefslogtreecommitdiff
path: root/LibC
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-11-11 10:11:09 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-11-11 10:11:09 +0100
commite48182d91b352525d31105989be3b0e5f77f772a (patch)
treec4e50b54b55e9828ec6f8cb14b721641d670511c /LibC
parent7cc4caee4f879efd12a079a206b00a689a254609 (diff)
downloadserenity-e48182d91b352525d31105989be3b0e5f77f772a.zip
Add setvbuf(), setlinebuf(), setbuf().
Diffstat (limited to 'LibC')
-rw-r--r--LibC/entry.cpp14
-rw-r--r--LibC/limits.h1
-rw-r--r--LibC/stdio.cpp83
-rw-r--r--LibC/stdio.h17
-rw-r--r--LibC/unistd.cpp2
-rw-r--r--LibC/unistd.h1
6 files changed, 86 insertions, 32 deletions
diff --git a/LibC/entry.cpp b/LibC/entry.cpp
index 2753137e2c..5a54b85f59 100644
--- a/LibC/entry.cpp
+++ b/LibC/entry.cpp
@@ -5,27 +5,17 @@
extern "C" int main(int, char**);
-FILE __default_streams[3];
-
int errno;
-FILE* stdin;
-FILE* stdout;
-FILE* stderr;
char** environ;
extern "C" void __malloc_init();
+extern "C" void __stdio_init();
extern "C" int _start()
{
errno = 0;
- memset(__default_streams, 0, sizeof(__default_streams));
- __default_streams[0].fd = 0;
- stdin = &__default_streams[0];
- __default_streams[1].fd = 1;
- stdout = &__default_streams[1];
- __default_streams[2].fd = 2;
- stderr = &__default_streams[2];
+ __stdio_init();
__malloc_init();
StringImpl::initializeGlobals();
diff --git a/LibC/limits.h b/LibC/limits.h
index f13e1ef5b7..aae9ecc7ad 100644
--- a/LibC/limits.h
+++ b/LibC/limits.h
@@ -3,6 +3,7 @@
#include <stdint.h>
#define PATH_MAX 4096
+#define BUFSIZ 1024
#define INT_MAX INT32_MAX
#define INT_MIN INT32_MIN
diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp
index 5c1409591f..d4df7762a8 100644
--- a/LibC/stdio.cpp
+++ b/LibC/stdio.cpp
@@ -6,11 +6,70 @@
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
+#include <unistd.h>
#include <Kernel/Syscall.h>
#include <AK/printf.cpp>
extern "C" {
+static FILE __default_streams[3];
+FILE* stdin;
+FILE* stdout;
+FILE* stderr;
+
+void init_FILE(FILE& fp, int fd, int mode)
+{
+ fp.fd = fd;
+ fp.buffer = fp.default_buffer;
+ fp.buffer_size = BUFSIZ;
+ fp.mode = mode;
+}
+
+static FILE* make_FILE(int fd)
+{
+ auto* fp = (FILE*)malloc(sizeof(FILE));
+ memset(fp, 0, sizeof(FILE));
+ init_FILE(*fp, fd, isatty(fd));
+ return fp;
+}
+
+void __stdio_init()
+{
+ stdin = &__default_streams[0];
+ stdout = &__default_streams[1];
+ stderr = &__default_streams[2];
+ init_FILE(*stdin, 0, isatty(0) ? _IOLBF : _IOFBF);
+ init_FILE(*stdout, 1, isatty(1) ? _IOLBF : _IOFBF);
+ init_FILE(*stderr, 2, _IONBF);
+}
+
+int setvbuf(FILE* stream, char* buf, int mode, size_t size)
+{
+ if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) {
+ errno = EINVAL;
+ return -1;
+ }
+ stream->mode = mode;
+ if (buf) {
+ stream->buffer = buf;
+ stream->buffer_size = size;
+ } else {
+ stream->buffer = stream->default_buffer;
+ stream->buffer_size = BUFSIZ;
+ }
+ return 0;
+}
+
+void setbuf(FILE* stream, char* buf)
+{
+ setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
+
+void setlinebuf(FILE* stream, char* buf)
+{
+ setvbuf(stream, buf, buf ? _IOLBF : _IONBF, BUFSIZ);
+}
+
int fileno(FILE* stream)
{
assert(stream);
@@ -28,10 +87,10 @@ int fflush(FILE* stream)
// FIXME: Implement buffered streams, duh.
if (!stream)
return -EBADF;
- if (!stream->write_buffer_index)
+ if (!stream->buffer_index)
return 0;
- int rc = write(stream->fd, stream->write_buffer, stream->write_buffer_index);
- stream->write_buffer_index = 0;
+ int rc = write(stream->fd, stream->buffer, stream->buffer_index);
+ stream->buffer_index = 0;
return rc;
}
@@ -75,9 +134,11 @@ int getchar()
int fputc(int ch, FILE* stream)
{
assert(stream);
- assert(stream->write_buffer_index < __STDIO_FILE_BUFFER_SIZE);
- stream->write_buffer[stream->write_buffer_index++] = ch;
- if (ch == '\n' || stream->write_buffer_index >= __STDIO_FILE_BUFFER_SIZE)
+ assert(stream->buffer_index < stream->buffer_size);
+ stream->buffer[stream->buffer_index++] = ch;
+ if (stream->buffer_index >= stream->buffer_size)
+ fflush(stream);
+ else if (stream->mode == _IOLBF && ch == '\n')
fflush(stream);
if (stream->eof)
return EOF;
@@ -218,10 +279,7 @@ FILE* fopen(const char* pathname, const char* mode)
int fd = open(pathname, O_RDONLY);
if (fd < 0)
return nullptr;
- auto* fp = (FILE*)malloc(sizeof(FILE));
- memset(fp, 0, sizeof(FILE));
- fp->fd = fd;
- return fp;
+ return make_FILE(fd);
}
FILE* fdopen(int fd, const char* mode)
@@ -229,10 +287,7 @@ FILE* fdopen(int fd, const char* mode)
assert(!strcmp(mode, "r") || !strcmp(mode, "rb"));
if (fd < 0)
return nullptr;
- auto* fp = (FILE*)malloc(sizeof(FILE));
- memset(fp, 0, sizeof(FILE));
- fp->fd = fd;
- return fp;
+ return make_FILE(fd);
}
int fclose(FILE* stream)
diff --git a/LibC/stdio.h b/LibC/stdio.h
index 452dddee5d..9547019a69 100644
--- a/LibC/stdio.h
+++ b/LibC/stdio.h
@@ -2,6 +2,7 @@
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <limits.h>
__BEGIN_DECLS
#ifndef EOF
@@ -12,16 +13,19 @@ __BEGIN_DECLS
#define SEEK_CUR 1
#define SEEK_END 2
-#define __STDIO_FILE_BUFFER_SIZE 128
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
struct __STDIO_FILE {
int fd;
int eof;
int error;
- char read_buffer[__STDIO_FILE_BUFFER_SIZE];
- size_t read_buffer_index;
- char write_buffer[__STDIO_FILE_BUFFER_SIZE];
- size_t write_buffer_index;
+ int mode;
+ char* buffer;
+ size_t buffer_size;
+ size_t buffer_index;
+ char default_buffer[BUFSIZ];
};
typedef struct __STDIO_FILE FILE;
@@ -55,6 +59,9 @@ int fputs(const char*, FILE*);
void perror(const char*);
int sscanf (const char* buf, const char* fmt, ...);
int fscanf(FILE*, const char* fmt, ...);
+int setvbuf(FILE*, char* buf, int mode, size_t);
+void setbuf(FILE*, char* buf);
+void setlinebuf(FILE*, char* buf);
__END_DECLS
diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp
index d1aaeaa3d9..7e767d72e7 100644
--- a/LibC/unistd.cpp
+++ b/LibC/unistd.cpp
@@ -212,7 +212,7 @@ int isatty(int fd)
int getdtablesize()
{
int rc = Syscall::invoke(Syscall::SC_getdtablesize);
- __RETURN_WITH_ERRNO(rc, 1, 0);
+ __RETURN_WITH_ERRNO(rc, rc, -1);
}
int dup(int old_fd)
diff --git a/LibC/unistd.h b/LibC/unistd.h
index 85b07a4e8f..a809a91151 100644
--- a/LibC/unistd.h
+++ b/LibC/unistd.h
@@ -50,6 +50,7 @@ int dup2(int old_fd, int new_fd);
int pipe(int pipefd[2]);
unsigned int alarm(unsigned int seconds);
int access(const char* pathname, int mode);
+int isatty(int fd);
#define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
#define WTERMSIG(status) ((status) & 0x7f)