diff options
Diffstat (limited to 'lib/io')
-rw-r--r-- | lib/io/src/unix/istream.c | 39 | ||||
-rw-r--r-- | lib/io/src/unix/ostream.c | 49 | ||||
-rw-r--r-- | lib/io/src/win32/istream.c | 76 | ||||
-rw-r--r-- | lib/io/src/win32/ostream.c | 136 |
4 files changed, 131 insertions, 169 deletions
diff --git a/lib/io/src/unix/istream.c b/lib/io/src/unix/istream.c index 60abff1..e96bc6c 100644 --- a/lib/io/src/unix/istream.c +++ b/lib/io/src/unix/istream.c @@ -105,7 +105,7 @@ static void file_destroy(sqfs_object_t *obj) free(file); } -istream_t *istream_open_file(const char *path) +istream_t *istream_open_handle(const char *path, int fd) { file_istream_t *file = calloc(1, sizeof(*file)); istream_t *strm = (istream_t *)file; @@ -123,11 +123,12 @@ istream_t *istream_open_file(const char *path) goto fail_free; } - file->fd = open(path, O_RDONLY); + file->fd = dup(fd); if (file->fd < 0) { perror(path); goto fail_path; } + close(fd); strm->get_buffered_data = file_get_buffered_data; strm->advance_buffer = file_advance_buffer; @@ -140,27 +141,25 @@ fail_free: return NULL; } -istream_t *istream_open_stdin(void) +istream_t *istream_open_file(const char *path) { - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; + istream_t *out; + int fd; - if (file == NULL) - goto fail; + fd = open(path, O_RDONLY); + if (fd < 0) { + perror(path); + return NULL; + } - sqfs_object_init(file, file_destroy, NULL); + out = istream_open_handle(path, fd); + if (out == NULL) + close(fd); - file->path = strdup("stdin"); - if (file->path == NULL) - goto fail; + return out; +} - file->fd = STDIN_FILENO; - strm->get_buffered_data = file_get_buffered_data; - strm->advance_buffer = file_advance_buffer; - strm->get_filename = file_get_filename; - return strm; -fail: - perror("creating file wrapper for stdin"); - free(file); - return NULL; +istream_t *istream_open_stdin(void) +{ + return istream_open_handle("stdin", STDIN_FILENO); } diff --git a/lib/io/src/unix/ostream.c b/lib/io/src/unix/ostream.c index 5ef2af2..294a15e 100644 --- a/lib/io/src/unix/ostream.c +++ b/lib/io/src/unix/ostream.c @@ -90,9 +90,7 @@ static void file_destroy(sqfs_object_t *obj) { file_ostream_t *file = (file_ostream_t *)obj; - if (file->fd != STDOUT_FILENO) - close(file->fd); - + close(file->fd); free(file->path); free(file); } @@ -104,7 +102,7 @@ static const char *file_get_filename(ostream_t *strm) return file->path; } -ostream_t *ostream_open_file(const char *path, int flags) +ostream_t *ostream_open_handle(const char *path, int fd, int flags) { file_ostream_t *file = calloc(1, sizeof(*file)); ostream_t *strm = (ostream_t *)file; @@ -122,17 +120,14 @@ ostream_t *ostream_open_file(const char *path, int flags) goto fail_free; } - if (flags & OSTREAM_OPEN_OVERWRITE) { - file->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - } else { - file->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); - } - + file->fd = dup(fd); if (file->fd < 0) { perror(path); goto fail_path; } + close(fd); + if (flags & OSTREAM_OPEN_SPARSE) strm->append_sparse = file_append_sparse; @@ -147,27 +142,25 @@ fail_free: return NULL; } -ostream_t *ostream_open_stdout(void) +ostream_t *ostream_open_file(const char *path, int flags) { - file_ostream_t *file = calloc(1, sizeof(*file)); - ostream_t *strm = (ostream_t *)file; + ostream_t *out; + int fd; - if (file == NULL) - goto fail; + if (flags & OSTREAM_OPEN_OVERWRITE) { + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + } else { + fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); + } - file->path = strdup("stdout"); - if (file->path == NULL) - goto fail; + out = ostream_open_handle(path, fd, flags); + if (out == NULL) + close(fd); - file->fd = STDOUT_FILENO; - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; + return out; +} - sqfs_object_init(file, file_destroy, NULL); - return strm; -fail: - perror("creating file wrapper for stdout"); - free(file); - return NULL; +ostream_t *ostream_open_stdout(void) +{ + return ostream_open_handle("stdout", STDOUT_FILENO, 0); } diff --git a/lib/io/src/win32/istream.c b/lib/io/src/win32/istream.c index 0d002cc..46bed30 100644 --- a/lib/io/src/win32/istream.c +++ b/lib/io/src/win32/istream.c @@ -24,7 +24,6 @@ static int precache(istream_t *strm) { file_istream_t *file = (file_istream_t *)strm; DWORD diff, actual; - HANDLE hnd; if (file->eof) return 0; @@ -38,12 +37,10 @@ static int precache(istream_t *strm) file->buffer_used -= file->buffer_offset; file->buffer_offset = 0; - hnd = file->path == NULL ? GetStdHandle(STD_INPUT_HANDLE) : file->hnd; - while (file->buffer_used < sizeof(file->buffer)) { diff = sizeof(file->buffer) - file->buffer_used; - if (!ReadFile(hnd, file->buffer + file->buffer_used, + if (!ReadFile(file->hnd, file->buffer + file->buffer_used, diff, &actual, NULL)) { DWORD error = GetLastError(); @@ -54,8 +51,7 @@ static int precache(istream_t *strm) } SetLastError(error); - - w32_perror(file->path == NULL ? "stdin" : file->path); + w32_perror(file->path); return -1; } @@ -103,28 +99,23 @@ static void file_advance_buffer(istream_t *strm, size_t count) static const char *file_get_filename(istream_t *strm) { - file_istream_t *file = (file_istream_t *)strm; - - return file->path == NULL ? "stdin" : file->path; + return ((file_istream_t *)strm)->path; } static void file_destroy(sqfs_object_t *obj) { file_istream_t *file = (file_istream_t *)obj; - if (file->path != NULL) { - CloseHandle(file->hnd); - free(file->path); - } - + CloseHandle(file->hnd); + free(file->path); free(file); } -istream_t *istream_open_file(const char *path) +istream_t *istream_open_handle(const char *path, HANDLE hnd) { file_istream_t *file = calloc(1, sizeof(*file)); istream_t *strm = (istream_t *)file; - WCHAR *wpath = NULL; + BOOL ret; if (file == NULL) { perror(path); @@ -133,25 +124,21 @@ istream_t *istream_open_file(const char *path) sqfs_object_init(file, file_destroy, NULL); - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - file->path = strdup(path); if (file->path == NULL) { perror(path); goto fail_free; } - file->hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { - perror(path); + ret = DuplicateHandle(GetCurrentProcess(), hnd, + GetCurrentProcess(), &file->hnd, + 0, FALSE, DUPLICATE_SAME_ACCESS); + if (!ret) { + w32_perror(path); goto fail_path; } - free(wpath); + CloseHandle(hnd); strm->get_buffered_data = file_get_buffered_data; strm->advance_buffer = file_advance_buffer; @@ -160,25 +147,40 @@ istream_t *istream_open_file(const char *path) fail_path: free(file->path); fail_free: - free(wpath); free(file); return NULL; } -istream_t *istream_open_stdin(void) +istream_t *istream_open_file(const char *path) { - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; + WCHAR *wpath = path_to_windows(path); + istream_t *out; + HANDLE hnd; - if (file == NULL) { - perror("stdin"); + if (wpath == NULL) + return NULL; + + hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hnd == INVALID_HANDLE_VALUE) { + w32_perror(path); + free(wpath); return NULL; } - sqfs_object_init(file, file_destroy, NULL); + free(wpath); - strm->get_buffered_data = file_get_buffered_data; - strm->advance_buffer = file_advance_buffer; - strm->get_filename = file_get_filename; - return strm; + out = istream_open_handle(path, hnd); + if (out == NULL) + CloseHandle(hnd); + + return out; +} + +istream_t *istream_open_stdin(void) +{ + HANDLE hnd = GetStdHandle(STD_INPUT_HANDLE); + + return istream_open_handle("stdin", hnd); } diff --git a/lib/io/src/win32/ostream.c b/lib/io/src/win32/ostream.c index 0fe04f3..d18130f 100644 --- a/lib/io/src/win32/ostream.c +++ b/lib/io/src/win32/ostream.c @@ -15,14 +15,14 @@ typedef struct { HANDLE hnd; } file_ostream_t; -static int w32_append(HANDLE hnd, const char *filename, - const void *data, size_t size) +static int file_append(ostream_t *strm, const void *data, size_t size) { + file_ostream_t *file = (file_ostream_t *)strm; DWORD diff; while (size > 0) { - if (!WriteFile(hnd, data, size, &diff, NULL)) { - w32_perror(filename); + if (!WriteFile(file->hnd, data, size, &diff, NULL)) { + w32_perror(file->path); return -1; } @@ -33,25 +33,6 @@ static int w32_append(HANDLE hnd, const char *filename, return 0; } -static int w32_flush(HANDLE hnd, const char *filename) -{ - if (!FlushFileBuffers(hnd)) { - w32_perror(filename); - return -1; - } - - return 0; -} - -/*****************************************************************************/ - -static int file_append(ostream_t *strm, const void *data, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return w32_append(file->hnd, file->path, data, size); -} - static int file_append_sparse(ostream_t *strm, size_t size) { file_ostream_t *file = (file_ostream_t *)strm; @@ -75,7 +56,12 @@ static int file_flush(ostream_t *strm) { file_ostream_t *file = (file_ostream_t *)strm; - return w32_flush(file->hnd, file->path); + if (!FlushFileBuffers(file->hnd)) { + w32_perror(file->path); + return -1; + } + + return 0; } static void file_destroy(sqfs_object_t *obj) @@ -94,41 +80,11 @@ static const char *file_get_filename(ostream_t *strm) return file->path; } -/*****************************************************************************/ - -static int stdout_append(ostream_t *strm, const void *data, size_t size) -{ - (void)strm; - return w32_append(GetStdHandle(STD_OUTPUT_HANDLE), "stdout", - data, size); -} - -static int stdout_flush(ostream_t *strm) -{ - (void)strm; - return w32_flush(GetStdHandle(STD_OUTPUT_HANDLE), "stdout"); -} - -static void stdout_destroy(sqfs_object_t *obj) -{ - free(obj); -} - -static const char *stdout_get_filename(ostream_t *strm) -{ - (void)strm; - return "stdout"; -} - -/*****************************************************************************/ - -ostream_t *ostream_open_file(const char *path, int flags) +ostream_t *ostream_open_handle(const char *path, HANDLE hnd, int flags) { file_ostream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; ostream_t *strm = (ostream_t *)file; - int access_flags, creation_mode; - WCHAR *wpath = NULL; + BOOL ret; if (file == NULL) { perror(path); @@ -137,33 +93,21 @@ ostream_t *ostream_open_file(const char *path, int flags) sqfs_object_init(file, file_destroy, NULL); - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - file->path = strdup(path); if (file->path == NULL) { perror(path); goto fail_free; } - access_flags = GENERIC_WRITE; - - if (flags & OSTREAM_OPEN_OVERWRITE) { - creation_mode = CREATE_ALWAYS; - } else { - creation_mode = CREATE_NEW; - } - - file->hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { + ret = DuplicateHandle(GetCurrentProcess(), hnd, + GetCurrentProcess(), &file->hnd, + 0, FALSE, DUPLICATE_SAME_ACCESS); + if (!ret) { w32_perror(path); goto fail_path; } - free(wpath); + CloseHandle(hnd); if (flags & OSTREAM_OPEN_SPARSE) strm->append_sparse = file_append_sparse; @@ -176,24 +120,48 @@ fail_path: free(file->path); fail_free: free(file); - free(wpath); return NULL; } -ostream_t *ostream_open_stdout(void) +ostream_t *ostream_open_file(const char *path, int flags) { - ostream_t *strm = calloc(1, sizeof(*strm)); - sqfs_object_t *obj = (sqfs_object_t *)strm; + WCHAR *wpath = path_to_windows(path); + int access_flags, creation_mode; + ostream_t *out; + HANDLE hnd; - if (strm == NULL) { - perror("creating stdout file wrapper"); + if (wpath == NULL) return NULL; + + access_flags = GENERIC_WRITE; + + if (flags & OSTREAM_OPEN_OVERWRITE) { + creation_mode = CREATE_ALWAYS; + } else { + creation_mode = CREATE_NEW; } - sqfs_object_init(strm, stdout_destroy, NULL); + hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, + FILE_ATTRIBUTE_NORMAL, NULL); - strm->append = stdout_append; - strm->flush = stdout_flush; - strm->get_filename = stdout_get_filename; - return strm; + if (hnd == INVALID_HANDLE_VALUE) { + w32_perror(path); + free(wpath); + return NULL; + } + + free(wpath); + + out = ostream_open_handle(path, hnd, flags); + if (out == NULL) + CloseHandle(hnd); + + return out; +} + +ostream_t *ostream_open_stdout(void) +{ + HANDLE hnd = GetStdHandle(STD_OUTPUT_HANDLE); + + return ostream_open_handle("stdout", hnd, 0); } |