1  /* wait.c -- functions for getting wait status values.
       2  
       3     Copyright 2011 The Go Authors. All rights reserved.
       4     Use of this source code is governed by a BSD-style
       5     license that can be found in the LICENSE file.
       6  
       7     We use C code to extract the wait status so that we can easily be
       8     OS-independent.  */
       9  
      10  #include <stdint.h>
      11  #include <sys/wait.h>
      12  
      13  #include "runtime.h"
      14  
      15  #ifndef WCOREDUMP
      16  #define WCOREDUMP(status) (((status) & 0200) != 0)
      17  #endif
      18  
      19  #ifndef WIFCONTINUED
      20  #define WIFCONTINUED(x) 0
      21  #endif
      22  
      23  extern _Bool Exited (uint32_t *w)
      24    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Exited");
      25  
      26  _Bool
      27  Exited (uint32_t *w)
      28  {
      29    return WIFEXITED (*w) != 0;
      30  }
      31  
      32  extern _Bool Signaled (uint32_t *w)
      33    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Signaled");
      34  
      35  _Bool
      36  Signaled (uint32_t *w)
      37  {
      38    return WIFSIGNALED (*w) != 0;
      39  }
      40  
      41  extern _Bool Stopped (uint32_t *w)
      42    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Stopped");
      43  
      44  _Bool
      45  Stopped (uint32_t *w)
      46  {
      47    return WIFSTOPPED (*w) != 0;
      48  }
      49  
      50  extern _Bool Continued (uint32_t *w)
      51    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Continued");
      52  
      53  _Bool
      54  Continued (uint32_t *w __attribute__ ((unused)))
      55  {
      56    return WIFCONTINUED (*w) != 0;
      57  }
      58  
      59  extern _Bool CoreDump (uint32_t *w)
      60    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.CoreDump");
      61  
      62  _Bool
      63  CoreDump (uint32_t *w)
      64  {
      65    return WCOREDUMP (*w) != 0;
      66  }
      67  
      68  extern intgo ExitStatus (uint32_t *w)
      69    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.ExitStatus");
      70  
      71  intgo
      72  ExitStatus (uint32_t *w)
      73  {
      74    if (!WIFEXITED (*w))
      75      return -1;
      76    return WEXITSTATUS (*w);
      77  }
      78  
      79  extern intgo Signal (uint32_t *w)
      80    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.Signal");
      81  
      82  intgo
      83  Signal (uint32_t *w)
      84  {
      85    if (!WIFSIGNALED (*w))
      86      return -1;
      87    return WTERMSIG (*w);
      88  }
      89  
      90  extern intgo StopSignal (uint32_t *w)
      91    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.StopSignal");
      92  
      93  intgo
      94  StopSignal (uint32_t *w)
      95  {
      96    if (!WIFSTOPPED (*w))
      97      return -1;
      98    return WSTOPSIG (*w);
      99  }
     100  
     101  extern intgo TrapCause (uint32_t *w)
     102    __asm__ (GOSYM_PREFIX "syscall.WaitStatus.TrapCause");
     103  
     104  intgo
     105  TrapCause (uint32_t *w __attribute__ ((unused)))
     106  {
     107  #ifndef __linux__
     108    return -1;
     109  #else
     110    if (!WIFSTOPPED (*w) || WSTOPSIG (*w) != SIGTRAP)
     111      return -1;
     112    return *w >> 16;
     113  #endif
     114  }