-
Notifications
You must be signed in to change notification settings - Fork 9
/
proc_win.h
156 lines (125 loc) · 3.65 KB
/
proc_win.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* Windows doesn't really use signals, and it doesn't have a mechanism
* to gracefully shutdown an unrelated process, so we just kill the
* child process dead for all signals. */
#define IPC_PROC_SIGTERM 0
#define IPC_PROC_SIGKILL 0
#define IPC_PROC_BUFSIZE 1024
typedef struct {
HANDLE child;
/* process info structure? */
int exitstatus;
char const* exitkind;
char const* inbuf;
size_t inlen; /* length of the string `inbuf` */
char outbuf[ IPC_PROC_BUFSIZE ];
char errbuf[ IPC_PROC_BUFSIZE ];
OVERLAPPED inov;
OVERLAPPED outov;
OVERLAPPED errov;
} ipc_proc_handle;
static void ipc_proc_error( char* buf, size_t len, int code ) {
if( len > 0 ) {
if( 0 == FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
0,
buf,
len,
NULL ) ) {
strncpy( buf, "unknown error", len-1 );
buf[ len-1 ] = '\0';
} else { /* Windows puts an extra newline in there! */
size_t n = strlen( buf );
while( n > 0 && isspace( (unsigned char)buf[ --n ] ) )
buf[ n ] = '\0';
}
}
}
static int ipc_proc_waitprocess_( ipc_proc_handle* h, DWORD timeout ) {
DWORD exitcode = 0;
if( h->exitkind != NULL )
return 0;
switch( WaitForSingleObject( h->child, timeout ) ) {
case WAIT_OBJECT_0:
if( !GetExitCodeProcess( h->child, &exitcode ) )
return IPC_ERR( GetLastError() );
h->exitstatus = exitcode;
h->exitkind = "exit";
return 0;
case WAIT_TIMEOUT:
return 0;
default:
return IPC_ERR( GetLastError() );
}
return 0;
}
static int ipc_proc_kill( ipc_proc_handle* h, int signum ) {
(void)signum;
ipc_proc_waitprocess_( h, 0 );
if( h->exitkind != 0 ) {
if( !TerminateProcess( h->child, 3 ) )
return IPC_ERR( GetLastError() );
}
return 0;
}
static int ipc_proc_wait( ipc_proc_handle* h, int* status,
char const** what ) {
int rv = ipc_proc_waitprocess_( h, INFINITE );
if( rv != 0 )
return IPC_ERR( rv );
*status = h->exitstatus;
*what = h->exitkind;
return 0;
}
static int ipc_proc_trywrite_( ipc_proc_handle* h, int* done ) {
/* TODO */
return 0;
}
static int ipc_proc_stdinready( ipc_proc_handle* h, int* done ) {
/* TODO */
return 0;
}
static int ipc_proc_closestdin( ipc_proc_handle* h ) {
/* TODO */
return 0;
}
static int ipc_proc_write( ipc_proc_handle* h, char const* s,
size_t len, int* completed ) {
/* TODO */
return 0;
}
static int ipc_proc_waitio( ipc_proc_handle* h, int* child_complete,
int* stdin_complete, int* stdout_complete,
int* stderr_complete ) {
/* TODO */
return 0;
}
static int ipc_proc_stdoutready( ipc_proc_handle* h, char const** data,
size_t* len ) {
/* TODO */
return 0;
}
static int ipc_proc_stderrready( ipc_proc_handle* h, char const** data,
size_t* len ) {
/* TODO */
return 0;
}
static int ipc_proc_spawn( ipc_proc_handle* h, char const* cmdline,
FILE* cstdin, int pstdin,
FILE* cstdout, int pstdout,
FILE* cstderr, int pstderr ) {
/* TODO */
return 0;
}
static int ipc_proc_prepare( void ) {
/* no global preparation necessary on Windows */
return 0;
}