From b4f7616fd618875768b8fffc122b58bdb84a9969 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 19 Sep 2013 16:27:24 -0700 Subject: [PATCH] Ensure we have the off64_t variant of every function that takes an off_t. Change-Id: Ib2eee0cf13162be3b62559b84e90c6dcf5aab1c3 --- libc/SYSCALLS.TXT | 6 ++- libc/arch-arm/syscalls.mk | 2 + libc/arch-arm/syscalls/sendfile64.S | 15 +++++++ libc/arch-arm/syscalls/truncate64.S | 15 +++++++ libc/arch-mips/syscalls.mk | 2 + libc/arch-mips/syscalls/sendfile64.S | 22 ++++++++++ libc/arch-mips/syscalls/truncate64.S | 22 ++++++++++ libc/arch-x86/syscalls.mk | 2 + libc/arch-x86/syscalls/sendfile64.S | 30 +++++++++++++ libc/arch-x86/syscalls/truncate64.S | 27 ++++++++++++ libc/bionic/lseek64.c | 16 +++---- libc/include/sys/sendfile.h | 4 +- libc/include/sys/types.h | 2 +- libc/include/unistd.h | 1 + tests/Android.mk | 1 + tests/TemporaryFile.h | 38 +++++++++++++++++ tests/sys_sendfile_test.cpp | 64 ++++++++++++++++++++++++++++ tests/unistd_test.cpp | 41 ++++++++++++++++++ 18 files changed, 298 insertions(+), 12 deletions(-) create mode 100644 libc/arch-arm/syscalls/sendfile64.S create mode 100644 libc/arch-arm/syscalls/truncate64.S create mode 100644 libc/arch-mips/syscalls/sendfile64.S create mode 100644 libc/arch-mips/syscalls/truncate64.S create mode 100644 libc/arch-x86/syscalls/sendfile64.S create mode 100644 libc/arch-x86/syscalls/truncate64.S create mode 100644 tests/TemporaryFile.h create mode 100644 tests/sys_sendfile_test.cpp diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 88c980f6c..132e3837d 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -118,7 +118,7 @@ int __openat:openat (int, const char*, int, mode_t) 1 int close (int) 1 int creat(const char*, mode_t) stub off_t lseek(int, off_t, int) 1 -int __llseek:_llseek (int, unsigned long, unsigned long, loff_t*, int) 1 +int __llseek:_llseek (int, unsigned long, unsigned long, off64_t*, int) 1 pid_t getpid () 1 void * mmap(void *, size_t, int, int, int, long) stub void * __mmap2:mmap2(void*, size_t, int, int, int, long) 1 @@ -153,7 +153,8 @@ int fchown:fchown(int, uid_t, gid_t) -1,-1,1 void sync(void) 1 int __fcntl64:fcntl64(int, int, void *) 1 int __fstatfs64:fstatfs64(int, size_t, struct statfs *) 1 -ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) 1 +ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) 1 +ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count) 1 int fstatat:fstatat64(int dirfd, const char *path, struct stat *buf, int flags) 1 int mkdirat(int dirfd, const char *pathname, mode_t mode) 1 int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags) 1 @@ -191,6 +192,7 @@ int faccessat(int, const char *, int, int) 1 int symlink(const char *, const char *) 1 int fchdir(int) 1 int truncate(const char*, off_t) 1 +int truncate64(const char*, off64_t) 1 int setxattr(const char *, const char *, const void *, size_t, int) 1 int lsetxattr(const char *, const char *, const void *, size_t, int) 1 ssize_t getxattr(const char *, const char *, void *, size_t) 1 diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 252a428c4..33e520f07 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -84,6 +84,7 @@ syscall_src += arch-arm/syscalls/sync.S syscall_src += arch-arm/syscalls/__fcntl64.S syscall_src += arch-arm/syscalls/__fstatfs64.S syscall_src += arch-arm/syscalls/sendfile.S +syscall_src += arch-arm/syscalls/sendfile64.S syscall_src += arch-arm/syscalls/fstatat.S syscall_src += arch-arm/syscalls/mkdirat.S syscall_src += arch-arm/syscalls/fchownat.S @@ -116,6 +117,7 @@ syscall_src += arch-arm/syscalls/faccessat.S syscall_src += arch-arm/syscalls/symlink.S syscall_src += arch-arm/syscalls/fchdir.S syscall_src += arch-arm/syscalls/truncate.S +syscall_src += arch-arm/syscalls/truncate64.S syscall_src += arch-arm/syscalls/setxattr.S syscall_src += arch-arm/syscalls/lsetxattr.S syscall_src += arch-arm/syscalls/getxattr.S diff --git a/libc/arch-arm/syscalls/sendfile64.S b/libc/arch-arm/syscalls/sendfile64.S new file mode 100644 index 000000000..87de344f6 --- /dev/null +++ b/libc/arch-arm/syscalls/sendfile64.S @@ -0,0 +1,15 @@ +/* autogenerated by gensyscalls.py */ +#include +#include +#include + +ENTRY(sendfile64) + mov ip, r7 + ldr r7, =__NR_sendfile64 + swi #0 + mov r7, ip + cmn r0, #(MAX_ERRNO + 1) + bxls lr + neg r0, r0 + b __set_errno +END(sendfile64) diff --git a/libc/arch-arm/syscalls/truncate64.S b/libc/arch-arm/syscalls/truncate64.S new file mode 100644 index 000000000..059bd9716 --- /dev/null +++ b/libc/arch-arm/syscalls/truncate64.S @@ -0,0 +1,15 @@ +/* autogenerated by gensyscalls.py */ +#include +#include +#include + +ENTRY(truncate64) + mov ip, r7 + ldr r7, =__NR_truncate64 + swi #0 + mov r7, ip + cmn r0, #(MAX_ERRNO + 1) + bxls lr + neg r0, r0 + b __set_errno +END(truncate64) diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index 23393a244..b34b0a9d6 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -87,6 +87,7 @@ syscall_src += arch-mips/syscalls/sync.S syscall_src += arch-mips/syscalls/__fcntl64.S syscall_src += arch-mips/syscalls/__fstatfs64.S syscall_src += arch-mips/syscalls/sendfile.S +syscall_src += arch-mips/syscalls/sendfile64.S syscall_src += arch-mips/syscalls/fstatat.S syscall_src += arch-mips/syscalls/mkdirat.S syscall_src += arch-mips/syscalls/fchownat.S @@ -119,6 +120,7 @@ syscall_src += arch-mips/syscalls/faccessat.S syscall_src += arch-mips/syscalls/symlink.S syscall_src += arch-mips/syscalls/fchdir.S syscall_src += arch-mips/syscalls/truncate.S +syscall_src += arch-mips/syscalls/truncate64.S syscall_src += arch-mips/syscalls/setxattr.S syscall_src += arch-mips/syscalls/lsetxattr.S syscall_src += arch-mips/syscalls/getxattr.S diff --git a/libc/arch-mips/syscalls/sendfile64.S b/libc/arch-mips/syscalls/sendfile64.S new file mode 100644 index 000000000..5b747090b --- /dev/null +++ b/libc/arch-mips/syscalls/sendfile64.S @@ -0,0 +1,22 @@ +/* autogenerated by gensyscalls.py */ +#include + .text + .globl sendfile64 + .align 4 + .ent sendfile64 + +sendfile64: + .set noreorder + .cpload $t9 + li $v0, __NR_sendfile64 + syscall + bnez $a3, 1f + move $a0, $v0 + j $ra + nop +1: + la $t9,__set_errno + j $t9 + nop + .set reorder + .end sendfile64 diff --git a/libc/arch-mips/syscalls/truncate64.S b/libc/arch-mips/syscalls/truncate64.S new file mode 100644 index 000000000..57f0b5fd5 --- /dev/null +++ b/libc/arch-mips/syscalls/truncate64.S @@ -0,0 +1,22 @@ +/* autogenerated by gensyscalls.py */ +#include + .text + .globl truncate64 + .align 4 + .ent truncate64 + +truncate64: + .set noreorder + .cpload $t9 + li $v0, __NR_truncate64 + syscall + bnez $a3, 1f + move $a0, $v0 + j $ra + nop +1: + la $t9,__set_errno + j $t9 + nop + .set reorder + .end truncate64 diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 11573de6c..7180cf2f2 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -88,6 +88,7 @@ syscall_src += arch-x86/syscalls/sync.S syscall_src += arch-x86/syscalls/__fcntl64.S syscall_src += arch-x86/syscalls/__fstatfs64.S syscall_src += arch-x86/syscalls/sendfile.S +syscall_src += arch-x86/syscalls/sendfile64.S syscall_src += arch-x86/syscalls/fstatat.S syscall_src += arch-x86/syscalls/mkdirat.S syscall_src += arch-x86/syscalls/fchownat.S @@ -120,6 +121,7 @@ syscall_src += arch-x86/syscalls/faccessat.S syscall_src += arch-x86/syscalls/symlink.S syscall_src += arch-x86/syscalls/fchdir.S syscall_src += arch-x86/syscalls/truncate.S +syscall_src += arch-x86/syscalls/truncate64.S syscall_src += arch-x86/syscalls/setxattr.S syscall_src += arch-x86/syscalls/lsetxattr.S syscall_src += arch-x86/syscalls/getxattr.S diff --git a/libc/arch-x86/syscalls/sendfile64.S b/libc/arch-x86/syscalls/sendfile64.S new file mode 100644 index 000000000..9731806a2 --- /dev/null +++ b/libc/arch-x86/syscalls/sendfile64.S @@ -0,0 +1,30 @@ +/* autogenerated by gensyscalls.py */ +#include +#include +#include + +ENTRY(sendfile64) + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + mov 20(%esp), %ebx + mov 24(%esp), %ecx + mov 28(%esp), %edx + mov 32(%esp), %esi + movl $__NR_sendfile64, %eax + int $0x80 + cmpl $-MAX_ERRNO, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax +1: + popl %esi + popl %edx + popl %ecx + popl %ebx + ret +END(sendfile64) diff --git a/libc/arch-x86/syscalls/truncate64.S b/libc/arch-x86/syscalls/truncate64.S new file mode 100644 index 000000000..f9118bba8 --- /dev/null +++ b/libc/arch-x86/syscalls/truncate64.S @@ -0,0 +1,27 @@ +/* autogenerated by gensyscalls.py */ +#include +#include +#include + +ENTRY(truncate64) + pushl %ebx + pushl %ecx + pushl %edx + mov 16(%esp), %ebx + mov 20(%esp), %ecx + mov 24(%esp), %edx + movl $__NR_truncate64, %eax + int $0x80 + cmpl $-MAX_ERRNO, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax +1: + popl %edx + popl %ecx + popl %ebx + ret +END(truncate64) diff --git a/libc/bionic/lseek64.c b/libc/bionic/lseek64.c index db0c41352..c24ae64bf 100644 --- a/libc/bionic/lseek64.c +++ b/libc/bionic/lseek64.c @@ -25,16 +25,16 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #include -extern int __llseek(int fd, unsigned long offset_hi, unsigned long offset_lo, loff_t* result, int whence); +extern int __llseek(int fd, unsigned long offset_hi, unsigned long offset_lo, off64_t* result, int whence); -off64_t lseek64(int fd, off64_t off, int whence) -{ - loff_t result; +off64_t lseek64(int fd, off64_t off, int whence) { + off64_t result; + if (__llseek(fd, (unsigned long)(off >> 32),(unsigned long)(off), &result, whence) < 0) { + return -1; + } - if ( __llseek(fd, (unsigned long)(off >> 32),(unsigned long)(off), &result, whence ) < 0 ) - return -1; - - return result; + return result; } diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h index d5aba269d..81a3c44d5 100644 --- a/libc/include/sys/sendfile.h +++ b/libc/include/sys/sendfile.h @@ -25,6 +25,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #ifndef _SYS_SENDFILE_H_ #define _SYS_SENDFILE_H_ @@ -33,7 +34,8 @@ __BEGIN_DECLS -extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); +extern ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count); +extern ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count); __END_DECLS diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h index a0ce405b4..8b7fea869 100644 --- a/libc/include/sys/types.h +++ b/libc/include/sys/types.h @@ -65,7 +65,7 @@ typedef __kernel_nlink_t nlink_t; typedef __kernel_off_t off_t; #endif typedef __kernel_loff_t loff_t; -typedef loff_t off64_t; /* GLibc-specific */ +typedef loff_t off64_t; typedef __kernel_pid_t pid_t; diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 61d3d6edc..60964f0f7 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -122,6 +122,7 @@ extern int chown(const char *, uid_t, gid_t); extern int fchown(int, uid_t, gid_t); extern int lchown(const char *, uid_t, gid_t); extern int truncate(const char *, off_t); +extern int truncate64(const char *, off64_t); extern char *getcwd(char *, size_t); extern int sync(void); diff --git a/tests/Android.mk b/tests/Android.mk index 39e94095d..e60b90893 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -80,6 +80,7 @@ test_src_files = \ string_test.cpp \ strings_test.cpp \ stubs_test.cpp \ + sys_sendfile_test.cpp \ sys_stat_test.cpp \ system_properties_test.cpp \ time_test.cpp \ diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h new file mode 100644 index 000000000..878fb13dc --- /dev/null +++ b/tests/TemporaryFile.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +class TemporaryFile { + public: + TemporaryFile() { +#if __BIONIC__ + const char* tmp_dir = "/data/local/tmp"; +#else + const char* tmp_dir = "/tmp"; +#endif + snprintf(filename, sizeof(filename), "%s/TemporaryFile-XXXXXX", tmp_dir); + fd = mkstemp(filename); + } + + ~TemporaryFile() { + close(fd); + unlink(filename); + } + + int fd; + char filename[1024]; +}; diff --git a/tests/sys_sendfile_test.cpp b/tests/sys_sendfile_test.cpp new file mode 100644 index 000000000..bf23d3d8d --- /dev/null +++ b/tests/sys_sendfile_test.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "TemporaryFile.h" + +#include +#include +#include +#include +#include + +TEST(sys_sendfile, sendfile) { + TemporaryFile src_file; + ASSERT_EQ(5, TEMP_FAILURE_RETRY(write(src_file.fd, "hello", 5))); + + TemporaryFile dst_file; + + off_t offset = 2; + size_t count = 2; + ssize_t rc = sendfile(dst_file.fd, src_file.fd, &offset, count); + ASSERT_EQ(2, rc); + ASSERT_EQ(4, offset); + + ASSERT_EQ(0, lseek(dst_file.fd, 0, SEEK_SET)); + char buf[3]; + buf[2] = '\0'; + ASSERT_EQ(2, TEMP_FAILURE_RETRY(read(dst_file.fd, &buf, 2))); + ASSERT_STREQ("ll", buf); +} + +#if __BIONIC__ +TEST(sys_sendfile, sendfile64) { + TemporaryFile src_file; + ASSERT_EQ(5, TEMP_FAILURE_RETRY(write(src_file.fd, "hello", 5))); + + TemporaryFile dst_file; + + off64_t offset = 2; + size_t count = 2; + ssize_t rc = sendfile64(dst_file.fd, src_file.fd, &offset, count); + ASSERT_EQ(2, rc); + ASSERT_EQ(4, offset); + + ASSERT_EQ(0, lseek(dst_file.fd, 0, SEEK_SET)); + char buf[3]; + buf[2] = '\0'; + ASSERT_EQ(2, TEMP_FAILURE_RETRY(read(dst_file.fd, &buf, 2))); + ASSERT_STREQ("ll", buf); +} +#endif diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp index 3ccaf3bed..319308360 100644 --- a/tests/unistd_test.cpp +++ b/tests/unistd_test.cpp @@ -15,6 +15,7 @@ */ #include +#include "TemporaryFile.h" #include #include @@ -32,3 +33,43 @@ TEST(unistd, sbrk) { void* final_break = sbrk(0); ASSERT_EQ(final_break, new_break); } + +TEST(unistd, truncate) { + TemporaryFile tf; + ASSERT_EQ(0, close(tf.fd)); + ASSERT_EQ(0, truncate(tf.filename, 123)); + + struct stat sb; + ASSERT_EQ(0, stat(tf.filename, &sb)); + ASSERT_EQ(123, sb.st_size); +} + +TEST(unistd, truncate64) { + TemporaryFile tf; + ASSERT_EQ(0, close(tf.fd)); + ASSERT_EQ(0, truncate64(tf.filename, 123)); + + struct stat sb; + ASSERT_EQ(0, stat(tf.filename, &sb)); + ASSERT_EQ(123, sb.st_size); +} + +TEST(unistd, ftruncate) { + TemporaryFile tf; + ASSERT_EQ(0, ftruncate(tf.fd, 123)); + ASSERT_EQ(0, close(tf.fd)); + + struct stat sb; + ASSERT_EQ(0, stat(tf.filename, &sb)); + ASSERT_EQ(123, sb.st_size); +} + +TEST(unistd, ftruncate64) { + TemporaryFile tf; + ASSERT_EQ(0, ftruncate64(tf.fd, 123)); + ASSERT_EQ(0, close(tf.fd)); + + struct stat sb; + ASSERT_EQ(0, stat(tf.filename, &sb)); + ASSERT_EQ(123, sb.st_size); +}