| Index: gdb/nat/linux-waitpid.c | 
| diff --git a/gdb/nat/linux-waitpid.c b/gdb/nat/linux-waitpid.c | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..2debea488758d7722fbe148b873c883d38672d78 | 
| --- /dev/null | 
| +++ b/gdb/nat/linux-waitpid.c | 
| @@ -0,0 +1,120 @@ | 
| +/* Wrapper implementation for waitpid for GNU/Linux (LWP layer). | 
| + | 
| +   Copyright (C) 2001-2013 Free Software Foundation, Inc. | 
| + | 
| +   This file is part of GDB. | 
| + | 
| +   This program is free software; you can redistribute it and/or modify | 
| +   it under the terms of the GNU General Public License as published by | 
| +   the Free Software Foundation; either version 3 of the License, or | 
| +   (at your option) any later version. | 
| + | 
| +   This program is distributed in the hope that it will be useful, | 
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| +   GNU General Public License for more details. | 
| + | 
| +   You should have received a copy of the GNU General Public License | 
| +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
| + | 
| +#ifdef GDBSERVER | 
| +#include "server.h" | 
| +#else | 
| +#include "defs.h" | 
| +#include "signal.h" | 
| +#endif | 
| + | 
| +#include "nat/linux-nat.h" | 
| +#include "nat/linux-waitpid.h" | 
| +#include "gdb_wait.h" | 
| + | 
| +/* Print debugging output based on the format string FORMAT and | 
| +   its parameters.  */ | 
| + | 
| +static inline void | 
| +linux_debug (const char *format, ...) | 
| +{ | 
| +#ifdef GDBSERVER | 
| +  if (debug_threads) | 
| +    { | 
| +      va_list args; | 
| +      va_start (args, format); | 
| +      vfprintf (stderr, format, args); | 
| +      fprintf (stderr, "\n"); | 
| +      va_end (args); | 
| +    } | 
| +#else | 
| +  /* GDB-specific debugging output.  */ | 
| +#endif | 
| +} | 
| + | 
| +/* Wrapper function for waitpid which handles EINTR, and emulates | 
| +   __WALL for systems where that is not available.  */ | 
| + | 
| +int | 
| +my_waitpid (int pid, int *status, int flags) | 
| +{ | 
| +  int ret, out_errno; | 
| + | 
| +  linux_debug ("my_waitpid (%d, 0x%x)\n", pid, flags); | 
| + | 
| +  if (flags & __WALL) | 
| +    { | 
| +      sigset_t block_mask, org_mask, wake_mask; | 
| +      int wnohang; | 
| + | 
| +      wnohang = (flags & WNOHANG) != 0; | 
| +      flags &= ~(__WALL | __WCLONE); | 
| +      flags |= WNOHANG; | 
| + | 
| +      /* Block all signals while here.  This avoids knowing about | 
| +	 LinuxThread's signals.  */ | 
| +      sigfillset (&block_mask); | 
| +      sigprocmask (SIG_BLOCK, &block_mask, &org_mask); | 
| + | 
| +      /* ... except during the sigsuspend below.  */ | 
| +      sigemptyset (&wake_mask); | 
| + | 
| +      while (1) | 
| +	{ | 
| +	  /* Since all signals are blocked, there's no need to check | 
| +	     for EINTR here.  */ | 
| +	  ret = waitpid (pid, status, flags); | 
| +	  out_errno = errno; | 
| + | 
| +	  if (ret == -1 && out_errno != ECHILD) | 
| +	    break; | 
| +	  else if (ret > 0) | 
| +	    break; | 
| + | 
| +	  if (flags & __WCLONE) | 
| +	    { | 
| +	      /* We've tried both flavors now.  If WNOHANG is set, | 
| +		 there's nothing else to do, just bail out.  */ | 
| +	      if (wnohang) | 
| +		break; | 
| + | 
| +	      linux_debug ("blocking\n"); | 
| + | 
| +	      /* Block waiting for signals.  */ | 
| +	      sigsuspend (&wake_mask); | 
| +	    } | 
| +	  flags ^= __WCLONE; | 
| +	} | 
| + | 
| +      sigprocmask (SIG_SETMASK, &org_mask, NULL); | 
| +    } | 
| +  else | 
| +    { | 
| +      do | 
| +	ret = waitpid (pid, status, flags); | 
| +      while (ret == -1 && errno == EINTR); | 
| +      out_errno = errno; | 
| +    } | 
| + | 
| +  linux_debug ("my_waitpid (%d, 0x%x): status(%x), %d\n", | 
| +	       pid, flags, status ? *status : -1, ret); | 
| + | 
| +  errno = out_errno; | 
| +  return ret; | 
| +} | 
|  |