summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-04-02 15:51:39 +0100
committerVincent Sanders <vince@kyllikki.org>2015-04-02 15:51:39 +0100
commit2d6282f46bf44ea82ea9cc562f62af4456714052 (patch)
tree9366c5be3e0e91b219f55fc99f2fed0e7ef66861 /src
parentee700511bdd5af06304382abf0d6ff4cc9bd43f0 (diff)
downloadlibnsutils-2d6282f46bf44ea82ea9cc562f62af4456714052.tar.gz
libnsutils-2d6282f46bf44ea82ea9cc562f62af4456714052.tar.bz2
Added pread and pwrite wrappers.
This adds wrappers for the pread and pwrite standard calls with fixed semantics across all supported platforms. The main variation (so far) is some platforms not having the calls at all and AmigaOS not allowing seeks beyond existing extents.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/unistd.c67
2 files changed, 68 insertions, 1 deletions
diff --git a/src/Makefile b/src/Makefile
index 28bfc5f..b4fd96a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,3 +1,3 @@
-DIR_SOURCES := base64.c time.c
+DIR_SOURCES := base64.c time.c unistd.c
include $(NSBUILD)/Makefile.subdir
diff --git a/src/unistd.c b/src/unistd.c
new file mode 100644
index 0000000..219e9ec
--- /dev/null
+++ b/src/unistd.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of libnsutils.
+ *
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+/**
+ * \file
+ * unistd style operations.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+#include "nsutils/unistd.h"
+
+/* exported interface documented in nsutils/unistd.h */
+ssize_t nsu_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+#if defined(__riscos) || defined(__amiga)
+ off_t sk;
+
+ sk = lseek(fd, offset, SEEK_SET);
+ if (sk == (off_t)-1) {
+#if defined(__amiga)
+ /* amigaos cannot seek past the end of the existing file so use
+ * ftruncate to make the file long enough and retry the seek.
+ */
+ int ret;
+ if (errno == ESPIPE) {
+ ret = ftruncate(fd, offset);
+ if (ret == -1) {
+ return -1;
+ }
+ sk = lseek(fd, offset, SEEK_SET);
+ if (sk == (off_t)-1) {
+ return -1;
+ }
+ } else
+#endif
+ return -1;
+ }
+ return write(fd, buf, count);
+#else
+ return pwrite(fd, buf, count, offset);
+#endif
+}
+
+/* exported interface documented in nsutils/unistd.h */
+ssize_t nsu_pread(int fd, void *buf, size_t count, off_t offset)
+{
+#if defined(__riscos)
+ off_t sk;
+
+ sk = lseek(fd, offset, SEEK_SET);
+ if (sk == -1) {
+ return (off_t)-1;
+ }
+ return read(fd, buf, count);
+#else
+ return pread(fd, buf, count, offset);
+#endif
+
+}