diff options
author | Elliott Hughes <enh@google.com> | 2016-01-26 14:13:04 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2016-01-26 14:45:13 -0800 |
commit | 03e65eb03bf0bfaafa797daf91e80e8308968db3 (patch) | |
tree | 9f3158666a6a63833a0ae6beb23f3e0979de1fd8 /libc/stdio/stdio.cpp | |
parent | ced73ee45e04a991ce1295a38364568a17884eed (diff) |
Implement funopen64.
Bug: http://b/24807045
Change-Id: I161920978161389be34b707cc6ce8e05f760d552
Diffstat (limited to 'libc/stdio/stdio.cpp')
-rw-r--r-- | libc/stdio/stdio.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp index 23b69715a..2139621cc 100644 --- a/libc/stdio/stdio.cpp +++ b/libc/stdio/stdio.cpp @@ -538,3 +538,56 @@ int fgetpos64(FILE* fp, fpos64_t* pos) { *pos = ftello64(fp); return (*pos == -1); } + +static FILE* __funopen(const void* cookie, + int (*read_fn)(void*, char*, int), + int (*write_fn)(void*, const char*, int), + int (*close_fn)(void*)) { + if (read_fn == nullptr && write_fn == nullptr) { + errno = EINVAL; + return nullptr; + } + + FILE* fp = __sfp(); + if (fp == nullptr) return nullptr; + + if (read_fn != nullptr && write_fn != nullptr) { + fp->_flags = __SRW; + } else if (read_fn != nullptr) { + fp->_flags = __SRD; + } else if (write_fn != nullptr) { + fp->_flags = __SWR; + } + + fp->_file = -1; + fp->_cookie = const_cast<void*>(cookie); // The funopen(3) API is incoherent. + fp->_read = read_fn; + fp->_write = write_fn; + fp->_close = close_fn; + + return fp; +} + +FILE* funopen(const void* cookie, + int (*read_fn)(void*, char*, int), + int (*write_fn)(void*, const char*, int), + fpos_t (*seek_fn)(void*, fpos_t, int), + int (*close_fn)(void*)) { + FILE* fp = __funopen(cookie, read_fn, write_fn, close_fn); + if (fp != nullptr) { + fp->_seek = seek_fn; + } + return fp; +} + +FILE* funopen64(const void* cookie, + int (*read_fn)(void*, char*, int), + int (*write_fn)(void*, const char*, int), + fpos64_t (*seek_fn)(void*, fpos64_t, int), + int (*close_fn)(void*)) { + FILE* fp = __funopen(cookie, read_fn, write_fn, close_fn); + if (fp != nullptr) { + _EXT(fp)->_seek64 = seek_fn; + } + return fp; +} |