Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / examples / APG / Processes / Spawn.cpp
blob711b10cb5fff1d9d85466d4722f5d133cfc280dc
1 #include "ace/OS_NS_stdio.h"
2 #include "ace/OS_NS_fcntl.h"
3 #include "ace/OS_NS_pwd.h"
4 #include "ace/os_include/os_pwd.h"
5 #include "ace/OS_NS_stdlib.h"
6 #include "ace/OS_NS_string.h"
7 #include "ace/OS_NS_unistd.h"
8 #include "ace/OS_NS_pwd.h"
9 #include "ace/Process.h"
10 #include "ace/Log_Msg.h"
12 // Listing 1 code/ch10
13 class Manager : public ACE_Process
15 public:
16 Manager (const ACE_TCHAR* program_name)
18 ACE_TRACE ("Manager::Manager");
19 ACE_OS::strcpy (programName_, program_name);
22 int doWork ()
24 ACE_TRACE ("Manager::doWork");
26 // Spawn the new process; prepare() hook is called first.
27 ACE_Process_Options options;
28 pid_t pid = this->spawn (options);
29 if (pid == ACE_INVALID_PID)
30 ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"),
31 ACE_TEXT ("spawn")), -1);
33 // Wait forever for my child to exit.
34 if (this->wait () == -1)
35 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
36 ACE_TEXT ("wait")), -1);
38 // Dump whatever happened.
39 this->dumpRun ();
40 return 0;
42 // Listing 1
44 private:
45 // Listing 3 code/ch10
46 int dumpRun ()
48 ACE_TRACE ("Manager::dumpRun");
50 if (ACE_OS::lseek (this->outputfd_, 0, SEEK_SET) == -1)
51 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
52 ACE_TEXT ("lseek")), -1);
54 char buf[1024];
55 ssize_t length = 0;
57 // Read the contents of the error stream written
58 // by the child and print it out.
59 while ((length = ACE_OS::read (this->outputfd_,
60 buf, sizeof(buf)-1)) > 0)
62 buf[length] = 0;
63 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%C\n"), buf));
66 ACE_OS::close (this->outputfd_);
67 return 0;
69 // Listing 3
71 // Listing 2 code/ch10
72 // prepare() is inherited from ACE_Process.
73 int prepare (ACE_Process_Options &options)
75 ACE_TRACE ("Manager::prepare");
77 options.command_line (ACE_TEXT ("%s 1"), this->programName_);
78 if (this->setStdHandles (options) == -1 ||
79 this->setEnvVariable (options) == -1)
80 return -1;
81 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_PWD_FUNCTIONS)
82 return this->setUserID (options);
83 #else
84 return 0;
85 #endif
88 int setStdHandles (ACE_Process_Options &options)
90 ACE_TRACE ("Manager::setStdHandles");
92 ACE_OS::unlink ("output.dat");
93 this->outputfd_ =
94 ACE_OS::open ("output.dat", O_RDWR | O_CREAT);
95 return options.set_handles
96 (ACE_STDIN, ACE_STDOUT, this->outputfd_);
99 int setEnvVariable (ACE_Process_Options &options)
101 ACE_TRACE ("Manager::setEnvVariables");
102 return options.setenv
103 (ACE_TEXT ("PRIVATE_VAR=/that/seems/to/be/it"));
105 // Listing 2
107 #if !defined (ACE_LACKS_PWD_FUNCTIONS)
108 // Listing 10 code/ch10
109 int setUserID (ACE_Process_Options &options)
111 ACE_TRACE ("Manager::setUserID");
112 passwd* pw = ACE_OS::getpwnam ("nobody");
113 if (pw == 0)
114 return -1;
115 options.seteuid (pw->pw_uid);
116 return 0;
118 // Listing 10
119 #endif /* !ACE_LACKS_PWD_FUNCTIONS */
121 private:
122 ACE_HANDLE outputfd_;
123 ACE_TCHAR programName_[256];
126 // Listing 4 code/ch10
127 class Slave
129 public:
130 Slave ()
132 ACE_TRACE ("Slave::Slave");
135 int doWork ()
137 ACE_TRACE ("Slave::doWork");
139 ACE_DEBUG ((LM_INFO,
140 ACE_TEXT ("(%P) started at %T, parent is %d\n"),
141 ACE_OS::getppid ()));
142 this->showWho ();
143 ACE_DEBUG ((LM_INFO,
144 ACE_TEXT ("(%P) the private environment is %s\n"),
145 ACE_OS::getenv ("PRIVATE_VAR")));
147 ACE_TCHAR str[128];
148 ACE_OS::sprintf (str, ACE_TEXT ("(%d) Enter your command\n"),
149 static_cast<int>(ACE_OS::getpid ()));
150 ACE_OS::write (ACE_STDOUT, str, ACE_OS::strlen (str));
151 this->readLine (str);
152 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Executed: %C\n"),
153 str));
154 return 0;
156 // Listing 4
158 void showWho ()
160 ACE_TRACE ("Slave::showWho");
161 #if !defined (ACE_LACKS_PWD_FUNCTIONS)
162 passwd *pw = ::getpwuid (ACE_OS::geteuid ());
163 ACE_DEBUG ((LM_INFO,
164 ACE_TEXT ("(%P) Running this process as:%s\n"),
165 pw->pw_name));
166 #endif
169 ACE_TCHAR* readLine (ACE_TCHAR* str)
171 ACE_TRACE ("Slave::readLine");
173 int i = 0;
174 while (true)
176 ssize_t retval = ACE_OS::read (ACE_STDIN, &str[i], 1);
177 if (retval > 0)
179 if (str[i] == '\n')
181 str[++i] = 0;
182 return str;
184 i++;
186 else
187 return str;
192 // Listing 0 code/ch10
193 int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
195 if (argc > 1) // Slave mode
197 Slave s;
198 return s.doWork ();
201 // Else, Master mode
202 Manager m (argv[0]);
203 return m.doWork ();
205 // Listing 0