Merge branch 'exec_rm_compat' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg...
[pandora-kernel.git] / arch / um / os-Linux / util.c
index a6f31d4..42827ca 100644 (file)
@@ -1,39 +1,25 @@
 /*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <limits.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include "asm/types.h"
-#include <ctype.h>
-#include <signal.h>
-#include <wait.h>
 #include <errno.h>
-#include <stdarg.h>
-#include <sched.h>
-#include <termios.h>
+#include <signal.h>
 #include <string.h>
-#include "kern_util.h"
-#include "user.h"
-#include "mem_user.h"
-#include "init.h"
-#include "ptrace_user.h"
-#include "uml-config.h"
-#include "os.h"
-#include "longjmp.h"
+#include <termios.h>
+#include <wait.h>
+#include <sys/mman.h>
+#include <sys/utsname.h>
 #include "kern_constants.h"
+#include "os.h"
+#include "user.h"
 
 void stack_protections(unsigned long address)
 {
-       if(mprotect((void *) address, UM_THREAD_SIZE,
+       if (mprotect((void *) address, UM_THREAD_SIZE,
                    PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
                panic("protecting stack failed, errno = %d", errno);
 }
@@ -44,17 +30,19 @@ int raw(int fd)
        int err;
 
        CATCH_EINTR(err = tcgetattr(fd, &tt));
-       if(err < 0)
+       if (err < 0)
                return -errno;
 
        cfmakeraw(&tt);
 
        CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
-       if(err < 0)
+       if (err < 0)
                return -errno;
 
-       /* XXX tcsetattr could have applied only some changes
-        * (and cfmakeraw() is a set of changes) */
+       /*
+        * XXX tcsetattr could have applied only some changes
+        * (and cfmakeraw() is a set of changes)
+        */
        return 0;
 }
 
@@ -88,6 +76,26 @@ void setup_hostinfo(char *buf, int len)
                 host.release, host.version, host.machine);
 }
 
+/*
+ * We cannot use glibc's abort(). It makes use of tgkill() which
+ * has no effect within UML's kernel threads.
+ * After that glibc would execute an invalid instruction to kill
+ * the calling process and UML crashes with SIGSEGV.
+ */
+static inline void __attribute__ ((noreturn)) uml_abort(void)
+{
+       sigset_t sig;
+
+       fflush(NULL);
+
+       if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT))
+               sigprocmask(SIG_UNBLOCK, &sig, 0);
+
+       for (;;)
+               if (kill(getpid(), SIGABRT) < 0)
+                       exit(127);
+}
+
 void os_dump_core(void)
 {
        int pid;
@@ -129,5 +137,5 @@ void os_dump_core(void)
        while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0)
                os_kill_ptraced_process(pid, 0);
 
-       abort();
+       uml_abort();
 }