- Feb 07, 2012
-
-
Nat Goodspeed authored
Once again we've been bitten by comparison failure between "c:\somepath" and "C:\somepath". Normalize paths in both Python helper scripts to make that comparison more robust.
-
Nat Goodspeed authored
Apparently something in the Linux system header chain #defines a macro Status as 'int'. That's just Bad in C++ land. It should at the very least be a typedef! #undefining it in llprocess.h permits the viewer to build.
-
Nat Goodspeed authored
-
Nat Goodspeed authored
Include logic to engage Linden apr_procattr_autokill_set() extension: on Windows, magic CreateProcess() flag must be pushed down into apr_proc_create() level. When using an APR package without that extension, present implementation should lock (e.g.) SLVoice.exe lifespan to viewer's on Windows XP but probably won't on Windows 7: need magic flag on CreateProcess(). Using APR child-termination callback requires us to define state (e.g. LLProcess::RUNNING). Take the opportunity to present Status, capturing state and (if terminated) rc or signal number; but since most of the time all caller really wants is to log the outcome, also present status string, encapsulating logic to examine state and describe exited-with-rc vs. killed-by-signal. New Status logic may report clearer results in the case of a Windows child process killed by exception. Clarify that static LLProcess::isRunning(handle) overload is only for use when the original LLProcess object has been destroyed: really only for unit tests. We necessarily retain our original platform-specific implementations for just that one method. (Nonstatic isRunning() no longer calls static method.) Clarify log output from llprocess_test.cpp in a couple places.
-
- Feb 06, 2012
-
-
Nat Goodspeed authored
Any RAII class should either be noncopyable or should deal appropriately with a copy operation. ManageAPR is intended only for extremely simple cases, and hence should be noncopyable.
-
- Feb 03, 2012
-
-
Nat Goodspeed authored
TeamCity requires that certain characters (notably "'") must be escaped when embedded in service messages: http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ServiceMessages TUT frequently outputs messages containing "'", e.g. from ensure_equals() failure. We've seen TC output nesting get confused when it fails to process service messages properly due to parsing unescaped messages. Along with test<n> number, report test name (from set_test_name()) when available. Eliminate horsing around to produce normal output on both std::cout and possible output file. When output file is specified, use boost::iostreams::tee_device to do fanout for us. Improve placement (and possibly reliability) of service messages. Clean up a startling amount of redundancy in service-message production.
- Jan 30, 2012
-
-
Nat Goodspeed authored
Windows 7 and friends tend to create a process already implicitly allocated to a job object, and a process can only belong to a single job object. Passing CREATE_BREAKAWAY_FROM_JOB in CreateProcessA()'s dwCreationFlags seems to bypass the access-denied error observed with AssignProcessToJobObject() otherwise. This change should (!) enable OS lifespan management for SLVoice.exe et al.
-
Nat Goodspeed authored
-
Nat Goodspeed authored
On Posix, these and the corresponding getProcessID()/getProcessHandle() accessors produce the same pid_t value; but on Windows, it's useful to distinguish an int-like 'id' useful to human log readers versus an opaque 'handle' for passing to platform-specific API functions. So make the distinction in a platform-independent way.
-
Nat Goodspeed authored
-
- Jan 27, 2012
-
-
Nat Goodspeed authored
On Posix platforms, the OS argument mechanism makes quoting/reparsing unnecessary anyway, so this only affects Windows. Add optional 'triggers' parameter to LLStringUtils::quote() (default: space and double-quote). Only if the passed string contains a character in 'triggers' will it be double-quoted. This is observed to fix a Windows-specific problem in which plugin child process would fail to start because it wasn't expecting a quoted number. Use LLStringUtils::quote() more consistently in LLProcess implementation for logging.
-
- Jan 23, 2012
-
-
Nat Goodspeed authored
That is, we try to pass through each args entry as a separate child-process arvg[] entry, whitespace and all.
-
Nat Goodspeed authored
-
Nat Goodspeed authored
-
Nat Goodspeed authored
If LLProcess can't set the right flag on a Windows Job Object, the object isn't useful to us, so we might as well discard it. quote() is sufficiently general that it belongs in LLStringUtil instead of buried as a static helper function in llprocess.cpp.
-
- Jan 22, 2012
-
-
Nat Goodspeed authored
-
Nat Goodspeed authored
This appears to close a long-pending action item, as it seems the original LLProcessLauncher implementation was in fact cloned-and-edited from this logic in LLVivoxVoiceClient::stateMachine(). In any case, leveraging LLProcess buys us: - reduced redundancy; fewer maintenance points - logging for both success and errors - (possibly) better SLVoice.exe lifespan management.
-
Nat Goodspeed authored
Much as I dislike viewer log spam, seems to me starting a child process, killing it and observing its termination are noteworthy events. New logging makes LLExternalEditor launch message redundant; removed.
-
Nat Goodspeed authored
-
Nat Goodspeed authored
The idea is that, with the right flag settings, this will cause the OS to terminate remaining viewer child processes when the viewer terminates -- whether or not it terminates intentionally. Of course, if LLProcess's caller specifies autokill=false, e.g. to run the viewer updater, that asserts that we WANT the child to persist beyond the viewer session itself.
-
- Jan 21, 2012
-
-
Nat Goodspeed authored
-
Nat Goodspeed authored
Using a Params block gives compile-time checking against attribute typos. One might inadvertently set myLLSD["autofill"] = false and only discover it when things behave strangely at runtime; but trying to set myParams.autofill will produce a compile error. However, it's excellent that the same LLProcess::create() method can accept either LLProcess::Params or a properly-constructed LLSD block.
-
- Jan 20, 2012
-
-
Nat Goodspeed authored
This allows callers to pass either LLSD formatted as before -- which all callers still do -- or an actual LLProcess::Params block.
-
Nat Goodspeed authored
LLProcessLauncher had the somewhat fuzzy mandate of (1) accumulating parameters with which to launch a child process and (2) sometimes tracking the lifespan of the ensuing child process. But a valid LLProcessLauncher object might or might not have ever been associated with an actual child process. LLProcess specifically tracks a child process. In effect, it's a fairly thin wrapper around a process HANDLE (on Windows) or pid_t (elsewhere), with lifespan management thrown in. A static LLProcess::create() method launches a new child; create() accepts an LLSD bundle with child parameters. So building up a parameter bundle is deferred to LLSD rather than conflated with the process management object. Reconcile all known LLProcessLauncher consumers in the viewer code base, notably the class unit tests.
-
Richard Linden authored
-
Richard Linden authored
moved LLInitParam, and LLRegistry to llcommon moved LLUIColor, LLTrans, and LLXUIParser to llui reviewed by Nat
-
- Jan 19, 2012
-
-
Nat Goodspeed authored
-
Nat Goodspeed authored
Despite LLProcessLauncher's list-of-argument-strings API, on Windows it must ram them all into a single command-line string anyway. This means that if arguments contain spaces (or anything else that would confuse Windows command- line parsing), the target process won't receive the intended arguments. Introduce double quotes for any arguments not already double-quoted by caller.
-
- Jan 18, 2012
-
-
Nat Goodspeed authored
Apparently our TeamCity build machines are still not up to Python 2.6.
-
Nat Goodspeed authored
-
Nat Goodspeed authored
typedef LLProcessLauncher::ll_pid_t to be HANDLE on Windows, pid_t elsewhere. Then we can define getProcessID() returning ll_pid_t on all platforms, retaining getProcessHandle() for hypothetical existing consumers... of which there are none in practice. This lets us define isRunning(ll_pid_t) to encapsulate the platform-specific logic to actually check on a running child process, turning non-static isRunning() into a fairly trivial wrapper.
-
- Jan 17, 2012
-
-
Nat Goodspeed authored
-
Nat Goodspeed authored
Instead of free python() and python_out() functions containing a local temporary LLProcessLauncher instance, with a 'tweak' callback param to "do stuff" to that inaccessible object, change to a PythonProcessLauncher class that sets up a (public) LLProcessLauncher member, then allows you to run() or run() and then readfile() the output. Now you can construct an instance and tweak to your heart's content -- without funky callback syntax -- before running the script. Move all such helpers from TUT fixture struct to namespace scope. While fixture-struct methods can freely call one another, introducing a nested class gets awkward: constructor must explicitly require and bind a fixture-struct pointer or reference. Namespace scope solves this. (Truthfully, I only put them in the fixture struct originally because I thought it necessary for calling ensure() et al. But ensure() and friends are free functions; need only qualify them with tut:: namespace.)
-
Nat Goodspeed authored
NamedTempFile makes no attempt to deal with copying, therefore make it noncopyable.
-
Nat Goodspeed authored
Run INTEGRATION_TEST_llprocesslauncher using setpython.py so we can find the Python interpreter of interest. Introduce python() function to run a Python script specified using NamedTempFile conventions. Introduce a convention by which we can read output from a Python script using only the limited pre-January-2012 LLProcessLauncher API. Introduce python_out() function to leverage that convention. Exercise a couple of LLProcessLauncher methods using all the above.
-
Nat Goodspeed authored
On a Posix platform (vfork()/execv() implementation), if for any reason the execv() failed (e.g. executable not on PATH), the viewer would never know, nor the user: the vfork() child produced no output, and terminated with rc 0! Add logging, make child terminate with nonzero rc. Remove pointless addArgument(const char*) overload: this does nothing for you that the compiler won't do implicitly. In llupdateinstaller.cpp, remove pointless c_str() call in addArgument() arg: we were starting with a std::string, then extracting its c_str(), only to construct a whole new std::string from it!
-
Nat Goodspeed authored
-
- Jan 13, 2012
-
-
Nat Goodspeed authored
Specifically: Introduce ManageAPR class in indra/test/manageapr.h. This is useful for a simple test program without lots of static constructors. Extract NamedTempFile from llsdserialize_test.cpp to indra/test/ namedtempfile.h. Refactor to use APR file operations rather than platform- dependent APIs. Use NamedTempFile for llprocesslauncher_test.cpp.
-