diff options
Diffstat (limited to 'examples/APG/Processes/Spawn.cpp')
-rw-r--r-- | examples/APG/Processes/Spawn.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/examples/APG/Processes/Spawn.cpp b/examples/APG/Processes/Spawn.cpp new file mode 100644 index 00000000000..a8a3e76e6f6 --- /dev/null +++ b/examples/APG/Processes/Spawn.cpp @@ -0,0 +1,205 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_pwd.h" +#include "ace/os_include/os_pwd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Process.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch10 +class Manager : public ACE_Process +{ +public: + Manager (const ACE_TCHAR* program_name) + { + ACE_TRACE (ACE_TEXT ("Manager::Manager")); + ACE_OS::strcpy (programName_, program_name); + } + + int doWork (void) + { + ACE_TRACE (ACE_TEXT ("Manager::doWork")); + + // Spawn the new process; prepare() hook is called first. + ACE_Process_Options options; + pid_t pid = this->spawn (options); + if (pid == -1) + ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("spawn")), -1); + + // Wait forever for my child to exit. + if (this->wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("wait")), -1); + + // Dump whatever happened. + this->dumpRun (); + return 0; + } +// Listing 1 + +private: + // Listing 3 code/ch10 + int dumpRun (void) + { + ACE_TRACE (ACE_TEXT ("Manager::dumpRun")); + + if (ACE_OS::lseek (this->outputfd_, 0, SEEK_SET) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("lseek")), -1); + + char buf[1024]; + int length = 0; + + // Read the contents of the error stream written + // by the child and print it out. + while ((length = ACE_OS::read (this->outputfd_, + buf, sizeof(buf)-1)) > 0) + { + buf[length] = 0; + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%C\n"), buf)); + } + + ACE_OS::close (this->outputfd_); + return 0; + } + // Listing 3 + + // Listing 2 code/ch10 + // prepare() is inherited from ACE_Process. + int prepare (ACE_Process_Options &options) + { + ACE_TRACE (ACE_TEXT ("Manager::prepare")); + + options.command_line ("%s 1", this->programName_); + if (this->setStdHandles (options) == -1 || + this->setEnvVariable (options) == -1) + return -1; +#if !defined (ACE_WIN32) + return this->setUserID (options); +#else + return 0; +#endif + } + + int setStdHandles (ACE_Process_Options &options) + { + ACE_TRACE(ACE_TEXT ("Manager::setStdHandles")); + + ACE_OS::unlink ("output.dat"); + this->outputfd_ = + ACE_OS::open ("output.dat", O_RDWR | O_CREAT); + return options.set_handles + (ACE_STDIN, ACE_STDOUT, this->outputfd_); + } + + int setEnvVariable (ACE_Process_Options &options) + { + ACE_TRACE (ACE_TEXT ("Manager::setEnvVariables")); + return options.setenv ("PRIVATE_VAR=/that/seems/to/be/it"); + } + // Listing 2 + +#if !defined (ACE_WIN32) + // Listing 10 code/ch10 + int setUserID (ACE_Process_Options &options) + { + ACE_TRACE (ACE_TEXT ("Manager::setUserID")); + passwd* pw = ACE_OS::getpwnam ("nobody"); + if (pw == 0) + return -1; + options.seteuid (pw->pw_uid); + return 0; + } + // Listing 10 +#endif /* ACE_WIN32 */ + +private: + ACE_HANDLE outputfd_; + ACE_TCHAR programName_[256]; +}; + +// Listing 4 code/ch10 +class Slave +{ +public: + Slave () + { + ACE_TRACE (ACE_TEXT ("Slave::Slave")); + } + + int doWork (void) + { + ACE_TRACE (ACE_TEXT ("Slave::doWork")); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) started at %T, parent is %d\n"), + ACE_OS::getppid ())); + this->showWho (); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) the private environment is %s\n"), + ACE_OS::getenv ("PRIVATE_VAR"))); + + ACE_TCHAR str[128]; + ACE_OS::sprintf (str, ACE_TEXT ("(%d) Enter your command\n"), + ACE_OS::getpid ()); + ACE_OS::write (ACE_STDOUT, str, ACE_OS::strlen (str)); + this->readLine (str); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Executed: %C\n"), + str)); + return 0; + } +// Listing 4 + + void showWho (void) + { + ACE_TRACE (ACE_TEXT ("Slave::showWho")); +#if !defined (ACE_WIN32) + passwd *pw = ::getpwuid (::geteuid ()); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) Running this process as:%s\n"), + pw->pw_name)); +#endif + } + + ACE_TCHAR* readLine (ACE_TCHAR* str) + { + ACE_TRACE (ACE_TEXT ("Slave::readLine")); + + int i = 0; + while (true) + { + int retval = ACE_OS::read (ACE_STDIN, &str[i], 1); + if (retval > 0) + { + if (str[i] == '\n') + { + str[++i] = 0; + return str; + } + i++; + } + else + return str; + } + } +}; + +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Slave mode + { + Slave s; + return s.doWork (); + } + + // Else, Master mode + Manager m (argv[0]); + return m.doWork (); +} +// Listing 0 |