GNUnet  0.10.x
Functions | Variables
gnunet-helper-w32-console.c File Reference

Does blocking reads from the console, writes the results into stdout, turning blocking console I/O into non-blocking pipe I/O. More...

#include "platform.h"
#include "gnunet_crypto_lib.h"
#include "gnunet_common.h"
#include "gnunet-helper-w32-console.h"
Include dependency graph for gnunet-helper-w32-console.c:

Go to the source code of this file.

Functions

static int write_all (int output, const void *buf, size_t size)
 Write size bytes from buf into output. More...
 
static int write_message (int output, uint16_t message_type, const char *data, size_t data_length)
 Write message to the master process. More...
 
static int read_events (HANDLE console, int output_stream)
 Main function of the helper process. More...
 
static int read_chars (HANDLE console, int output_stream)
 Main function of the helper process. More...
 
DWORD WINAPI watch_parent (LPVOID param)
 
int main (int argc, char *const *argv)
 Main function of the helper process to extract meta data. More...
 

Variables

static unsigned long buffer_size
 
static int chars
 
static HANDLE parent_handle
 

Detailed Description

Does blocking reads from the console, writes the results into stdout, turning blocking console I/O into non-blocking pipe I/O.

For W32 only.

Author
LRN

Definition in file gnunet-helper-w32-console.c.

Function Documentation

◆ write_all()

static int write_all ( int  output,
const void *  buf,
size_t  size 
)
static

Write size bytes from buf into output.

Parameters
outputthe descriptor to write into
bufbuffer with data to write
sizenumber of bytes to write
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 48 of file gnunet-helper-w32-console.c.

References buf, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, and GNUNET_SYSERR.

Referenced by write_message().

51 {
52  const char *cbuf = buf;
53  size_t total;
54  ssize_t wr;
55 
56  total = 0;
57  do
58  {
59  wr = write (output,
60  &cbuf[total],
61  size - total);
62  if (wr > 0)
63  total += wr;
64  } while ( (wr > 0) && (total < size) );
65  if (wr <= 0)
67  "Failed to write to stdout: %s\n",
68  strerror (errno));
69  return (total == size) ? GNUNET_OK : GNUNET_SYSERR;
70 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static char buf[2048]
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define GNUNET_log(kind,...)
Here is the caller graph for this function:

◆ write_message()

static int write_message ( int  output,
uint16_t  message_type,
const char *  data,
size_t  data_length 
)
static

Write message to the master process.

Parameters
outputthe descriptor to write into
message_typemessage type to use
datadata to append, NULL for none
data_lengthnumber of bytes in data
Returns
GNUNET_SYSERR to stop scanning (the pipe was broken somehow)

Definition at line 83 of file gnunet-helper-w32-console.c.

References GNUNET_OK, GNUNET_SYSERR, GNUNET_MessageHeader::size, GNUNET_MessageHeader::type, and write_all().

Referenced by read_chars(), and read_events().

87 {
88  struct GNUNET_MessageHeader hdr;
89 
90 #if 0
91  fprintf (stderr,
92  "Helper sends %u-byte message of type %u\n",
93  (unsigned int) (sizeof (struct GNUNET_MessageHeader) + data_length),
94  (unsigned int) message_type);
95 #endif
96  hdr.type = htons (message_type);
97  hdr.size = htons (sizeof (struct GNUNET_MessageHeader) + data_length);
98  if (GNUNET_OK != write_all (output, &hdr, sizeof (hdr)))
99  return GNUNET_SYSERR;
100  if (GNUNET_OK != write_all (output, data, data_length))
101  return GNUNET_SYSERR;
102  return GNUNET_OK;
103 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int write_all(int output, const void *buf, size_t size)
Write size bytes from buf into output.
Header for all communications.
uint32_t data
The data value.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_events()

static int read_events ( HANDLE  console,
int  output_stream 
)
static

Main function of the helper process.

Reads input events from console, writes messages, into stdout.

Parameters
consolea handle to a console to read from
output_streama stream to write messages to
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 115 of file gnunet-helper-w32-console.c.

References buf, buffer_size, GNUNET_MESSAGE_TYPE_W32_CONSOLE_HELPER_INPUT, GNUNET_OK, GNUNET_SYSERR, result, and write_message().

Referenced by main().

116 {
117  DWORD rr;
118  BOOL b;
119  INPUT_RECORD *buf;
120  DWORD i;
121  int result;
122 
123  result = GNUNET_SYSERR;
124  buf = malloc (sizeof (INPUT_RECORD) * buffer_size);
125  if (NULL == buf)
126  return result;
127  b = TRUE;
128  rr = 1;
129  while (TRUE == b && 0 < rr)
130  {
131  rr = 0;
132  b = ReadConsoleInput (console, buf, buffer_size, &rr);
133  if (FALSE == b && ERROR_SUCCESS != GetLastError ())
134  break;
135  for (i = 0; i < rr; i++)
136  {
137  int r;
140  (const char *) &buf[i],
141  sizeof (INPUT_RECORD));
142  if (GNUNET_OK != r)
143  break;
144  }
145  if (rr + 1 != i)
146  break;
147  }
148  return result;
149 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_MESSAGE_TYPE_W32_CONSOLE_HELPER_INPUT
Input event from the console.
static char buf[2048]
static int result
Global testing status.
static int write_message(int output, uint16_t message_type, const char *data, size_t data_length)
Write message to the master process.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int output_stream
File descriptor we use for IPC with the parent.
static unsigned long buffer_size
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_chars()

static int read_chars ( HANDLE  console,
int  output_stream 
)
static

Main function of the helper process.

Reads chars from console, writes messages, into stdout.

Parameters
consolea handle to a console to read from
output_streama stream to write messages to
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 161 of file gnunet-helper-w32-console.c.

References buf, buffer_size, conv, GNUNET_MESSAGE_TYPE_W32_CONSOLE_HELPER_CHARS, GNUNET_OK, GNUNET_SYSERR, result, and write_message().

Referenced by main().

162 {
163  DWORD rr;
164  BOOL b;
165  wchar_t *buf;
166  char *small_ubuf;
167  char *large_ubuf;
168  char *ubuf;
169  int conv;
170  int r;
171  int result;
172 
173  result = GNUNET_SYSERR;
174  buf = malloc (sizeof (wchar_t) * buffer_size);
175  if (NULL == buf)
176  return result;
177  small_ubuf = malloc (sizeof (char) * buffer_size * 2);
178  if (NULL == small_ubuf)
179  {
180  free (buf);
181  return result;
182  }
183  b = TRUE;
184  rr = 1;
185  while (TRUE == b)
186  {
187  large_ubuf = NULL;
188  rr = 0;
189  b = ReadConsoleW (console, buf, buffer_size, &rr, NULL);
190  if (FALSE == b && ERROR_SUCCESS != GetLastError ())
191  break;
192  if (0 == rr)
193  continue;
194  /* Caveat: if the UTF-16-encoded string is longer than BUFFER_SIZE,
195  * there's a possibility that we will read up to a word that constitutes
196  * a part of a multi-byte UTF-16 codepoint. Converting that to UTF-8
197  * will either drop invalid word (flags == 0) or bail out because of it
198  * (flags == WC_ERR_INVALID_CHARS).
199  */
200  conv = WideCharToMultiByte (CP_UTF8, 0, buf, rr, small_ubuf, 0, NULL, FALSE);
201  if (0 == conv || 0xFFFD == conv)
202  continue;
203  if (conv <= buffer_size * 2 - 1)
204  {
205  memset (small_ubuf, 0, buffer_size * 2);
206  conv = WideCharToMultiByte (CP_UTF8, 0, buf, rr, small_ubuf, buffer_size * 2 - 1, NULL, FALSE);
207  if (0 == conv || 0xFFFD == conv)
208  continue;
209  ubuf = small_ubuf;
210  }
211  else
212  {
213  large_ubuf = malloc (conv + 1);
214  if (NULL == large_ubuf)
215  continue;
216  memset (large_ubuf, 0, conv + 1);
217  conv = WideCharToMultiByte (CP_UTF8, 0, buf, rr, large_ubuf, conv, NULL, FALSE);
218  if (0 == conv || 0xFFFD == conv)
219  {
220  free (large_ubuf);
221  large_ubuf = NULL;
222  continue;
223  }
224  ubuf = large_ubuf;
225  }
228  ubuf,
229  conv + 1);
230  if (large_ubuf)
231  free (large_ubuf);
232  if (GNUNET_OK != r)
233  break;
234  }
235  free (small_ubuf);
236  free (buf);
237  return result;
238 }
static GstElement * conv
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static char buf[2048]
static int result
Global testing status.
#define GNUNET_MESSAGE_TYPE_W32_CONSOLE_HELPER_CHARS
Chars from the console.
static int write_message(int output, uint16_t message_type, const char *data, size_t data_length)
Write message to the master process.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static int output_stream
File descriptor we use for IPC with the parent.
static unsigned long buffer_size
Here is the call graph for this function:
Here is the caller graph for this function:

◆ watch_parent()

DWORD WINAPI watch_parent ( LPVOID  param)

Definition at line 242 of file gnunet-helper-w32-console.c.

References parent_handle.

Referenced by main().

243 {
244  WaitForSingleObject (parent_handle, INFINITE);
245  ExitProcess (1);
246  return 0;
247 }
static HANDLE parent_handle
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

Main function of the helper process to extract meta data.

Parameters
argcshould be 3
argv[0] our binary name [1] name of the file or directory to process [2] "-" to disable extraction, NULL for defaults, otherwise custom plugins to load from LE
Returns
0 on success

Definition at line 260 of file gnunet-helper-w32-console.c.

References buffer_size, chars, GNUNET_NO, GNUNET_YES, parent_handle, read_chars(), read_events(), and watch_parent().

262 {
263  HANDLE os_stdin;
264  DWORD parent_pid;
265  /* We're using stdout to communicate binary data back to the parent; use
266  * binary mode.
267  */
268  _setmode (1, _O_BINARY);
269 
270  if (argc != 4)
271  {
272  fprintf (stderr,
273  "Usage: gnunet-helper-w32-console <chars|events> <buffer size> <parent pid>\n");
274  return 2;
275  }
276 
277  if (0 == strcmp (argv[1], "chars"))
278  chars = GNUNET_YES;
279  else if (0 == strcmp (argv[1], "events"))
280  chars = GNUNET_NO;
281  else
282  return 3;
283 
284  buffer_size = strtoul (argv[2], NULL, 10);
285  if (buffer_size <= 0)
286  return 4;
287 
288  parent_pid = (DWORD) strtoul (argv[3], NULL, 10);
289  if (parent_pid == 0)
290  return 5;
291  parent_handle = OpenProcess (SYNCHRONIZE, FALSE, parent_pid);
292  if (NULL == parent_handle)
293  return 6;
294 
295  CreateThread (NULL, 0, watch_parent, NULL, 0, NULL);
296 
297  if (0 == AttachConsole (ATTACH_PARENT_PROCESS))
298  {
299  if (ERROR_ACCESS_DENIED != GetLastError ())
300  return 5;
301  }
302 
303  /* Helper API overrides stdin, so we just attach to the console that we
304  * inherited. If we did.
305  */
306  os_stdin = CreateFile ("CONIN$", GENERIC_READ | GENERIC_WRITE,
307  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
308  if (INVALID_HANDLE_VALUE == os_stdin)
309  return 1;
310 
311  if (GNUNET_NO == chars)
312  return read_events (os_stdin, 1);
313  else
314  return read_chars (os_stdin, 1);
315 
316 }
#define GNUNET_NO
Definition: gnunet_common.h:81
static int read_events(HANDLE console, int output_stream)
Main function of the helper process.
static unsigned long buffer_size
static int read_chars(HANDLE console, int output_stream)
Main function of the helper process.
#define GNUNET_YES
Definition: gnunet_common.h:80
static HANDLE parent_handle
DWORD WINAPI watch_parent(LPVOID param)
static int chars
Here is the call graph for this function:

Variable Documentation

◆ buffer_size

unsigned long buffer_size
static

Definition at line 33 of file gnunet-helper-w32-console.c.

Referenced by main(), read_chars(), and read_events().

◆ chars

int chars
static

Definition at line 35 of file gnunet-helper-w32-console.c.

Referenced by handle_command_string(), and main().

◆ parent_handle

HANDLE parent_handle
static

Definition at line 37 of file gnunet-helper-w32-console.c.

Referenced by main(), and watch_parent().