diff options
author | elliott_c <elliott_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-06-30 12:40:44 +0000 |
---|---|---|
committer | elliott_c <elliott_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-06-30 12:40:44 +0000 |
commit | 42d033238aa52a0584d868b37c1c7b3475f954f2 (patch) | |
tree | 965491a039d125e99c551a3927f3662b788cfb52 | |
parent | c5c7c4195d984a1d4ed5d1eaadadf973a6fc668e (diff) | |
download | ATCD-42d033238aa52a0584d868b37c1c7b3475f954f2.tar.gz |
ChangeLogTag: Mon Jun 30 12:41:00 UTC 2008 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r-- | ACE/ChangeLog | 21 | ||||
-rw-r--r-- | ACE/ace/Process.cpp | 93 | ||||
-rw-r--r-- | ACE/ace/Process.h | 17 | ||||
-rw-r--r-- | ACE/tests/Process_Env_Test.cpp | 73 | ||||
-rw-r--r-- | ACE/tests/run_test.lst | 1 | ||||
-rw-r--r-- | ACE/tests/tests.mpc | 7 |
6 files changed, 209 insertions, 3 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog index c78f27d0ba3..46ddda07abf 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,24 @@ +Mon Jun 30 12:41:00 UTC 2008 Chad Elliott <elliott_c@ociweb.com> + + * ace/Process.h: + * ace/Process.cpp: + + Added an option to ACE_Process_Options to use a wchar_t environmet + buffer instead of char. This is useful only on Windows with + ACE_USES_WCHAR undefined. The benefit of using a wchar_t + environment buffer is that it is not limited to 32kb as a char + environment buffer is. + + In ACE_Process::spawn(), convert the char environment buffer to a + wchar_t environment buffer if specified to do so in the process + options. + + * tests/Process_Env_Test.cpp: + * tests/run_test.lst: + * tests/tests.mpc: + + Added a test for the above feature. + Fri Jun 27 18:04:52 UTC 2008 Steve Huston <shuston@riverace.com> * include/makeinclude/rules.local.GNU: Removed the first setting of diff --git a/ACE/ace/Process.cpp b/ACE/ace/Process.cpp index 46488b6b4a4..67006690bc4 100644 --- a/ACE/ace/Process.cpp +++ b/ACE/ace/Process.cpp @@ -20,6 +20,7 @@ #include "ace/OS_Memory.h" #include "ace/Countdown_Time.h" #include "ace/Truncate.h" +#include "ace/Vector_T.h" #if defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600) && defined (__RTP__) # include <rtpLib.h> @@ -157,18 +158,35 @@ ACE_Process::spawn (ACE_Process_Options &options) return ACE_INVALID_PID; #elif defined (ACE_WIN32) + void* env_buf = options.env_buf (); + DWORD flags = options.creation_flags (); +# if !defined (ACE_USES_WCHAR) + wchar_t* wenv_buf = 0; + if (options.use_unicode_environment ()) + { + wenv_buf = this->convert_env_buffer (options.env_buf ()); + env_buf = wenv_buf; + flags |= CREATE_UNICODE_ENVIRONMENT; + } +# endif + BOOL fork_result = ACE_TEXT_CreateProcess (0, options.command_line_buf (), options.get_process_attributes (), options.get_thread_attributes (), options.handle_inheritence (), - options.creation_flags (), - options.env_buf (), // environment variables + flags, + env_buf, // environment variables options.working_directory (), options.startup_info (), &this->process_info_); +# if !defined (ACE_USES_WCHAR) + if (options.use_unicode_environment ()) + delete wenv_buf; +# endif + if (fork_result) { parent (this->getpid ()); @@ -712,6 +730,56 @@ ACE_Process::close_passed_handles (void) return; } +#if defined (ACE_WIN32) && !defined (ACE_USES_WCHAR) && !defined (ACE_HAS_WINCE) +wchar_t* +ACE_Process::convert_env_buffer (const char* env) const +{ + // Total starts out at 1 due to the final block nul terminator + size_t total = 1; + + // Convert each individual character string to the equivalent wide + // character string. + ACE_Vector<wchar_t*> buffer; + size_t start = 0; + size_t i = 0; + while (true) + { + if (env[i] == '\0') + { + // Convert the char string to wchar_t + wchar_t* str = ACE_Ascii_To_Wide::convert (env + start); + + // Add the length of the string plus the nul terminator + total += ACE_OS::strlen (str) + 1; + + // Save it and set up for the next string + buffer.push_back (str); + start = ++i; + if (env[start] == '\0') + break; + } + else + { + i += ACE_OS::strlen (env + i); + } + } + + // Copy each string into the buffer leaving a nul terminator between + // each string and adding a second nul terminator at the end + start = 0; + wchar_t* wenv = new wchar_t[total]; + size_t length = buffer.size (); + for (i = 0; i < length; ++i) + { + ACE_OS::strcpy(wenv + start, buffer[i]); + start += ACE_OS::strlen (buffer[i]) + 1; + delete [] buffer[i]; + } + wenv[start] = 0; + return wenv; +} +#endif + ACE_Process_Options::ACE_Process_Options (bool inherit_environment, int command_line_buf_len, int env_buf_len, @@ -749,7 +817,8 @@ ACE_Process_Options::ACE_Process_Options (bool inherit_environment, command_line_buf_ (0), command_line_copy_ (0), command_line_buf_len_ (command_line_buf_len), - process_group_ (ACE_INVALID_PID) + process_group_ (ACE_INVALID_PID), + use_unicode_environment_ (false) { ACE_NEW (command_line_buf_, ACE_TCHAR[command_line_buf_len]); @@ -818,6 +887,24 @@ ACE_Process_Options::env_argv (void) #endif /* ACE_WIN32 */ +void +ACE_Process_Options::enable_unicode_environment (void) +{ + this->use_unicode_environment_ = true; +} + +void +ACE_Process_Options::disable_unicode_environment (void) +{ + this->use_unicode_environment_ = false; +} + +bool +ACE_Process_Options::use_unicode_environment (void) const +{ + return this->use_unicode_environment_; +} + int ACE_Process_Options::setenv (ACE_TCHAR *envp[]) { diff --git a/ACE/ace/Process.h b/ACE/ace/Process.h index 0d209d2e0ab..96f097502af 100644 --- a/ACE/ace/Process.h +++ b/ACE/ace/Process.h @@ -260,6 +260,16 @@ public: /// Get current value for avoid_zombies. int avoid_zombies (void); + /// Enable the use of a Unicode environment. This only makes sense + /// for Win32 when ACE_USES_WCHAR is not defined. + void enable_unicode_environment (void); + + /// Disable the use of a Unicode environment. + void disable_unicode_environment (void); + + /// Return the unicode environment status + bool use_unicode_environment (void) const; + #if defined (ACE_WIN32) // = Non-portable accessors for when you "just have to use them." @@ -427,6 +437,9 @@ protected: /// Pathname for the process. Relative path or absolute path or just /// the program name. ACE_TCHAR process_name_[MAXPATHLEN + 1]; + + /// Indicate if a Unicode environment should be used + bool use_unicode_environment_; }; //class ACE_Process_Manager; @@ -604,6 +617,10 @@ protected: /// Make sure that we're allocated dynamically! virtual ~ACE_Managed_Process (void); +private: +#if defined (ACE_WIN32) && !defined (ACE_USES_WCHAR) && !defined (ACE_HAS_WINCE) + wchar_t* convert_env_buffer (const char* env) const; +#endif }; ACE_END_VERSIONED_NAMESPACE_DECL diff --git a/ACE/tests/Process_Env_Test.cpp b/ACE/tests/Process_Env_Test.cpp new file mode 100644 index 00000000000..6eadccd383d --- /dev/null +++ b/ACE/tests/Process_Env_Test.cpp @@ -0,0 +1,73 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// tests +// +// = FILENAME +// Process_Env_Test.cpp +// +// = DESCRIPTION +// This program tests the limits of the Windows CreateProcess +// environment buffer. +// +// = AUTHOR +// Chad Elliott <elliott_c@ociweb.com> +// +// ============================================================================ + +#include "test_config.h" +#include "ace/Process.h" + +ACE_RCSID(tests, + Process_Env_Test, + "$Id$"); + +int +run_main (int, ACE_TCHAR*[]) +{ + int test_status = 0; + ACE_START_TEST (ACE_TEXT ("Process_Env_Test")); + +#if defined (ACE_WIN32) && !defined (ACE_USES_WCHAR) && !defined (ACE_HAS_WINCE) + ACE_Process_Options options ( + 0, + ACE_Process_Options::DEFAULT_COMMAND_LINE_BUF_LEN, + 32 * 1024); + options.command_line (ACE_TEXT ("attrib.exe /?")); + static const size_t varsize = 1200; + for(int i = 0; i < 26; i++) + { + char name[2] = { 'A' + i, '\0' }; + char value[varsize]; + memset(value, 'R', varsize); + value[varsize - 1] = '\0'; + options.setenv (ACE_TEXT (name), ACE_TEXT (value)); + } + + + ACE_OS::fclose(stdout); + ACE_Process process; + if (process.spawn (options) != -1) + { + ACE_ERROR ((LM_DEBUG, + "ERROR: This should have failed due to the large " + "environment buffer\n")); + test_status = 1; + } + + options.enable_unicode_environment (); + if (process.spawn (options) == -1) + { + ACE_ERROR ((LM_DEBUG, + "ERROR: This should have succeeded\n")); + test_status = 1; + } +#else + ACE_ERROR ((LM_INFO, "This test is for Win32 without ACE_USES_WCHAR\n")); +#endif /* ACE_WIN32 && !ACE_USES_WCHAR && !ACE_HAS_WINCE */ + + ACE_END_TEST; + return test_status; +} diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst index a01be97fe28..b61ecbe70a0 100644 --- a/ACE/tests/run_test.lst +++ b/ACE/tests/run_test.lst @@ -121,6 +121,7 @@ Proactor_Scatter_Gather_Test: !VxWorks !nsk !ACE_FOR_TAO Proactor_Test: !VxWorks !LynxOS !nsk !ACE_FOR_TAO !BAD_AIO Proactor_Timer_Test: !VxWorks !nsk !ACE_FOR_TAO Proactor_UDP_Test: !VxWorks !LynxOS !nsk !ACE_FOR_TAO !BAD_AIO +Process_Env_Test: !VxWorks !PHARLAP Process_Manager_Test: !VxWorks !ACE_FOR_TAO !PHARLAP Process_Manual_Event_Test: !HPUX !VxWorks !ACE_FOR_TAO !PHARLAP Process_Mutex_Test: !VxWorks !ACE_FOR_TAO !PHARLAP diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc index a6a2dce1ebd..8fcb885cc6d 100644 --- a/ACE/tests/tests.mpc +++ b/ACE/tests/tests.mpc @@ -1548,3 +1548,10 @@ project(Bug_2610_Regression_Test) : acetest { Bug_2610_Regression_Test.cpp } } + +project(Process_Env_Test) : acetest { + exename = Process_Env_Test + Source_Files { + Process_Env_Test.cpp + } +} |