Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / tests / Process_Test.cpp
blobda2c0f67bb2e0630c838225c0d83d28c8817d0e8
2 //=============================================================================
3 /**
4 * @file Process_Test.cpp
6 * Tests ACE_Process file handle inheritance for UNIX-like systems
8 * @author Christian Fromme <kaner@strace.org>
9 */
10 //=============================================================================
12 #include "test_config.h"
13 #include "ace/Process.h"
14 #include "ace/Get_Opt.h"
15 #include "ace/Lib_Find.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/OS_NS_sys_stat.h"
18 #include "ace/OS_NS_unistd.h"
19 #include "ace/Dirent.h"
20 #include "ace/SString.h"
21 #include "ace/OS_NS_stdlib.h"
23 // This will only work on Linux. Even UNIX-ish with /proc filesys lacks the
24 // 'self' level and link to the opened file name.
25 static const char *proc_self_fd = "/proc/self/fd/";
27 int
28 test_setenv ()
30 int status = 0;
31 ACE_Process_Options opts;
32 ACE_TCHAR bigval[5010] = ACE_TEXT ("");
33 for (int i = 0; i < 100; ++i)
34 ACE_OS::strcat (bigval,
35 ACE_TEXT ("01234567890123456789012345678901234567890123456789"));
36 #ifndef ACE_LACKS_VA_FUNCTIONS
37 if (0 != opts.setenv (ACE_TEXT ("A"), ACE_TEXT ("%") ACE_TEXT_PRIs, bigval))
39 status = errno;
40 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("setenv")));
42 else
44 size_t env_len = ACE_OS::strlen (opts.env_buf ());
45 if (env_len != 5002)
47 status = 1;
48 ACE_ERROR ((LM_ERROR,
49 ACE_TEXT ("setenv result should be 5002 chars, not %B\n"),
50 env_len));
53 #endif
54 return status;
58 int
59 check_temp_file (const ACE_TString &tmpfilename)
61 ACE_DIRENT *dir = 0;
62 ACE_Dirent entr;
63 ACE_stat stat;
64 char filename[MAXPATHLEN + 1];
66 ACE_OS::memset (&stat, 0, sizeof (stat));
67 ACE_OS::memset (&entr, 0, sizeof (entr));
69 // Loop through /proc/self/fs/
70 if (entr.open (ACE_TEXT_CHAR_TO_TCHAR(proc_self_fd)) == -1)
71 ACE_ERROR_RETURN ((LM_ERROR,
72 ACE_TEXT ("Could not open dir %C\n"),
73 proc_self_fd),
74 -1);
76 while ((dir = entr.read ()))
78 ACE_CString fullp = proc_self_fd;
79 #if defined (ACE_HAS_TCHAR_DIRENT)
80 fullp += ACE_TEXT_ALWAYS_CHAR(dir->d_name);
81 #else
82 fullp += dir->d_name;
83 #endif
85 if ((ACE_OS::lstat (fullp.c_str (), &stat)) == -1)
86 ACE_ERROR_RETURN ((LM_ERROR,
87 ACE_TEXT ("Stat failed for %C\n"),
88 fullp.c_str ()),
89 -1);
91 if (S_ISLNK (stat.st_mode))
93 ssize_t size = 0;
94 if ((size= ACE_OS::readlink (fullp.c_str (),
95 filename,
96 MAXPATHLEN + 1)) == -1)
97 ACE_ERROR_RETURN ((LM_ERROR,
98 ACE_TEXT ("Readlink failed for %C\n"),
99 fullp.c_str ()),
100 -1);
101 filename[size] = '\0';
102 if (tmpfilename == ACE_TString (ACE_TEXT_CHAR_TO_TCHAR (filename)))
103 return 1;
107 return 0;
111 run_parent (bool inherit_files)
113 int status = 0;
115 ACE_TCHAR t[] = ACE_TEXT ("ace_testXXXXXX");
117 // Create tempfile. This will be tested for inheritance.
118 ACE_TCHAR tempfile[MAXPATHLEN + 1];
120 if (ACE::get_temp_dir (tempfile, MAXPATHLEN - sizeof (t)) == -1)
121 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could not get temp dir\n")));
123 ACE_OS::strcat (tempfile, t);
125 ACE_HANDLE file_handle = ACE_OS::mkstemp (tempfile);
126 if (file_handle == ACE_INVALID_HANDLE)
128 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could not get temp filename\n")));
129 status = 1;
132 // Build child options
133 ACE_TString exe_sub_dir;
134 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
135 if (subdir_env)
137 exe_sub_dir = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
138 exe_sub_dir += ACE_DIRECTORY_SEPARATOR_STR;
141 ACE_Process_Options options;
142 #ifndef ACE_LACKS_VA_FUNCTIONS
143 options.command_line (ACE_TEXT (".") ACE_DIRECTORY_SEPARATOR_STR
144 ACE_TEXT ("%sProcess_Test")
145 ACE_PLATFORM_EXE_SUFFIX
146 ACE_TEXT (" -c -h %d -f %s"),
147 exe_sub_dir.c_str(),
148 (int)inherit_files,
149 tempfile);
150 #endif
151 options.handle_inheritance (inherit_files); /* ! */
153 // Spawn child
154 ACE_Process child;
156 pid_t result = child.spawn (options);
157 if (result == -1)
159 status = errno;
160 ACE_ERROR ((LM_ERROR,
161 ACE_TEXT ("Parent could NOT spawn child process\n")));
163 else
164 ACE_DEBUG ((LM_DEBUG,
165 ACE_TEXT ("Parent spawned child process with pid = %d.\n"),
166 child.getpid ()));
168 ACE_exitcode child_status;
169 result = child.wait (&child_status);
170 if (result == -1)
172 status = errno;
173 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Could NOT wait on child process\n")));
175 else if (child_status == 0)
176 ACE_DEBUG ((LM_DEBUG,
177 ACE_TEXT ("Child %d finished ok\n"),
178 child.getpid ()));
179 else
181 status = child_status;
182 ACE_ERROR ((LM_ERROR,
183 ACE_TEXT ("Child %d finished with status %d\n"),
184 child.getpid (), child_status));
187 return status;
191 run_main (int argc, ACE_TCHAR *argv[])
193 int c = 0;
194 int handle_inherit = 0; /* Disable inheritance by default */
195 bool ischild = false;
196 ACE_TString temp_file_name;
198 ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("ch:f:"));
200 while ((c = getopt ()) != -1)
201 switch ((char) c)
203 case 'c':
204 ischild = true;
205 break;
206 case 'h':
207 handle_inherit = ACE_OS::atoi (getopt.opt_arg ());
208 break;
209 case 'f':
210 temp_file_name = getopt.opt_arg ();
211 break;
212 default:
213 // Don't forgive bad options
214 ACE_ERROR_RETURN ((LM_ERROR,
215 ACE_TEXT ("Bad option\n")),
216 -1);
217 break;
220 if (ischild)
222 ACE_TCHAR lognm[MAXPATHLEN];
223 int const mypid (ACE_OS::getpid ());
224 ACE_OS::snprintf (lognm, MAXPATHLEN,
225 ACE_TEXT ("Process_Test-child-%d"), mypid);
226 ACE_START_TEST (lognm);
228 int result = check_temp_file (temp_file_name);
229 // Check descriptor inheritance
230 if (result == -1)
231 ACE_ERROR_RETURN ((LM_ERROR,
232 ACE_TEXT ("Could not retrieve open files\n")),
233 -1);
234 else if (result == handle_inherit)
235 result = 0;
236 else
237 ACE_ERROR ((LM_ERROR,
238 ACE_TEXT ("Handle inheritance test failed with ")
239 ACE_TEXT ("%d, expected %d\n"), result, handle_inherit));
240 ACE_END_LOG;
241 return result;
243 else
245 ACE_START_TEST (ACE_TEXT ("Process_Test"));
247 int status = test_setenv ();
249 // The rest of this test relies on the ability to get a list of open
250 // files for a process and examine each file descriptor to see which
251 // file is open, matching against an expected opened file name.
252 // Although most systems provide some mechanism to do this, the code
253 // in this test uses Linux-specific techniques. Thus, although it
254 // is possible to add the code for the checks on, for example,
255 // HP-UX (pstat_getproc, pstat_getpathname)
256 #if defined (ACE_LACKS_FORK) || defined (ACE_LACKS_READLINK) || !defined(ACE_LINUX)
257 ACE_ERROR ((LM_INFO,
258 ACE_TEXT ("The remainder of this test is not supported on this platform\n")));
259 #else
260 // Test handle inheritance set to true
261 if (!status)
262 status = run_parent (true);
264 // ... and set to false
265 if (!status)
266 run_parent (false);
267 #endif /* ! ACE_LACKS_FORK */
269 ACE_END_TEST;
270 return status;