Skip to content

Instantly share code, notes, and snippets.

@aont
Last active February 21, 2020 15:43
Show Gist options
  • Select an option

  • Save aont/e371fb3affcac6e192aaf92dc5fa2cfc to your computer and use it in GitHub Desktop.

Select an option

Save aont/e371fb3affcac6e192aaf92dc5fa2cfc to your computer and use it in GitHub Desktop.

use namedpipe on Windows

client -> server

# on terminal A
namedpipe.exe server test read
# you will see "hoge"

# on terminal B
echo hoge | namedpipe.exe client test write

client <- server

# on terminal A
echo hoge | namedpipe.exe server test write

# on terminal B
namedpipe.exe client test read
# you will see "hoge"

Environment: Windows10 1903
Compiler: VC++ cl.exe 15.00.30729.01 for x64

#include <stdio.h>
#include <windows.h>
#include <io.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int const argc, char** const argv) {
if(argc < 4) {
fprintf(stderr, "Usage: %s run_type={client,server} pipename access={read,write} [block_size=65536]\n", argv[0]);
return -1;
}
setmode(0, O_BINARY);
setmode(1, O_BINARY);
char* run_type_str = argv[1];
int run_server = 1;
if(strcmp(run_type_str, "client")==0) {
run_server = 0;
} else if(strcmp(run_type_str, "server")==0) {
run_server = 1;
} else {
fprintf(stderr, "[err] run_type %s invalid\n", run_type_str);
return -1;
}
char* pipefn = argv[2];
char* pipe_access_str = argv[3];
char pipename[128];
sprintf(pipename, "\\\\.\\PIPE\\%s", pipefn);
int pipe_read_write;
if(strcmp("read", pipe_access_str)==0) {
pipe_read_write = 1;
} else if(strcmp("write", pipe_access_str)==0) {
pipe_read_write = 0;
} else {
fprintf(stderr, "[err] %s: not supported\n", pipe_access_str);
return -1;
}
DWORD pipe_access = 0;
if(run_server) {
if(pipe_read_write==1) {
pipe_access = PIPE_ACCESS_INBOUND;
} else if(pipe_read_write==0) {
pipe_access = PIPE_ACCESS_OUTBOUND;
} else {
fprintf(stderr, "[err] unexpected pipe_read_write=%d\n", pipe_read_write);
return -1;
}
} else {
if(pipe_read_write==1) {
pipe_access = GENERIC_READ;
} else if(pipe_read_write==0) {
pipe_access = GENERIC_WRITE;
} else {
fprintf(stderr, "[err] unexpected pipe_read_write=%d\n", pipe_read_write);
return -1;
}
}
char *endptr;
long block_size = 65536;
if(argc>4) {
char* block_size_str = argv[4];
block_size = strtol(block_size_str, &endptr, 10);
if(block_size_str==endptr) {
fprintf(stderr, "[err] %s is a invalid number.\n", block_size_str);
return -1;
}
}
HANDLE hPipe = INVALID_HANDLE_VALUE;
if(run_server)
hPipe = CreateNamedPipe(pipename, pipe_access, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 0, 100, NULL);
else
hPipe = CreateFile(pipename, pipe_access, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hPipe == INVALID_HANDLE_VALUE) {
fprintf(stderr, "[err] unable to create NamedPipe\n");
return 1;
}
if (run_server && !ConnectNamedPipe(hPipe, NULL)) {
fprintf(stderr, "[err] unable to connect to NamedPipe\n");
CloseHandle(hPipe);
return 1;
}
char* szBuff = (char*)malloc(block_size+1);
if(pipe_read_write==1) {
// ovl.hEvent = CreateEvent(NULL, FALSE, FALSE, "olp");
while (1) {
DWORD dwBytesRead;
if (!ReadFile(hPipe, szBuff, block_size, &dwBytesRead, NULL)) {
fprintf(stderr, "[info] unable to read NamedPipe\n");
break;
}
// szBuff[dwBytesRead] = '\0';
int const fd_stdout = 1;
int const num_write = write(1, szBuff, dwBytesRead);
// size_t const num_write = fwrite(szBuff, dwBytesRead, 1, stdout);
if (num_write<dwBytesRead) {
fprintf(stderr, "[info] unable to write to stdout\n");
break;
}
//fprintf(stderr, "\nwrite\n");
//Sleep(1000);
}
// CloseHandle(ovl.hEvent);
} else if(pipe_read_write==0) {
// HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
while (1) {
// size_t const num_read = fread(szBuff, block_size, 1, stdin);
int const fd_stdin = 0;
int const num_read = read(0, szBuff, block_size);
if(num_read==0) {
fprintf(stderr, "[info] unable to read stdin\n");
break;
}
//szBuff[block_size] = '\0';
//fprintf(stderr, "[info] read=%s::::\n", szBuff);
DWORD dwBytesWritten;
if (!WriteFile(hPipe, szBuff, num_read, &dwBytesWritten, NULL)) {
fprintf(stderr, "[info] unable to write NamedPipe.");
break;
}
//Sleep(1000);
}
}
free(szBuff);
if(pipe_read_write==0) FlushFileBuffers(hPipe);
if(run_server) DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment