Implement some of the missing LFS64 support.

This gives us:

* <dirent.h>
  struct dirent64
  readdir64, readdir64_r, alphasort64, scandir64

* <fcntl.h>
  creat64, openat64, open64.

* <sys/stat.h>
  struct stat64
  fstat64, fstatat64, lstat64, stat64.

* <sys/statvfs.h>
  struct statvfs64
  statvfs64, fstatvfs64.

* <sys/vfs.h>
  struct statfs64
  statfs64, fstatfs64.

This also removes some of the incorrect #define hacks we've had in the
past (for stat64, for example, which we promised to clean up way back
in bug 8472078).

Bug: 11865851
Bug: 8472078
Change-Id: Ia46443521918519f2dfa64d4621027dfd13ac566
This commit is contained in:
Elliott Hughes 2014-01-17 18:42:49 -08:00
parent 3623d80675
commit db1ea34748
39 changed files with 456 additions and 319 deletions

View file

@ -378,7 +378,6 @@ libc_upstream_freebsd_src_files := \
libc_upstream_netbsd_src_files := \
upstream-netbsd/common/lib/libc/hash/sha1/sha1.c \
upstream-netbsd/common/lib/libc/inet/inet_addr.c \
upstream-netbsd/libc/compat-43/creat.c \
upstream-netbsd/libc/gen/ftw.c \
upstream-netbsd/libc/gen/nftw.c \
upstream-netbsd/libc/gen/nice.c \

View file

@ -127,8 +127,6 @@ int fdatasync(int) all
int fchown:fchown32(int, uid_t, gid_t) arm,x86
int fchown:fchown(int, uid_t, gid_t) arm64,mips,mips64,x86_64
void sync(void) all
int __fstatfs64:fstatfs64(int, size_t, struct statfs*) arm,mips,x86
int fstatfs(int, struct statfs*) arm64,mips64,x86_64
int fsetxattr(int, const char*, const void*, size_t, int) all
ssize_t fgetxattr(int, const char*, void*, size_t) all
ssize_t flistxattr(int, char*, size_t) all
@ -145,8 +143,8 @@ int __openat:openat(int, const char*, int, mode_t) all
int faccessat(int, const char*, int, int) all
int fchmodat(int, const char*, mode_t, int) all
int fchownat(int, const char*, uid_t, gid_t, int) all
int fstatat:fstatat64(int, const char*, struct stat*, int) arm,mips,x86
int fstatat:newfstatat(int, const char*, struct stat*, int) arm64,mips64,x86_64
int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int) arm,mips,x86
int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int) arm64,mips64,x86_64
int linkat(int, const char*, int, const char*, int) all
int mkdirat(int, const char*, mode_t) all
int mknodat(int, const char*, mode_t, dev_t) all
@ -179,12 +177,18 @@ void* mmap|mmap64(void*, size_t, int, int, int, off_t) arm64,mips64,x86_64
int fallocate64:fallocate(int, int, off64_t, off64_t) arm,mips,x86
int fallocate|fallocate64(int, int, off_t, off_t) arm64,mips64,x86_64
int __fstatfs64:fstatfs64(int, size_t, struct statfs*) arm,mips,x86
int fstatfs64|fstatfs:fstatfs(int, struct statfs*) arm64,mips64,x86_64
int __statfs64:statfs64(const char*, size_t, struct statfs*) arm,mips,x86
int statfs64|statfs:statfs(const char*, struct statfs*) arm64,mips64,x86_64
int fstat64|fstat:fstat64(int, struct stat*) arm,mips,x86
int fstat64|fstat:fstat(int, struct stat*) arm64,mips64,x86_64
# file system
int chdir(const char*) all
int mount(const char*, const char*, const char*, unsigned long, const void*) all
int umount2(const char*, int) all
int fstat:fstat64(int, struct stat*) arm,mips,x86
int fstat(int, struct stat*) arm64,mips64,x86_64
int __getcwd:getcwd(char* buf, size_t size) all
int fchdir(int) all
int setxattr(const char*, const char*, const void*, size_t, int) all
@ -195,8 +199,6 @@ ssize_t listxattr(const char*, char*, size_t) all
ssize_t llistxattr(const char*, char*, size_t) all
int removexattr(const char*, const char*) all
int lremovexattr(const char*, const char*) all
int __statfs64:statfs64(const char*, size_t, struct statfs*) arm,mips,x86
int statfs(const char*, struct statfs*) arm64,mips64,x86_64
int swapon(const char*, int) all
int swapoff(const char*) all

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstat)
ENTRY(fstat64)
mov ip, r7
ldr r7, =__NR_fstat64
swi #0
@ -11,4 +11,7 @@ ENTRY(fstat)
bxls lr
neg r0, r0
b __set_errno
END(fstat)
END(fstat64)
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatat)
ENTRY(fstatat64)
mov ip, r7
ldr r7, =__NR_fstatat64
swi #0
@ -11,4 +11,7 @@ ENTRY(fstatat)
bxls lr
neg r0, r0
b __set_errno
END(fstatat)
END(fstatat64)
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstat)
ENTRY(fstat64)
stp x29, x30, [sp, #-16]!
mov x29, sp
str x8, [sp, #-16]!
@ -18,4 +18,7 @@ ENTRY(fstat)
b.hi __set_errno
ret
END(fstat)
END(fstat64)
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatat)
ENTRY(fstatat64)
stp x29, x30, [sp, #-16]!
mov x29, sp
str x8, [sp, #-16]!
@ -18,4 +18,7 @@ ENTRY(fstatat)
b.hi __set_errno
ret
END(fstatat)
END(fstatat64)
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatfs)
ENTRY(fstatfs64)
stp x29, x30, [sp, #-16]!
mov x29, sp
str x8, [sp, #-16]!
@ -18,4 +18,7 @@ ENTRY(fstatfs)
b.hi __set_errno
ret
END(fstatfs)
END(fstatfs64)
.globl _C_LABEL(fstatfs)
.equ _C_LABEL(fstatfs), _C_LABEL(fstatfs64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(statfs)
ENTRY(statfs64)
stp x29, x30, [sp, #-16]!
mov x29, sp
str x8, [sp, #-16]!
@ -18,4 +18,7 @@ ENTRY(statfs)
b.hi __set_errno
ret
END(statfs)
END(statfs64)
.globl _C_LABEL(statfs)
.equ _C_LABEL(statfs), _C_LABEL(statfs64)

View file

@ -2,11 +2,11 @@
#include <asm/unistd.h>
.text
.globl fstat
.globl fstat64
.align 4
.ent fstat
.ent fstat64
fstat:
fstat64:
.set noreorder
.cpload $t9
li $v0, __NR_fstat64
@ -20,4 +20,7 @@ fstat:
j $t9
nop
.set reorder
.end fstat
.end fstat64
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -2,11 +2,11 @@
#include <asm/unistd.h>
.text
.globl fstatat
.globl fstatat64
.align 4
.ent fstatat
.ent fstatat64
fstatat:
fstatat64:
.set noreorder
.cpload $t9
li $v0, __NR_fstatat64
@ -20,4 +20,7 @@ fstatat:
j $t9
nop
.set reorder
.end fstatat
.end fstatat64
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -4,11 +4,11 @@
#include <machine/asm.h>
#include <machine/regdef.h>
.text
.globl fstat
.globl fstat64
.align 4
.ent fstat
.ent fstat64
fstat:
fstat64:
.set push
.set noreorder
li v0, __NR_fstat
@ -28,4 +28,7 @@ fstat:
j t9
move ra, t0
.set pop
.end fstat
.end fstat64
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -4,11 +4,11 @@
#include <machine/asm.h>
#include <machine/regdef.h>
.text
.globl fstatat
.globl fstatat64
.align 4
.ent fstatat
.ent fstatat64
fstatat:
fstatat64:
.set push
.set noreorder
li v0, __NR_newfstatat
@ -28,4 +28,7 @@ fstatat:
j t9
move ra, t0
.set pop
.end fstatat
.end fstatat64
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -4,11 +4,11 @@
#include <machine/asm.h>
#include <machine/regdef.h>
.text
.globl fstatfs
.globl fstatfs64
.align 4
.ent fstatfs
.ent fstatfs64
fstatfs:
fstatfs64:
.set push
.set noreorder
li v0, __NR_fstatfs
@ -28,4 +28,7 @@ fstatfs:
j t9
move ra, t0
.set pop
.end fstatfs
.end fstatfs64
.globl _C_LABEL(fstatfs)
.equ _C_LABEL(fstatfs), _C_LABEL(fstatfs64)

View file

@ -4,11 +4,11 @@
#include <machine/asm.h>
#include <machine/regdef.h>
.text
.globl statfs
.globl statfs64
.align 4
.ent statfs
.ent statfs64
statfs:
statfs64:
.set push
.set noreorder
li v0, __NR_statfs
@ -28,4 +28,7 @@ statfs:
j t9
move ra, t0
.set pop
.end statfs
.end statfs64
.globl _C_LABEL(statfs)
.equ _C_LABEL(statfs), _C_LABEL(statfs64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstat)
ENTRY(fstat64)
pushl %ebx
pushl %ecx
.cfi_def_cfa_offset 8
@ -23,4 +23,7 @@ ENTRY(fstat)
popl %ecx
popl %ebx
ret
END(fstat)
END(fstat64)
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatat)
ENTRY(fstatat64)
pushl %ebx
pushl %ecx
pushl %edx
@ -31,4 +31,7 @@ ENTRY(fstatat)
popl %ecx
popl %ebx
ret
END(fstatat)
END(fstatat64)
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstat)
ENTRY(fstat64)
movl $__NR_fstat, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@ -13,4 +13,7 @@ ENTRY(fstat)
orq $-1, %rax
1:
ret
END(fstat)
END(fstat64)
.globl _C_LABEL(fstat)
.equ _C_LABEL(fstat), _C_LABEL(fstat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatat)
ENTRY(fstatat64)
movq %rcx, %r10
movl $__NR_newfstatat, %eax
syscall
@ -14,4 +14,7 @@ ENTRY(fstatat)
orq $-1, %rax
1:
ret
END(fstatat)
END(fstatat64)
.globl _C_LABEL(fstatat)
.equ _C_LABEL(fstatat), _C_LABEL(fstatat64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(fstatfs)
ENTRY(fstatfs64)
movl $__NR_fstatfs, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@ -13,4 +13,7 @@ ENTRY(fstatfs)
orq $-1, %rax
1:
ret
END(fstatfs)
END(fstatfs64)
.globl _C_LABEL(fstatfs)
.equ _C_LABEL(fstatfs), _C_LABEL(fstatfs64)

View file

@ -2,7 +2,7 @@
#include <private/bionic_asm.h>
ENTRY(statfs)
ENTRY(statfs64)
movl $__NR_statfs, %eax
syscall
cmpq $-MAX_ERRNO, %rax
@ -13,4 +13,7 @@ ENTRY(statfs)
orq $-1, %rax
1:
ret
END(statfs)
END(statfs64)
.globl _C_LABEL(statfs)
.equ _C_LABEL(statfs), _C_LABEL(statfs64)

View file

@ -105,6 +105,7 @@ dirent* readdir(DIR* d) {
ScopedPthreadMutexLocker locker(&d->mutex_);
return __readdir_locked(d);
}
__strong_alias(readdir64, readdir);
int readdir_r(DIR* d, dirent* entry, dirent** result) {
ErrnoRestorer errno_restorer;
@ -125,6 +126,7 @@ int readdir_r(DIR* d, dirent* entry, dirent** result) {
}
return 0;
}
__strong_alias(readdir64_r, readdir_r);
int closedir(DIR* d) {
if (d == NULL) {
@ -147,3 +149,4 @@ void rewinddir(DIR* d) {
int alphasort(const dirent** a, const dirent** b) {
return strcoll((*a)->d_name, (*b)->d_name);
}
__strong_alias(alphasort64, alphasort);

View file

@ -59,11 +59,13 @@ int fcntl(int fd, int cmd, ...) {
int fstatfs(int fd, struct statfs* stat) {
return __fstatfs64(fd, sizeof(*stat), stat);
}
__strong_alias(fstatfs64, fstatfs);
// For statfs we need to add the extra argument giving the kernel the size of the buffer.
int statfs(const char* path, struct statfs* stat) {
return __statfs64(path, sizeof(*stat), stat);
}
__strong_alias(statfs64, statfs);
// For lseek64 we need to use the llseek system call which splits the off64_t in two and
// returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results.

View file

@ -34,3 +34,4 @@
int lstat(const char* path, struct stat* sb) {
return fstatat(AT_FDCWD, path, sb, AT_SYMLINK_NOFOLLOW);
}
__strong_alias(lstat64, lstat);

View file

@ -43,6 +43,11 @@ static inline int force_O_LARGEFILE(int flags) {
#endif
}
int creat(const char* pathname, mode_t mode) {
return open(pathname, O_CREAT | O_TRUNC | O_WRONLY, mode);
}
__strong_alias(creat64, creat);
int open(const char* pathname, int flags, ...) {
mode_t mode = 0;
@ -55,6 +60,7 @@ int open(const char* pathname, int flags, ...) {
return __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), mode);
}
__strong_alias(open64, open);
int __open_2(const char* pathname, int flags) {
if (__predict_false((flags & O_CREAT) != 0)) {
@ -76,6 +82,7 @@ int openat(int fd, const char *pathname, int flags, ...) {
return __openat(fd, pathname, force_O_LARGEFILE(flags), mode);
}
__strong_alias(openat64, openat);
int __openat_2(int fd, const char* pathname, int flags) {
if ((flags & O_CREAT) != 0) {

View file

@ -113,3 +113,4 @@ int scandir(const char* dirname, dirent*** name_list,
*name_list = names.release();
return size;
}
__strong_alias(scandir64, scandir);

View file

@ -34,3 +34,4 @@
int stat(const char* path, struct stat* sb) {
return fstatat(AT_FDCWD, path, sb, 0);
}
__strong_alias(stat64, stat);

View file

@ -53,6 +53,7 @@ int statvfs(const char* path, struct statvfs* result) {
__statfs_to_statvfs(tmp, result);
return 0;
}
__strong_alias(statvfs64, statvfs);
int fstatvfs(int fd, struct statvfs* result) {
struct statfs tmp;
@ -63,3 +64,4 @@ int fstatvfs(int fd, struct statvfs* result) {
__statfs_to_statvfs(tmp, result);
return 0;
}
__strong_alias(fstatvfs64, fstatvfs);

View file

@ -46,27 +46,33 @@ __BEGIN_DECLS
#define DT_WHT 14
#endif
struct dirent {
uint64_t d_ino;
int64_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256];
};
#define __DIRENT64_BODY \
uint64_t d_ino; \
int64_t d_off; \
unsigned short d_reclen; \
unsigned char d_type; \
char d_name[256]; \
struct dirent { __DIRENT64_BODY };
struct dirent64 { __DIRENT64_BODY };
#define d_fileno d_ino
#define dirent64 dirent
typedef struct DIR DIR;
extern DIR* opendir(const char*);
extern DIR* fdopendir(int);
extern struct dirent* readdir(DIR*);
extern struct dirent64* readdir64(DIR*);
extern int readdir_r(DIR*, struct dirent*, struct dirent**);
extern int readdir64_r(DIR*, struct dirent64*, struct dirent64**);
extern int closedir(DIR*);
extern void rewinddir(DIR*);
extern int dirfd(DIR*);
extern int alphasort(const struct dirent**, const struct dirent**);
extern int alphasort64(const struct dirent64**, const struct dirent64**);
extern int scandir(const char*, struct dirent***, int (*)(const struct dirent*), int (*)(const struct dirent**, const struct dirent**));
extern int scandir64(const char*, struct dirent64***, int (*)(const struct dirent64*), int (*)(const struct dirent64**, const struct dirent64**));
extern int getdents(unsigned int, struct dirent*, unsigned int);
__END_DECLS

View file

@ -42,11 +42,14 @@ __BEGIN_DECLS
#endif
extern int creat(const char*, mode_t);
extern int creat64(const char*, mode_t);
extern int fallocate64(int, int, off64_t, off64_t);
extern int fallocate(int, int, off_t, off_t);
extern int fcntl(int, int, ...);
extern int openat(int, const char*, int, ...);
extern int openat64(int, const char*, int, ...);
extern int open(const char*, int, ...);
extern int open64(const char*, int, ...);
extern int posix_fallocate64(int, off64_t, off64_t);
extern int posix_fallocate(int, off_t, off_t);
extern int unlinkat(int, const char*, int);

View file

@ -38,101 +38,101 @@
__BEGIN_DECLS
#if defined(__aarch64__)
struct stat {
unsigned long st_dev;
unsigned long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned long st_rdev;
unsigned long __pad1;
long st_size;
int st_blksize;
int __pad2;
long st_blocks;
long st_atime;
unsigned long st_atime_nsec;
long st_mtime;
unsigned long st_mtime_nsec;
long st_ctime;
unsigned long st_ctime_nsec;
unsigned int __unused4;
unsigned int __unused5;
};
#define __STAT64_BODY \
unsigned long st_dev; \
unsigned long st_ino; \
unsigned int st_mode; \
unsigned int st_nlink; \
unsigned int st_uid; \
unsigned int st_gid; \
unsigned long st_rdev; \
unsigned long __pad1; \
long st_size; \
int st_blksize; \
int __pad2; \
long st_blocks; \
long st_atime; \
unsigned long st_atime_nsec; \
long st_mtime; \
unsigned long st_mtime_nsec; \
long st_ctime; \
unsigned long st_ctime_nsec; \
unsigned int __unused4; \
unsigned int __unused5; \
#elif defined(__mips__)
struct stat {
unsigned int st_dev;
unsigned int __pad0[3];
unsigned long long st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned int st_uid;
unsigned int st_gid;
unsigned int st_rdev;
unsigned int __pad1[3];
long long st_size;
unsigned int st_atime;
unsigned int st_atime_nsec;
unsigned int st_mtime;
unsigned int st_mtime_nsec;
unsigned int st_ctime;
unsigned int st_ctime_nsec;
unsigned int st_blksize;
unsigned int __pad2;
unsigned long long st_blocks;
};
#define __STAT64_BODY \
unsigned int st_dev; \
unsigned int __pad0[3]; \
unsigned long long st_ino; \
unsigned int st_mode; \
unsigned int st_nlink; \
unsigned int st_uid; \
unsigned int st_gid; \
unsigned int st_rdev; \
unsigned int __pad1[3]; \
long long st_size; \
unsigned int st_atime; \
unsigned int st_atime_nsec; \
unsigned int st_mtime; \
unsigned int st_mtime_nsec; \
unsigned int st_ctime; \
unsigned int st_ctime_nsec; \
unsigned int st_blksize; \
unsigned int __pad2; \
unsigned long long st_blocks; \
#elif defined(__x86_64__)
struct stat {
unsigned long st_dev;
unsigned long st_ino;
unsigned long st_nlink;
unsigned int st_mode;
unsigned int st_uid;
unsigned int st_gid;
unsigned int __pad0;
unsigned long st_rdev;
long st_size;
long st_blksize;
long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
long __pad3[3];
};
#define __STAT64_BODY \
unsigned long st_dev; \
unsigned long st_ino; \
unsigned long st_nlink; \
unsigned int st_mode; \
unsigned int st_uid; \
unsigned int st_gid; \
unsigned int __pad0; \
unsigned long st_rdev; \
long st_size; \
long st_blksize; \
long st_blocks; \
unsigned long st_atime; \
unsigned long st_atime_nsec; \
unsigned long st_mtime; \
unsigned long st_mtime_nsec; \
unsigned long st_ctime; \
unsigned long st_ctime_nsec; \
long __pad3[3]; \
#else
struct stat {
unsigned long long st_dev;
unsigned char __pad0[4];
unsigned long __st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned long st_uid;
unsigned long st_gid;
unsigned long long st_rdev;
unsigned char __pad3[4];
long long st_size;
unsigned long st_blksize;
unsigned long long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long long st_ino;
};
#define __STAT64_BODY \
unsigned long long st_dev; \
unsigned char __pad0[4]; \
unsigned long __st_ino; \
unsigned int st_mode; \
unsigned int st_nlink; \
unsigned long st_uid; \
unsigned long st_gid; \
unsigned long long st_rdev; \
unsigned char __pad3[4]; \
long long st_size; \
unsigned long st_blksize; \
unsigned long long st_blocks; \
unsigned long st_atime; \
unsigned long st_atime_nsec; \
unsigned long st_mtime; \
unsigned long st_mtime_nsec; \
unsigned long st_ctime; \
unsigned long st_ctime_nsec; \
unsigned long long st_ino; \
#endif
/* For compatibility with GLibc, we provide macro aliases
* for the non-Posix nano-seconds accessors.
*/
#define st_atimensec st_atime_nsec
#define st_mtimensec st_mtime_nsec
#define st_ctimensec st_ctime_nsec
struct stat { __STAT64_BODY };
struct stat64 { __STAT64_BODY };
#define st_atimensec st_atime_nsec
#define st_mtimensec st_mtime_nsec
#define st_ctimensec st_ctime_nsec
#ifdef __USE_BSD
/* Permission macros provided by glibc for compatibility with BSDs. */
@ -141,21 +141,26 @@ struct stat {
#define DEFFILEMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) /* 0666 */
#endif
extern int chmod(const char *, mode_t);
extern int fchmod(int, mode_t);
extern int mkdir(const char *, mode_t);
extern int chmod(const char*, mode_t);
extern int fchmod(int, mode_t);
extern int mkdir(const char*, mode_t);
extern int stat(const char *, struct stat *);
extern int fstat(int, struct stat *);
extern int lstat(const char *, struct stat *);
extern int mknod(const char *, mode_t, dev_t);
extern int fstat(int, struct stat*);
extern int fstat64(int, struct stat64*);
extern int fstatat(int, const char*, struct stat*, int);
extern int fstatat64(int, const char*, struct stat64*, int);
extern int lstat(const char*, struct stat*);
extern int lstat64(const char*, struct stat64*);
extern int stat(const char*, struct stat*);
extern int stat64(const char*, struct stat64*);
extern int mknod(const char*, mode_t, dev_t);
extern mode_t umask(mode_t);
#if defined(__BIONIC_FORTIFY)
extern mode_t __umask_chk(mode_t);
extern mode_t __umask_real(mode_t)
__asm__(__USER_LABEL_PREFIX__ "umask");
extern mode_t __umask_real(mode_t) __asm__(__USER_LABEL_PREFIX__ "umask");
__errordecl(__umask_invalid_mode, "umask called with invalid mode");
__BIONIC_FORTIFY_INLINE
@ -172,20 +177,14 @@ mode_t umask(mode_t mode) {
}
#endif /* defined(__BIONIC_FORTIFY) */
#define stat64 stat
#define fstat64 fstat
#define lstat64 lstat
extern int mkfifo(const char*, mode_t);
extern int fchmodat(int, const char*, mode_t, int);
extern int fstatat(int, const char*, struct stat*, int);
extern int mkdirat(int, const char*, mode_t);
extern int mknodat(int, const char*, mode_t, dev_t);
# define UTIME_NOW ((1l << 30) - 1l)
# define UTIME_OMIT ((1l << 30) - 2l)
#define UTIME_NOW ((1L << 30) - 1L)
#define UTIME_OMIT ((1L << 30) - 2L)
extern int utimensat(int fd, const char *path, const struct timespec times[2], int flags);
extern int futimens(int fd, const struct timespec times[2]);

View file

@ -23,19 +23,21 @@
__BEGIN_DECLS
struct statvfs {
unsigned long f_bsize;
unsigned long f_frsize;
fsblkcnt_t f_blocks;
fsblkcnt_t f_bfree;
fsblkcnt_t f_bavail;
fsfilcnt_t f_files;
fsfilcnt_t f_ffree;
fsfilcnt_t f_favail;
unsigned long f_fsid;
unsigned long f_flag;
unsigned long f_namemax;
};
#define __STATVFS64_BODY \
unsigned long f_bsize; \
unsigned long f_frsize; \
fsblkcnt_t f_blocks; \
fsblkcnt_t f_bfree; \
fsblkcnt_t f_bavail; \
fsfilcnt_t f_files; \
fsfilcnt_t f_ffree; \
fsfilcnt_t f_favail; \
unsigned long f_fsid; \
unsigned long f_flag; \
unsigned long f_namemax; \
struct statvfs { __STATVFS64_BODY };
struct statvfs64 { __STATVFS64_BODY };
#define ST_RDONLY 0x0001
#define ST_NOSUID 0x0002
@ -48,7 +50,9 @@ struct statvfs {
#define ST_RELATIME 0x1000
extern int statvfs(const char* __restrict, struct statvfs* __restrict) __nonnull((1, 2));
extern int statvfs64(const char* __restrict, struct statvfs64* __restrict) __nonnull((1, 2));
extern int fstatvfs(int, struct statvfs*) __nonnull((2));
extern int fstatvfs64(int, struct statvfs64*) __nonnull((2));
__END_DECLS

View file

@ -39,73 +39,73 @@ typedef struct { int __val[2]; } __fsid_t;
typedef __fsid_t fsid_t;
#if defined(__aarch64__) || defined(__x86_64__)
struct statfs {
uint64_t f_type;
uint64_t f_bsize;
uint64_t f_blocks;
uint64_t f_bfree;
uint64_t f_bavail;
uint64_t f_files;
uint64_t f_ffree;
fsid_t f_fsid;
uint64_t f_namelen;
uint64_t f_frsize;
uint64_t f_flags;
uint64_t f_spare[4];
};
#define __STATFS64_BODY \
uint64_t f_type; \
uint64_t f_bsize; \
uint64_t f_blocks; \
uint64_t f_bfree; \
uint64_t f_bavail; \
uint64_t f_files; \
uint64_t f_ffree; \
fsid_t f_fsid; \
uint64_t f_namelen; \
uint64_t f_frsize; \
uint64_t f_flags; \
uint64_t f_spare[4]; \
#elif defined(__mips__) && defined(__LP64__)
/* 64-bit MIPS. */
struct statfs {
uint64_t f_type;
uint64_t f_bsize;
uint64_t f_frsize; /* Fragment size - unsupported. */
uint64_t f_blocks;
uint64_t f_bfree;
uint64_t f_files;
uint64_t f_ffree;
uint64_t f_bavail;
fsid_t f_fsid;
uint64_t f_namelen;
uint64_t f_flags;
uint64_t f_spare[5];
};
#define __STATFS64_BODY \
uint64_t f_type; \
uint64_t f_bsize; \
uint64_t f_frsize; /* Fragment size - unsupported. */ \
uint64_t f_blocks; \
uint64_t f_bfree; \
uint64_t f_files; \
uint64_t f_ffree; \
uint64_t f_bavail; \
fsid_t f_fsid; \
uint64_t f_namelen; \
uint64_t f_flags; \
uint64_t f_spare[5]; \
#elif defined(__mips__)
/* 32-bit MIPS (corresponds to the kernel's statfs64 type). */
struct statfs {
uint32_t f_type;
uint32_t f_bsize;
uint32_t f_frsize;
uint32_t __pad;
uint64_t f_blocks;
uint64_t f_bfree;
uint64_t f_files;
uint64_t f_ffree;
uint64_t f_bavail;
fsid_t f_fsid;
uint32_t f_namelen;
uint32_t f_flags;
uint32_t f_spare[5];
};
#define __STATFS64_BODY \
uint32_t f_type; \
uint32_t f_bsize; \
uint32_t f_frsize; \
uint32_t __pad; \
uint64_t f_blocks; \
uint64_t f_bfree; \
uint64_t f_files; \
uint64_t f_ffree; \
uint64_t f_bavail; \
fsid_t f_fsid; \
uint32_t f_namelen; \
uint32_t f_flags; \
uint32_t f_spare[5]; \
#else
/* 32-bit ARM or x86 (corresponds to the kernel's statfs64 type). */
struct statfs {
uint32_t f_type;
uint32_t f_bsize;
uint64_t f_blocks;
uint64_t f_bfree;
uint64_t f_bavail;
uint64_t f_files;
uint64_t f_ffree;
fsid_t f_fsid;
uint32_t f_namelen;
uint32_t f_frsize;
uint32_t f_flags;
uint32_t f_spare[4];
};
#define __STATFS64_BODY \
uint32_t f_type; \
uint32_t f_bsize; \
uint64_t f_blocks; \
uint64_t f_bfree; \
uint64_t f_bavail; \
uint64_t f_files; \
uint64_t f_ffree; \
fsid_t f_fsid; \
uint32_t f_namelen; \
uint32_t f_frsize; \
uint32_t f_flags; \
uint32_t f_spare[4]; \
#endif
/* Source compatibility with glibc. */
#define statfs64 statfs
struct statfs { __STATFS64_BODY };
struct statfs64 { __STATFS64_BODY };
/* Declare that we have the f_namelen, f_frsize, and f_flags fields. */
#define _STATFS_F_NAMELEN
@ -158,7 +158,9 @@ struct statfs {
#define _XIAFS_SUPER_MAGIC 0x012FD16D
extern int statfs(const char*, struct statfs*) __nonnull((1, 2));
extern int statfs64(const char*, struct statfs64*) __nonnull((1, 2));
extern int fstatfs(int, struct statfs*) __nonnull((2));
extern int fstatfs64(int, struct statfs64*) __nonnull((2));
__END_DECLS

View file

@ -130,7 +130,7 @@ class SysCallsTxtParser:
if arch in all_arches:
t[arch] = True
else:
E("invalid syscall architecture list in '%s'" % line)
E("invalid syscall architecture '%s' in '%s'" % (arch, line))
return
self.syscalls.append(t)

View file

@ -1,52 +0,0 @@
/* $NetBSD: creat.c,v 1.10 2003/08/07 16:42:39 agc Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)creat.c 8.1 (Berkeley) 6/2/93";
#else
__RCSID("$NetBSD: creat.c,v 1.10 2003/08/07 16:42:39 agc Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
int
creat(const char *path, mode_t mode)
{
_DIAGASSERT(path != NULL);
return(open(path, O_WRONLY|O_CREAT|O_TRUNC, mode));
}

View file

@ -59,7 +59,6 @@ libBionicStandardTests_src_files := \
stack_protector_test.cpp \
stack_unwinding_test.cpp \
stack_unwinding_test_impl.c \
statvfs_test.cpp \
stdio_test.cpp \
stdlib_test.cpp \
string_test.cpp \
@ -71,9 +70,11 @@ libBionicStandardTests_src_files := \
sys_select_test.cpp \
sys_sendfile_test.cpp \
sys_stat_test.cpp \
sys_statvfs_test.cpp \
sys_syscall_test.cpp \
sys_time_test.cpp \
sys_types_test.cpp \
sys_vfs_test.cpp \
system_properties_test.cpp \
time_test.cpp \
unistd_test.cpp \

View file

@ -37,21 +37,31 @@ static void CheckProcSelf(std::set<std::string>& names) {
ASSERT_TRUE(names.find("stat") != names.end());
}
TEST(dirent, scandir) {
template <typename DirEntT>
void ScanEntries(DirEntT** entries, int entry_count,
std::set<std::string>& name_set, std::vector<std::string>& name_list) {
for (size_t i = 0; i < static_cast<size_t>(entry_count); ++i) {
name_set.insert(entries[i]->d_name);
name_list.push_back(entries[i]->d_name);
free(entries[i]);
}
free(entries);
}
TEST(dirent, scandir_scandir64) {
// Get everything from /proc/self...
dirent** entries;
int entry_count = scandir("/proc/self", &entries, NULL, alphasort);
ASSERT_GE(entry_count, 0);
dirent64** entries64;
int entry_count64 = scandir64("/proc/self", &entries64, NULL, alphasort64);
ASSERT_EQ(entry_count, entry_count64);
// Turn the directory entries into a set and vector of the names.
std::set<std::string> name_set;
std::vector<std::string> unsorted_name_list;
for (size_t i = 0; i < static_cast<size_t>(entry_count); ++i) {
name_set.insert(entries[i]->d_name);
unsorted_name_list.push_back(entries[i]->d_name);
free(entries[i]);
}
free(entries);
ScanEntries(entries, entry_count, name_set, unsorted_name_list);
// No duplicates.
ASSERT_EQ(name_set.size(), unsorted_name_list.size());
@ -61,6 +71,13 @@ TEST(dirent, scandir) {
std::sort(sorted_name_list.begin(), sorted_name_list.end());
ASSERT_EQ(sorted_name_list, unsorted_name_list);
// scandir64 returned the same results as scandir.
std::set<std::string> name_set64;
std::vector<std::string> unsorted_name_list64;
ScanEntries(entries64, entry_count64, name_set64, unsorted_name_list64);
ASSERT_EQ(name_set, name_set64);
ASSERT_EQ(unsorted_name_list, unsorted_name_list64);
CheckProcSelf(name_set);
}
@ -133,6 +150,23 @@ TEST(dirent, readdir) {
CheckProcSelf(name_set);
}
TEST(dirent, readdir64) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != NULL);
std::set<std::string> name_set;
errno = 0;
dirent64* e;
while ((e = readdir64(d)) != NULL) {
name_set.insert(e->d_name);
}
// Reading to the end of the directory is not an error.
// readdir64(3) returns NULL, but leaves errno as 0.
ASSERT_EQ(0, errno);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, readdir_r) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != NULL);
@ -151,6 +185,24 @@ TEST(dirent, readdir_r) {
CheckProcSelf(name_set);
}
TEST(dirent, readdir64_r) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != NULL);
std::set<std::string> name_set;
errno = 0;
dirent64 storage;
dirent64* e = NULL;
while (readdir64_r(d, &storage, &e) == 0 && e != NULL) {
name_set.insert(e->d_name);
}
// Reading to the end of the directory is not an error.
// readdir64_r(3) returns NULL, but leaves errno as 0.
ASSERT_EQ(0, errno);
ASSERT_EQ(closedir(d), 0);
CheckProcSelf(name_set);
}
TEST(dirent, rewinddir) {
DIR* d = opendir("/proc/self");
ASSERT_TRUE(d != NULL);

View file

@ -35,6 +35,39 @@ TEST(fcntl, fcntl_smoke) {
flags = fcntl(fd, F_GETFD);
ASSERT_TRUE(flags != -1);
ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
close(fd);
}
TEST(fcntl, open_open64) {
int fd;
fd = open("/proc/version", O_RDONLY);
ASSERT_TRUE(fd != -1);
close(fd);
fd = open64("/proc/version", O_RDONLY);
ASSERT_TRUE(fd != -1);
close(fd);
}
TEST(fcntl, openat_openat64) {
int fd;
fd = openat(AT_FDCWD, "/proc/version", O_RDONLY);
ASSERT_TRUE(fd != -1);
close(fd);
fd = openat64(AT_FDCWD, "/proc/version", O_RDONLY);
ASSERT_TRUE(fd != -1);
close(fd);
}
TEST(fcntl, creat_creat64) {
ASSERT_EQ(-1, creat("", 0666));
ASSERT_EQ(ENOENT, errno);
ASSERT_EQ(-1, creat64("", 0666));
ASSERT_EQ(ENOENT, errno);
}
TEST(fcntl, fallocate_EINVAL) {

View file

@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
@ -68,3 +69,12 @@ TEST(sys_stat, mkfifo) {
ASSERT_TRUE(S_ISFIFO(sb.st_mode));
unlink(path.c_str());
}
TEST(sys_stat, stat64_lstat64_fstat64) {
struct stat64 sb;
ASSERT_EQ(0, stat64("/proc/version", &sb));
ASSERT_EQ(0, lstat64("/proc/version", &sb));
int fd = open("/proc/version", O_RDONLY);
ASSERT_EQ(0, fstat64(fd, &sb));
close(fd);
}

View file

@ -24,12 +24,7 @@
#include <string>
TEST(statvfs, statvfs) {
struct statvfs sb;
memset(&sb, 0, sizeof(sb));
ASSERT_EQ(0, statvfs("/proc", &sb));
template <typename StatVfsT> void Check(StatVfsT& sb) {
EXPECT_EQ(4096U, sb.f_bsize);
EXPECT_EQ(0U, sb.f_bfree);
EXPECT_EQ(0U, sb.f_ffree);
@ -37,17 +32,29 @@ TEST(statvfs, statvfs) {
EXPECT_EQ(255U, sb.f_namemax);
}
TEST(statvfs, fstatvfs) {
TEST(sys_statvfs, statvfs) {
struct statvfs sb;
memset(&sb, 0, sizeof(sb));
ASSERT_EQ(0, statvfs("/proc", &sb));
Check(sb);
}
TEST(sys_statvfs, statvfs64) {
struct statvfs64 sb;
ASSERT_EQ(0, statvfs64("/proc", &sb));
Check(sb);
}
TEST(sys_statvfs, fstatvfs) {
struct statvfs sb;
int fd = open("/proc", O_RDONLY);
ASSERT_EQ(0, fstatvfs(fd, &sb));
close(fd);
EXPECT_EQ(4096U, sb.f_bsize);
EXPECT_EQ(0U, sb.f_bfree);
EXPECT_EQ(0U, sb.f_ffree);
EXPECT_EQ(0U, sb.f_fsid);
EXPECT_EQ(255U, sb.f_namemax);
Check(sb);
}
TEST(sys_statvfs, fstatvfs64) {
struct statvfs64 sb;
int fd = open("/proc", O_RDONLY);
ASSERT_EQ(0, fstatvfs64(fd, &sb));
close(fd);
Check(sb);
}