+#ifdef HAVE_SET_RESTORE_SIGMASK
+asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
+ int __user *upeer_addrlen,
+ const sigset_t __user *sigmask,
+ size_t sigsetsize, int flags)
+{
+ sigset_t ksigmask, sigsaved;
+ int ret;
+
+ if (sigmask) {
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+ if (copy_from_user(&ksigmask, sigmask, sizeof(ksigmask)))
+ return -EFAULT;
+
+ sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
+ sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+ }
+
+ ret = do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
+
+ if (ret < 0 && signal_pending(current)) {
+ /*
+ * Don't restore the signal mask yet. Let do_signal() deliver
+ * the signal on the way back to userspace, before the signal
+ * mask is restored.
+ */
+ if (sigmask) {
+ memcpy(¤t->saved_sigmask, &sigsaved,
+ sizeof(sigsaved));
+ set_restore_sigmask();
+ }
+ } else if (sigmask)
+ sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
+ return ret;
+}
+#else
+asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
+ int __user *upeer_addrlen,
+ const sigset_t __user *sigmask,
+ size_t sigsetsize, int flags)
+{
+ /* The platform does not support restoring the signal mask in the
+ * return path. So we do not allow using paccept() with a signal
+ * mask. */
+ if (sigmask)
+ return -EINVAL;
+
+ return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
+}
+#endif
+
+asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
+ int __user *upeer_addrlen)
+{
+ return do_accept(fd, upeer_sockaddr, upeer_addrlen, 0);
+}
+