summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelliott_c <elliott_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-06-30 12:40:44 +0000
committerelliott_c <elliott_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2008-06-30 12:40:44 +0000
commit42d033238aa52a0584d868b37c1c7b3475f954f2 (patch)
tree965491a039d125e99c551a3927f3662b788cfb52
parentc5c7c4195d984a1d4ed5d1eaadadf973a6fc668e (diff)
downloadATCD-42d033238aa52a0584d868b37c1c7b3475f954f2.tar.gz
ChangeLogTag: Mon Jun 30 12:41:00 UTC 2008 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r--ACE/ChangeLog21
-rw-r--r--ACE/ace/Process.cpp93
-rw-r--r--ACE/ace/Process.h17
-rw-r--r--ACE/tests/Process_Env_Test.cpp73
-rw-r--r--ACE/tests/run_test.lst1
-rw-r--r--ACE/tests/tests.mpc7
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
+ }
+}