extern "C" {
#endif
-#ifdef WIN32
-
-/* -------------------------------------------------------------------
- * Implement a simple Win32 strerror function for our purposes.
- * These error values weren't handled by FormatMessage;
- * any particular reason why not??
- * ------------------------------------------------------------------- */
-
-struct mesg {
- DWORD err;
- const char* str;
-};
-
-const struct mesg error_mesgs[] =
-{
- { WSAEACCES, "Permission denied"},
- { WSAEADDRINUSE, "Address already in use"},
- { WSAEADDRNOTAVAIL, "Cannot assign requested address"},
- { WSAEAFNOSUPPORT, "Address family not supported by protocol family"},
- { WSAEALREADY, "Operation already in progress"},
- { WSAECONNABORTED, "Software caused connection abort"},
- { WSAECONNREFUSED, "Connection refused"},
- { WSAECONNRESET, "Connection reset by peer"},
- { WSAEDESTADDRREQ, "Destination address required"},
- { WSAEFAULT, "Bad address"},
- { WSAEHOSTDOWN, "Host is down"},
- { WSAEHOSTUNREACH, "No route to host"},
- { WSAEINPROGRESS, "Operation now in progress"},
- { WSAEINTR, "Interrupted function call."},
- { WSAEINVAL, "Invalid argument."},
- { WSAEISCONN, "Socket is already connected."},
- { WSAEMFILE, "Too many open files."},
- { WSAEMSGSIZE, "Message too long"},
- { WSAENETDOWN, "Network is down"},
- { WSAENETRESET, "Network dropped connection on reset"},
- { WSAENETUNREACH, "Network is unreachable"},
- { WSAENOBUFS, "No buffer space available."},
- { WSAENOPROTOOPT, "Bad protocol option."},
- { WSAENOTCONN, "Socket is not connected"},
- { WSAENOTSOCK, "Socket operation on non-socket."},
- { WSAEOPNOTSUPP, "Operation not supported"},
- { WSAEPFNOSUPPORT, "Protocol family not supported"},
- { WSAEPROCLIM, "Too many processes."},
- { WSAEPROTONOSUPPORT, "Protocol not supported"},
- { WSAEPROTOTYPE, "Protocol wrong type for socket"},
- { WSAESHUTDOWN, "Cannot send after socket shutdown"},
- { WSAESOCKTNOSUPPORT, "Socket type not supported."},
- { WSAETIMEDOUT, "Connection timed out."},
- { WSATYPE_NOT_FOUND, "Class type not found."},
- { WSAEWOULDBLOCK, "Resource temporarily unavailable"},
- { WSAHOST_NOT_FOUND, "Host not found."},
- { WSA_INVALID_HANDLE, "Specified event object handle is invalid."},
- { WSA_INVALID_PARAMETER, "One or more parameters are invalid."},
- { WSA_IO_INCOMPLETE, "Overlapped I/O event object not in signaled state."},
- { WSA_IO_PENDING, "Overlapped operations will complete later."},
- { WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available."},
- { WSANOTINITIALISED, "Successful WSAStartup not yet performed."},
- { WSANO_DATA, "Valid name, no data record of requested type."},
- { WSANO_RECOVERY, "This is a non-recoverable error."},
- { WSASYSCALLFAILURE, "System call failure."},
- { WSASYSNOTREADY, "Network subsystem is unavailable."},
- { WSATRY_AGAIN, "Non-authoritative host not found."},
- { WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range."},
- { WSAEDISCON, "Graceful shutdown in progress."},
- { WSA_OPERATION_ABORTED, "Overlapped operation aborted."},
- { 0, "No error."}
-
- /* These appeared in the documentation, but didn't compile.
- * { WSAINVALIDPROCTABLE, "Invalid procedure table from service provider." },
- * { WSAINVALIDPROVIDER, "Invalid service provider version number." },
- * { WSAPROVIDERFAILEDINIT, "Unable to initialize a service provider." },
- */
-
-}; /* end error_mesgs[] */
-
-const char* winsock_strerror( DWORD inErrno );
-
-/* -------------------------------------------------------------------
- * winsock_strerror
- *
- * returns a string representing the error code. The error messages
- * were taken from Microsoft's online developer library.
- * ------------------------------------------------------------------- */
-
-const char* winsock_strerror( DWORD inErrno ) {
- const char* str = "Unknown error";
- int i;
- for ( i = 0; i < sizeof(error_mesgs); i++ ) {
- if ( error_mesgs[i].err == inErrno ) {
- str = error_mesgs[i].str;
- break;
- }
- }
-
- return str;
-} /* end winsock_strerror */
-
-#endif /* WIN32 */
-
/* -------------------------------------------------------------------
* warn
*
const char* my_str;
/* get platform's errno and error message */
-#ifdef WIN32
- my_err = WSAGetLastError();
- my_str = winsock_strerror( my_err );
-#else
my_err = errno;
my_str = strerror( my_err );
-#endif
fflush( 0 );
pthread_cond_t mCondition;
pthread_mutex_t mMutex;
} Condition;
-#elif defined( HAVE_WIN32_THREAD )
-typedef struct Condition {
- HANDLE mCondition;
- HANDLE mMutex;
-} Condition;
#else
typedef struct Condition {
int mCondition;
Mutex_Initialize( &(Cond)->mMutex ); \
pthread_cond_init( &(Cond)->mCondition, NULL ); \
} while ( 0 )
-#elif defined( HAVE_WIN32_THREAD )
- // set all conditions to be broadcast
- // unfortunately in Win32 you have to know at creation
- // whether the signal is broadcast or not.
- #define Condition_Initialize( Cond ) do { \
- Mutex_Initialize( &(Cond)->mMutex ); \
- (Cond)->mCondition = CreateEvent( NULL, true, false, NULL ); \
- } while ( 0 )
#else
#define Condition_Initialize( Cond )
#endif
pthread_cond_destroy( &(Cond)->mCondition ); \
Mutex_Destroy( &(Cond)->mMutex ); \
} while ( 0 )
-#elif defined( HAVE_WIN32_THREAD )
- #define Condition_Destroy( Cond ) do { \
- CloseHandle( (Cond)->mCondition ); \
- Mutex_Destroy( &(Cond)->mMutex ); \
- } while ( 0 )
#else
#define Condition_Destroy( Cond )
#endif
// sleep this thread, waiting for condition signal
#if defined( HAVE_POSIX_THREAD )
#define Condition_Wait( Cond ) pthread_cond_wait( &(Cond)->mCondition, &(Cond)->mMutex )
-#elif defined( HAVE_WIN32_THREAD )
- // atomically release mutex and wait on condition,
- // then re-acquire the mutex
- #define Condition_Wait( Cond ) do { \
- SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, INFINITE, false ); \
- Mutex_Lock( &(Cond)->mMutex ); \
- } while ( 0 )
#else
#define Condition_Wait( Cond )
#endif
absTimeout.tv_nsec = 0; \
pthread_cond_timedwait( &(Cond)->mCondition, &(Cond)->mMutex, &absTimeout ); \
} while ( 0 )
-#elif defined( HAVE_WIN32_THREAD )
- // atomically release mutex and wait on condition,
- // then re-acquire the mutex
- #define Condition_TimedWait( Cond, inSeconds ) do { \
- SignalObjectAndWait( (Cond)->mMutex, (Cond)->mCondition, inSeconds*1000, false ); \
- Mutex_Lock( &(Cond)->mMutex ); \
- } while ( 0 )
#else
#define Condition_TimedWait( Cond, inSeconds )
#endif
// use PulseEvent to auto-reset the signal after waking all threads
#if defined( HAVE_POSIX_THREAD )
#define Condition_Signal( Cond ) pthread_cond_signal( &(Cond)->mCondition )
-#elif defined( HAVE_WIN32_THREAD )
- #define Condition_Signal( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Signal( Cond )
#endif
// send a condition signal to wake all threads waiting on condition
#if defined( HAVE_POSIX_THREAD )
#define Condition_Broadcast( Cond ) pthread_cond_broadcast( &(Cond)->mCondition )
-#elif defined( HAVE_WIN32_THREAD )
- #define Condition_Broadcast( Cond ) PulseEvent( (Cond)->mCondition )
#else
#define Condition_Broadcast( Cond )
#endif
* ------------------------------------------------------------------- */
extern const char usage_short[];
-
-#ifdef WIN32
-extern const char usage_long1[];
-extern const char usage_long2[];
-#else
extern const char usage_long[];
-#endif
-
extern const char version[];
/* -------------------------------------------------------------------
#if defined( HAVE_POSIX_THREAD )
typedef pthread_mutex_t Mutex;
-#elif defined( HAVE_WIN32_THREAD )
- typedef HANDLE Mutex;
#else
typedef int Mutex;
#endif
// initialize mutex
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Initialize( MutexPtr ) pthread_mutex_init( MutexPtr, NULL )
-#elif defined( HAVE_WIN32_THREAD )
- #define Mutex_Initialize( MutexPtr ) *MutexPtr = CreateMutex( NULL, false, NULL )
#else
#define Mutex_Initialize( MutexPtr )
#endif
// lock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Lock( MutexPtr ) pthread_mutex_lock( MutexPtr )
-#elif defined( HAVE_WIN32_THREAD )
- #define Mutex_Lock( MutexPtr ) WaitForSingleObject( *MutexPtr, INFINITE )
#else
#define Mutex_Lock( MutexPtr )
#endif
// unlock the mutex variable
#if defined( HAVE_POSIX_THREAD )
#define Mutex_Unlock( MutexPtr ) pthread_mutex_unlock( MutexPtr )
-#elif defined( HAVE_WIN32_THREAD )
- #define Mutex_Unlock( MutexPtr ) ReleaseMutex( *MutexPtr )
#else
#define Mutex_Unlock( MutexPtr )
#endif
pthread_mutex_destroy( MutexPtr ); \
} \
} while ( 0 )
-#elif defined( HAVE_WIN32_THREAD )
- #define Mutex_Destroy( MutexPtr ) CloseHandle( *MutexPtr )
#else
#define Mutex_Destroy( MutexPtr )
#endif
iperf_sockaddr local;
Socklen_t size_local;
nthread_t mTID;
-#if defined( HAVE_WIN32_THREAD )
- HANDLE mHandle;
-#endif
} thread_Settings;
/*
#define HAVE_THREAD 1
-#elif defined( HAVE_WIN32_THREAD )
-
-/* Definitions for Win32 NT Threads */
-typedef DWORD nthread_t;
-
- #define HAVE_THREAD 1
-
#else
/* Definitions for no threads */
* ------------------------------------------------------------------- */
#if defined( HAVE_POSIX_THREAD )
#define thread_getid() pthread_self()
- #elif defined( HAVE_WIN32_THREAD )
- #define thread_getid() GetCurrentThreadId()
#else
#define thread_getid() 0
#endif
nthread_t thread_zeroid( void );
-#if defined( HAVE_WIN32_THREAD )
- DWORD WINAPI thread_run_wrapper( void* paramPtr );
-#else
- void* thread_run_wrapper( void* paramPtr );
-#endif
+ void* thread_run_wrapper( void* paramPtr );
void thread_rest ( void );
#include <time.h>
#include <math.h>
-#ifdef WIN32
-
-/* Windows config file */
- #include "config.win32.h"
-
-/* Windows headers */
- #define _WIN32_WINNT 0x0400 /* use (at least) WinNT 4.0 API */
- #define WIN32_LEAN_AND_MEAN /* exclude unnecesary headers */
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
-
-/* define EINTR, just to help compile; it isn't useful */
- #ifndef EINTR
- #define EINTR WSAEINTR
- #endif // EINTR
-
-/* Visual C++ has INT64, but not 'long long'.
- * Metrowerks has 'long long', but INT64 doesn't work. */
- #ifdef __MWERKS__
- #define int64_t long long
- #else
- #define int64_t INT64
- #endif // __MWERKS__
-
-/* Visual C++ has _snprintf instead of snprintf */
- #ifndef __MWERKS__
- #define snprintf _snprintf
- #endif // __MWERKS__
-
-/* close, read, and write only work on files in Windows.
- * I get away with #defining them because I don't read files. */
- #define close( s ) closesocket( s )
- #define read( s, b, l ) recv( s, (char*) b, l, 0 )
- #define write( s, b, l ) send( s, (char*) b, l, 0 )
-
-#else /* not defined WIN32 */
-
/* required on AIX for FD_SET (requires bzero).
* often this is the same as <string.h> */
#ifdef HAVE_STRINGS_H
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
-#endif /* not defined WIN32 */
-
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 40
#endif
SigfuncPtr my_signal( int inSigno, SigfuncPtr inFunc );
-#ifdef WIN32
-
-/* under windows, emulate unix signals */
-enum {
- SIGINT,
- SIGTERM,
- SIGPIPE,
- _NSIG
-};
-
-BOOL WINAPI sig_dispatcher( DWORD type );
-
-#endif
-
/* -------------------------------------------------------------------
* error handlers
* error.c
* spawn a new Server thread.
* ------------------------------------------------------------------- */
void Listener::Run( void ) {
-#ifdef WIN32
- if ( isUDP( mSettings ) && !isSingleUDP( mSettings ) ) {
- UDPSingleServer();
- } else
-#else
#ifdef sun
if ( ( isUDP( mSettings ) &&
isMulticast( mSettings ) &&
if ( isSingleUDP( mSettings ) ) {
UDPSingleServer();
} else
-#endif
#endif
{
bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
}
// Start the server
-#if defined(WIN32) && defined(HAVE_THREAD)
- if ( UDP ) {
- // WIN32 does bad UDP handling so run single threaded
- if ( server->runNow != NULL ) {
- thread_start( server->runNow );
- }
- server_spawn( server );
- if ( server->runNext != NULL ) {
- thread_start( server->runNext );
- }
- } else
-#endif
thread_start( server );
// create a new socket
#endif
: AF_INET);
-#ifdef WIN32
- if ( SockAddr_isMulticast( &mSettings->local ) ) {
- // Multicast on Win32 requires special handling
- mSettings->mSock = WSASocket( domain, type, 0, 0, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF );
- WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
-
- } else
-#endif
- {
- mSettings->mSock = socket( domain, type, 0 );
- WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
- }
+ mSettings->mSock = socket( domain, type, 0 );
+ WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
SetSocketOptions( mSettings );
setsockopt( mSettings->mSock, SOL_SOCKET, SO_REUSEADDR, (char*) &boolean, len );
// bind socket to server address
-#ifdef WIN32
- if ( SockAddr_isMulticast( &mSettings->local ) ) {
- // Multicast on Win32 requires special handling
- rc = WSAJoinLeaf( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local,0,0,0,0,JL_BOTH);
- WARN_errno( rc == SOCKET_ERROR, "WSAJoinLeaf (aka bind)" );
- } else
-#endif
- {
- rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local );
- WARN_errno( rc == SOCKET_ERROR, "bind" );
- }
+ rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local );
+ WARN_errno( rc == SOCKET_ERROR, "bind" );
+
// listen for connections (TCP only).
// default backlog traditionally 5
if ( !isUDP( mSettings ) ) {
WARN_errno( rc == SOCKET_ERROR, "listen" );
}
-#ifndef WIN32
// if multicast, join the group
if ( SockAddr_isMulticast( &mSettings->local ) ) {
McastJoin( );
}
-#endif
} // end Listen
/* -------------------------------------------------------------------
* --------------------------------------------------------------------*/
void Listener::runAsDaemon(const char *pname, int facility) {
-#ifndef WIN32
pid_t pid;
/* Create a child process & if successful, exit from the parent process */
fflush(stderr);
fclose(stdin);
-#else
- fprintf( stderr, "Use the precompiled windows version for service (daemon) option\n");
-#endif
-
}
#ifdef HAVE_CONFIG_H
#include "config.h"
#else
-#ifdef WIN32
-#include "config.win32.h"
-#endif
#endif
#ifdef __cplusplus
Usage: %s [-s|-c host] [options]\n\
Try `%s --help' for more information.\n";
-#ifdef WIN32
-const char usage_long1[] = "\
-Usage: iperf [-s|-c host] [options]\n\
- iperf [-h|--help] [-v|--version]\n\
-\n\
-Client/Server:\n\
- -f, --format [kmKM] format to report: Kbits, Mbits, KBytes, MBytes\n\
- -i, --interval # seconds between periodic bandwidth reports\n\
- -l, --len #[KM] length of buffer to read or write (default 8 KB)\n\
- -m, --print_mss print TCP maximum segment size (MTU - TCP/IP header)\n\
- -o, --output <filename> output the report or error message to this specified file\n\
- -p, --port # server port to listen on/connect to\n\
- -u, --udp use UDP rather than TCP\n\
- -w, --window #[KM] TCP window size (socket buffer size)\n\
- -B, --bind <host> bind to <host>, an interface or multicast address\n\
- -C, --compatibility for use with older versions does not sent extra msgs\n\
- -M, --mss # set TCP maximum segment size (MTU - 40 bytes)\n\
- -N, --nodelay set TCP no delay, disabling Nagle's Algorithm\n\
- -V, --IPv6Version Set the domain to IPv6\n\
-\n\
-Server specific:\n\
- -s, --server run in server mode\n\
- -U, --single_udp run in single threaded UDP mode\n\
- -D, --daemon run the server as a daemon\n\
- -R, --remove remove service in win32\n";
-
-const char usage_long2[] = "\
-\n\
-Client specific:\n\
- -b, --bandwidth #[KM] for UDP, bandwidth to send at in bits/sec\n\
- (default 1 Mbit/sec, implies -u)\n\
- -c, --client <host> run in client mode, connecting to <host>\n\
- -d, --dualtest Do a bidirectional test simultaneously\n\
- -n, --num #[KM] number of bytes to transmit (instead of -t)\n\
- -r, --tradeoff Do a bidirectional test individually\n\
- -t, --time # time in seconds to transmit for (default 10 secs)\n\
- -F, --fileinput <name> input the data to be transmitted from a file\n\
- -I, --stdin input the data to be transmitted from stdin\n\
- -L, --listenport # port to recieve bidirectional tests back on\n\
- -P, --parallel # number of parallel client threads to run\n\
- -T, --ttl # time-to-live, for multicast (default 1)\n\
-\n\
-Miscellaneous:\n\
- -h, --help print this message and quit\n\
- -v, --version print version information and quit\n\
-\n\
-[KM] Indicates options that support a K or M suffix for kilo- or mega-\n\
-\n\
-The TCP window size option can be set by the environment variable\n\
-TCP_WINDOW_SIZE. Most other options can be set by an environment variable\n\
-IPERF_<long option name>, such as IPERF_BANDWIDTH.\n\
-\n\
-Report bugs to <dast@nlanr.net>\n";
-
-#else
const char usage_long[] = "\
Usage: iperf [-s|-c host] [options]\n\
iperf [-h|--help] [-v|--version]\n\
IPERF_<long option name>, such as IPERF_BANDWIDTH.\n\
\n\
Report bugs to <dast@nlanr.net>\n";
-#endif
// include a description of the threading in the version
#if defined( HAVE_POSIX_THREAD )
#define IPERF_THREADS "pthreads"
-#elif defined( HAVE_WIN32_THREAD )
- #define IPERF_THREADS "win32 threads"
#else
#define IPERF_THREADS "single threaded"
#endif
"%s,%s,%d,%.1f-%.1f,%lld,%lld,%.3f,%d,%d,%.3f,%d\n";
#endif // HAVE_PRINTF_QD
#else // HAVE_QUAD_SUPPORT
-#ifdef WIN32
-const char reportCSV_bw_format[] =
-"%s,%s,%d,%.1f-%.1f,%I64d,%I64d\n";
-
-const char reportCSV_bw_jitter_loss_format[] =
-"%s,%s,%d,%.1f-%.1f,%I64d,%I64d,%.3f,%d,%d,%.3f,%d\n";
-#else
const char reportCSV_bw_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d\n";
const char reportCSV_bw_jitter_loss_format[] =
"%s,%s,%d,%.1f-%.1f,%d,%d,%.3f,%d,%d,%.3f,%d\n";
-#endif //WIN32
#endif //HAVE_QUAD_SUPPORT
/* -------------------------------------------------------------------
* warnings
break;
case 'h': // print help and exit
-#ifndef WIN32
fprintf( stderr, usage_long );
-#else
- fprintf(stderr, usage_long1);
- fprintf(stderr, usage_long2);
-#endif
exit(1);
break;
(*client)->mAmount = ntohl(hdr->mAmount);
if ( ((*client)->mAmount & 0x80000000) > 0 ) {
setModeTime( (*client) );
-#ifndef WIN32
(*client)->mAmount |= 0xFFFFFFFF00000000LL;
-#else
- (*client)->mAmount |= 0xFFFFFFFF00000000;
-#endif
(*client)->mAmount = -(*client)->mAmount;
}
(*client)->mFileName = NULL;
#include "List.h"
#include "util.h"
-#ifdef WIN32
-#include "service.h"
-#endif
-
/* -------------------------------------------------------------------
* prototypes
* ------------------------------------------------------------------- */
my_signal( SIGTERM, Sig_Interupt );
my_signal( SIGINT, Sig_Interupt );
-#ifndef WIN32
- // Ignore broken pipes
- signal(SIGPIPE,SIG_IGN);
-#else
- // Start winsock
- WSADATA wsaData;
- int rc = WSAStartup( 0x202, &wsaData );
- WARN_errno( rc == SOCKET_ERROR, "WSAStartup" );
- if (rc == SOCKET_ERROR)
- return 0;
-
- // Tell windows we want to handle our own signals
- SetConsoleCtrlHandler( sig_dispatcher, true );
-#endif
// Initialize global mutexes and conditions
Condition_Initialize ( &ReportCond );
// Check for either having specified client or server
if ( ext_gSettings->mThreadMode == kMode_Client
|| ext_gSettings->mThreadMode == kMode_Listener ) {
-#ifdef WIN32
- // Start the server as a daemon
- // Daemon mode for non-windows in handled
- // in the listener_spawn function
- if ( isDaemon( ext_gSettings ) ) {
- CmdInstallService(argc, argv);
- return 0;
- }
-
- // Remove the Windows service if requested
- if ( isRemoveService( ext_gSettings ) ) {
- // remove the service
- if ( CmdRemoveService() ) {
- fprintf(stderr, "IPerf Service is removed.\n");
-
- return 0;
- }
- }
-#endif
// initialize client(s)
if ( ext_gSettings->mThreadMode == kMode_Client ) {
client_init( ext_gSettings );
// neither server nor client mode was specified
// print usage and exit
-#ifdef WIN32
- // In Win32 we also attempt to start a previously defined service
- // Starting in 2.0 to restart a previously defined service
- // you must call iperf with "iperf -D" or using the environment variable
- SERVICE_TABLE_ENTRY dispatchTable[] =
- {
- { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main},
- { NULL, NULL}
- };
-
- // Only attempt to start the service if "-D" was specified
- if ( !isDaemon(ext_gSettings) ||
- // starting the service by SCM, there is no arguments will be passed in.
- // the arguments will pass into Service_Main entry.
- !StartServiceCtrlDispatcher(dispatchTable) )
- // If the service failed to start then print usage
-#endif
fprintf( stderr, usage_short, argv[0], argv[0] );
return 0;
* ------------------------------------------------------------------- */
void cleanup( void ) {
-#ifdef WIN32
- // Shutdown Winsock
- WSACleanup();
-#endif
// clean up the list of clients
Iperf_destroy ( &clients );
thread_destroy( );
} // end cleanup
-#ifdef WIN32
-/*--------------------------------------------------------------------
- * ServiceStart
- *
- * each time starting the service, this is the entry point of the service.
- * Start the service, certainly it is on server-mode
- *
- *-------------------------------------------------------------------- */
-VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) {
-
- // report the status to the service control manager.
- //
- if ( !ReportStatusToSCMgr(
- SERVICE_START_PENDING, // service state
- NO_ERROR, // exit code
- 3000) ) // wait hint
- goto clean;
-
- thread_Settings* ext_gSettings = new thread_Settings;
-
- // Initialize settings to defaults
- Settings_Initialize( ext_gSettings );
- // read settings from environment variables
- Settings_ParseEnvironment( ext_gSettings );
- // read settings from command-line parameters
- Settings_ParseCommandLine( dwArgc, lpszArgv, ext_gSettings );
-
- // report the status to the service control manager.
- //
- if ( !ReportStatusToSCMgr(
- SERVICE_START_PENDING, // service state
- NO_ERROR, // exit code
- 3000) ) // wait hint
- goto clean;
-
- // if needed, redirect the output into a specified file
- if ( !isSTDOUT( ext_gSettings ) ) {
- redirect( ext_gSettings->mOutputFileName );
- }
-
- // report the status to the service control manager.
- //
- if ( !ReportStatusToSCMgr(
- SERVICE_START_PENDING, // service state
- NO_ERROR, // exit code
- 3000) ) // wait hint
- goto clean;
-
- // initialize client(s)
- if ( ext_gSettings->mThreadMode == kMode_Client ) {
- client_init( ext_gSettings );
- }
-
- // start up the reporter and client(s) or listener
- {
- thread_Settings *into = NULL;
-#ifdef HAVE_THREAD
- Settings_Copy( ext_gSettings, &into );
- into->mThreadMode = kMode_Reporter;
- into->runNow = ext_gSettings;
-#else
- into = ext_gSettings;
-#endif
- thread_start( into );
- }
-
- // report the status to the service control manager.
- //
- if ( !ReportStatusToSCMgr(
- SERVICE_RUNNING, // service state
- NO_ERROR, // exit code
- 0) ) // wait hint
- goto clean;
-
- clean:
- // wait for other (client, server) threads to complete
- thread_joinall();
-}
-
-
-//
-// FUNCTION: ServiceStop
-//
-// PURPOSE: Stops the service
-//
-// PARAMETERS:
-// none
-//
-// RETURN VALUE:
-// none
-//
-// COMMENTS:
-// If a ServiceStop procedure is going to
-// take longer than 3 seconds to execute,
-// it should spawn a thread to execute the
-// stop code, and return. Otherwise, the
-// ServiceControlManager will believe that
-// the service has stopped responding.
-//
-VOID ServiceStop() {
-#ifdef HAVE_THREAD
- Sig_Interupt( 1 );
-#else
- sig_exit(1);
-#endif
-}
-
-#endif
-
-
-
-
-
* return: none
* ------------------------------------------------------------------- */
-void redirect(const char *inOutputFileName) {
-#ifdef WIN32
-
- FILE *fp;
-
- if ( inOutputFileName == NULL ) {
- fprintf(stderr, "should specify the output file name.\n");
- return;
- }
-
- fp = freopen(inOutputFileName, "a+", stdout);
- if ( fp == NULL ) {
- fprintf(stderr, "redirect stdout failed!\n");
- return;
- }
-
-#endif
-
+void redirect(const char *inOutputFileName)
+{
return;
}