diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2008-03-04 14:51:23 +0000 |
commit | 99aa8c60282c7b8072eb35eb9ac815702f5bf586 (patch) | |
tree | bda96bf8c3a4c2875a083d7b16720533c8ffeaf4 /ACE/bin/LabVIEW_RT | |
parent | c4078c377d74290ebe4e66da0b4975da91732376 (diff) | |
download | ATCD-99aa8c60282c7b8072eb35eb9ac815702f5bf586.tar.gz |
undoing accidental deletion
Diffstat (limited to 'ACE/bin/LabVIEW_RT')
-rw-r--r-- | ACE/bin/LabVIEW_RT/PXI_Reset.exe | bin | 0 -> 890570 bytes | |||
-rwxr-xr-x | ACE/bin/LabVIEW_RT/PXI_Reset.ini | 14 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/README | 57 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/Reboot_Target.exe | bin | 0 -> 147456 bytes | |||
-rwxr-xr-x | ACE/bin/LabVIEW_RT/Reboot_Target.ini | 14 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/ReadMe.txt | 77 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.cpp | 599 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.sln | 32 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.vcproj | 158 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.cpp | 9 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.h | 14 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/test.cpp | 17 | ||||
-rw-r--r-- | ACE/bin/LabVIEW_RT/labview_test_controller/test.vcproj | 134 |
13 files changed, 1125 insertions, 0 deletions
diff --git a/ACE/bin/LabVIEW_RT/PXI_Reset.exe b/ACE/bin/LabVIEW_RT/PXI_Reset.exe Binary files differnew file mode 100644 index 00000000000..7849adb56bd --- /dev/null +++ b/ACE/bin/LabVIEW_RT/PXI_Reset.exe diff --git a/ACE/bin/LabVIEW_RT/PXI_Reset.ini b/ACE/bin/LabVIEW_RT/PXI_Reset.ini new file mode 100755 index 00000000000..5141112e34c --- /dev/null +++ b/ACE/bin/LabVIEW_RT/PXI_Reset.ini @@ -0,0 +1,14 @@ +[PXI_Reset] +server.app.propertiesEnabled=True +server.ole.enabled=True +server.tcp.paranoid=True +server.tcp.servic="My Computer/VI Server" +server.vi.callsEnabled=True +server.vi.propertiesEnabled=True +WebServer.DirectoryIndex="index.htm" +WebServer.MimeTypes="htm;text/html;gif;image/gif;jpg;image/jpeg;png;image/png;txt;text/plain;html;text/html;jpeg;image/jpeg;css;text/css;llb;application/x-labview-llb;vi;application/x-labview-vi;doc;application/msword;dot;application/msword;bin;application/octet-stream;exe;application/octet-stream;rtf;application/rtf;pdf;application/pdf;ai;application/postscript;eps;application/postscript;ps;application/postscript;csh;application/x-csh;gtar;application/x-gtar;gz;application/x-gz;sh;application/x-sh;tar;application/x-tar;zip;application/zip;hqx;application/mac-binhex40;ua;audio/basic;wav;audio/wav;tif;image/tiff;tiff;image/tiff;xbm;image/x-xbitmap;rtx;text/richtext;qt;video/quicktime;mov;video/quicktime;avi;video/x-msvideo;movie;video/x-sgi-movie;aif;audio/aif;aifc;audio/aif;aiff;audio/aif;aim;application/x-aim;dif;video/x-dv;div;video/x-dv;js;application/x-javascript;pntg;image/x-macpaint;xlb;application/vnd.ms-excel;xls;application/vnd.ms-excel;ppa;application/vnd.ms-powerpoint;ppt;application/vnd.ms-powerpoint;pps;application/vnd.ms-powerpoint;pot;application/vnd.ms-powerpoint;pwz;application/vnd.ms-powerpoint;mid;audio/mid;midi;audio/mid;enc;video/mpeg;m1v;video/mpeg;mp2;video/mpeg;mpa;video/mpeg;mpe;video/mpeg;mpeg;video/mpeg;mpg;video/mpeg;psd;image/x-photoshop;bmp;image/bmp;pic;image/pic;ra;audio/vnd.rn-realaudio;rf;image/vnd.rf-realflash;rm;application/vnd.rn-realmedia;rp;image/vnd.rn-realpix;ram;audio/x-pn-realaudio;rmm;audio/x-pn-realaudio;rnx;application/vnd.rn-realplayer;rt;text/vnd.rn-realtext;rv;video/vnd.rn-realvideo;smi;application/smil;ssm;application/streamingmedia;sithqx;application/mac-binhex40;sit;application/x-stuffit" +WebServer.RootPath=C:\Program Files\National Instruments\LabVIEW 8.0\www +WebServer.TcpAccess="c+*" +WebServer.ViAccess="+*" +DebugServerEnabled=False +DebugServerWaitOnLaunch=False diff --git a/ACE/bin/LabVIEW_RT/README b/ACE/bin/LabVIEW_RT/README new file mode 100644 index 00000000000..f79c607704e --- /dev/null +++ b/ACE/bin/LabVIEW_RT/README @@ -0,0 +1,57 @@ +# $Id$ + +This directory contains utilities for running the ACE+TAO test suite on +a LabVIEW RT 8 / Phar Lap ETS target. Although it's running Phar Lap ETS, +and thus would normally be able to run programs, this environment is +different than plain Phar Lap ETS in that the LabVIEW RT layer takes up +the only process able to run on Phar Lap. Thus, everything executed needs +to be done via LabVIEW RT facilities. Thus, we have the following +restrictions: + +1. There's no NFS, no SMB; there's a target filesystem but no direct access. +2. No executables can be directly executed. + +This yields the following: + +- All test "programs" are built as DLLs instead of executables. The DLL has + a known "main" entrypoint. To run the test, the DLL must be copied down + to the target, explicitly loaded, and its entrypoint called. MPC will + automatically build these DLLs when an executable is specified in the MPC + file by basing the MPC project on the labviewrt_dll.mpb base. This is done + by supplying "-base labviewrt_dll" on the MPC command line. + +- There is a test-controlling DLL that lives on the LabVIEW RT target, and is + loaded when the target boots. This DLL spawns a thread that listens on a + TCP port for connections; it runs a text-based protocol by which it can + be directed to load and run test DLLs and report results. This DLL is in + the labview_test_controller subdirectory; see its ReadMe.txt file for + more details. + +- The Perl test framework in PerlACE has a ProcessLVRT.pm and + TestTarget_LVRT.pm that know how to run the test protocol, get the log file + back from the target, etc. in order to integrate the LabVIEW RT scheme into + the ACE+TAO testing framework. + +- If a test encounters any significant errors that would produce something akin + to a crash or significant leak on a multi-process OS, it will probably + render the LabVIEW RT target unuseable and unresponsive. There are two + utilities in this directory that will help in this sort of situation: + + 1. Reboot_Target.exe: A Windows executable that runs a LabVIEW VI to + reboot a local target box. If the box is alive enough to be contacted + and run the LabVIEW VI that triggers the reboot, this works fine. + However, if the box is unresponsive, as it usually is, this doesn't + work. The advantage of this utility is that it doesn't require any + additional hardware or software. + + 2. PXI_Reset.exe: A Windows executable that runs a LabVIEW VI to + trigger a hardware reset on the target box. This utility works all + the time since it does a hardware reset. However, it requires an + additional piece of hardware that connects to the host PC via USB + and connects to the DB9 on the back of the PXI target. This little + hardware box was custom-made by Lockheed Martin, so you can't just + go buy one at Radio Shack. + + If neither of these utilities is workable for you, you can probably use a + programmable power strip that can cycle the power on the target, and write + a utility that drives it. diff --git a/ACE/bin/LabVIEW_RT/Reboot_Target.exe b/ACE/bin/LabVIEW_RT/Reboot_Target.exe Binary files differnew file mode 100644 index 00000000000..c2054f79866 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/Reboot_Target.exe diff --git a/ACE/bin/LabVIEW_RT/Reboot_Target.ini b/ACE/bin/LabVIEW_RT/Reboot_Target.ini new file mode 100755 index 00000000000..9010340ee2b --- /dev/null +++ b/ACE/bin/LabVIEW_RT/Reboot_Target.ini @@ -0,0 +1,14 @@ +[Reboot_Target] +server.app.propertiesEnabled=True +server.ole.enabled=True +server.tcp.paranoid=True +server.tcp.servic="My Computer/VI Server" +server.vi.callsEnabled=True +server.vi.propertiesEnabled=True +WebServer.DirectoryIndex="index.htm" +WebServer.MimeTypes="htm;text/html;gif;image/gif;jpg;image/jpeg;png;image/png;txt;text/plain;html;text/html;jpeg;image/jpeg;css;text/css;llb;application/x-labview-llb;vi;application/x-labview-vi;doc;application/msword;dot;application/msword;bin;application/octet-stream;exe;application/octet-stream;rtf;application/rtf;pdf;application/pdf;ai;application/postscript;eps;application/postscript;ps;application/postscript;csh;application/x-csh;gtar;application/x-gtar;gz;application/x-gz;sh;application/x-sh;tar;application/x-tar;zip;application/zip;hqx;application/mac-binhex40;ua;audio/basic;wav;audio/wav;tif;image/tiff;tiff;image/tiff;xbm;image/x-xbitmap;rtx;text/richtext;qt;video/quicktime;mov;video/quicktime;avi;video/x-msvideo;movie;video/x-sgi-movie;aif;audio/aif;aifc;audio/aif;aiff;audio/aif;aim;application/x-aim;dif;video/x-dv;div;video/x-dv;js;application/x-javascript;pntg;image/x-macpaint;xlb;application/vnd.ms-excel;xls;application/vnd.ms-excel;ppa;application/vnd.ms-powerpoint;ppt;application/vnd.ms-powerpoint;pps;application/vnd.ms-powerpoint;pot;application/vnd.ms-powerpoint;pwz;application/vnd.ms-powerpoint;mid;audio/mid;midi;audio/mid;enc;video/mpeg;m1v;video/mpeg;mp2;video/mpeg;mpa;video/mpeg;mpe;video/mpeg;mpeg;video/mpeg;mpg;video/mpeg;psd;image/x-photoshop;bmp;image/bmp;pic;image/pic;ra;audio/vnd.rn-realaudio;rf;image/vnd.rf-realflash;rm;application/vnd.rn-realmedia;rp;image/vnd.rn-realpix;ram;audio/x-pn-realaudio;rmm;audio/x-pn-realaudio;rnx;application/vnd.rn-realplayer;rt;text/vnd.rn-realtext;rv;video/vnd.rn-realvideo;smi;application/smil;ssm;application/streamingmedia;sithqx;application/mac-binhex40;sit;application/x-stuffit" +WebServer.RootPath=C:\Program Files\National Instruments\LabVIEW 8.2\www +WebServer.TcpAccess="c+*" +WebServer.ViAccess="+*" +DebugServerEnabled=False +DebugServerWaitOnLaunch=False diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/ReadMe.txt b/ACE/bin/LabVIEW_RT/labview_test_controller/ReadMe.txt new file mode 100644 index 00000000000..c2362a229e6 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/ReadMe.txt @@ -0,0 +1,77 @@ +======================================================================== + DYNAMIC LINK LIBRARY : labview_test_controller Project Overview +======================================================================== + +The labview_test_controller DLL is needed to control execution and reporting +for ACE+TAO tests on a LabVIEW RT/Pharlap ETS target. The LabVIEW RT +environment can not execute programs - LabVIEW RT itself is the one program +that runs on the Pharlap ETS base, so no other processes can be started. +This DLL is built on the host VC7.1 Windows machine and copied to the +target. The target's \ni-rt.ini file must have the full path of the +labview_test_controller.dll on the target added to the [STARTUP] section, +EarlyStartupLibraries key. If there are already entries in that key, +append labview_test_controller.dll's path with a semi-colon separator. +For example, this is what mine ended up as: +[STARTUP] +EarlyStartupLibraries=C:\ni-rt\system\lvuste.dll;C:\ni-rt\system\tsengine.dll;C:\ni-rt\system\nisl_emb.dll;C:\ni-rt\labview_test_controller.dll; +MainExe=/ni-rt/system/emblview.exe + +After setting up the ni-rt.ini file and the DLL, reboot the target to +load the controller DLL. + +Keep in mind that the current working directory while tests are running will +be, at least on mine, \ni-rt\system. The test logs end up in \ni-rt\system\log. + +The labview_test_controller spawns a thread when the DLL is loaded at +system start. The child thread starts listening on TCP port 8888. For each +new connection to port 8888 a new thread is spawned to run the session. +The test host issues text commands to the controller via this TCP connection. +The responses are text as well. Thus, it's possible to test it using plain +telnet. There's also a "test" project in this VC7.1 solution. The test +project is a simple console app that calls the main thread's entrypoint +in labview_test_controller, facilitating its testing on the host Windows +machine where there's decent debugging capability. Debugging on the LabVIEW +target is by printf only. + +The client side of the TCP connection that drives this test controller is +in the ACE_wrappers/bin/PerlACE/ProcessLVRT.pm. The TestTarget_LVRT.pm is +also involved in testing on the LabVIEW RT target. + +The remainder of this is what Visual Studio .NET generated for this project. +======================================================================== +AppWizard has created this labview_test_controller DLL for you. +This file contains a summary of what you will find in each of the files that +make up your labview_test_controller application. + + +labview_test_controller.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +labview_test_controller.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named labview_test_controller.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.cpp b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.cpp new file mode 100644 index 00000000000..728c847121c --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.cpp @@ -0,0 +1,599 @@ +// $Id$ +// +// Defines the entry point for the LabVIEW RT test controller DLL application. +// This DLL is loaded at system boot by LabVIEW RT. The controller waits for +// TCP connections from the ACE+TAO test scripts. The test scripts will direct +// operation of the tests via commands sent over TCP. In order to be ready for +// connections without intervention via VI, the initial load will spawn a +// thread that sets up the listening socket. + +#include "stdafx.h" +#include <errno.h> +#include <fcntl.h> +#include <io.h> +#include <memory.h> +#include <process.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <Winsock2.h> + +// NULL is the documented way to check DLL handles, and this is plain +// Windows code, not ACE, so we stick to the Microsoft way... +// FUZZ: disable check_for_NULL + +// This is plain Windows code, not ACE. Therefore we disable +// the check for ACE_OS +// FUZZ: disable check_for_lack_ACE_OS + +// TEST_FUNC is the prototype for the called test's main entrypoint. It's +// the normal C main. +typedef int (*TEST_FUNC) (int argc, char *argv[]); + +// Thread entrypoints +static unsigned int __stdcall test_control (void *param); +static unsigned int __stdcall peer_svc (void *peer_p); +static unsigned int __stdcall run_test (void *test_p); + +static const char *format_errmsg (unsigned int errcode, const char *prefix); + +// Logging information +static const char *LogName = "acetao.log"; +static HANDLE logf = INVALID_HANDLE_VALUE; + +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + return (0 != _beginthreadex (0, // security + 8 * 1024, // stack size + test_control, // entrypoint + 0, // param + 0, // creation flags + 0)); // ptr to thread id + } + + return TRUE; +} + +class Test +{ +public: + Test () : dll_handle_ (NULL), + thr_handle_ (0), + entry_ (0), + running_ (false), + status_ (-1) + {} + ~Test (); + + HANDLE handle (void) { return this->thr_handle_; } + int run (void); + const char *start (const char *name); + bool status (int *exit_status); + int wait (void); + void kill (void); + + // Clean up remnants of a test run. + void cleanup (void); + +private: + HMODULE dll_handle_; + HANDLE thr_handle_; + TEST_FUNC entry_; + bool running_; + int status_; + enum { CMDLINE_LEN = 1024, ARGV_SIZE = 100 }; + char name_[CMDLINE_LEN]; + char cmdline_[CMDLINE_LEN]; + int argc_; + char *argv_[ARGV_SIZE]; +}; + +class Peer +{ +public: + Peer (SOCKET h) : handle_ (h) {} + + // Run the Peer's session; intended to be called from a new thread devoted + // to this peer's session. + int svc (void); + +private: + Peer () {}; + + // Process command input from socket. + int command (void); + + // Send a reply string to the peer. + int reply (const char *msg); + + SOCKET handle_; + Test test_; +}; + +// Run a peer session; assume there's a thread for each session, so this +// object has all it needs for context located in 'this' object, and it can +// block at any point as long as one remembers that there is one or more +// test threads running and some attention must be paid to the encapsulated +// socket handle over which this object receives control commands from the +// host test driver. +int +Peer::svc (void) +{ + // Read commands until EOF (peer closed) or protocol error + while (0 == this->command ()) + ; + closesocket (this->handle_); + this->handle_ = INVALID_SOCKET; + return 0; +} + +int +Peer::command (void) +{ + // The protocol exchanges with the peer are execpted to be lock-step + // request-reply command lines, so we can make assumptions about a complete + // line being available to make life easier. + const int MAX_RECV = 1024; + char line[MAX_RECV], *p; + p = &line[0]; + int count = 0, len = 0; + while ((count = recv (this->handle_, p, MAX_RECV - len, 0)) > 0) + { + p[count] = '\0'; + len += count; + p += count; + char *nl; + if ((nl = strchr (line, '\n')) == 0) + continue; + + // At this point we have a 0-terminated string with a newline ending + // the command line. Break out and process the command. + break; + } + if (count <= 0) + return -1; // Relay closed/error socket to caller + + char *cmd = strtok (line, "\t \n\r"); + if (cmd == 0) + { + char err[1024]; + sprintf (err, "Can't parse input: %s\n", line); + this->reply (err); + return -1; + } + // Which command is it? These commands are known: + // + // run <test-dll> [args] + // Run test in the named test-dll; respond with "OK" or an error string. + // status + // If test still running return "RUNNING" else return exit status. + // wait + // Wait for test to exit; return "OK" + // kill + // Kill the thread with the most recent test; return "OK". + // snaplog + // Take a snapshot of the current stdout/stderr log to a new file + // name and reset the stdout/stderr log. + if (strcmp ("run", cmd) == 0) + { + char *test = strtok (0, "\t \n\r"); + if (test == 0) + { + this->reply ("Malformed run command\n"); + return -1; + } + // start() pulls apart the rest of the command line... + const char *errmsg = this->test_.start (test); + if (errmsg == 0) + this->reply ("OK\n"); + else + this->reply (errmsg); + } + else if (strcmp ("status", cmd) == 0) + { + int status; + if (this->test_.status (&status)) + { + char retvalmsg[64]; + sprintf (retvalmsg, "%d\n", status); + this->reply (retvalmsg); + } + else + this->reply ("RUNNING\n"); + } + else if (strcmp ("wait", cmd) == 0) + { + int status = this->test_.wait (); + char retvalmsg[64]; + sprintf (retvalmsg, "%d\n", status); + this->reply (retvalmsg); + } + else if (strcmp ("kill", cmd) == 0) + { + // Killing things is bad... say we can't and the host should reboot us. + this->reply ("NO - please reboot me\n"); + } + else if (strcmp ("waitforfile", cmd) == 0) + { + char *name = strtok (0, "\t \n\r"); + if (name == 0) + { + this->reply ("Malformed waitforfile command\n"); + return -1; + } + char *secs_s = strtok (0, "\t \n\r"); + int secs = 0; + if (secs_s == 0 || (secs = atoi (secs_s)) <= 0) + { + this->reply ("Malformed waitforfile command\n"); + return -1; + } + struct _stat info; + const char *msg = 0; + bool found = false; + while (secs > 0) + { + if (_stat (name, &info) == -1) // No file yet + { + if (errno != ENOENT) + { + // Something more serious than no file yet; bail out. + msg = format_errmsg (errno, name); + break; + } + } + else + { + if (info.st_size > 0) + { + found = true; + break; + } + } + // Either no file yet, or it's there but with no content yet. + Sleep (1 * 1000); // arg is in msec + --secs; + } + if (found) + this->reply ("OK\n"); + else if (secs == 0) + this->reply ("TIMEOUT\n"); + else + this->reply (msg); + } + else if (strcmp ("snaplog", cmd) == 0) + { + if (logf == INVALID_HANDLE_VALUE) + { + this->reply ("NONE\n"); + } + else + { + CloseHandle (logf); + if (0 == rename (LogName, "snapshot.txt")) + { + char abspath[1024]; + if (_fullpath (abspath, "snapshot.txt", 1024)) + { + strcat (abspath, "\n"); + this->reply (abspath); + } + else + { + // Last ditch effort to get a name back to the client + this->reply ("\\ni-rt\\system\\snapshot.txt\n"); + } + } + else + { + this->reply ("NONE\n"); + } + // Reset stdout/stderr to a new file + logf = CreateFile (LogName, + FILE_ALL_ACCESS, + FILE_SHARE_READ, + 0, // security + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + SetStdHandle (STD_OUTPUT_HANDLE, logf); + SetStdHandle (STD_ERROR_HANDLE, logf); + } + } + else + { + this->reply ("Unrecognized command\n"); + return -1; + } + return 0; +} + +int +Peer::reply (const char *msg) +{ + int len = (int)strlen (msg); // size_t -> int + return send (this->handle_, msg, len, 0) > 0 ? 0 : -1; +} + +Test::~Test () +{ + this->cleanup (); +} + +int +Test::run (void) +{ + this->running_ = true; + this->status_ = (this->entry_) (this->argc_, this->argv_); + this->running_ = false; + // It's possible to cleanup() here; however, that would introduce a race + // with start() following beginthreadex(). So do all the cleanup on user + // action - either getting status, waiting, killing, or running another + // test. Or, terminating the connection. + return 0; +} + +const char * +Test::start (const char *name) +{ + if (this->running_) + return "Already running\n"; + + const char *msg = 0; + + // Reset test status to not inadvertantly report a previous test. + this->status_ = -1; + this->cleanup (); // Resets cmdline_, argc_, argv_ + + // The command line is part-way through being tokenized by strtok(). It + // left off after the program name. Anything remaining are the command + // line arguments for the program. Pick off whatever is there, copy it + // to the cmdline_ array and fill in argc_/argv_ for the eventual run. + strcpy (this->name_, name); + this->argv_[0] = this->name_; + this->argc_ = 1; + size_t cmdchars = 0; + for (char *token = strtok (0, "\t \n\r"); + token != 0 && (cmdchars + strlen (token) + 1) < CMDLINE_LEN; + token = strtok (0, "\t \n\r")) + { + // We have a new token and it will fit in cmdline_. Copy it to the + // next spot in cmdline_, add it to argv_/argc_ then update cmdchars + // to account for the copied-in token and its nul terminator. + strcpy (&this->cmdline_[cmdchars], token); + this->argv_[this->argc_] = &this->cmdline_[cmdchars]; + ++this->argc_; + cmdchars += (strlen (token) + 1); + } + char libspec[1024]; + sprintf (libspec, "%s.dll", name); + if ((this->dll_handle_ = LoadLibrary (libspec)) == NULL) + return format_errmsg (GetLastError (), libspec); + + this->entry_ = (TEST_FUNC) GetProcAddress (this->dll_handle_, "main"); + if (this->entry_ == NULL) + { + msg = format_errmsg (GetLastError (), "main"); + this->cleanup (); + return msg; + } + else + { + unsigned int thread_id; /* unused */ + uintptr_t h = _beginthreadex (0, // security + 1024 * 1024, // stack size + run_test, // entrypoint + (void *)this, // arglist + 0, // initflag + &thread_id); // thread ID + this->thr_handle_ = (HANDLE) h; + if (h == 0) // Test thread may have access to thr_handle_ + { + msg = format_errmsg (GetLastError (), "spawn"); + this->cleanup (); + return msg; + } + } + return 0; +} + +bool +Test::status (int *exit_status) +{ + if (this->running_) + return false; // still running + + *exit_status = this->status_; + this->cleanup (); + return true; +} + +int +Test::wait (void) +{ + WaitForSingleObject (this->thr_handle_, INFINITE); + if (!this->running_) + this->cleanup (); + return this->status_; +} + +void +Test::kill (void) +{ + TerminateThread (this->thr_handle_, -1); + this->cleanup (); + this->running_ = false; + this->status_ = -1; +} + +// Clean up remnants of a test run. +void +Test::cleanup (void) +{ + if (this->dll_handle_ != NULL) + { + FreeLibrary (this->dll_handle_); + this->dll_handle_ = NULL; + } + if (this->thr_handle_ != 0) + { + CloseHandle (this->thr_handle_); + this->thr_handle_ = 0; + } + this->entry_ = 0; + this->argc_ = 0; + for (int i = 0; i < ARGV_SIZE; ++i) + this->argv_[i] = 0; + memset (this->cmdline_, 0, CMDLINE_LEN); +} + +static unsigned int __stdcall +test_control (void * /* param */) +{ + // cd to ace dir?? (can this be an env variable?) + + // redirect stdout/stderr to a file + logf = CreateFile (LogName, + FILE_ALL_ACCESS, + FILE_SHARE_READ, + 0, // security + OPEN_ALWAYS, // Don't crush a previous one + FILE_ATTRIBUTE_NORMAL, + 0); + if (logf == INVALID_HANDLE_VALUE) + perror (LogName); + else + { + SetFilePointer (logf, 0, 0, FILE_END); // Append new content + SetStdHandle (STD_OUTPUT_HANDLE, logf); + SetStdHandle (STD_ERROR_HANDLE, logf); + } + + WORD want; + WSADATA offer; + want = MAKEWORD (2, 2); + if (0 != WSAStartup (want, &offer)) + { + perror ("WSAStartup"); + CloseHandle (logf); + return WSAGetLastError (); + } + + // listen on port 8888 (can I set an env variable for this?) + SOCKET acceptor = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + sockaddr_in listen_addr; + memset (&listen_addr, 0, sizeof (listen_addr)); + listen_addr.sin_family = AF_INET; + listen_addr.sin_addr.s_addr = INADDR_ANY; + listen_addr.sin_port = htons (8888); + if (SOCKET_ERROR == bind (acceptor, + (struct sockaddr *)&listen_addr, + sizeof (listen_addr))) + { + perror ("bind"); + } + else + { + listen (acceptor, 10); + SOCKET peer; + while ((peer = accept (acceptor, 0, 0)) != INVALID_SOCKET) + { + Peer *p = new Peer (peer); + if (p == 0) + { + perror ("Out of memory"); + closesocket (peer); + peer = INVALID_SOCKET; + continue; + } + if (0 == _beginthreadex (0, // security + 64 * 1024, // stack size + peer_svc, // entrypoint + (void *)p, // param + 0, // creation flags + 0)) // ptr to thread id + { + perror ("beginthreadex peer"); + closesocket (peer); + delete p; + } + p = 0; + peer = INVALID_SOCKET; + } + perror ("accept"); + } + + closesocket (acceptor); + WSACleanup (); + return 0; +} + +// Entrypoint for thread that's spawned to run a peer's session. Direct +// control to the peer class. +static unsigned int __stdcall +peer_svc (void *peer_p) +{ + Peer *p = (Peer *)peer_p; + DWORD status = p->svc (); + delete p; + return status; +} + +// Entrypoint for the thread spawned to run a test. The thread arg is the +// Test * - call back to the test's run() method; return the test exit code +// as the thread's return value. +static unsigned int __stdcall +run_test (void *test_p) +{ + Test *t = (Test *)test_p; + return t->run (); +} + +// Format a Windows system or Winsock error message given an error code. +static const char * +format_errmsg (unsigned int errcode, const char *prefix) +{ + static const size_t errmsgsize = 1024; + static char errmsg[errmsgsize]; + + sprintf (errmsg, "%s: ", prefix); + size_t len = strlen (errmsg); + char *next = &errmsg[len]; + size_t max_fmt = errmsgsize - len; + if (0 != FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + 0, + errcode, + 0, // Use default language + next, + (DWORD)max_fmt, + 0)) + { + strcat (errmsg, "\n"); + return errmsg; + } + + errno = errcode; + char *msg = _strerror (prefix); + sprintf (errmsg, "err %d: %s", errcode, msg); + return errmsg; +} + +#ifdef TEST_RUNNER_EXPORTS +#define TEST_RUNNER_API __declspec(dllexport) +#else +#define TEST_RUNNER_API __declspec(dllimport) +#endif + +__declspec(dllexport) int test_entry(void) +{ + return 0; +} diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.sln b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.sln new file mode 100644 index 00000000000..877fb7e68f2 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.sln @@ -0,0 +1,32 @@ +Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "labview_test_controller", "labview_test_controller.vcproj", "{646E6863-F3BE-403A-8B53-20C02664907B}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{01781FA2-36A3-49DA-A00C-2DEAE6A286FF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {646E6863-F3BE-403A-8B53-20C02664907B} = {646E6863-F3BE-403A-8B53-20C02664907B}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {646E6863-F3BE-403A-8B53-20C02664907B}.Debug.ActiveCfg = Debug|Win32
+ {646E6863-F3BE-403A-8B53-20C02664907B}.Debug.Build.0 = Debug|Win32
+ {646E6863-F3BE-403A-8B53-20C02664907B}.Release.ActiveCfg = Release|Win32
+ {646E6863-F3BE-403A-8B53-20C02664907B}.Release.Build.0 = Release|Win32
+ {01781FA2-36A3-49DA-A00C-2DEAE6A286FF}.Debug.ActiveCfg = Debug|Win32
+ {01781FA2-36A3-49DA-A00C-2DEAE6A286FF}.Debug.Build.0 = Debug|Win32
+ {01781FA2-36A3-49DA-A00C-2DEAE6A286FF}.Release.ActiveCfg = Release|Win32
+ {01781FA2-36A3-49DA-A00C-2DEAE6A286FF}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.vcproj b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.vcproj new file mode 100644 index 00000000000..2974e566a4c --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/labview_test_controller.vcproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="labview_test_controller"
+ ProjectGUID="{646E6863-F3BE-403A-8B53-20C02664907B}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LABVIEW_TEST_CONTROLLER_EXPORTS"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="wsock32.lib"
+ OutputFile="$(OutDir)/labview_test_controller.dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/labview_test_controller.pdb"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/labview_test_controller.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LABVIEW_TEST_CONTROLLER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="3"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="wsock32.lib"
+ OutputFile="$(OutDir)/labview_test_controller.dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary="$(OutDir)/labview_test_controller.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\labview_test_controller.cpp">
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\stdafx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.cpp b/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.cpp new file mode 100644 index 00000000000..2c613e15662 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.cpp @@ -0,0 +1,9 @@ +// $Id$ +// stdafx.cpp : source file that includes just the standard includes +// labview_test_controller.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.h b/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.h new file mode 100644 index 00000000000..8b9e996b7c0 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/stdafx.h @@ -0,0 +1,14 @@ +// $Id$ +// stdafx.h : include file for standard system include files, or +// project specific include files that are used frequently, but are +// changed infrequently +// + +#pragma once + + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include <windows.h> + +// TODO: reference additional headers your program requires here diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/test.cpp b/ACE/bin/LabVIEW_RT/labview_test_controller/test.cpp new file mode 100644 index 00000000000..4c2a2589fb4 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/test.cpp @@ -0,0 +1,17 @@ +// $Id$ + +#include <stdio.h> +__declspec(dllimport) int test_entry(void); + +// This is plain Windows code, not ACE. Therefore we disable +// the check for ACE_OS +// FUZZ: disable check_for_lack_ACE_OS + +int main (int, char *[]) +{ + char line[80]; + test_entry(); + puts ("Ok, go... hit return to stop."); + gets (line); + return 0; +} diff --git a/ACE/bin/LabVIEW_RT/labview_test_controller/test.vcproj b/ACE/bin/LabVIEW_RT/labview_test_controller/test.vcproj new file mode 100644 index 00000000000..85a01d4d638 --- /dev/null +++ b/ACE/bin/LabVIEW_RT/labview_test_controller/test.vcproj @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="test"
+ ProjectGUID="{01781FA2-36A3-49DA-A00C-2DEAE6A286FF}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="5"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="labview_test_controller.lib"
+ OutputFile="$(OutDir)/test.exe"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="$(OutDir)"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/test.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="4"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/test.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\test.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
|