This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

select/listen (win xp sp1) bug, due to Windows login somehow.


Hello list.

Here is an example of a very simple Windows service.

This code works fine if

a) You start/stop from the Windows Service Control Manager. Always a telnet from another machine to port 1984 on the app-machine suceeds and writes back data.

b) You reboot the machine and _don't_ log in. If you simply leave the machine at the login prompt, this particular Windows Service, will always behave as expected.

However, if you do start the login process and poll programatically/by hand the service to return data, you should notice as I have that roughly 1-2 seconds before the full login, to the Windows desktop, that the process stops accepting connections, but, is still listed as a running process.
At this point a "netstat -an" will show BugTester in TIME_WAIT for port 1984, however, if left long enough, it will disappear (from the netstat -an list, not from the process list).


I've included the strace output of an instance of BugTester which mysteriously disappeared from netstat.

In fact I've just run two straces on this test process, the first strace is before the BugTester application disappears from a netstat -an and quite simply the process seems to be doing nothing, the second strace is attached in part in this email, and shows what the process is doing _after_ it disappears from netstat -an.

ie, it looks as if

a: BugTester simply _isn't_ doing it's select once the full windows login has occured, despite being listed in netstat

b: As soon as BugTester disappears from the netstat listing that the select stuff is running, but, is not picking up incoming connections.

c: However, critically, if a login to a Windows desktop doesn't occur (at least on my machine), BugTester seems to _always_ work.


The host operating system is Windows XP SP1.


Cygwin dll version : 1005.12.0.0

gcc 3.3.3 (cygwin special)


I'm not subscribed to the list, so if anybody can crack this/answers, I'd appreciate a cc.


Thanks

--
Bryan



#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>

#include <windows.h>
#include <winsvc.h>
#include <assert.h>

#define REG_PATH "Software\\Bugtestpath\\BugTest\\MyPath"
#define PATH_KEY "PathVal"

sem_t aSem;
//// Global /////////////////////////////////////////////////////////
FILE* pLog;
char* ServiceName = "BugTest"; // Name of the service
HANDLE terminateEvent = NULL; // Event used to hold ServerMain from completing
// Handle used to communicate status info with
// the SCM. Created by RegisterService3Handler
HANDLE threadHandle = 0; // Thread for the actual work
BOOL pauseService = FALSE; // Flags holding current state of service
BOOL runningService = FALSE; //
SERVICE_STATUS_HANDLE serviceStatusHandle; //


DWORD WINAPI ServiceThread( LPDWORD lParam);
BOOL SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
void StopService();


void    ServiceCtrlHandler(DWORD controlCode);
void    ServiceMain(DWORD argc, LPTSTR *argv);
void    ErrorHandler(char *s, int err);
void    GetStatus(SC_HANDLE service);
void    ShowUsage();
// service config program tasks
bool    InstallService();
bool    UninstallService();
bool    GetConfiguration();
bool    ChangeConfig();
// service control program tasks
bool    ServiceRun();
bool    ServiceControl(char* CONTROL);

static void mainThread(void*arg);
void    startTestHttpThread();
void    stopTestHttpThread();

int main(int argc, char *argv[])
{
    SERVICE_TABLE_ENTRY serviceTable[] =
    {
        { ServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
        { NULL, NULL}
    };
    BOOL success;

    if(argc == 2)
    {
        if (stricmp("-i", argv[1]) == 0)
            InstallService();
        else if (stricmp("-u", argv[1]) == 0)
            UninstallService();
        else if (stricmp("-r", argv[1]) == 0)
            ServiceRun();
        else
            ShowUsage();
    }

    else
    {
        //register with SCM
        success = StartServiceCtrlDispatcher(serviceTable);
        if (!success)
            ErrorHandler("StartServiceCtrlDispatcher",GetLastError());
    }

    return 0;
}
/********* Thread stuff *********/

/* Variables */
pthread_t ptHandle;
sem_t semSignal;

/* Functions */
static void mainThread(void*arg){
    //printf("%s started id %lu\n",__FUNCTION__, pthread_self());
    //printf("Main thread started\n");
    int sock_handle=-1;
    struct sockaddr_in sin;

    sock_handle=socket(AF_INET,SOCK_STREAM,0);
    if(sock_handle<0)
        goto done;
    sin.sin_addr.s_addr=INADDR_ANY;
    sin.sin_port=htons(1984);
    sin.sin_family=AF_INET;

    if(bind(sock_handle,(struct sockaddr*)&sin,sizeof(sin))<0){
        fprintf(stderr,"Extreme error, couldn't bind 1984!\n");
        goto done;
    }

listen(sock_handle,5);

    fd_set fd1,fd2;
    char naff_buff[128];
    struct timeval tm;

    while(1){
            FD_ZERO(&fd1);
            FD_SET(sock_handle,&fd1);

            fd2=fd1;
            tm.tv_sec=0;
            tm.tv_usec=1000;    //Check often
            int val=select(FD_SETSIZE,&fd2,NULL,NULL,&tm);

            if(FD_ISSET(sock_handle,&fd2)){
                        //deal with request
                //printf("Have information pending on socket\n");
                struct sockaddr_in sin_in;
                int sin_size=sizeof(sin_in);

int sess_sock=accept(sock_handle,(struct sockaddr*)&sin_in,&sin_size);

                int nbytes=read(sess_sock,naff_buff,128);
                if(nbytes<=0){
                    close(sess_sock);
                    break;
                }

char * noddy_string="HTTP 1/0 200 OK\r\nServer: BugTester \r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<HTML><HEAD><TITLE>BugTester working</TITLE></HEAD><BODY>BUGTESTER WORKING !!</BODY></HTML>";
write(sess_sock,noddy_string,strlen(noddy_string));
close(sess_sock);
}
//else check state of semaphore
if(sem_trywait(&semSignal)==0){
//printf("Locked semaphore shutdown condition\n");
goto done;
}
}


done:
    if(sock_handle!=-1)
        close(sock_handle);

    pthread_exit(0);
}

void startTestHttpThread(void){

    sem_init(&semSignal,0,0);
    if(pthread_create(&ptHandle,NULL,(void*(*)(void*))mainThread,NULL)<0){
        ErrorHandler("Unable to start main thread",GetLastError());
       }

 return;
}

void stopTestHttpThread(void){
    sem_post(&semSignal);
    pthread_join(ptHandle,NULL);

 return;
}


void ServiceMain(DWORD argc, LPTSTR *argv) { BOOL success;

//immediately call registration function
serviceStatusHandle = RegisterServiceCtrlHandler(ServiceName, (LPHANDLER_FUNCTION)ServiceCtrlHandler);
if (!serviceStatusHandle)
{
exit(-1);
return;
}


//notify SCM
success = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 1, 5000);
if (!success)
{
exit(-1);
return;
}


    //create termination event
    terminateEvent = CreateEvent (0, TRUE, FALSE, 0);
    if (!terminateEvent)
    {
        exit(-1);
        return;
    }

//notify SCM
success = SendStatusToSCM(SERVICE_START_PENDING, NO_ERROR, 0 , 2, 1000);
if (!success)
{
exit(-1);
return;
}


    //start service
     DWORD dwType, dwLen;

    HKEY hKey;
    DWORD disposition, size, type;

char *stringData=0;

    // Open our registry key
    RegCreateKeyEx(HKEY_LOCAL_MACHINE,REG_PATH, 0, NULL,
        REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
        &hKey, &disposition);



    // Check if the value exists, and how long it is
    long result = RegQueryValueEx(hKey, PATH_KEY, 0,&type, NULL, &size);

    if (result != ERROR_SUCCESS)
         MessageBox(NULL, "The value named 'PathVal'"
             " was not found in the registry",
             "Problem", MB_OK);
       else
         if (type == REG_SZ)
         {
               stringData = new char[size];
               RegQueryValueEx(hKey, PATH_KEY,
                0, &type, (BYTE*)stringData, &size);
         }
     else       // If the value exists,
               // but isn't a REG_SZ value
           MessageBox(NULL,
           "The value named 'Message' does not "
           "contain string data", "Problem", MB_OK);

    // Close the key
    RegCloseKey(hKey);


chdir(stringData); /* hack */ if(stringData) delete[] stringData;


sem_init(&aSem,0,0); startTestHttpThread(); //notify SCM service is runnning success = SendStatusToSCM(SERVICE_RUNNING, NO_ERROR, 0 , 0, 0); if (!success) { exit(-1); return; }

    //wait for stop signal and then terminate
    sem_wait(&aSem);

    exit(0);
}


//stops service by allowing ServiceMain to complete void StopService() { runningService = FALSE; //set the event that is holding ServiceMain stopTestHttpThread(); sem_post(&aSem); }

//this function consolidates the activities of updating
//the service status with SetServiceStatus
BOOL SendStatusToSCM(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
{
BOOL success;
SERVICE_STATUS serviceStatus;


    //fill in all of the SERVICE_STATUS fields
    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    serviceStatus.dwCurrentState = dwCurrentState;

    //if in the process of something, then accept
    //no control events, else accept anything
    if (dwCurrentState == SERVICE_START_PENDING)
        serviceStatus.dwControlsAccepted = 0;
    else
        serviceStatus.dwControlsAccepted =
            SERVICE_ACCEPT_STOP |
            SERVICE_ACCEPT_SHUTDOWN;

//if a specific exit code is defines, set up the win32 exit code properly
if (dwServiceSpecificExitCode == 0)
serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
else
serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;


    serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
    serviceStatus.dwCheckPoint = dwCheckPoint;
    serviceStatus.dwWaitHint = dwWaitHint;

    success = SetServiceStatus (serviceStatusHandle, &serviceStatus);
    if (!success)
        StopService();

    return success;
}

void ServiceCtrlHandler(DWORD controlCode)
{
    DWORD currentState = 0;
    BOOL success;

    switch(controlCode)
    {
        // START = ServiceMain()

        // STOP
        case SERVICE_CONTROL_STOP:
            currentState = SERVICE_STOP_PENDING;
            //notify SCM
            success = SendStatusToSCM(
                SERVICE_STOP_PENDING,
                NO_ERROR,
                0,
                1,
                5000);
            //stop service
            StopService();
            return;

        case SERVICE_CONTROL_SHUTDOWN:
            //do nothing
            return;
        default:
            break;
    }
    //notify SCM current state
    SendStatusToSCM(currentState, NO_ERROR, 0, 0, 0);
}

void ErrorHandler(char *s, int err)
{
    pLog = fopen("server.log","a");
    fprintf(pLog, "%s failed, error code = %d\n",s , err);
    fclose(pLog);

    exit(-err);
}

void ShowUsage()
{
        printf("USAGE:\n");
        printf("server -i\tInstall service\n");
        printf("server -u\tUninstall service\n");
        printf("server status\tCurrent status\n");
}


bool SaveRegistrySettings(){


    char zBuf[1024];
    DWORD dwLen=1024;
    GetCurrentDirectory(dwLen,zBuf);

    HKEY hKey;
    DWORD disposition;

    // Open our registry key
    RegCreateKeyEx(HKEY_LOCAL_MACHINE,
    REG_PATH, 0, NULL,
    REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
    &hKey, &disposition);



    // Set a value
    DWORD data = 42;
    RegSetValueEx(hKey, PATH_KEY, 0,
        REG_SZ, (BYTE *)zBuf, strlen(zBuf));

    RegCloseKey(hKey);
    return true;
}

////////////////////////////////////////////////////////////////////////////////
// Purpose    :Install service into SCM.
// Parameter:N/A
// Returns    :N/A
////////////////////////////////////////////////////////////////////////////////
bool InstallService()
{
    SC_HANDLE newService;
    SC_HANDLE scm;
    char szBuffer[255];
    char szPath[MAX_PATH];

    //get file path
    GetModuleFileName( GetModuleHandle(NULL), szPath, MAX_PATH );
    strcpy( szBuffer, "\"" );
    strcat( szBuffer, szPath );
    strcat( szBuffer, "\"" );

    //open connection to SCM
    scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!scm)
        ErrorHandler("OpenSCManager", GetLastError());

//install service
newService = CreateService(
scm, //scm database
ServiceName, //service name
ServiceName, //display name
SERVICE_ALL_ACCESS, //access rights to the service
SERVICE_WIN32_OWN_PROCESS, //service type
SERVICE_AUTO_START, //service start type
SERVICE_ERROR_NORMAL, //error control type
szBuffer, //service path
NULL, //no load ordering group
NULL, //no tag identifier
"RPCSS\0\LanmanWorkstation\0", //no dependencies
NULL, //LocalSystem account
NULL); //no password
if(!newService)
{
ErrorHandler("CreateService", GetLastError());
return false;
}
else
{
//Save chdir path to Registry
if(SaveRegistrySettings()){
printf("Service Installed\n");
ServiceRun();
}
}


    //clean up
    CloseServiceHandle(newService);
    CloseServiceHandle(scm);

return true;

}

////////////////////////////////////////////////////////////////////////////////
// Purpose    :Uninstall service from SCM.
// Parameter:N/A
// Returns    :N/A
////////////////////////////////////////////////////////////////////////////////
bool UninstallService()
{
    SC_HANDLE service;
    SC_HANDLE scm;
    BOOL SUCCESS;
    SERVICE_STATUS status;

    //Open connection to SCM
    scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!scm)
        ErrorHandler("OpenSCManager", GetLastError());

    //Get service's handle
    service = OpenService(scm, ServiceName, SERVICE_ALL_ACCESS | DELETE);
    if (!service)
        ErrorHandler("OpenService", GetLastError());

    //Get service status
    SUCCESS    = QueryServiceStatus(service, &status);
    if (!SUCCESS)
        ErrorHandler("QueryServiceStatus", GetLastError());

    //Stop service if necessary
    if (status.dwCurrentState != SERVICE_STOPPED)
    {
        printf( "Stopping service...\n");
        SUCCESS = ControlService(service, SERVICE_CONTROL_STOP, &status);
        if (!SUCCESS)
            ErrorHandler("ControlService", GetLastError());
        Sleep(500);
    }

    //Delete service
    SUCCESS = DeleteService(service);
    if (SUCCESS)
        printf("Service Uninstalled\n");
    else
        ErrorHandler("DeleteService", GetLastError());

    //Clean up
    CloseServiceHandle(service);
    CloseServiceHandle(scm);

    return true;
}


//////////////////////////////////////////////////////////////////////////////// // Purpose :Run service // Parameter:N/A // Returns :N/A //////////////////////////////////////////////////////////////////////////////// bool ServiceRun() { SC_HANDLE scm, Service; SERVICE_STATUS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwStatus;

    //open connection to SCM
    scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!scm)
        ErrorHandler("OpenSCManager", GetLastError());

    //open service
    Service = OpenService(scm, ServiceName, SERVICE_ALL_ACCESS);
    if(!Service)
    {
        ErrorHandler("OpenService", GetLastError());
        return false;
    }
    else
    {
        //start service
        StartService(Service, 0, NULL);
        GetStatus(Service);

        // Check the status until the service is no longer start pending.
        if (!QueryServiceStatus( Service, &ssStatus) )
            ErrorHandler("QueryServiceStatus", GetLastError());
        // Save the tick count and initial checkpoint.
        dwStartTickCount = GetTickCount();
        dwOldCheckPoint = ssStatus.dwCheckPoint;

        while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
        {
            // Do not wait longer than the wait hint. A good interval is
            // one tenth the wait hint, but no less than 1 second and no
            // more than 10 seconds.
            dwWaitTime = ssStatus.dwWaitHint / 10;

            if( dwWaitTime < 1000 )
                dwWaitTime = 1000;
            else if ( dwWaitTime > 10000 )
                dwWaitTime = 10000;

Sleep( dwWaitTime );

            // Check the status again.
            if (!QueryServiceStatus(Service, &ssStatus) )
                break;

            if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
            {
                // The service is making progress.
                dwStartTickCount = GetTickCount();
                dwOldCheckPoint = ssStatus.dwCheckPoint;
            }
            else
            {
                if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
                {
                    // No progress made within the wait hint
                    break;
                }
            }
        }

        if (ssStatus.dwCurrentState == SERVICE_RUNNING)
        {
            GetStatus(Service);
            dwStatus = NO_ERROR;
        }
        else
        {

printf("Service not started.\n");
printf("Current State: %lu\n",ssStatus.dwCurrentState);
printf("Exit Code: %lu\n",ssStatus.dwWin32ExitCode);
printf("Service Specific Exit Code: %lu\n",ssStatus.dwServiceSpecificExitCode);
printf("Check Point: %lu\n",ssStatus.dwCheckPoint);
printf("Wait Hint: %lu\n",ssStatus.dwWaitHint);
dwStatus = GetLastError();
}
}


    CloseServiceHandle(scm);
    CloseServiceHandle(Service);
    return true;
}



////////////////////////////////////////////////////////////////////////////////
// Purpose    :Get the current status of the service
// Parameter:service handle.
// Returns    :N/A
////////////////////////////////////////////////////////////////////////////////
void GetStatus(SC_HANDLE service)
{
    BOOL SUCCESS;
    SERVICE_STATUS status;
    DWORD CurrentState;

SUCCESS = QueryServiceStatus(service, &status);

    switch(status.dwCurrentState)
    {
        case SERVICE_RUNNING:
            CurrentState = SERVICE_RUNNING;
            printf("Service RUNNING.\n");
            break;
        case SERVICE_STOPPED:
            CurrentState = SERVICE_STOPPED;
            printf("Service STOPPED.\n");
            break;
        case SERVICE_START_PENDING:
            CurrentState = SERVICE_START_PENDING;
            printf( "Service is starting...\n");
            break;
        case SERVICE_STOP_PENDING:
            CurrentState = SERVICE_STOP_PENDING;
            printf( "Service is stopping...\n");
            break;
        default:
            break;
    }
    SendStatusToSCM(CurrentState, NO_ERROR, 0, 0, 0);
}


/////////////////////////////////////////////////////////////////////////////////////// // Logging functions





6191 1284598550 [unknown (0x4F4)] BugTester 1244 select_stuff::~select_stuff: deleting select records
6264 1284604814 [unknown (0x4F4)] BugTester 1244 cygwin_select: 64, 0xCDEEE8, 0x0, 0x0, 0xCDEEF0
6002 1284610816 [unknown (0x4F4)] BugTester 1244 dtable::select_read: fd 0
6114 1284616930 [unknown (0x4F4)] BugTester 1244 cygwin_select: to->tv_sec 0, to->tv_usec 1000, ms 1
6019 1284622949 [unknown (0x4F4)] BugTester 1244 cygwin_select: sel.always_ready 0
6212 1284629161 [unknown (0x4F4)] BugTester 1244 start_thread_socket: Handle 0x138
5954 1284635115 [unknown (0x4F4)] BugTester 1244 start_thread_socket: Added to readfds
6108 1284641223 [unknown (0x4F4)] BugTester 1244 start_thread_socket: exitsock 0x140
5948 1284647171 [unknown (0x4F4)] BugTester 1244 start_thread_socket: stuff_start 0xCDEE54
6624 1284653795 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: m 2, ms 1
5560 1284659355 [select_socket] BugTester 1244 thread_socket: stuff_start 0xA05540C
6234 1284665589 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: timed out
6379 1284671968 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: returning 1
5693 1284677661 [unknown (0x4F4)] BugTester 1244 select_stuff::cleanup: calling cleanup routines
6261 1284683922 [unknown (0x4F4)] BugTester 1244 socket_cleanup: si 0xA0523F8 si->thread 0x610F4870
5986 1284689908 [unknown (0x4F4)] BugTester 1244 socket_cleanup: sent a byte to exitsock 0x140, res 1
6163 1284696071 [select_socket] BugTester 1244 thread_socket: Win32 select returned 1
5909 1284701980 [select_socket] BugTester 1244 thread_socket: s 0xA0523C8, testing fd 0 ()
6178 1284708158 [select_socket] BugTester 1244 thread_socket: saw exitsock read
6014 1284714172 [unknown (0x4F4)] BugTester 1244 socket_cleanup: reading a byte from exitsock 0x140
6184 1284720356 [unknown (0x4F4)] BugTester 1244 socket_cleanup: recv returned 1
5986 1284726342 [unknown (0x4F4)] BugTester 1244 socket_cleanup: returning
6169 1284732511 [unknown (0x4F4)] BugTester 1244 peek_socket: considering handle 0x138
5915 1284738426 [unknown (0x4F4)] BugTester 1244 peek_socket: adding read fd_set , fd 0
6179 1284744605 [unknown (0x4F4)] BugTester 1244 peek_socket: WINSOCK_SELECT returned 0
6120 1284750725 [unknown (0x4F4)] BugTester 1244 select_stuff::poll: returning 0
6044 1284756769 [unknown (0x4F4)] BugTester 1244 select_stuff::cleanup: calling cleanup routines
6188 1284762957 [unknown (0x4F4)] BugTester 1244 select_stuff::~select_stuff: deleting select records
6062 1284769019 [unknown (0x4F4)] BugTester 1244 cygwin_select: 64, 0xCDEEE8, 0x0, 0x0, 0xCDEEF0
6172 1284775191 [unknown (0x4F4)] BugTester 1244 dtable::select_read: fd 0
5995 1284781186 [unknown (0x4F4)] BugTester 1244 cygwin_select: to->tv_sec 0, to->tv_usec 1000, ms 1
6092 1284787278 [unknown (0x4F4)] BugTester 1244 cygwin_select: sel.always_ready 0
6059 1284793337 [unknown (0x4F4)] BugTester 1244 start_thread_socket: Handle 0x138
6088 1284799425 [unknown (0x4F4)] BugTester 1244 start_thread_socket: Added to readfds
5937 1284805362 [unknown (0x4F4)] BugTester 1244 start_thread_socket: exitsock 0x140
6193 1284811555 [unknown (0x4F4)] BugTester 1244 start_thread_socket: stuff_start 0xCDEE54
6154 1284817709 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: m 2, ms 1
6095 1284823804 [select_socket] BugTester 1244 thread_socket: stuff_start 0xA05540C
20378 1284844182 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: timed out
3345 1284847527 [unknown (0x4F4)] BugTester 1244 select_stuff::wait: returning 1
6216 1284853743 [unknown (0x4F4)] BugTester 1244 select_stuff::cleanup: calling cleanup routines
5982 1284859725 [unknown (0x4F4)] BugTester 1244 socket_cleanup: si 0xA0523F8 si->thread 0x610F4870
6391 1284866116 [unknown (0x4F4)] BugTester 1244 socket_cleanup: sent a byte to exitsock 0x140, res 1
^C



-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]