mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: [UGLY PATCH v3] Support for no-legacy-syscalls archs
Date: Tue, 27 May 2014 01:26:25 -0400	[thread overview]
Message-ID: <20140527052625.GC507@brightrain.aerifal.cx> (raw)
In-Reply-To: <20140525054237.GA18085@brightrain.aerifal.cx>

[-- Attachment #1: Type: text/plain, Size: 706 bytes --]

This updated patch should actually compile if you #undef all the SYS_*
constants for syscalls that new archs don't provide. Major changes
include:

- use of pause in exit and quick_exit
- fixed bugs in poll and select
- linux epoll/inotify/eventfd/signalfd
- other functions i'd overlooked that use some of these syscalls

In the case of epoll, etc. I reworked the code to always prefer the
new syscalls and only fallback to the old ones if (1) they exist, and
(2) the new one returned ENOSYS. signalfd already has fallback code
that handles FD_CLOEXEC as best it can when the new syscall is not
available, but the others seem to be lacking the proper fallback code
so I should perhaps add that too.

Rich

[-- Attachment #2: no_legacy_syscall_archs_v3.diff --]
[-- Type: text/plain, Size: 22279 bytes --]

diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index d7481c2..c10a3f3 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -1,6 +1,7 @@
 #include <elf.h>
 #include <poll.h>
 #include <fcntl.h>
+#include <signal.h>
 #include "syscall.h"
 #include "atomic.h"
 #include "libc.h"
@@ -48,7 +49,11 @@ void __init_libc(char **envp, char *pn)
 		&& !aux[AT_SECURE]) return;
 
 	struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
+#ifdef SYS_poll
 	__syscall(SYS_poll, pfd, 3, 0);
+#else
+	__syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
+#endif
 	for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
 		if (__sys_open("/dev/null", O_RDWR)<0)
 			a_crash();
diff --git a/src/exit/exit.c b/src/exit/exit.c
index 353f50b..6ac90c3 100644
--- a/src/exit/exit.c
+++ b/src/exit/exit.c
@@ -1,5 +1,6 @@
 #include <stdlib.h>
 #include <stdint.h>
+#include "futex.h"
 #include "libc.h"
 #include "atomic.h"
 #include "syscall.h"
@@ -24,7 +25,12 @@ _Noreturn void exit(int code)
 	static int lock;
 
 	/* If more than one thread calls exit, hang until _Exit ends it all */
-	while (a_swap(&lock, 1)) __syscall(SYS_pause);
+	while (a_swap(&lock, 1))
+#ifdef SYS_pausex
+		__syscall(SYS_pause);
+#else
+		__syscall(SYS_futex, &lock, FUTEX_WAIT, 1, 0);
+#endif
 
 	__funcs_on_exit();
 
diff --git a/src/exit/quick_exit.c b/src/exit/quick_exit.c
index 1175d80..01e304b 100644
--- a/src/exit/quick_exit.c
+++ b/src/exit/quick_exit.c
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include "futex.h"
 #include "syscall.h"
 #include "atomic.h"
 #include "libc.h"
@@ -9,7 +10,12 @@ weak_alias(dummy, __funcs_on_quick_exit);
 _Noreturn void quick_exit(int code)
 {
 	static int lock;
-	while (a_swap(&lock, 1)) __syscall(SYS_pause);
+	while (a_swap(&lock, 1))
+#ifdef SYS_pause
+		__syscall(SYS_pause);
+#else
+		__syscall(SYS_futex, &lock, FUTEX_WAIT, 1, 0);
+#endif
 	__funcs_on_quick_exit();
 	_Exit(code);
 }
diff --git a/src/linux/epoll.c b/src/linux/epoll.c
index 030786d..b45344f 100644
--- a/src/linux/epoll.c
+++ b/src/linux/epoll.c
@@ -4,12 +4,16 @@
 
 int epoll_create(int size)
 {
-	return syscall(SYS_epoll_create, size);
+	return epoll_create1(0);
 }
 
 int epoll_create1(int flags)
 {
-	return syscall(SYS_epoll_create1, flags);
+	int r = __syscall(SYS_epoll_create1, flags);
+#ifdef SYS_epoll_create
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
+#endif
+	return __syscall_ret(r);
 }
 
 int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
@@ -19,10 +23,14 @@ int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
 
 int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
 {
-	return syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+	int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
+#ifdef SYS_epoll_wait
+	if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
+#endif
+	return __syscall_ret(r);
 }
 
 int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
 {
-	return syscall(SYS_epoll_wait, fd, ev, cnt, to);
+	return epoll_pwait(fd, ev, cnt, to, 0);
 }
diff --git a/src/linux/eventfd.c b/src/linux/eventfd.c
index 5306648..3996803 100644
--- a/src/linux/eventfd.c
+++ b/src/linux/eventfd.c
@@ -4,7 +4,11 @@
 
 int eventfd(unsigned int count, int flags)
 {
-	return syscall(flags ? SYS_eventfd2 : SYS_eventfd, count, flags);
+	int r = __syscall(SYS_eventfd2, count, flags);
+#ifdef SYS_eventfd
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
+#endif
+	return __syscall_ret(r);
 }
 
 int eventfd_read(int fd, eventfd_t *value)
diff --git a/src/linux/inotify.c b/src/linux/inotify.c
index a417c89..84a5615 100644
--- a/src/linux/inotify.c
+++ b/src/linux/inotify.c
@@ -3,11 +3,15 @@
 
 int inotify_init()
 {
-	return syscall(SYS_inotify_init);
+	return inotify_init1(0);
 }
 int inotify_init1(int flags)
 {
-	return syscall(SYS_inotify_init1, flags);
+	int r = __syscall(SYS_inotify_init1, flags);
+#ifdef SYS_inotify_init
+	if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
+#endif
+	return __syscall_ret(r);
 }
 
 int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
diff --git a/src/linux/signalfd.c b/src/linux/signalfd.c
index da6bced..4bf4332 100644
--- a/src/linux/signalfd.c
+++ b/src/linux/signalfd.c
@@ -7,6 +7,7 @@
 int signalfd(int fd, const sigset_t *sigs, int flags)
 {
 	int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
+#ifdef SYS_signalfd
 	if (ret != -ENOSYS) return __syscall_ret(ret);
 	ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
 	if (ret >= 0) {
@@ -15,5 +16,6 @@ int signalfd(int fd, const sigset_t *sigs, int flags)
 		if (flags & SFD_NONBLOCK)
 			__syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
 	}
+#endif
 	return __syscall_ret(ret);
 }
diff --git a/src/linux/utimes.c b/src/linux/utimes.c
index 70c0695..b814c88 100644
--- a/src/linux/utimes.c
+++ b/src/linux/utimes.c
@@ -1,7 +1,10 @@
 #include <sys/time.h>
+#include "fcntl.h"
 #include "syscall.h"
 
+int __futimesat(int, const char *, const struct timeval [2]);
+
 int utimes(const char *path, const struct timeval times[2])
 {
-	return syscall(SYS_utimes, path, times);
+	return __futimesat(AT_FDCWD, path, times);
 }
diff --git a/src/process/fork.c b/src/process/fork.c
index 864c7d7..f8cf21e 100644
--- a/src/process/fork.c
+++ b/src/process/fork.c
@@ -1,5 +1,6 @@
 #include <unistd.h>
 #include <string.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 #include "pthread_impl.h"
@@ -16,7 +17,11 @@ pid_t fork(void)
 	sigset_t set;
 	__fork_handler(-1);
 	__block_all_sigs(&set);
+#ifdef SYS_fork
 	ret = syscall(SYS_fork);
+#else
+	ret = syscall(SYS_clone, SIGCHLD, 0);
+#endif
 	if (libc.has_thread_pointer && !ret) {
 		pthread_t self = __pthread_self();
 		self->tid = self->pid = __syscall(SYS_getpid);
diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
index 08644f5..6fa33cb 100644
--- a/src/process/posix_spawn.c
+++ b/src/process/posix_spawn.c
@@ -22,6 +22,18 @@ struct args {
 
 void __get_handler_set(sigset_t *);
 
+static int do_dup2(int old, int new)
+{
+	int r;
+#ifdef SYS_dup2
+	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+	while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+	if (r==-EINVAL && old==new) return new;
+#endif
+	return r;
+}
+
 static int child(void *args_vp)
 {
 	int i, ret;
@@ -92,14 +104,14 @@ static int child(void *args_vp)
 					goto fail;
 				break;
 			case FDOP_DUP2:
-				if ((ret=__syscall(SYS_dup2, op->srcfd, op->fd))<0)
+				if ((ret=do_dup2(op->srcfd, op->fd))<0)
 					goto fail;
 				break;
 			case FDOP_OPEN:
 				fd = __sys_open(op->path, op->oflag, op->mode);
 				if ((ret=fd) < 0) goto fail;
 				if (fd != op->fd) {
-					if ((ret=__syscall(SYS_dup2, fd, op->fd))<0)
+					if ((ret=do_dup2(fd, op->fd))<0)
 						goto fail;
 					__syscall(SYS_close, fd);
 				}
diff --git a/src/select/poll.c b/src/select/poll.c
index f1e73e8..9e0bcbd 100644
--- a/src/select/poll.c
+++ b/src/select/poll.c
@@ -1,8 +1,16 @@
 #include <poll.h>
+#include <time.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 
 int poll(struct pollfd *fds, nfds_t n, int timeout)
 {
+#ifdef SYS_poll
 	return syscall_cp(SYS_poll, fds, n, timeout);
+#else
+	return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ?
+		&((struct timespec){ .tv_sec = timeout/1000,
+		.tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8);
+#endif
 }
diff --git a/src/select/select.c b/src/select/select.c
index f93597b..7b5f6dc 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -1,8 +1,26 @@
 #include <sys/select.h>
+#include <signal.h>
+#include <stdint.h>
+#include <errno.h>
 #include "syscall.h"
 #include "libc.h"
 
 int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
 {
+#ifdef SYS_select
 	return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
+#else
+	syscall_arg_t data[2] = { 0, _NSIG/8 };
+	struct timespec ts;
+	if (tv) {
+		if (tv->tv_sec < 0 || tv->tv_usec < 0)
+			return __syscall_ret(-EINVAL);
+		time_t extra_secs = tv->tv_usec / 1000000;
+		ts.tv_nsec = tv->tv_usec % 1000000 * 1000;
+		const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
+		ts.tv_sec = extra_secs > max_time - tv->tv_sec ?
+			max_time : tv->tv_sec + extra_secs;
+	}
+	return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
+#endif
 }
diff --git a/src/stat/chmod.c b/src/stat/chmod.c
index beb66e5..d4f53c5 100644
--- a/src/stat/chmod.c
+++ b/src/stat/chmod.c
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int chmod(const char *path, mode_t mode)
 {
+#ifdef SYS_chmod
 	return syscall(SYS_chmod, path, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+#endif
 }
diff --git a/src/stat/fchmod.c b/src/stat/fchmod.c
index 6d28141..93e1b64 100644
--- a/src/stat/fchmod.c
+++ b/src/stat/fchmod.c
@@ -13,5 +13,9 @@ int fchmod(int fd, mode_t mode)
 
 	char buf[15+3*sizeof(int)];
 	__procfdname(buf, fd);
+#ifdef SYS_chmod
 	return syscall(SYS_chmod, buf, mode);
+#else
+	return syscall(SYS_fchmodat, AT_FDCWD, buf, mode);
+#endif
 }
diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
index 12e7ff0..52029ec 100644
--- a/src/stat/fchmodat.c
+++ b/src/stat/fchmodat.c
@@ -29,7 +29,7 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
 
 	__procfdname(proc, fd2);
 	if (!(ret = __syscall(SYS_stat, proc, &st)) && !S_ISLNK(st.st_mode))
-		ret = __syscall(SYS_chmod, proc, mode);
+		ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
 
 	__syscall(SYS_close, fd2);
 	return __syscall_ret(ret);
diff --git a/src/stat/futimesat.c b/src/stat/futimesat.c
index dbefc84..5990aa6 100644
--- a/src/stat/futimesat.c
+++ b/src/stat/futimesat.c
@@ -1,10 +1,23 @@
 #define _GNU_SOURCE
 #include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
 #include "syscall.h"
+#include "libc.h"
 
-#ifdef SYS_futimesat
-int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
+int __futimesat(int dirfd, const char *pathname, const struct timeval times[2])
 {
-	return syscall(SYS_futimesat, dirfd, pathname, times);
+	struct timespec ts[2];
+	if (times) {
+		int i;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_usec >= 1000000U)
+				return __syscall_ret(-EINVAL);
+			ts[i].tv_sec = times[i].tv_sec;
+			ts[i].tv_nsec = times[i].tv_usec * 1000;
+		}
+	}
+	return utimensat(dirfd, pathname, times ? ts : 0, 0);
 }
-#endif
+
+weak_alias(__futimesat, futimesat);
diff --git a/src/stat/lstat.c b/src/stat/lstat.c
index 8f60358..5e8b84f 100644
--- a/src/stat/lstat.c
+++ b/src/stat/lstat.c
@@ -1,10 +1,15 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 #include "libc.h"
 
 int lstat(const char *restrict path, struct stat *restrict buf)
 {
+#ifdef SYS_lstat
 	return syscall(SYS_lstat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+#endif
 }
 
 LFS64(lstat);
diff --git a/src/stat/mkdir.c b/src/stat/mkdir.c
index 770e1cc..32625b7 100644
--- a/src/stat/mkdir.c
+++ b/src/stat/mkdir.c
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int mkdir(const char *path, mode_t mode)
 {
+#ifdef SYS_mkdir
 	return syscall(SYS_mkdir, path, mode);
+#else
+	return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
 }
diff --git a/src/stat/mknod.c b/src/stat/mknod.c
index c319657..beebd84 100644
--- a/src/stat/mknod.c
+++ b/src/stat/mknod.c
@@ -1,7 +1,12 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int mknod(const char *path, mode_t mode, dev_t dev)
 {
+#ifdef SYS_mknod
 	return syscall(SYS_mknod, path, mode, dev);
+#else
+	return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
+#endif
 }
diff --git a/src/stat/stat.c b/src/stat/stat.c
index c6de716..b4433a0 100644
--- a/src/stat/stat.c
+++ b/src/stat/stat.c
@@ -1,10 +1,15 @@
 #include <sys/stat.h>
+#include <fcntl.h>
 #include "syscall.h"
 #include "libc.h"
 
 int stat(const char *restrict path, struct stat *restrict buf)
 {
+#ifdef SYS_stat
 	return syscall(SYS_stat, path, buf);
+#else
+	return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
+#endif
 }
 
 LFS64(stat);
diff --git a/src/stat/utimensat.c b/src/stat/utimensat.c
index 929698b..abc8d74 100644
--- a/src/stat/utimensat.c
+++ b/src/stat/utimensat.c
@@ -1,7 +1,40 @@
 #include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <errno.h>
 #include "syscall.h"
 
 int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
 {
-	return syscall(SYS_utimensat, fd, path, times, flags);
+	int r = __syscall(SYS_utimensat, fd, path, times, flags);
+	if (r != -ENOSYS || flags) return __syscall_ret(r);
+
+#ifdef SYS_futimesat
+	struct timeval *tv = 0;
+	if (times) {
+		struct timeval tmp[2];
+		int i;
+		tv = tmp;
+		for (i=0; i<2; i++) {
+			if (times[i].tv_nsec >= 1000000000U) {
+				if (times[i].tv_nsec == UTIME_NOW &&
+				    times[1-i].tv_nsec == UTIME_NOW) {
+					tv = 0;
+					break;
+				}
+				if (times[i].tv_nsec == UTIME_OMIT)
+					return __syscall_ret(-ENOSYS);
+				return __syscall_ret(-EINVAL);
+			}
+			tmp[i].tv_sec = times[i].tv_sec;
+			tmp[i].tv_usec = times[i].tv_nsec / 1000;
+		}
+	}
+
+	r = __syscall(SYS_futimesat, fd, path, tv);
+	if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r);
+	r = __syscall(SYS_utimes, path, tv);
+#endif
+
+	return __syscall_ret(r);
 }
diff --git a/src/stdio/remove.c b/src/stdio/remove.c
index e147ba2..942e301 100644
--- a/src/stdio/remove.c
+++ b/src/stdio/remove.c
@@ -1,9 +1,19 @@
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int remove(const char *path)
 {
-	int r = syscall(SYS_unlink, path);
-	return (r && errno == EISDIR) ? syscall(SYS_rmdir, path) : r;
+#ifdef SYS_unlink
+	int r = __syscall(SYS_unlink, path);
+#else
+	int r = __syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
+#ifdef SYS_rmdir
+	if (r==-EISDIR) r = __syscall(SYS_rmdir, path);
+#else
+	if (r==-EISDIR) r = __syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
+	return __syscall_ret(r);
 }
diff --git a/src/stdio/rename.c b/src/stdio/rename.c
index 97f1453..04c90c0 100644
--- a/src/stdio/rename.c
+++ b/src/stdio/rename.c
@@ -1,7 +1,12 @@
 #include <stdio.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int rename(const char *old, const char *new)
 {
+#ifdef SYS_rename
 	return syscall(SYS_rename, old, new);
+#else
+	return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
+#endif
 }
diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
index 9bf8c72..45a5f26 100644
--- a/src/stdio/tempnam.c
+++ b/src/stdio/tempnam.c
@@ -36,7 +36,12 @@ char *tempnam(const char *dir, const char *pfx)
 
 	for (try=0; try<MAXTRIES; try++) {
 		__randname(s+l-6);
+#ifdef SYS_lstat
 		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
 		if (r == -ENOENT) return strdup(s);
 	}
 	return 0;
diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c
index c856994..a7d0000 100644
--- a/src/stdio/tmpfile.c
+++ b/src/stdio/tmpfile.c
@@ -17,7 +17,11 @@ FILE *tmpfile(void)
 		fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
 		if (fd >= 0) {
 			f = __fdopen(fd, "w+");
+#ifdef SYS_unlink
 			__syscall(SYS_unlink, s);
+#else
+			__syscall(SYS_unlinkat, AT_FDCWD, s, 0);
+#endif
 			return f;
 		}
 	}
diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
index 92f699c..ccb8a4c 100644
--- a/src/stdio/tmpnam.c
+++ b/src/stdio/tmpnam.c
@@ -16,7 +16,12 @@ char *tmpnam(char *buf)
 	int r;
 	for (try=0; try<MAXTRIES; try++) {
 		__randname(s+12);
+#ifdef SYS_lstat
 		r = __syscall(SYS_lstat, s, &(struct stat){0});
+#else
+		r = __syscall(SYS_fstatat, AT_FDCWD, s,
+			&(struct stat){0}, AT_SYMLINK_NOFOLLOW);
+#endif
 		if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
 	}
 	return 0;
diff --git a/src/time/utime.c b/src/time/utime.c
index b2b5741..3b5f4e3 100644
--- a/src/time/utime.c
+++ b/src/time/utime.c
@@ -1,14 +1,16 @@
 #include <utime.h>
-#include <sys/time.h>
-#include "syscall.h"
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
 
 int utime(const char *path, const struct utimbuf *times)
 {
+	struct timespec *ts = 0;
 	if (times) {
-		struct timeval tv[2] = {
+		struct timespec tmp[2] = {
 			{ .tv_sec = times->actime },
 			{ .tv_sec = times->modtime } };
-		return syscall(SYS_utimes, path, tv);
+		ts = tmp;
 	}
-	return syscall(SYS_utimes, path, 0);
+	return utimensat(AT_FDCWD, path, ts, 0);
 }
diff --git a/src/unistd/access.c b/src/unistd/access.c
index e7ce73a..d6eed68 100644
--- a/src/unistd/access.c
+++ b/src/unistd/access.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int access(const char *filename, int amode)
 {
+#ifdef SYS_access
 	return syscall(SYS_access, filename, amode);
+#else
+	return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
 }
diff --git a/src/unistd/chown.c b/src/unistd/chown.c
index 95f6f61..14b0325 100644
--- a/src/unistd/chown.c
+++ b/src/unistd/chown.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int chown(const char *path, uid_t uid, gid_t gid)
 {
+#ifdef SYS_chown
 	return syscall(SYS_chown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
 }
diff --git a/src/unistd/dup2.c b/src/unistd/dup2.c
index 87a0d44..ed04a89 100644
--- a/src/unistd/dup2.c
+++ b/src/unistd/dup2.c
@@ -5,6 +5,11 @@
 int dup2(int old, int new)
 {
 	int r;
+#ifdef SYS_dup2
 	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+	while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+	if (r==-EINVAL && old==new) return new;
+#endif
 	return __syscall_ret(r);
 }
diff --git a/src/unistd/dup3.c b/src/unistd/dup3.c
index 1f7134b..0eb6caf 100644
--- a/src/unistd/dup3.c
+++ b/src/unistd/dup3.c
@@ -8,6 +8,7 @@
 int __dup3(int old, int new, int flags)
 {
 	int r;
+#ifdef SYS_dup2
 	if (old==new) return __syscall_ret(-EINVAL);
 	if (flags & O_CLOEXEC) {
 		while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
@@ -15,6 +16,9 @@ int __dup3(int old, int new, int flags)
 	}
 	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
 	if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+#else
+	while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
+#endif
 	return __syscall_ret(r);
 }
 
diff --git a/src/unistd/fchown.c b/src/unistd/fchown.c
index 36633b0..0345984 100644
--- a/src/unistd/fchown.c
+++ b/src/unistd/fchown.c
@@ -13,5 +13,10 @@ int fchown(int fd, uid_t uid, gid_t gid)
 
 	char buf[15+3*sizeof(int)];
 	__procfdname(buf, fd);
+#ifdef SYS_chown
 	return syscall(SYS_chown, buf, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid);
+#endif
+
 }
diff --git a/src/unistd/getpgrp.c b/src/unistd/getpgrp.c
index 433f42e..90e9bb0 100644
--- a/src/unistd/getpgrp.c
+++ b/src/unistd/getpgrp.c
@@ -3,5 +3,5 @@
 
 pid_t getpgrp(void)
 {
-	return __syscall(SYS_getpgrp);
+	return __syscall(SYS_getpgid, 0);
 }
diff --git a/src/unistd/lchown.c b/src/unistd/lchown.c
index de871ae..ccd5ee0 100644
--- a/src/unistd/lchown.c
+++ b/src/unistd/lchown.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int lchown(const char *path, uid_t uid, gid_t gid)
 {
+#ifdef SYS_lchown
 	return syscall(SYS_lchown, path, uid, gid);
+#else
+	return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
 }
diff --git a/src/unistd/link.c b/src/unistd/link.c
index 20193f2..feec18e 100644
--- a/src/unistd/link.c
+++ b/src/unistd/link.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int link(const char *existing, const char *new)
 {
+#ifdef SYS_link
 	return syscall(SYS_link, existing, new);
+#else
+	return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
 }
diff --git a/src/unistd/pause.c b/src/unistd/pause.c
index f7ed17d..e259017 100644
--- a/src/unistd/pause.c
+++ b/src/unistd/pause.c
@@ -1,8 +1,15 @@
 #include <unistd.h>
+#include <signal.h>
 #include "syscall.h"
 #include "libc.h"
 
 int pause(void)
 {
+#ifdef SYS_pause
 	return syscall_cp(SYS_pause);
+#else
+	sigset_t mask;
+	__syscall(SYS_rt_sigprocmask, SIG_BLOCK, 0, &mask, _NSIG/8);
+	return syscall_cp(SYS_rt_sigsuspend, &mask, _NSIG/8);
+#endif
 }
diff --git a/src/unistd/pipe.c b/src/unistd/pipe.c
index 36c6f13..d07b8d2 100644
--- a/src/unistd/pipe.c
+++ b/src/unistd/pipe.c
@@ -3,5 +3,9 @@
 
 int pipe(int fd[2])
 {
+#ifdef SYS_pipe
 	return syscall(SYS_pipe, fd);
+#else
+	return syscall(SYS_pipe2, fd, 0);
+#endif
 }
diff --git a/src/unistd/readlink.c b/src/unistd/readlink.c
index ec291e3..a152d52 100644
--- a/src/unistd/readlink.c
+++ b/src/unistd/readlink.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
 {
+#ifdef SYS_readlink
 	return syscall(SYS_readlink, path, buf, bufsize);
+#else
+	return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
 }
diff --git a/src/unistd/rmdir.c b/src/unistd/rmdir.c
index dfe1605..6825ffc 100644
--- a/src/unistd/rmdir.c
+++ b/src/unistd/rmdir.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int rmdir(const char *path)
 {
+#ifdef SYS_rmdir
 	return syscall(SYS_rmdir, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
 }
diff --git a/src/unistd/symlink.c b/src/unistd/symlink.c
index 5902d45..0973d78 100644
--- a/src/unistd/symlink.c
+++ b/src/unistd/symlink.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int symlink(const char *existing, const char *new)
 {
+#ifdef SYS_symlink
 	return syscall(SYS_symlink, existing, new);
+#else
+	return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
 }
diff --git a/src/unistd/unlink.c b/src/unistd/unlink.c
index bdb37be..c40c28d 100644
--- a/src/unistd/unlink.c
+++ b/src/unistd/unlink.c
@@ -1,7 +1,12 @@
 #include <unistd.h>
+#include <fcntl.h>
 #include "syscall.h"
 
 int unlink(const char *path)
 {
+#ifdef SYS_unlink
 	return syscall(SYS_unlink, path);
+#else
+	return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
 }

  parent reply	other threads:[~2014-05-27  5:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-25  5:42 [UGLY PATCH] " Rich Felker
2014-05-25  9:52 ` Szabolcs Nagy
2014-05-25  9:57   ` Justin Cormack
2014-05-25 11:45   ` Rich Felker
2014-05-26  4:28 ` Rich Felker
2014-05-26 18:40 ` [UGLY PATCH v2] " Rich Felker
2014-05-26 21:13   ` Szabolcs Nagy
2014-05-26 21:54     ` Rich Felker
2014-05-26 22:39       ` Szabolcs Nagy
2014-05-26 22:46         ` Rich Felker
2014-05-27  5:26 ` Rich Felker [this message]
2014-05-27 11:29   ` [UGLY PATCH v3] " Szabolcs Nagy
2014-05-27 19:01     ` Rich Felker
2014-05-29 21:46   ` Rich Felker
2014-05-29 23:04   ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140527052625.GC507@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).