diff --git a/libc/Makefile b/libc/Makefile
index 05acc584..72141123 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -424,9 +424,12 @@ signal/signal.o \
signal/sigpending.o \
signal/sigprocmask.o \
signal/sigsuspend.o \
+stdio/fdio_close.o \
stdio/fdio_install_fd.o \
stdio/fdio_install_path.o \
-stdio/fdio.o \
+stdio/fdio_read.o \
+stdio/fdio_seek.o \
+stdio/fdio_write.o \
stdio/fdopen.o \
stdio/fgetpos.o \
stdio/fileno.o \
diff --git a/libc/include/FILE.h b/libc/include/FILE.h
index 905b2ec9..8b361d41 100644
--- a/libc/include/FILE.h
+++ b/libc/include/FILE.h
@@ -79,11 +79,9 @@ struct __FILE
unsigned char* buffer;
void* user;
void* free_user;
- int (*reopen_func)(void* user, const char* mode);
ssize_t (*read_func)(void* user, void* ptr, size_t size);
ssize_t (*write_func)(void* user, const void* ptr, size_t size);
off_t (*seek_func)(void* user, off_t offset, int whence);
- int (*fileno_func)(void* user);
int (*close_func)(void* user);
void (*free_func)(void* free_user, FILE* fp);
pthread_mutex_t file_lock;
@@ -92,6 +90,7 @@ struct __FILE
FILE* next;
int flags;
int buffer_mode;
+ int fd;
size_t offset_input_buffer;
size_t amount_input_buffered;
size_t amount_output_buffered;
diff --git a/libc/stdio/fdio.cpp b/libc/stdio/fdio.cpp
deleted file mode 100644
index 11776215..00000000
--- a/libc/stdio/fdio.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
-
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
-
- This file is part of the Sortix C Library.
-
- The Sortix C Library is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or (at your
- option) any later version.
-
- The Sortix C Library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with the Sortix C Library. If not, see .
-
- stdio/fdio.cpp
- Handles the file descriptor backend for the FILE* API.
-
-*******************************************************************************/
-
-#include
-#include
-
-#include "fdio.h"
-
-int fdio_reopen(void* user, const char* mode)
-{
- (void) user;
- (void) mode;
- // TODO: Unfortunately, we don't support this yet. Note that we don't really
- // have to support this according to POSIX - but it'd be nicer to push this
- // restriction into the kernel and argue it's a security problem "What? No
- // you can't make this read-only descriptor writable!".
- return errno = ENOTSUP, -1;
-}
-
-ssize_t fdio_read(void* user, void* ptr, size_t size)
-{
- struct fdio_state* fdio = (struct fdio_state*) user;
- return read(fdio->fd, ptr, size);
-}
-
-ssize_t fdio_write(void* user, const void* ptr, size_t size)
-{
- struct fdio_state* fdio = (struct fdio_state*) user;
- return write(fdio->fd, ptr, size);
-}
-
-off_t fdio_seek(void* user, off_t offset, int whence)
-{
- struct fdio_state* fdio = (struct fdio_state*) user;
- return lseek(fdio->fd, offset, whence);
-}
-
-int fdio_fileno(void* user)
-{
- struct fdio_state* fdio = (struct fdio_state*) user;
- return fdio->fd;
-}
-
-int fdio_close(void* user)
-{
- struct fdio_state* fdio = (struct fdio_state*) user;
- int result = close(fdio->fd);
- if ( fdio->free_indirect )
- fdio->free_indirect(fdio);
- return result;
-}
diff --git a/libc/stdio/fdio.h b/libc/stdio/fdio.h
index 5f6d43e2..e7221132 100644
--- a/libc/stdio/fdio.h
+++ b/libc/stdio/fdio.h
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2014.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2014, 2015.
This file is part of the Sortix C Library.
@@ -38,17 +38,9 @@
extern "C" {
#endif
-struct fdio_state
-{
- void (*free_indirect)(void*);
- int fd;
-};
-
-int fdio_reopen(void* user, const char* mode);
ssize_t fdio_read(void* user, void* ptr, size_t size);
ssize_t fdio_write(void* user, const void* ptr, size_t size);
off_t fdio_seek(void* user, off_t offset, int whence);
-int fdio_fileno(void* user);
int fdio_close(void* user);
bool fdio_install_fd(FILE* fp, int fd, const char* mode);
diff --git a/libc/stdio/fdio_close.cpp b/libc/stdio/fdio_close.cpp
new file mode 100644
index 00000000..1b058907
--- /dev/null
+++ b/libc/stdio/fdio_close.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ stdio/fdio_close.cpp
+ File descriptor FILE backend closing.
+
+*******************************************************************************/
+
+#include
+#include
+
+#include "fdio.h"
+
+extern "C"
+int fdio_close(void* user)
+{
+ FILE* fp = (FILE*) user;
+ return close(fp->fd);
+}
diff --git a/libc/stdio/fdio_install_fd.cpp b/libc/stdio/fdio_install_fd.cpp
index a5e3912c..41ae7edc 100644
--- a/libc/stdio/fdio_install_fd.cpp
+++ b/libc/stdio/fdio_install_fd.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
This file is part of the Sortix C Library.
@@ -47,24 +47,15 @@ extern "C" bool fdio_install_fd(FILE* fp, int fd, const char* mode)
S_ISDIR(st.st_mode) )
return errno = EISDIR, false;
- struct fdio_state* fdio = (struct fdio_state*) malloc(sizeof(struct fdio_state));
- if ( !fdio )
- return false;
-
- fdio->free_indirect = free;
- fdio->fd = fd;
-
if ( mode_flags & FILE_MODE_READ )
fp->flags |= _FILE_READABLE;
if ( mode_flags & FILE_MODE_WRITE )
fp->flags |= _FILE_WRITABLE;
-
- fp->user = fdio;
- fp->reopen_func = fdio_reopen;
+ fp->fd = fd;
+ fp->user = fp;
fp->read_func = fdio_read;
fp->write_func = fdio_write;
fp->seek_func = fdio_seek;
- fp->fileno_func = fdio_fileno;
fp->close_func = fdio_close;
return true;
diff --git a/libc/stdio/fdio_read.cpp b/libc/stdio/fdio_read.cpp
new file mode 100644
index 00000000..6a1578a3
--- /dev/null
+++ b/libc/stdio/fdio_read.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ stdio/fdio_read.cpp
+ File descriptor FILE backend reading.
+
+*******************************************************************************/
+
+#include
+#include
+
+#include "fdio.h"
+
+extern "C"
+ssize_t fdio_read(void* user, void* ptr, size_t size)
+{
+ FILE* fp = (FILE*) user;
+ return read(fp->fd, ptr, size);
+}
diff --git a/libc/stdio/fdio_seek.cpp b/libc/stdio/fdio_seek.cpp
new file mode 100644
index 00000000..59fa76f7
--- /dev/null
+++ b/libc/stdio/fdio_seek.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ stdio/fdio_seek.cpp
+ File descriptor FILE backend seeking.
+
+*******************************************************************************/
+
+#include
+#include
+
+#include "fdio.h"
+
+extern "C"
+off_t fdio_seek(void* user, off_t offset, int whence)
+{
+ FILE* fp = (FILE*) user;
+ return lseek(fp->fd, offset, whence);
+}
diff --git a/libc/stdio/fdio_write.cpp b/libc/stdio/fdio_write.cpp
new file mode 100644
index 00000000..49f3d20c
--- /dev/null
+++ b/libc/stdio/fdio_write.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014, 2015.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ stdio/fdio_write.cpp
+ File descriptor FILE backend writing.
+
+*******************************************************************************/
+
+#include
+#include
+
+#include "fdio.h"
+
+extern "C"
+ssize_t fdio_write(void* user, const void* ptr, size_t size)
+{
+ FILE* fp = (FILE*) user;
+ return write(fp->fd, ptr, size);
+}
diff --git a/libc/stdio/fileno.cpp b/libc/stdio/fileno.cpp
index 5d5d5b91..5eacb9a8 100644
--- a/libc/stdio/fileno.cpp
+++ b/libc/stdio/fileno.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2015.
This file is part of the Sortix C Library.
diff --git a/libc/stdio/fileno_unlocked.cpp b/libc/stdio/fileno_unlocked.cpp
index 05b7a35b..98308495 100644
--- a/libc/stdio/fileno_unlocked.cpp
+++ b/libc/stdio/fileno_unlocked.cpp
@@ -27,7 +27,5 @@
extern "C" int fileno_unlocked(FILE* fp)
{
- if ( !fp->fileno_func )
- return errno = EBADF, -1;
- return fp->fileno_func(fp->user);
+ return fp->fd;
}
diff --git a/libc/stdio/fmemopen.cpp b/libc/stdio/fmemopen.cpp
index 066c7015..0808f89c 100644
--- a/libc/stdio/fmemopen.cpp
+++ b/libc/stdio/fmemopen.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2014.
+ Copyright(C) Jonas 'Sortie' Termansen 2014, 2015.
This file is part of the Sortix C Library.
@@ -213,7 +213,7 @@ FILE* fmemopen(void* restrict buffer_ptr,
fp->flags |= _FILE_READABLE;
if ( mode & FILE_MODE_WRITE )
fp->flags |= _FILE_WRITABLE;
-
+ fp->fd = -1;
fp->user = state;
fp->read_func = fmemopen_read;
fp->write_func = fmemopen_write;
diff --git a/libc/stdio/freopen.cpp b/libc/stdio/freopen.cpp
index c8db23d7..c718993a 100644
--- a/libc/stdio/freopen.cpp
+++ b/libc/stdio/freopen.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2013.
+ Copyright(C) Jonas 'Sortie' Termansen 2013, 2015.
This file is part of the Sortix C Library.
@@ -29,18 +29,8 @@
extern "C" FILE* freopen(const char* path, const char* mode, FILE* fp)
{
- // If no path is given, simply try to change the mode of the file.
if ( !path )
- {
- // TODO: Determine whether the file should be closed in case we fail
- // here to change the mode. A quick look at POSIX doesn't mention that
- // it should be closed, so we'll assume it shouldn't!
- if ( !fp->reopen_func )
- return errno = EBADF, (FILE*) NULL;
- if ( !fp->reopen_func(fp->user, mode) )
- return NULL;
- return fp;
- }
+ return errno = EBADF, (FILE*) NULL;
// Uninstall the current backend of the FILE (after flushing) and return the
// FILE to the default state (like a new object from fnewfile).
diff --git a/libc/stdio/open_memstream.cpp b/libc/stdio/open_memstream.cpp
index 1ac30ee1..f223c7a3 100644
--- a/libc/stdio/open_memstream.cpp
+++ b/libc/stdio/open_memstream.cpp
@@ -113,6 +113,7 @@ extern "C" FILE* open_memstream(char** string_out, size_t* used_out)
ms->used = 0;
ms->size = 0;
fp->flags |= _FILE_WRITABLE;
+ fp->fd = -1;
fp->user = ms;
fp->write_func = memstream_write;
fp->seek_func = memstream_seek;
diff --git a/libc/stdio/popen.cpp b/libc/stdio/popen.cpp
index 5ba01fa8..e5881792 100644
--- a/libc/stdio/popen.cpp
+++ b/libc/stdio/popen.cpp
@@ -56,12 +56,6 @@ static off_t popen_seek(void* /*user*/, off_t /*offset*/, int /*whence*/)
return errno = ESPIPE, -1;
}
-static int popen_fileno(void* user)
-{
- popen_t* info = (popen_t*) user;
- return info->fd;
-}
-
static int popen_close(void* user)
{
popen_t* info = (popen_t*) user;
@@ -76,13 +70,12 @@ static int popen_close(void* user)
return status;
}
-void popen_install(FILE* fp, popen_t* info)
+static void popen_install(FILE* fp, popen_t* info)
{
fp->user = info;
fp->read_func = popen_read;
fp->write_func = popen_write;
fp->seek_func = popen_seek;
- fp->fileno_func = popen_fileno;
fp->close_func = popen_close;
}
@@ -127,6 +120,7 @@ extern "C" FILE* popen(const char* command, const char* type)
info->pid = childpid;
popen_install(fp, info);
fp->flags |= writing ? _FILE_WRITABLE : _FILE_READABLE;
+ fp->fd = info->fd;
return fp;
}
diff --git a/libc/stdio/stderr.cpp b/libc/stdio/stderr.cpp
index ba951d6f..d353cfa2 100644
--- a/libc/stdio/stderr.cpp
+++ b/libc/stdio/stderr.cpp
@@ -27,17 +27,14 @@
#include "fdio.h"
-static struct fdio_state stderr_fdio = { NULL, 2 };
static FILE stderr_file
{
/* buffer = */ NULL,
- /* user = */ &stderr_fdio,
+ /* user = */ &stderr_file,
/* free_user = */ NULL,
- /* reopen_func = */ fdio_reopen,
- /* read_func = */ fdio_read,
+ /* read_func = */ NULL,
/* write_func = */ fdio_write,
/* seek_func = */ fdio_seek,
- /* fileno_func = */ fdio_fileno,
/* close_func = */ fdio_close,
/* free_func = */ NULL,
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -46,6 +43,7 @@ static FILE stderr_file
/* next = */ NULL,
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
/* buffer_mode = */ _IONBF,
+ /* fd = */ 2,
/* offset_input_buffer = */ 0,
/* amount_input_buffered = */ 0,
/* amount_output_buffered = */ 0,
diff --git a/libc/stdio/stdin.cpp b/libc/stdio/stdin.cpp
index 4f3436bf..3dda2220 100644
--- a/libc/stdio/stdin.cpp
+++ b/libc/stdio/stdin.cpp
@@ -28,17 +28,14 @@
#include "fdio.h"
static unsigned char stdin_buffer[BUFSIZ];
-static struct fdio_state stdin_fdio = { NULL, 0 };
static FILE stdin_file =
{
/* buffer = */ stdin_buffer,
- /* user = */ &stdin_fdio,
+ /* user = */ &stdin_file,
/* free_user = */ NULL,
- /* reopen_func = */ fdio_reopen,
/* read_func = */ fdio_read,
- /* write_func = */ fdio_write,
+ /* write_func = */ NULL,
/* seek_func = */ fdio_seek,
- /* fileno_func = */ fdio_fileno,
/* close_func = */ fdio_close,
/* free_func = */ NULL,
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -47,6 +44,7 @@ static FILE stdin_file =
/* next = */ NULL,
/* flags = */ _FILE_REGISTERED | _FILE_READABLE,
/* buffer_mode = */ -1,
+ /* fd = */ 0,
/* offset_input_buffer = */ 0,
/* amount_input_buffered = */ 0,
/* amount_output_buffered = */ 0,
diff --git a/libc/stdio/stdout.cpp b/libc/stdio/stdout.cpp
index 63735576..6a61c249 100644
--- a/libc/stdio/stdout.cpp
+++ b/libc/stdio/stdout.cpp
@@ -28,17 +28,14 @@
#include "fdio.h"
static unsigned char stdout_buffer[BUFSIZ];
-static struct fdio_state stdout_fdio = { NULL, 1 };
static FILE stdout_file
{
/* buffer = */ stdout_buffer,
- /* user = */ &stdout_fdio,
+ /* user = */ &stdout_file,
/* free_user = */ NULL,
- /* reopen_func = */ fdio_reopen,
- /* read_func = */ fdio_read,
+ /* read_func = */ NULL,
/* write_func = */ fdio_write,
/* seek_func = */ fdio_seek,
- /* fileno_func = */ fdio_fileno,
/* close_func = */ fdio_close,
/* free_func = */ NULL,
/* file_lock = */ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -47,6 +44,7 @@ static FILE stdout_file
/* next = */ NULL,
/* flags = */ _FILE_REGISTERED | _FILE_WRITABLE,
/* buffer_mode = */ -1,
+ /* fd = */ 1,
/* offset_input_buffer = */ 0,
/* amount_input_buffered = */ 0,
/* amount_output_buffered = */ 0,