aboutsummaryrefslogtreecommitdiffstats
path: root/src/input/file_input_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/file_input_plugin.c')
-rw-r--r--src/input/file_input_plugin.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/src/input/file_input_plugin.c b/src/input/file_input_plugin.c
index bda1777ac..e8ad87f45 100644
--- a/src/input/file_input_plugin.c
+++ b/src/input/file_input_plugin.c
@@ -17,8 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "config.h" /* must be first for large file support */
#include "input/file_input_plugin.h"
#include "input_plugin.h"
+#include "fd_util.h"
#include <sys/stat.h>
#include <fcntl.h>
@@ -30,20 +32,28 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "input_file"
+static inline GQuark
+file_quark(void)
+{
+ return g_quark_from_static_string("file");
+}
+
static bool
-input_file_open(struct input_stream *is, const char *filename)
+input_file_open(struct input_stream *is, const char *filename,
+ GError **error_r)
{
int fd, ret;
struct stat st;
- if (filename[0] != '/')
+ if (!g_path_is_absolute(filename))
return false;
- fd = open(filename, O_RDONLY);
+ fd = open_cloexec(filename, O_RDONLY, 0);
if (fd < 0) {
- is->error = errno;
- g_debug("Failed to open \"%s\": %s",
- filename, g_strerror(errno));
+ if (errno != ENOENT && errno != ENOTDIR)
+ g_set_error(error_r, file_quark(), errno,
+ "Failed to open \"%s\": %s",
+ filename, g_strerror(errno));
return false;
}
@@ -51,14 +61,16 @@ input_file_open(struct input_stream *is, const char *filename)
ret = fstat(fd, &st);
if (ret < 0) {
- is->error = errno;
+ g_set_error(error_r, file_quark(), errno,
+ "Failed to stat \"%s\": %s",
+ filename, g_strerror(errno));
close(fd);
return false;
}
if (!S_ISREG(st.st_mode)) {
- g_debug("Not a regular file: %s", filename);
- is->error = EINVAL;
+ g_set_error(error_r, file_quark(), 0,
+ "Not a regular file: %s", filename);
close(fd);
return false;
}
@@ -77,13 +89,15 @@ input_file_open(struct input_stream *is, const char *filename)
}
static bool
-input_file_seek(struct input_stream *is, off_t offset, int whence)
+input_file_seek(struct input_stream *is, goffset offset, int whence,
+ GError **error_r)
{
int fd = GPOINTER_TO_INT(is->data);
- offset = lseek(fd, offset, whence);
+ offset = (goffset)lseek(fd, (off_t)offset, whence);
if (offset < 0) {
- is->error = errno;
+ g_set_error(error_r, file_quark(), errno,
+ "Failed to seek: %s", g_strerror(errno));
return false;
}
@@ -92,16 +106,16 @@ input_file_seek(struct input_stream *is, off_t offset, int whence)
}
static size_t
-input_file_read(struct input_stream *is, void *ptr, size_t size)
+input_file_read(struct input_stream *is, void *ptr, size_t size,
+ GError **error_r)
{
int fd = GPOINTER_TO_INT(is->data);
ssize_t nbytes;
nbytes = read(fd, ptr, size);
if (nbytes < 0) {
- is->error = errno;
- g_debug("input_file_read: error reading: %s\n",
- strerror(is->error));
+ g_set_error(error_r, file_quark(), errno,
+ "Failed to read: %s", g_strerror(errno));
return 0;
}