mailing list of musl libc
 help / color / mirror / code / Atom feed
* [UGLY PATCH] Support for no-legacy-syscalls archs
@ 2014-05-25  5:42 Rich Felker
  2014-05-25  9:52 ` Szabolcs Nagy
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Rich Felker @ 2014-05-25  5:42 UTC (permalink / raw)
  To: musl

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

Here's a proposed next phase for supporting no-legacy-syscall archs
(aarch64 and or1k, among others). It's not complete but I think it
covers most of the important syscalls for standard functionality (not
linux-specific stuff tho). Some of them might be missing some error
cases or otherwise buggy so I'm sending the patch for review before
committing.

Rich

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

diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index d7481c2..f98a858 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, 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/process/fork.c b/src/process/fork.c
index 864c7d7..89b04c6 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);
+#endif
 	if (libc.has_thread_pointer && !ret) {
 		pthread_t self = __pthread_self();
 		self->tid = self->pid = __syscall(SYS_getpid);
diff --git a/src/select/poll.c b/src/select/poll.c
index f1e73e8..4f13cfb 100644
--- a/src/select/poll.c
+++ b/src/select/poll.c
@@ -4,5 +4,11 @@
 
 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,
+		&(struct timespec){ .tv_sec = timeout/1000,
+		.tv_nsec = timeout%1000*1000000 }, 0, _NSIG/8);
+#endif
 }
diff --git a/src/select/select.c b/src/select/select.c
index f93597b..5e7fe1f 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -4,5 +4,15 @@
 
 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
+	long data[2] = { 0, _NSIG/8 };
+	struct timespec ts;
+	if (tv) {
+		ts.tv_sec = tv->tv_sec;
+		ts.tv_nsec = tv->tv_usec * 1000;
+	}
+	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/futimesat.c b/src/stat/futimesat.c
index dbefc84..ad33484 100644
--- a/src/stat/futimesat.c
+++ b/src/stat/futimesat.c
@@ -2,9 +2,18 @@
 #include <sys/time.h>
 #include "syscall.h"
 
-#ifdef SYS_futimesat
 int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
 {
+#ifdef SYS_futimesat
 	return syscall(SYS_futimesat, dirfd, pathname, times);
-}
+#else
+	struct timespec ts[2];
+	if (times) {
+		ts[0].tv_sec = times[0].tv_sec;
+		ts[0].tv_nsec = times[0].tv_usec * 1000;
+		ts[1].tv_sec = times[1].tv_sec;
+		ts[1].tv_nsec = times[1].tv_usec * 1000;
+	}
+	return syscall(SYS_utimensat, dirfd, pathname, times ? ts : 0, 0);
 #endif
+}
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/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/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..7bfcaf2 100644
--- a/src/unistd/dup2.c
+++ b/src/unistd/dup2.c
@@ -5,6 +5,15 @@
 int dup2(int old, int new)
 {
 	int r;
+#ifdef SYS_dup2
 	while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+	if (old==new) {
+		if (__syscall(SYS_fcntl, old, F_GETFD) < 0)
+			return __syscall_ret(-EBADF);
+		return 0;
+	}
+	while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+#endif
 	return __syscall_ret(r);
 }
diff --git a/src/unistd/getpgrp.c b/src/unistd/getpgrp.c
index 433f42e..2c8aae6 100644
--- a/src/unistd/getpgrp.c
+++ b/src/unistd/getpgrp.c
@@ -1,7 +1,16 @@
 #include <unistd.h>
 #include "syscall.h"
+#include "pthread_impl.h"
 
 pid_t getpgrp(void)
 {
+#ifdef SYS_getpgrp
 	return __syscall(SYS_getpgrp);
+#else
+	sigset_t set;
+	__block_app_sigs(&set);
+	pid_t ret = __syscall(SYS_getpgid, __syscall(SYS_getpid));
+	__restore_sigs(&set);
+	return ret;
+#endif
 }
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..50bf3b1 100644
--- a/src/unistd/pause.c
+++ b/src/unistd/pause.c
@@ -4,5 +4,11 @@
 
 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
 }

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2014-05-29 23:04 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-25  5:42 [UGLY PATCH] Support for no-legacy-syscalls archs 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 ` [UGLY PATCH v3] " Rich Felker
2014-05-27 11:29   ` Szabolcs Nagy
2014-05-27 19:01     ` Rich Felker
2014-05-29 21:46   ` Rich Felker
2014-05-29 23:04   ` Rich Felker

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).