Improve system call wrappers

This change improves copy_file_range(), sendfile(), splice(), openpty(),
closefrom(), close_range(), fadvise() and posix_fadvise() in addition to
writing tests that confirm things like errno and seeking behavior across
platforms. We now less aggressively polyfill behavior with some of these
functions when the platform support isn't available. Please see:

https://justine.lol/cosmopolitan/functions.html
This commit is contained in:
Justine Tunney 2022-09-19 15:01:48 -07:00
parent 224c12f54d
commit c7a8cd21e9
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
89 changed files with 1151 additions and 414 deletions

View file

@ -24,7 +24,8 @@
* @param guardsize will be set to guard size in bytes
* @return 0 on success, or errno on error
*/
int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) {
errno_t pthread_attr_getguardsize(const pthread_attr_t *attr,
size_t *guardsize) {
*guardsize = attr->guardsize;
return 0;
}

View file

@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/thread/thread.h"
#include "libc/runtime/stack.h"
#include "libc/thread/thread.h"
/**
* Returns configuration for thread stack.
@ -30,8 +30,8 @@
* @return 0 on success, or errno on error
* @see pthread_attr_setstacksize()
*/
int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr,
size_t *stacksize) {
errno_t pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr,
size_t *stacksize) {
*stackaddr = attr->stackaddr;
*stacksize = attr->stacksize;
return 0;

View file

@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/thread/thread.h"
#include "libc/runtime/stack.h"
#include "libc/thread/thread.h"
/**
* Returns size of thread stack.
@ -28,7 +28,7 @@
* @return 0 on success, or errno on error
* @see pthread_attr_setstacksize()
*/
int pthread_attr_getstacksize(const pthread_attr_t *a, size_t *x) {
errno_t pthread_attr_getstacksize(const pthread_attr_t *a, size_t *x) {
if (a->stacksize) {
*x = a->stacksize;
} else {

View file

@ -16,15 +16,15 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/thread/thread.h"
#include "libc/runtime/stack.h"
#include "libc/thread/thread.h"
/**
* Initializes pthread attributes.
*
* @return 0 on success, or errno on error
*/
int pthread_attr_init(pthread_attr_t *attr) {
errno_t pthread_attr_init(pthread_attr_t *attr) {
*attr = (pthread_attr_t){
.stacksize = GetStackSize(),
.guardsize = PAGESIZE,

View file

@ -24,7 +24,7 @@
* @param guardsize contains guard size in bytes
* @return 0 on success, or errno on error
*/
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) {
errno_t pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) {
attr->guardsize = guardsize;
return 0;
}

View file

@ -40,7 +40,7 @@
* @return 0 on success, or errno on error
* @raise EINVAL on bad value
*/
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) {
errno_t pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched) {
switch (inheritsched) {
case PTHREAD_INHERIT_SCHED:
case PTHREAD_EXPLICIT_SCHED:

View file

@ -62,8 +62,8 @@
* @raise EINVAL if parameters were unacceptable
* @see pthread_attr_setstacksize()
*/
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
size_t stacksize) {
errno_t pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
size_t stacksize) {
if (!stackaddr) {
attr->stackaddr = 0;
attr->stacksize = 0;

View file

@ -26,7 +26,7 @@
* @return 0 on success, or errno on error
* @raise EINVAL if `stacksize` is less than `PTHREAD_STACK_MIN`
*/
int pthread_attr_setstacksize(pthread_attr_t *a, size_t stacksize) {
errno_t pthread_attr_setstacksize(pthread_attr_t *a, size_t stacksize) {
if (stacksize < PTHREAD_STACK_MIN) return EINVAL;
a->stacksize = stacksize;
return 0;

View file

@ -30,7 +30,7 @@
* @return 0 on success, `PTHREAD_BARRIER_SERIAL_THREAD` to one lucky
* thread which was the last arrival, or an errno on error
*/
int pthread_barrier_wait(pthread_barrier_t *barrier) {
errno_t pthread_barrier_wait(pthread_barrier_t *barrier) {
if (nsync_counter_add(barrier->_nsync, -1)) {
nsync_counter_wait(barrier->_nsync, nsync_time_no_deadline);
return 0;

View file

@ -36,7 +36,7 @@
* @see pthread_cond_signal
* @see pthread_cond_wait
*/
int pthread_cond_broadcast(pthread_cond_t *cond) {
errno_t pthread_cond_broadcast(pthread_cond_t *cond) {
nsync_cv_broadcast((nsync_cv *)cond);
return 0;
}

View file

@ -36,7 +36,7 @@
* @see pthread_cond_broadcast
* @see pthread_cond_wait
*/
int pthread_cond_signal(pthread_cond_t *cond) {
errno_t pthread_cond_signal(pthread_cond_t *cond) {
nsync_cv_signal((nsync_cv *)cond);
return 0;
}

View file

@ -44,8 +44,8 @@
* @see pthread_cond_broadcast
* @see pthread_cond_signal
*/
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) {
errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime) {
if (abstime && !(0 <= abstime->tv_nsec && abstime->tv_nsec < 1000000000)) {
return EINVAL;
}

View file

@ -37,6 +37,6 @@
* @see pthread_cond_broadcast
* @see pthread_cond_signal
*/
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
errno_t pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
return pthread_cond_timedwait(cond, mutex, 0);
}

View file

@ -184,8 +184,8 @@ static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) {
* isn't authorized to use it
* @threadsafe
*/
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
errno_t pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
int rc, e = errno;
struct PosixThread *pt;
__require_tls();

View file

@ -31,8 +31,8 @@
* @return 0 on success, or errno on error
* @raise ENOSYS if not Linux or Windows
*/
int pthread_getaffinity_np(pthread_t thread, size_t bitsetsize,
cpu_set_t *bitset) {
errno_t pthread_getaffinity_np(pthread_t thread, size_t bitsetsize,
cpu_set_t *bitset) {
int rc, e = errno;
struct PosixThread *pt = (struct PosixThread *)thread;
if (!sched_getaffinity(pt->tid, bitsetsize, bitset)) {

View file

@ -44,7 +44,7 @@
* result will still be returned truncated if possible
* @raise ENOSYS on MacOS, Windows, FreeBSD, and OpenBSD
*/
int pthread_getname_np(pthread_t thread, char *name, size_t size) {
errno_t pthread_getname_np(pthread_t thread, char *name, size_t size) {
int e, fd, rc, tid, len;
if (!size) return 0;

View file

@ -24,7 +24,7 @@
*
* @return 0 on success, or errno on error
*/
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
errno_t pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
nsync_mu_rlock((nsync_mu *)rwlock);
return 0;
}

View file

@ -25,7 +25,7 @@
* @return 0 on success, or errno on error
* @raise EINVAL if lock is in a bad state
*/
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
errno_t pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
if (rwlock->_iswrite) {
rwlock->_iswrite = 0;
nsync_mu_unlock((nsync_mu *)rwlock);

View file

@ -24,7 +24,7 @@
*
* @return 0 on success, or errno on error
*/
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
errno_t pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
nsync_mu_lock((nsync_mu *)rwlock);
rwlock->_iswrite = 1;
return 0;

View file

@ -27,8 +27,8 @@
* @return 0 on success, or errno on error
* @raise ENOSYS if not Linux or Windows
*/
int pthread_setaffinity_np(pthread_t thread, size_t bitsetsize,
const cpu_set_t *bitset) {
errno_t pthread_setaffinity_np(pthread_t thread, size_t bitsetsize,
const cpu_set_t *bitset) {
int rc, e = errno;
struct PosixThread *pt = (struct PosixThread *)thread;
if (!sched_setaffinity(pt->tid, bitsetsize, bitset)) {

View file

@ -51,7 +51,7 @@
* @raise ENOSYS on MacOS, Windows, and OpenBSD
* @see pthread_getname_np()
*/
int pthread_setname_np(pthread_t thread, const char *name) {
errno_t pthread_setname_np(pthread_t thread, const char *name) {
char path[128], *p;
int e, fd, rc, tid, len;

View file

@ -23,6 +23,6 @@
*
* @return 0 on success, or errno on error
*/
int(pthread_spin_destroy)(pthread_spinlock_t *spin) {
errno_t(pthread_spin_destroy)(pthread_spinlock_t *spin) {
return pthread_spin_destroy(spin);
}

View file

@ -27,6 +27,6 @@
* @see pthread_spin_destroy
* @see pthread_spin_lock
*/
int(pthread_spin_init)(pthread_spinlock_t *spin, int pshared) {
errno_t(pthread_spin_init)(pthread_spinlock_t *spin, int pshared) {
return pthread_spin_init(spin, pshared);
}

View file

@ -50,6 +50,6 @@
* @see pthread_spin_unlock
* @see pthread_spin_init
*/
int(pthread_spin_lock)(pthread_spinlock_t *spin) {
errno_t(pthread_spin_lock)(pthread_spinlock_t *spin) {
return pthread_spin_lock(spin);
}

View file

@ -27,6 +27,6 @@
* @return 0 on success, or errno on error
* @raise EBUSY if lock is already held
*/
int(pthread_spin_trylock)(pthread_spinlock_t *spin) {
errno_t(pthread_spin_trylock)(pthread_spinlock_t *spin) {
return pthread_spin_trylock(spin);
}

View file

@ -24,6 +24,6 @@
* @return 0 on success, or errno on error
* @see pthread_spin_lock
*/
int(pthread_spin_unlock)(pthread_spinlock_t *spin) {
errno_t(pthread_spin_unlock)(pthread_spinlock_t *spin) {
return pthread_spin_unlock(spin);
}