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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
#include "globus_common.h"
#include "globus_xio.h"
#include "globus_xio_tcp_driver.h"
#include "globus_xio_file_driver.h"
#include "globus_gfork.h"
#define GFORK_CROWDED_MESSAGE "421 Too busy!\r\n"
#if !defined(GFORK_I_H)
#define GFORK_I_H 1
#ifdef __GNUC__
#define GForkFuncName(func) static const char * _gfork_func_name __attribute__((__unused__)) = #func
#else
#define GForkFuncName(func) static const char * _gfork_func_name = #func
#endif
#define GForkErrorErrno(_msg, _errno) \
globus_error_put(GForkErrorObjErrno(_msg, _errno))
#define GForkErrorObjErrno(_msg, _errno) \
globus_error_wrap_errno_error( \
GLOBUS_GFORK_CHILD_MODULE, \
(_errno), \
GLOBUS_GFORK_ERROR_ERRNO, \
__FILE__, \
_gfork_func_name, \
__LINE__, \
"System error in %s", \
_msg)
#define GForkErrorStr(_msg) \
globus_error_put(GForkErrorObjStr(_msg))
#define GForkErrorObjStr(str) \
globus_error_construct_error( \
GLOBUS_GFORK_CHILD_MODULE, \
NULL, \
GLOBUS_GFORK_ERROR_STR, \
__FILE__, \
_gfork_func_name, \
__LINE__, \
"GFork error: %s", \
(str))
GlobusDebugDeclare(GLOBUS_GFORK);
#define GlobusGForkDebugPrintf(level, message) \
GlobusDebugPrintf(GLOBUS_GFORK, level, message)
#define GlobusGForkDebugEnter() \
GlobusGForkDebugPrintf( \
GLOBUS_GFORK_DEBUG_TRACE, \
("[%s] Entering\n", _xio_name))
#define GlobusGForkDebugExit() \
GlobusGForkDebugPrintf( \
GLOBUS_GFORK_DEBUG_TRACE, \
("[%s] Exiting\n", _xio_name))
#define GlobusGForkDebugExitWithError() \
GlobusGForkDebugPrintf( \
GLOBUS_GFORK_DEBUG_TRACE, \
("[%s] Exiting with error\n", _xio_name))
#define GlobusGForkDebugState(_old, _new, _event) \
GlobusGForkDebugPrintf( \
GLOBUS_GFORK_DEBUG_STATE, \
("State Change from %s to %s when %s\n", _old, _new, _event))
enum
{
GLOBUS_GFORK_ERROR_ERRNO = 1,
GLOBUS_GFORK_ERROR_STR
};
typedef enum gfork_i_msg_type_e
{
GLOBUS_GFORK_MSG_OPEN = 'O',
GLOBUS_GFORK_MSG_CLOSE = 'C',
GLOBUS_GFORK_MSG_DATA = 'D'
} gfork_i_msg_type_t;
typedef struct gfork_i_msg_header_s
{
uint64_t size;
pid_t from_pid;
pid_t to_pid;
gfork_i_msg_type_t type;
} gfork_i_msg_header_t;
typedef struct gfork_i_msg_data_s
{
int ref;
globus_byte_t buffer[1];
} gfork_i_msg_data_t;
typedef struct gfork_i_msg_s
{
gfork_i_msg_header_t header;
struct gfork_i_child_handle_s * to_kid;
struct gfork_i_child_handle_s * from_kid;
void * user_arg;
globus_xio_iovec_t * iov;
int iovc;
globus_size_t nbytes;
globus_xio_iovec_t write_iov[2];
globus_xio_iovec_callback_t client_cb;
globus_xio_iovec_callback_t cb;
gfork_i_msg_data_t * data;
globus_byte_t * buffer;
struct gfork_i_lib_handle_s * lib_handle;
} gfork_i_msg_t;
typedef enum gfork_i_state_e
{
GFORK_STATE_NONE = 0,
GFORK_STATE_OPEN,
GFORK_STATE_OPENING,
GFORK_STATE_OPENING_AND_CLOSING,
GFORK_STATE_CLOSING,
GFORK_STATE_CLOSED,
GFORK_STATE_COUNT
} gfork_i_state_t;
typedef enum gfork_i_events_s
{
GFORK_EVENT_NONE = 0,
GFORK_EVENT_ACCEPT_CB,
GFORK_EVENT_OPEN_RETURNS,
GFORK_EVENT_SIGCHILD,
GFORK_EVENT_CLOSE_RETURNS,
GFORK_EVENT_COUNT
} gfork_i_events_t;
typedef struct gfork_i_options_s
{
char * id;
globus_list_t * protocol_list;
char * server;
globus_list_t * server_arg_list;
int port;
int instances;
int nice;
char * interface;
globus_list_t * env_list;
uid_t master_user;
char * master;
int master_nice;
globus_list_t * master_arg_list;
void * user_arg;
globus_bool_t quiet;
char * conf_file;
int log_level;
FILE * log_fptr;
char * crowded_msg;
int crowded_msg_len;
globus_list_t * master_list;
} gfork_i_options_t;
typedef struct gfork_i_handle_s
{
globus_xio_stack_t stack;
char ** server_argv;
char ** master_argv;
globus_list_t * loaded_drivers;
globus_xio_driver_t tcp_driver;
globus_xio_server_t server_xio;
gfork_i_options_t * opts;
globus_list_t * master_list;
} gfork_i_handle_t;
typedef struct gfork_i_child_handle_s
{
pid_t pid;
int write_fd;
int read_fd;
globus_xio_handle_t write_xio_handle;
globus_xio_handle_t read_xio_handle;
gfork_i_handle_t * whos_my_daddy;
void * user_arg;
gfork_i_state_t state;
globus_bool_t dead;
globus_fifo_t write_q;
globus_bool_t writting;
globus_bool_t master;
} gfork_i_child_handle_t;
typedef struct gfork_i_lib_handle_s
{
globus_xio_handle_t read_xio;
globus_xio_handle_t write_xio;
gfork_i_msg_header_t header;
globus_byte_t * data;
globus_gfork_incoming_cb_t incoming_cb;
globus_gfork_open_func_t open_cb;
globus_gfork_closed_func_t close_cb;
globus_gfork_error_func_t error_cb;
globus_bool_t master;
void * user_arg;
globus_mutex_t mutex;
gfork_i_state_t state;
globus_fifo_t write_q;
globus_bool_t writing;
globus_object_t * error_obj;
} gfork_i_lib_handle_t;
typedef struct gfork_i_master_program_ent_s
{
char * master;
uid_t master_uid;
int master_nice;
globus_list_t * master_arg_list;
globus_list_t * master_env;
} gfork_i_master_program_ent_t;
globus_result_t
gfork_i_make_xio_handle(
globus_xio_handle_t * xio_handle,
int fd);
void
gfork_i_state_init();
gfork_i_state_t
gfork_i_state_next(
gfork_i_state_t current_state,
gfork_i_events_t event);
globus_result_t
globus_i_opts_to_handle(
gfork_i_options_t * opts,
gfork_i_handle_t * handle);
extern globus_xio_stack_t gfork_i_file_stack;
extern globus_xio_attr_t gfork_i_file_attr;
extern globus_xio_driver_t gfork_i_file_driver;
extern globus_options_entry_t gfork_l_opts_table[];
#endif
|