ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dce-wait.cc
Go to the documentation of this file.
1 #include "dce-wait.h"
2 #include "utils.h"
3 #include "process.h"
4 #include "dce-manager.h"
5 #include "waiter.h"
6 #include "dce-stdlib.h"
7 #include "ns3/log.h"
8 #include "ns3/assert.h"
9 #include <errno.h>
10 #include <vector>
11 
12 NS_LOG_COMPONENT_DEFINE ("SimuWait");
13 
14 using namespace ns3;
15 
16 pid_t dce_wait (void *status)
17 {
18  return dce_waitpid (-1, (int*)status, 0);
19 }
20 
21 pid_t dce_waitpid (pid_t pid, int *status, int options)
22 {
23  Thread *thread = Current ();
24  NS_LOG_FUNCTION (thread);
25 
26  if ((options & WUNTRACED) || (options & WCONTINUED))
27  {
28  thread->err = EINVAL;
29  return -1;
30  }
31  if ((pid == 0) || (pid < -1)) // Process Group not yet supported.
32  {
33  thread->err = EINVAL;
34  return -1;
35  }
36 
37  while (true)
38  {
39  // Seek an ended child
40  int childCount = 0;
41 
42  for (std::set<uint16_t>::iterator it = thread->process->children.begin ();
43  it != thread->process->children.end (); it++)
44  {
45  if ((*it) > 1)
46  {
47  Process *p = thread->process->manager->SearchProcess (*it);
48 
49  if (p)
50  {
51  if ((pid == -1) || (pid == p->pid))
52  {
53  childCount++;
54  if (!p->alloc && !p->loader) // process zombie ?
55  {
56  pid_t id = p->pid;
57  int exitCode = p->timing.exitValue;
58 
59  std::set<uint16_t>::iterator it = thread->process->children.find (id);
60 
61  if (it != thread->process->children.end ())
62  {
63  thread->process->children.erase (it);
64  }
65  if (status)
66  {
67  *status = exitCode;
68  }
69  thread->process->manager->FinishChild (id);
70 
71  return id;
72  }
73  }
74  }
75  }
76  }
77  if (childCount)
78  {
79  if (options & WNOHANG)
80  {
81  return 0;
82  }
83  // I need wait
84  Waiter *waiter = new Waiter ();
85 
86  thread->childWaiter = waiter;
87 
88  if (waiter->WaitDoSignal ())
89  {
90  // loop retry
91  delete waiter;
92  thread->childWaiter = 0;
93  }
94  else
95  {
96  delete waiter;
97  thread->childWaiter = 0;
98  return -1;
99  }
100  }
101  else
102  {
103  thread->err = ECHILD;
104  return -1;
105  }
106  }
107 
108  return -1;
109 }