* nat/linux-waitpid.c (linux_debug): Remove extraneous \n from output.
[external/binutils.git] / gdb / nat / linux-waitpid.c
1 /* Wrapper implementation for waitpid for GNU/Linux (LWP layer).
2
3    Copyright (C) 2001-2014 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #ifdef GDBSERVER
21 #include "server.h"
22 #else
23 #include "defs.h"
24 #include "signal.h"
25 #endif
26
27 #include "nat/linux-nat.h"
28 #include "nat/linux-waitpid.h"
29 #include "gdb_wait.h"
30
31 /* Print debugging output based on the format string FORMAT and
32    its parameters.  */
33
34 static inline void
35 linux_debug (const char *format, ...)
36 {
37 #ifdef GDBSERVER
38   if (debug_threads)
39     {
40       va_list args;
41       va_start (args, format);
42       vfprintf (stderr, format, args);
43       va_end (args);
44     }
45 #else
46   /* GDB-specific debugging output.  */
47 #endif
48 }
49
50 /* Wrapper function for waitpid which handles EINTR, and emulates
51    __WALL for systems where that is not available.  */
52
53 int
54 my_waitpid (int pid, int *status, int flags)
55 {
56   int ret, out_errno;
57
58   linux_debug ("my_waitpid (%d, 0x%x)\n", pid, flags);
59
60   if (flags & __WALL)
61     {
62       sigset_t block_mask, org_mask, wake_mask;
63       int wnohang;
64
65       wnohang = (flags & WNOHANG) != 0;
66       flags &= ~(__WALL | __WCLONE);
67       flags |= WNOHANG;
68
69       /* Block all signals while here.  This avoids knowing about
70          LinuxThread's signals.  */
71       sigfillset (&block_mask);
72       sigprocmask (SIG_BLOCK, &block_mask, &org_mask);
73
74       /* ... except during the sigsuspend below.  */
75       sigemptyset (&wake_mask);
76
77       while (1)
78         {
79           /* Since all signals are blocked, there's no need to check
80              for EINTR here.  */
81           ret = waitpid (pid, status, flags);
82           out_errno = errno;
83
84           if (ret == -1 && out_errno != ECHILD)
85             break;
86           else if (ret > 0)
87             break;
88
89           if (flags & __WCLONE)
90             {
91               /* We've tried both flavors now.  If WNOHANG is set,
92                  there's nothing else to do, just bail out.  */
93               if (wnohang)
94                 break;
95
96               linux_debug ("blocking\n");
97
98               /* Block waiting for signals.  */
99               sigsuspend (&wake_mask);
100             }
101           flags ^= __WCLONE;
102         }
103
104       sigprocmask (SIG_SETMASK, &org_mask, NULL);
105     }
106   else
107     {
108       do
109         ret = waitpid (pid, status, flags);
110       while (ret == -1 && errno == EINTR);
111       out_errno = errno;
112     }
113
114   linux_debug ("my_waitpid (%d, 0x%x): status(%x), %d\n",
115                pid, flags, status ? *status : -1, ret);
116
117   errno = out_errno;
118   return ret;
119 }