summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/linux32/linux32_dummy.c2
-rw-r--r--sys/amd64/linux32/syscalls.master8
-rw-r--r--sys/compat/linux/linux_misc.c32
-rw-r--r--sys/compat/linux/linux_signal.c85
-rw-r--r--sys/i386/linux/linux_dummy.c2
-rw-r--r--sys/i386/linux/syscalls.master8
6 files changed, 129 insertions, 8 deletions
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c
index fc4d551..5babd4c 100644
--- a/sys/amd64/linux32/linux32_dummy.c
+++ b/sys/amd64/linux32/linux32_dummy.c
@@ -53,7 +53,6 @@ DUMMY(bdflush);
DUMMY(sysfs);
DUMMY(query_module);
DUMMY(nfsservctl);
-DUMMY(rt_sigtimedwait);
DUMMY(rt_sigqueueinfo);
DUMMY(capget);
DUMMY(capset);
@@ -77,7 +76,6 @@ DUMMY(timer_gettime);
DUMMY(timer_getoverrun);
DUMMY(timer_delete);
DUMMY(fstatfs64);
-DUMMY(utimes);
DUMMY(fadvise64_64);
DUMMY(mbind);
DUMMY(get_mempolicy);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 2487f46..d29c0fe 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -311,7 +311,10 @@
l_size_t sigsetsize); }
176 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \
l_size_t sigsetsize); }
-177 AUE_NULL STD { int linux_rt_sigtimedwait(void); }
+177 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \
+ l_siginfo_t *ptr, \
+ struct l_timeval *timeout, \
+ l_size_t sigsetsize); }
178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); }
179 AUE_NULL STD { int linux_rt_sigsuspend( \
l_sigset_t *newset, \
@@ -435,7 +438,8 @@
268 AUE_STATFS STD { int linux_statfs64(char *path, struct l_statfs64_buf *buf); }
269 AUE_FSTATFS STD { int linux_fstatfs64(void); }
270 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); }
-271 AUE_UTIMES STD { int linux_utimes(void); }
+271 AUE_UTIMES STD { int linux_utimes(char *fname, \
+ struct l_timeval *tptr); }
272 AUE_NULL STD { int linux_fadvise64_64(void); }
273 AUE_NULL UNIMPL
274 AUE_NULL STD { int linux_mbind(void); }
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 489b079..e137e6b 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -786,6 +786,38 @@ linux_utime(struct thread *td, struct linux_utime_args *args)
LFREEPATH(fname);
return (error);
}
+
+int
+linux_utimes(struct thread *td, struct linux_utimes_args *args)
+{
+ l_timeval ltv[2];
+ struct timeval tv[2], *tvp = NULL;
+ char *fname;
+ int error;
+
+ LCONVPATHEXIST(td, args->fname, &fname);
+
+#ifdef DEBUG
+ if (ldebug(utimes))
+ printf(ARGS(utimes, "%s, *"), fname);
+#endif
+
+ if (args->tptr != NULL) {
+ if ((error = copyin(args->tptr, ltv, sizeof ltv))) {
+ LFREEPATH(fname);
+ return (error);
+ }
+ tv[0].tv_sec = ltv[0].tv_sec;
+ tv[0].tv_usec = ltv[0].tv_usec;
+ tv[1].tv_sec = ltv[1].tv_sec;
+ tv[1].tv_usec = ltv[1].tv_usec;
+ tvp = tv;
+ }
+
+ error = kern_utimes(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE);
+ LFREEPATH(fname);
+ return (error);
+}
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
#define __WCLONE 0x80000000
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 7b17200..30561d6 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -422,6 +422,91 @@ linux_rt_sigpending(struct thread *td, struct linux_rt_sigpending_args *args)
return (copyout(&lset, args->set, args->sigsetsize));
}
+/*
+ * MPSAFE
+ */
+int
+linux_rt_sigtimedwait(struct thread *td,
+ struct linux_rt_sigtimedwait_args *args)
+{
+ int error;
+ l_timeval ltv;
+ struct timeval tv;
+ struct timespec ts, *tsa;
+ l_sigset_t lset;
+ sigset_t bset;
+ l_siginfo_t linfo;
+ ksiginfo_t info;
+
+#ifdef DEBUG
+ if (ldebug(rt_sigtimedwait))
+ printf(ARGS(rt_sigtimedwait, "*"));
+#endif
+ if (args->sigsetsize != sizeof(l_sigset_t))
+ return (EINVAL);
+
+ if ((error = copyin(args->mask, &lset, sizeof(lset))))
+ return (error);
+ linux_to_bsd_sigset(&lset, &bset);
+
+ tsa = NULL;
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &ltv, sizeof(ltv))))
+ return (error);
+#ifdef DEBUG
+ if (ldebug(rt_sigtimedwait))
+ printf(LMSG("linux_rt_sigtimedwait: incoming timeout (%d/%d)\n"),
+ ltv.tv_sec, ltv.tv_usec);
+#endif
+ tv.tv_sec = (long)ltv.tv_sec;
+ tv.tv_usec = (suseconds_t)ltv.tv_usec;
+ if (itimerfix(&tv)) {
+ /*
+ * The timeout was invalid. Convert it to something
+ * valid that will act as it does under Linux.
+ */
+ tv.tv_sec += tv.tv_usec / 1000000;
+ tv.tv_usec %= 1000000;
+ if (tv.tv_usec < 0) {
+ tv.tv_sec -= 1;
+ tv.tv_usec += 1000000;
+ }
+ if (tv.tv_sec < 0)
+ timevalclear(&tv);
+#ifdef DEBUG
+ if (ldebug(rt_sigtimedwait))
+ printf(LMSG("linux_rt_sigtimedwait: converted timeout (%d/%ld)\n"),
+ tv.tv_sec, tv.tv_usec);
+#endif
+ }
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+ tsa = &ts;
+ }
+ error = kern_sigtimedwait(td, bset, &info, tsa);
+#ifdef DEBUG
+ if (ldebug(rt_sigtimedwait))
+ printf(LMSG("linux_rt_sigtimedwait: sigtimedwait returning (%d)\n"), error);
+#endif
+ if (error)
+ return (error);
+
+ if (args->ptr) {
+ memset(&linfo, 0, sizeof(linfo));
+ linfo.lsi_signo = info.ksi_signo;
+ error = copyout(&linfo, args->ptr, sizeof(linfo));
+ }
+
+ /* Repost if we got an error. */
+ if (error && info.ksi_signo) {
+ PROC_LOCK(td->td_proc);
+ tdsignal(td->td_proc, td, info.ksi_signo, &info);
+ PROC_UNLOCK(td->td_proc);
+ } else
+ td->td_retval[0] = info.ksi_signo;
+
+ return (error);
+}
+
int
linux_kill(struct thread *td, struct linux_kill_args *args)
{
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 5f3afc4..cd2c615 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -56,7 +56,6 @@ DUMMY(sysfs);
DUMMY(vm86);
DUMMY(query_module);
DUMMY(nfsservctl);
-DUMMY(rt_sigtimedwait);
DUMMY(rt_sigqueueinfo);
DUMMY(capget);
DUMMY(capset);
@@ -73,7 +72,6 @@ DUMMY(epoll_ctl);
DUMMY(epoll_wait);
DUMMY(remap_file_pages);
DUMMY(fstatfs64);
-DUMMY(utimes);
DUMMY(fadvise64_64);
DUMMY(mbind);
DUMMY(get_mempolicy);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 4b09855..fea81d3 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -313,7 +313,10 @@
l_size_t sigsetsize); }
176 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \
l_size_t sigsetsize); }
-177 AUE_NULL STD { int linux_rt_sigtimedwait(void); }
+177 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \
+ l_siginfo_t *ptr, \
+ struct l_timeval *timeout, \
+ l_size_t sigsetsize); }
178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); }
179 AUE_NULL STD { int linux_rt_sigsuspend( \
l_sigset_t *newset, \
@@ -439,7 +442,8 @@
268 AUE_STATFS STD { int linux_statfs64(char *path, struct l_statfs64_buf *buf); }
269 AUE_FSTATFS STD { int linux_fstatfs64(void); }
270 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); }
-271 AUE_UTIMES STD { int linux_utimes(void); }
+271 AUE_UTIMES STD { int linux_utimes(char *fname, \
+ struct l_timeval *tptr); }
272 AUE_NULL STD { int linux_fadvise64_64(void); }
273 AUE_NULL UNIMPL
274 AUE_NULL STD { int linux_mbind(void); }
OpenPOWER on IntegriCloud