ReactOS  0.4.15-dev-985-gd905dd5
piperead.cpp
Go to the documentation of this file.
1 //
2 // piperead.cpp
3 //
4 // Martin Fuchs, 30.11.2003
5 //
6 // Jan Roeloffzen, 26.1.2010
7 // Pipe client, based on msdn example
8 
9 
10 #define WIN32_LEAN_AND_MEAN
11 #include <errno.h>
12 #include <windows.h>
13 #include <stdio.h>
14 
15 #define PIPEREAD_VERSION "0.3"
16 #define PIPEREAD_NOPIPE (-101)
17 
18  // This definition currently missing in MinGW.
19 #ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
20 #define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
21 #endif
22 
23 
24 #define BUFSIZE 1024
25 
26 static void print_error(DWORD win32_error)
27 {
28  fprintf(stderr, "WIN32 error %lu\n", win32_error);
29 }
30 
31 static int pipeServer(char *path)
32 {
34 
35  if (hPipe == INVALID_HANDLE_VALUE) {
37  return 1;
38  }
39 
40  for(;;) {
41  DWORD read;
43 
44  if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) {
46 
47  if (error == ERROR_PIPE_LISTENING) {
48  Sleep(1000);
49  } else if (error == ERROR_BROKEN_PIPE) {
50  CloseHandle(hPipe);
51 
53 
54  if (hPipe == INVALID_HANDLE_VALUE) {
55  fprintf(stderr,"INVALID_HANDLE_VALUE\n");
57  return 1;
58  }
59  } else {
60  fprintf(stderr,"error %lu\n",error);
62  break;
63  }
64  }
65 
66  if (read)
67  fwrite(buffer, read, 1, stdout);
68  }
69 
70  if (!CloseHandle(hPipe))
72 
73  return 0;
74 }
75 
76 
77 static int pipeClient(char *path)
78 {
80  TCHAR chBuf[BUFSIZE];
81  BOOL fSuccess = FALSE;
82  DWORD cbRead;
83  DWORD Err;
84  int res = 0;
85 
86  setvbuf(stdout, NULL, _IONBF, 0);
87  while (1) {
88  hPipe = CreateFile(path, // pipe name
90  0, // no sharing
91  NULL, // default security attributes
92  OPEN_EXISTING, // opens existing pipe
93  0, // default attributes
94  NULL); // no template file
95 
96  // Break if the pipe handle is valid.
97  if (hPipe != INVALID_HANDLE_VALUE)
98  break;
99 
100  // Exit if an error other than ERROR_PIPE_BUSY occurs.
101  Err = GetLastError();
102  if (Err != ERROR_PIPE_BUSY) {
103  if (ERROR_FILE_NOT_FOUND == Err)
104  {
106  return res;
107  }
108  else
109  {
110  fprintf(stderr,"Could not open pipe %s. Error=%lu\n", path, Err );
111  res = -1;
112  }
113  break;
114  }
115 
116  // All pipe instances are busy, so wait for 20 seconds.
117  if ( ! WaitNamedPipe(path, 20000)) {
118  fprintf(stderr,"Could not open pipe: 20 second wait timed out.");
119  res = -2;
120  break;
121  }
122  }
123 
124  if (!res) do {
125  fSuccess = ReadFile(hPipe, // pipe handle
126  chBuf, // buffer to receive reply
127  BUFSIZE, // size of buffer
128  &cbRead, // number of bytes read
129  NULL); // not overlapped
130 
131  if ( ! fSuccess ) {
132  Err = GetLastError();
133  if ( Err == ERROR_MORE_DATA ) {
134  fSuccess = TRUE;
135  } else {
136  fprintf(stderr, "ReadFile: Error %lu \n", Err );
137  res = -9;
138  break;
139  }
140  }
141 
142  fwrite(chBuf,1,cbRead,stdout);
143  } while ( fSuccess);
144 
145  if ( ! fSuccess) {
146  fprintf(stderr, "ReadFile from pipe failed. Error=%lu\n", GetLastError() );
147  }
148 
149  if (hPipe != INVALID_HANDLE_VALUE)
150  CloseHandle(hPipe);
151 
152  return res;
153 
154 }
155 
156 static int fileClient(const char *path)
157 {
158  int res = 0;
159  FILE *fin;
160  int c;
161 
162  setvbuf(stdout, NULL, _IONBF, 0);
163  if (!(fin = fopen(path, "r"))) {
164  fprintf(stderr,"Could not fopen %s (%s)\n", path, strerror(errno) );
165  return -1;
166  }
167 
168  while ((c = fgetc(fin)) != EOF) {
169  fputc(c, stdout);
170  }
171 
172  fclose(fin);
173  return res;
174 }
175 
176 void usage(void)
177 {
178  fprintf(stderr, "piperead " PIPEREAD_VERSION "\n\n");
179  fprintf(stderr, "Usage: piperead [-c] <named pipe>\n");
180  fprintf(stderr, "-c means Client mode\n");
181  fprintf(stderr, "Example: piperead -c \\\\.\\pipe\\kdbg | log2lines -c\n\n");
182 }
183 
184 int main(int argc, char** argv)
185 {
186  char path[MAX_PATH];
187  const char* pipe_name;
188  const char* clientMode;
189  int res = 0;
190 
191  pipe_name = "com_1";
192  clientMode = NULL;
193  switch (argc) {
194  case 3:
195  clientMode = *++argv;
196  if (strcmp(clientMode,"-c") != 0) {
197  fprintf(stderr,"Invalid option: %s\n", clientMode);
198  clientMode = NULL;
199  res = -6;
200  }
201  //fall through
202  case 2:
203  pipe_name = *++argv;
204  if (strcmp(pipe_name,"-h") == 0) {
205  res = -7;
206  }
207  break;
208  default:
209  res = -8;
210  break;
211  }
212  if (res) {
213  usage();
214  return res;
215  }
216 
217  if ( pipe_name[0] == '\\' ) {
218  //assume caller specified full path
219  sprintf(path, "%s", pipe_name);
220  } else {
221  sprintf(path, "\\\\.\\pipe\\%s", pipe_name);
222  }
223 
224  if ( clientMode ) {
225  res = pipeClient(path);
226  if (res == PIPEREAD_NOPIPE) {
227  res = fileClient(pipe_name);
228  }
229  } else {
230  res = pipeServer(path);
231  }
232 
233  return res;
234 }
static int argc
Definition: ServiceArgs.c:12
#define CreateNamedPipe
Definition: winbase.h:3597
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
#define CloseHandle
Definition: compat.h:487
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define error(str)
Definition: mkdosfs.c:1605
#define TRUE
Definition: types.h:120
static int pipeServer(char *path)
Definition: piperead.cpp:31
#define PIPE_WAIT
Definition: winbase.h:171
#define PIPEREAD_VERSION
Definition: piperead.cpp:15
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
static int fileClient(const char *path)
Definition: piperead.cpp:156
int errno
#define PIPEREAD_NOPIPE
Definition: piperead.cpp:16
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
const char * strerror(int err)
Definition: compat_str.c:23
FILE * stdout
#define BUFSIZE
Definition: piperead.cpp:24
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define PIPE_TYPE_BYTE
Definition: winbase.h:167
smooth NULL
Definition: ftsmooth.c:416
#define FILE_FLAG_FIRST_PIPE_INSTANCE
Definition: piperead.cpp:20
#define ERROR_PIPE_LISTENING
Definition: winerror.h:353
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define OPEN_EXISTING
Definition: compat.h:523
char TCHAR
Definition: xmlstorage.h:189
static void print_error(DWORD win32_error)
Definition: piperead.cpp:26
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:164
#define MAX_PATH
Definition: compat.h:34
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
#define ERROR_BROKEN_PIPE
Definition: winerror.h:183
#define ERROR_PIPE_BUSY
Definition: winerror.h:283
int main(int argc, char **argv)
Definition: piperead.cpp:184
#define WaitNamedPipe
Definition: winbase.h:3761
#define GENERIC_READ
Definition: compat.h:135
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define ERROR_MORE_DATA
Definition: dderror.h:13
unsigned char BYTE
Definition: xxhash.c:193
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:913
#define ReadFile(a, b, c, d, e)
Definition: compat.h:490
#define EOF
Definition: stdio.h:24
GLuint res
Definition: glext.h:9613
#define c
Definition: ke_i.h:80
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
_Check_return_opt_ _CRTIMP int __cdecl setvbuf(_Inout_ FILE *_File, _Inout_updates_opt_z_(_Size) char *_Buf, _In_ int _Mode, _In_ size_t _Size)
void usage(void)
Definition: piperead.cpp:176
#define _IONBF
Definition: stdio.h:130
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
static int pipeClient(char *path)
Definition: piperead.cpp:77
_Check_return_opt_ _CRTIMP int __cdecl fgetc(_Inout_ FILE *_File)