#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
-#include <sys/mman.h>
+#include <setjmp.h>
+#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <sys/utsname.h>
int status, ret;
while(1){
- if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
+ CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
+ if((ret < 0) ||
!WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
if(ret < 0){
- if(errno == EINTR) continue;
printk("wait failed, errno = %d\n",
errno);
}
else if(WIFEXITED(status))
- printk("process exited with status %d\n",
- WEXITSTATUS(status));
+ printk("process %d exited with status %d\n",
+ pid, WEXITSTATUS(status));
else if(WIFSIGNALED(status))
- printk("process exited with signal %d\n",
- WTERMSIG(status));
+ printk("process %d exited with signal %d\n",
+ pid, WTERMSIG(status));
else if((WSTOPSIG(status) == SIGVTALRM) ||
(WSTOPSIG(status) == SIGALRM) ||
(WSTOPSIG(status) == SIGIO) ||
ptrace(cont_type, pid, 0, WSTOPSIG(status));
continue;
}
- else printk("process stopped with signal %d\n",
- WSTOPSIG(status));
+ else printk("process %d stopped with signal %d\n",
+ pid, WSTOPSIG(status));
panic("wait_for_stop failed to wait for %d to stop "
"with %d\n", pid, sig);
}
}
}
-int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
-{
- int pid;
-
- pid = clone(fn, sp, flags, arg);
- if(pid < 0) return(-1);
- wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
- ptrace(PTRACE_CONT, pid, 0, 0);
- return(pid);
-}
-
-int raw(int fd, int complain)
+int raw(int fd)
{
struct termios tt;
int err;
- tcgetattr(fd, &tt);
+ CATCH_EINTR(err = tcgetattr(fd, &tt));
+ if (err < 0) {
+ printk("tcgetattr failed, errno = %d\n", errno);
+ return(-errno);
+ }
+
cfmakeraw(&tt);
- err = tcsetattr(fd, TCSANOW, &tt);
- if((err < 0) && complain){
- printk("tcsetattr failed, errno = %d\n", errno);
+
+ CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
+ if (err < 0) {
+ printk("tcsetattr failed, errno = %d\n", errno);
return(-errno);
}
+
+ /* XXX tcsetattr could have applied only some changes
+ * (and cfmakeraw() is a set of changes) */
return(0);
}
host.release, host.version, host.machine);
}
+int setjmp_wrapper(void (*proc)(void *, void *), ...)
+{
+ va_list args;
+ sigjmp_buf buf;
+ int n;
+
+ n = sigsetjmp(buf, 1);
+ if(n == 0){
+ va_start(args, proc);
+ (*proc)(&buf, &args);
+ }
+ va_end(args);
+ return(n);
+}
+
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically