summaryrefslogtreecommitdiff
path: root/libc/stdio/stdio.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2016-01-26 18:25:52 -0800
committerElliott Hughes <enh@google.com>2016-01-26 18:25:52 -0800
commit955426ef79ae635b74ff917c2b9ebc1a24c6a3ef (patch)
tree76d5403eaa41b9a00aa4447ae5700eb77170310f /libc/stdio/stdio.cpp
parent194860a9e638b1d093857f08b8fad37c9ec0e113 (diff)
Fix a sign extension bug in stdio.
This also lets us test the EOVERFLOW behavior, which pointed out that the fgetpos/fsetpos return on failure has always been wrong... Bug: http://b/24807045 Change-Id: I35273eb07c8c9155af858adb27569983397580b6
Diffstat (limited to 'libc/stdio/stdio.cpp')
-rw-r--r--libc/stdio/stdio.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 2139621cc..16cbd555c 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -426,7 +426,12 @@ static off64_t __seek_unlocked(FILE* fp, off64_t offset, int whence) {
if (_EXT(fp)->_seek64 != nullptr) {
return (*_EXT(fp)->_seek64)(fp->_cookie, offset, whence);
} else if (fp->_seek != nullptr) {
- return (*fp->_seek)(fp->_cookie, offset, whence);
+ off64_t result = (*fp->_seek)(fp->_cookie, offset, whence);
+#if !defined(__LP64__)
+ // Avoid sign extension if off64_t is larger than off_t.
+ if (result != -1) result &= 0xffffffff;
+#endif
+ return result;
} else {
errno = ESPIPE;
return -1;
@@ -531,12 +536,12 @@ off64_t ftello64(FILE* fp) {
int fgetpos(FILE* fp, fpos_t* pos) {
*pos = ftello(fp);
- return (*pos == -1);
+ return (*pos == -1) ? -1 : 0;
}
int fgetpos64(FILE* fp, fpos64_t* pos) {
*pos = ftello64(fp);
- return (*pos == -1);
+ return (*pos == -1) ? -1 : 0;
}
static FILE* __funopen(const void* cookie,