pipe.c

来自「Wine-20031016」· C语言 代码 · 共 602 行 · 第 1/2 页

C
602
字号
    trace("serverThreadMain2\n");    /* Set up a simple echo server */    hnp = CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,        PIPE_TYPE_BYTE | PIPE_WAIT,        /* nMaxInstances */ 2,        /* nOutBufSize */ 1024,        /* nInBufSize */ 1024,        /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,        /* lpSecurityAttrib */ NULL);    ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");    for (i = 0; ; i++) {        char buf[512];        DWORD written;        DWORD readden;        DWORD success;        /* Wait for client to connect */        trace("Server calling ConnectNamedPipe...\n");        ok(ConnectNamedPipe(hnp, NULL)            || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe");        trace("ConnectNamedPipe returned.\n");        /* Echo bytes once */        memset(buf, 0, sizeof(buf));        trace("Server reading...\n");        success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);        trace("Server done reading.\n");        ok(success, "ReadFile");        trace("Server writing...\n");        ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile");        trace("Server done writing.\n");        ok(written == readden, "write file len");        /* finish this connection, wait for next one */        ok(FlushFileBuffers(hnp), "FlushFileBuffers");        ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");        /* Set up next echo server */        hnpNext =            CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,            PIPE_TYPE_BYTE | PIPE_WAIT,            /* nMaxInstances */ 2,            /* nOutBufSize */ 1024,            /* nInBufSize */ 1024,            /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,            /* lpSecurityAttrib */ NULL);        ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");        ok(CloseHandle(hnp), "CloseHandle");        hnp = hnpNext;    }}/** Trivial byte echo server - uses overlapped named pipe calls */static DWORD CALLBACK serverThreadMain3(LPVOID arg){    int i;    HANDLE hEvent;    trace("serverThreadMain3\n");    /* Set up a simple echo server */    hnp = CreateNamedPipe(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,        PIPE_TYPE_BYTE | PIPE_WAIT,        /* nMaxInstances */ 1,        /* nOutBufSize */ 1024,        /* nInBufSize */ 1024,        /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,        /* lpSecurityAttrib */ NULL);    ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");    hEvent = CreateEvent(NULL,  /* security attribute */        TRUE,                   /* manual reset event */        FALSE,                  /* initial state */        NULL);                  /* name */    ok(hEvent != NULL, "CreateEvent");    for (i = 0; ; i++) {        char buf[512];        DWORD written;        DWORD readden;        DWORD dummy;        DWORD success;        OVERLAPPED oOverlap;        int letWFSOEwait = (i & 2);        int letGORwait = (i & 1);	DWORD err;        memset(&oOverlap, 0, sizeof(oOverlap));        oOverlap.hEvent = hEvent;        /* Wait for client to connect */        trace("Server calling overlapped ConnectNamedPipe...\n");        success = ConnectNamedPipe(hnp, &oOverlap);        err = GetLastError();        ok(success || err == ERROR_IO_PENDING            || err == ERROR_PIPE_CONNECTED, "overlapped ConnectNamedPipe");        trace("overlapped ConnectNamedPipe returned.\n");        if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)            ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ConnectNamedPipe");        success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);	if (!letGORwait && !letWFSOEwait && !success) {	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");	    success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);	}	ok(success, "GetOverlappedResult ConnectNamedPipe");        trace("overlapped ConnectNamedPipe operation complete.\n");        /* Echo bytes once */        memset(buf, 0, sizeof(buf));        trace("Server reading...\n");        success = ReadFile(hnp, buf, sizeof(buf), NULL, &oOverlap);        trace("Server ReadFile returned...\n");        err = GetLastError();        ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile");        trace("overlapped ReadFile returned.\n");        if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)            ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ReadFile");        success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);	if (!letGORwait && !letWFSOEwait && !success) {	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");	    success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);	}        trace("Server done reading.\n");        ok(success, "overlapped ReadFile");        trace("Server writing...\n");        success = WriteFile(hnp, buf, readden, NULL, &oOverlap);        trace("Server WriteFile returned...\n");        err = GetLastError();        ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile");        trace("overlapped WriteFile returned.\n");        if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)            ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait WriteFile");        success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);	if (!letGORwait && !letWFSOEwait && !success) {	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");	    success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);	}        trace("Server done writing.\n");        ok(success, "overlapped WriteFile");        ok(written == readden, "write file len");        /* finish this connection, wait for next one */        ok(FlushFileBuffers(hnp), "FlushFileBuffers");        ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");    }}static void exercizeServer(const char *pipename, HANDLE serverThread){    int i;    trace("exercizeServer starting\n");    for (i = 0; i < 8; i++) {        HANDLE hFile=INVALID_HANDLE_VALUE;        const char obuf[] = "Bit Bucket";        char ibuf[32];        DWORD written;        DWORD readden;        int loop;        for (loop = 0; loop < 3; loop++) {	    DWORD err;            trace("Client connecting...\n");            /* Connect to the server */            hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,                NULL, OPEN_EXISTING, 0, 0);            if (hFile != INVALID_HANDLE_VALUE)                break;	    err = GetLastError();	    if (loop == 0)	        ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe");	    else	        ok(err == ERROR_PIPE_BUSY, "connecting to pipe");            trace("connect failed, retrying\n");            Sleep(200);        }        ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe");        /* Make sure it can echo */        memset(ibuf, 0, sizeof(ibuf));        trace("Client writing...\n");        ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe");        ok(written == sizeof(obuf), "write file len");        trace("Client reading...\n");        ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe");        ok(readden == sizeof(obuf), "read file len");        ok(memcmp(obuf, ibuf, written) == 0, "content check");        trace("Client closing...\n");        ok(CloseHandle(hFile), "CloseHandle");    }    ok(TerminateThread(serverThread, 0), "TerminateThread");    CloseHandle(hnp);    trace("exercizeServer returning\n");}void test_NamedPipe_2(void){    HANDLE serverThread;    DWORD serverThreadId;    HANDLE alarmThread;    DWORD alarmThreadId;    trace("test_NamedPipe_2 starting\n");    /* Set up a ten second timeout */    alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 10000, 0, &alarmThreadId);    /* The servers we're about to exercize do try to clean up carefully,     * but to reduce the change of a test failure due to a pipe handle     * leak in the test code, we'll use a different pipe name for each server.     */    /* Try server #1 */    serverThread = CreateThread(NULL, 0, serverThreadMain1, 0, 0, &serverThreadId);    ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");    exercizeServer(PIPENAME "serverThreadMain1", serverThread);    /* Try server #2 */    serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);    ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");    exercizeServer(PIPENAME "serverThreadMain2", serverThread);    if( 0 ) /* overlapped pipe server doesn't work yet - it randomly fails */    {    /* Try server #3 */    serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);    ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");    exercizeServer(PIPENAME "serverThreadMain3", serverThread);    }    ok(TerminateThread(alarmThread, 0), "TerminateThread");    trace("test_NamedPipe_2 returning\n");}void test_DisconnectNamedPipe(void){    HANDLE hnp;    HANDLE hFile;    const char obuf[] = "Bit Bucket";    char ibuf[32];    DWORD written;    DWORD readden;    hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,        /* nMaxInstances */ 1,        /* nOutBufSize */ 1024,        /* nInBufSize */ 1024,        /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,        /* lpSecurityAttrib */ NULL);    ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");    ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0        && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe");    ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0        && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe");    hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);    ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed");    /* don't try to do i/o if one side couldn't be opened, as it hangs */    if (hFile != INVALID_HANDLE_VALUE) {        /* see what happens if server calls DisconnectNamedPipe         * when there are bytes in the pipe         */        ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile");        ok(written == sizeof(obuf), "write file len");        ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting");        ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0            && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe");        ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0            && GetLastError() == ERROR_PIPE_NOT_CONNECTED,            "ReadFile from disconnected pipe with bytes waiting");        ok(CloseHandle(hFile), "CloseHandle");    }    ok(CloseHandle(hnp), "CloseHandle");}START_TEST(pipe){    trace("test 1 of 4:\n");    test_DisconnectNamedPipe();    trace("test 2 of 4:\n");    test_CreateNamedPipe_instances_must_match();    trace("test 3 of 4:\n");    test_NamedPipe_2();    trace("test 4 of 4:\n");    test_CreateNamedPipe();    trace("all tests done\n");}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?