summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-27 01:40:55 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-27 01:40:55 +0100
commitd1e55fb4d95c790155f427bac980a1c24a1360f7 (patch)
tree3e37057c7d5c7136c5207b4f71e9f65725183252
parent0c2face7b0756ac5d8523551f20a95716d77b9c5 (diff)
downloadserenity-d1e55fb4d95c790155f427bac980a1c24a1360f7.zip
LibC: Add ungetc() and automatically flush streams on fclose().
-rw-r--r--LibC/fcntl.h2
-rw-r--r--LibC/inttypes.h4
-rw-r--r--LibC/limits.h1
-rw-r--r--LibC/locale.h1
-rw-r--r--LibC/stdint.h10
-rw-r--r--LibC/stdio.cpp20
-rw-r--r--LibC/stdio.h4
7 files changed, 39 insertions, 3 deletions
diff --git a/LibC/fcntl.h b/LibC/fcntl.h
index fd6b710823..ab0f2167e7 100644
--- a/LibC/fcntl.h
+++ b/LibC/fcntl.h
@@ -47,6 +47,8 @@ __BEGIN_DECLS
#define S_IWOTH 0002
#define S_IXOTH 0001
+#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+
#define S_IRWXG (S_IRWXU >> 3)
#define S_IRWXO (S_IRWXG >> 3)
diff --git a/LibC/inttypes.h b/LibC/inttypes.h
index d0b8ec0509..436aa24fc4 100644
--- a/LibC/inttypes.h
+++ b/LibC/inttypes.h
@@ -6,6 +6,10 @@
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "lld"
+#define PRIi8 "d"
+#define PRIi16 "d"
+#define PRIi32 "d"
+#define PRIi64 "lld"
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
diff --git a/LibC/limits.h b/LibC/limits.h
index a745d578f2..2561209168 100644
--- a/LibC/limits.h
+++ b/LibC/limits.h
@@ -5,7 +5,6 @@
#define PAGE_SIZE 4096
#define PATH_MAX 4096
-#define BUFSIZ 1024
#define INT_MAX INT32_MAX
#define INT_MIN INT32_MIN
diff --git a/LibC/locale.h b/LibC/locale.h
index 0bbe344e0f..b1c4e94275 100644
--- a/LibC/locale.h
+++ b/LibC/locale.h
@@ -10,6 +10,7 @@ enum {
LC_CTYPE,
LC_COLLATE,
LC_TIME,
+ LC_MONETARY,
};
struct lconv {
diff --git a/LibC/stdint.h b/LibC/stdint.h
index e5f84a5b79..62c5986c8b 100644
--- a/LibC/stdint.h
+++ b/LibC/stdint.h
@@ -24,6 +24,16 @@ typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+
#define __int8_t_defined 1
#define __uint8_t_defined 1
#define __int16_t_defined 1
diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp
index 9a976b4bb1..49de4da1c1 100644
--- a/LibC/stdio.cpp
+++ b/LibC/stdio.cpp
@@ -141,9 +141,12 @@ int getchar()
return getc(stdin);
}
-int ungetc(int, FILE*)
+int ungetc(int c, FILE* stream)
{
- ASSERT_NOT_REACHED();
+ ASSERT(stream);
+ stream->have_ungotten = true;
+ stream->ungotten = c;
+ return c;
}
int fputc(int ch, FILE* stream)
@@ -203,6 +206,18 @@ int ferror(FILE* stream)
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
{
assert(stream);
+ if (!size)
+ return 0;
+
+ if (stream->have_ungotten) {
+ // FIXME: Support ungotten character even if size != 1.
+ ASSERT(size == 1);
+ ((char*)ptr)[0] = stream->ungotten;
+ stream->have_ungotten = false;
+ --nmemb;
+ ptr = &((char*)ptr)[1];
+ }
+
ssize_t nread = read(stream->fd, ptr, nmemb * size);
if (nread < 0)
return 0;
@@ -388,6 +403,7 @@ FILE* fdopen(int fd, const char* mode)
int fclose(FILE* stream)
{
+ fflush(stream);
int rc = close(stream->fd);
free(stream);
return rc;
diff --git a/LibC/stdio.h b/LibC/stdio.h
index 5a886cbff4..990559f110 100644
--- a/LibC/stdio.h
+++ b/LibC/stdio.h
@@ -7,6 +7,8 @@
#include <stdarg.h>
#include <limits.h>
+#define BUFSIZ 1024
+
__BEGIN_DECLS
#ifndef EOF
#define EOF (-1)
@@ -28,6 +30,8 @@ struct __STDIO_FILE {
char* buffer;
size_t buffer_size;
size_t buffer_index;
+ bool have_ungotten;
+ char ungotten;
char default_buffer[BUFSIZ];
};