int fcntl_portable(int fd, int cmd, ...) { va_list ap; void * arg; va_start(ap, cmd); arg = va_arg(ap, void *); va_end(ap); if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) { struct flock64 x86_flock64; int result = __fcntl64(fd, cmd, (void *) &x86_flock64); struct flock64_portable * flock64 = (struct flock64_portable *) arg; flock64->l_type = x86_flock64.l_type; flock64->l_whence = x86_flock64.l_whence; flock64->l_start = x86_flock64.l_start; flock64->l_len = x86_flock64.l_len; flock64->l_pid = x86_flock64.l_pid; return result; } else { return __fcntl64(fd, cmd, arg); } }
int fcntl(int fd, int command, ...) { va_list args; int rc; int n; struct flock *flck; switch (command) { case F_DUPFD_CLOEXEC: case F_DUP2FD: case F_DUP2FD_CLOEXEC: va_start(args, command); rc = crystax_fcntl(fd, command, args); va_end(args); return rc; case F_GETFD: case F_GETFL: case F_GETLEASE: case F_GETOWN: case F_GETPIPE_SZ: case F_GETSIG: return __fcntl64(fd, command); case F_NOTIFY: case F_DUPFD: case F_SETFD: case F_SETFL: case F_SETLEASE: case F_SETOWN: case F_SETPIPE_SZ: case F_SETSIG: va_start(args, command); n = va_arg(args, int); rc = __fcntl64(fd, command, n); va_end(args); return rc; case F_GETLK: case F_SETLK: case F_SETLKW: #if !__LP64__ case F_GETLK64: case F_SETLK64: case F_SETLKW64: #endif va_start(args, command); flck = va_arg(args, struct flock *); rc = __fcntl64(fd, command, flck); va_end(args); return rc; default: DBG("Unknown fcntl command: %d", command); errno = EINVAL; return -1; } }
static int dupfd_cloexec(int fd, int fd2) { int rc = __fcntl64(fd, F_DUPFD, fd2); if (rc < 0) return -1; if (__fcntl64(rc, F_SETFD, FD_CLOEXEC) < 0) { int serrno = errno; close(rc); errno = serrno; return -1; } return rc; }
// For fcntl we use the fcntl64 system call to signal that we're using struct flock64. int fcntl(int fd, int cmd, ...) { va_list ap; va_start(ap, cmd); void* arg = va_arg(ap, void*); va_end(ap); return __fcntl64(fd, cmd, arg); }
/* * For 32 bit flocks we are converting a portable/ARM struct flock to a MIPS struct flock: * * MIPS: ARM: * struct flock { struct flock_portable { * short l_type; short l_type; * * short l_whence; short l_whence; * off_t l_start; loff_t l_start; * off_t l_len; loff_t l_len; * long l_sysid; * * __kernel_pid_t l_pid; pid_t l_pid; * long pad[4]; * }; } * * which have identically sized structure members: * * For a 64 bit flocks we only have to deal with * a four byte padding in the ARM/Portable structure: * * MIPS: ARM: * struct flock64 { struct flock64_portable { * short l_type; short l_type; * short l_whence; short l_whence; * unsigned char __padding[4]; <---- NOTE * loff_t l_start; loff_t l_start; * loff_t l_len; loff_t l_len; * pid_t l_pid; pid_t l_pid; * } } */ int WRAP(fcntl)(int fd, int portable_cmd, ...) { int flags; va_list ap; void *arg; int mips_cmd; int result = 0; struct flock flock; /* Native MIPS structure */ struct flock64 flock64; /* Native MIPS structure */ char *portable_cmd_name = map_portable_cmd_to_name(portable_cmd); struct flock_portable *flock_portable = NULL; struct flock64_portable *flock64_portable = NULL; ALOGV(" "); ALOGV("%s(fd:%d, portable_cmd:%d:'%s', ...) {", __func__, fd, portable_cmd, portable_cmd_name); va_start(ap, portable_cmd); arg = va_arg(ap, void *); va_end(ap); mips_cmd = fcntl_cmd_pton(portable_cmd); switch(mips_cmd) { case F_GETLK: case F_SETLK: case F_SETLKW: flock_portable = (struct flock_portable *) arg; if (invalid_pointer(flock_portable)) { ALOGE("%s: flock_portable:%p == {NULL||-1}", __func__, flock_portable); errno = EFAULT; result = -1; goto done; } /* * Lock type and Whence are the same for all ARCHs * (F_RDLCK:0, F_WRLCK:1, F_UNLCK:2) * (SEEK_SET:0, SEEK_CUR:1, SEEK_END:2) */ flock.l_type = flock_portable->l_type; flock.l_whence = flock_portable->l_whence; flock.l_start = (off_t) flock_portable->l_start; flock.l_len = (off_t) flock_portable->l_len; flock.l_sysid = 0L; flock.l_pid = flock_portable->l_pid; /* Perhaps 0 would be better */ result = __fcntl64(fd, mips_cmd, (void *) &flock); flock_portable->l_type = flock.l_type; flock_portable->l_whence = flock.l_whence; flock_portable->l_start = flock.l_start; flock_portable->l_len = flock.l_len; flock_portable->l_pid = flock.l_pid; break; case F_GETLK64: case F_SETLK64: case F_SETLKW64: flock64_portable = (struct flock64_portable *) arg; if (invalid_pointer(flock_portable)) { ALOGE("%s: flock_portable:%p == {NULL||-1}", __func__, flock_portable); errno = EFAULT; result = -1; goto done; } /* * Lock type and Whence are the same for all ARCHs * (F_RDLCK:0, F_WRLCK:1, F_UNLCK:2) * (SEEK_SET:0, SEEK_CUR:1, SEEK_END:2) */ flock64.l_type = flock64_portable->l_type; flock64.l_whence = flock64_portable->l_whence; flock64.l_start = (off_t) flock64_portable->l_start; flock64.l_len = (off_t) flock64_portable->l_len; flock64.l_pid = flock64_portable->l_pid; /* Perhaps 0 would be better */ result = __fcntl64(fd, mips_cmd, (void *) &flock); flock64_portable->l_type = flock64.l_type; flock64_portable->l_whence = flock64.l_whence; flock64_portable->l_start = flock64.l_start; flock64_portable->l_len = flock64.l_len; flock64_portable->l_pid = flock64.l_pid; break; case F_SETFL: flags = fcntl_flags_pton((int)arg); result = __fcntl64(fd, mips_cmd, (void *)flags); break; case F_GETFL: result = __fcntl64(fd, mips_cmd, arg); if (result != -1) result = fcntl_flags_ntop(result); break; case F_DUPFD: case F_GETFD: case F_SETFD: case F_SETOWN: case F_GETOWN: case F_SETSIG: case F_GETSIG: case F_SETLEASE: case F_GETLEASE: case F_NOTIFY: ALOGV("%s: Calling __fcntl64(fd:%d, mips_cmd:0x%x, arg:%p);", __func__, fd, mips_cmd, arg); result = __fcntl64(fd, mips_cmd, arg); if (result < 0) { ALOGV("%s: result = %d = __fcntl64(fd:%d, mips_cmd:0x%x, arg:%p);", __func__, result, fd, mips_cmd, arg); } else { if (mips_cmd == F_SETFD) { /* * File descriptor flag bits got set or cleared. */ flags = (int)arg; if (flags & FD_CLOEXEC) { filefd_CLOEXEC_enabled(fd); } else { filefd_CLOEXEC_disabled(fd); } } } break; default: /* * This is likely a rare situation, abort() would hang fcntl13 LTP test. */ ALOGE("%s: mips_cmd:%d doesn't appear to be supported;", __func__, mips_cmd); ALOGV("%s: Assume it doesn't need to be mapped!", __func__); result = __fcntl64(fd, mips_cmd, arg); } done: ALOGV("%s: return(result:%d); }", __func__, result); return result; }