summaryrefslogtreecommitdiff
path: root/Libraries/LibC/stdio.cpp
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-05-28 02:12:05 +0430
committerAndreas Kling <kling@serenityos.org>2020-05-28 11:01:08 +0200
commitdd2f9658f321b28bdd78a31dd23e786d84a20416 (patch)
tree5c081952ac1a2e6dc953f9bb92c503bebc31ad79 /Libraries/LibC/stdio.cpp
parentf9bf2c7e78e0a9b96d51a27039f28b3fb09b495f (diff)
downloadserenity-dd2f9658f321b28bdd78a31dd23e786d84a20416.zip
LibC: Add a O_CLOEXEC mode element to fopen()
This commit also changes the mode parsing to allow specifying the modes in any order.
Diffstat (limited to 'Libraries/LibC/stdio.cpp')
-rw-r--r--Libraries/LibC/stdio.cpp44
1 files changed, 28 insertions, 16 deletions
diff --git a/Libraries/LibC/stdio.cpp b/Libraries/LibC/stdio.cpp
index 249ad9aa01..2de6f2d95d 100644
--- a/Libraries/LibC/stdio.cpp
+++ b/Libraries/LibC/stdio.cpp
@@ -77,7 +77,6 @@ public:
void set_popen_child(pid_t child_pid) { m_popen_child = child_pid; }
private:
-
struct Buffer {
// A ringbuffer that also transparently implements ungetc().
public:
@@ -911,23 +910,36 @@ void perror(const char* s)
static int parse_mode(const char* mode)
{
int flags = 0;
+
// NOTE: rt is a non-standard mode which opens a file for read, explicitly
// specifying that it's a text file
- if (!strcmp(mode, "r") || !strcmp(mode, "rb") || !strcmp(mode, "rt"))
- flags = O_RDONLY;
- else if (!strcmp(mode, "r+") || !strcmp(mode, "rb+"))
- flags = O_RDWR;
- else if (!strcmp(mode, "w") || !strcmp(mode, "wb"))
- flags = O_WRONLY | O_CREAT | O_TRUNC;
- else if (!strcmp(mode, "w+") || !strcmp(mode, "wb+"))
- flags = O_RDWR | O_CREAT | O_TRUNC;
- else if (!strcmp(mode, "a") || !strcmp(mode, "ab"))
- flags = O_WRONLY | O_APPEND | O_CREAT;
- else if (!strcmp(mode, "a+") || !strcmp(mode, "ab+"))
- flags = O_RDWR | O_APPEND | O_CREAT;
- else {
- dbg() << "Unexpected mode _" << mode << "_";
- ASSERT_NOT_REACHED();
+ for (; *mode; ++mode) {
+ switch (*mode) {
+ case 'r':
+ flags |= O_RDONLY;
+ break;
+ case 'w':
+ flags |= O_WRONLY | O_CREAT | O_TRUNC;
+ break;
+ case 'a':
+ flags |= O_WRONLY | O_APPEND | O_CREAT;
+ break;
+ case '+':
+ flags |= O_RDWR;
+ break;
+ case 'e':
+ flags |= O_CLOEXEC;
+ break;
+ case 'b':
+ // Ok...
+ break;
+ case 't':
+ // Ok...
+ break;
+ default:
+ dbg() << "Unsupported mode _" << mode << "_ (because of '" << *mode << "')";
+ ASSERT_NOT_REACHED();
+ }
}
return flags;