@@ -26,38 +26,33 @@ static bool debug = false;
26
26
fprintf(stderr, "DEBUG| " fmt "\n", __VA_ARGS__); \
27
27
} while (0)
28
28
29
- static void print_vmnet_status (const char * func , vmnet_return_t v ) {
29
+ #define INFOF (fmt , ...) fprintf(stderr, "INFO | " fmt "\n", __VA_ARGS__)
30
+ #define ERROR (msg ) fprintf(stderr, "ERROR| " msg "\n")
31
+ #define ERRORF (fmt , ...) fprintf(stderr, "ERROR| " fmt "\n", __VA_ARGS__)
32
+ #define ERRORN (name ) ERRORF(name ": %s", strerror(errno))
33
+
34
+ static const char * vmnet_strerror (vmnet_return_t v ) {
30
35
switch (v ) {
31
36
case VMNET_SUCCESS :
32
- DEBUGF ("%s(): vmnet_return_t VMNET_SUCCESS" , func );
33
- break ;
37
+ return "VMNET_SUCCESS" ;
34
38
case VMNET_FAILURE :
35
- fprintf (stderr , "%s(): vmnet_return_t VMNET_FAILURE\n" , func );
36
- break ;
39
+ return "VMNET_FAILURE" ;
37
40
case VMNET_MEM_FAILURE :
38
- fprintf (stderr , "%s(): vmnet_return_t VMNET_MEM_FAILURE\n" , func );
39
- break ;
41
+ return "VMNET_MEM_FAILURE" ;
40
42
case VMNET_INVALID_ARGUMENT :
41
- fprintf (stderr , "%s(): vmnet_return_t VMNET_INVALID_ARGUMENT\n" , func );
42
- break ;
43
+ return "VMNET_INVALID_ARGUMENT" ;
43
44
case VMNET_SETUP_INCOMPLETE :
44
- fprintf (stderr , "%s(): vmnet_return_t VMNET_SETUP_INCOMPLETE\n" , func );
45
- break ;
45
+ return "VMNET_SETUP_INCOMPLETE" ;
46
46
case VMNET_INVALID_ACCESS :
47
- fprintf (stderr , "%s(): vmnet_return_t VMNET_INVALID_ACCESS\n" , func );
48
- break ;
47
+ return "VMNET_INVALID_ACCESS" ;
49
48
case VMNET_PACKET_TOO_BIG :
50
- fprintf (stderr , "%s(): vmnet_return_t VMNET_PACKET_TOO_BIG\n" , func );
51
- break ;
49
+ return "VMNET_PACKET_TOO_BIG" ;
52
50
case VMNET_BUFFER_EXHAUSTED :
53
- fprintf (stderr , "%s(): vmnet_return_t VMNET_BUFFER_EXHAUSTED\n" , func );
54
- break ;
51
+ return "VMNET_BUFFER_EXHAUSTED" ;
55
52
case VMNET_TOO_MANY_PACKETS :
56
- fprintf (stderr , "%s(): vmnet_return_t VMNET_TOO_MANY_PACKETS\n" , func );
57
- break ;
53
+ return "VMNET_TOO_MANY_PACKETS" ;
58
54
default :
59
- fprintf (stderr , "%s(): vmnet_return_t %d\n" , func , v );
60
- break ;
55
+ return "(unknown status)" ;
61
56
}
62
57
}
63
58
@@ -67,17 +62,17 @@ static void print_vmnet_start_param(xpc_object_t param) {
67
62
xpc_dictionary_apply (param , ^bool (const char * key , xpc_object_t value ) {
68
63
xpc_type_t t = xpc_get_type (value );
69
64
if (t == XPC_TYPE_UINT64 )
70
- printf ("* %s: %lld\n " , key , xpc_uint64_get_value (value ));
65
+ INFOF ("* %s: %lld" , key , xpc_uint64_get_value (value ));
71
66
else if (t == XPC_TYPE_INT64 )
72
- printf ("* %s: %lld\n " , key , xpc_int64_get_value (value ));
67
+ INFOF ("* %s: %lld" , key , xpc_int64_get_value (value ));
73
68
else if (t == XPC_TYPE_STRING )
74
- printf ("* %s: %s\n " , key , xpc_string_get_string_ptr (value ));
69
+ INFOF ("* %s: %s" , key , xpc_string_get_string_ptr (value ));
75
70
else if (t == XPC_TYPE_UUID ) {
76
71
char uuid_str [36 + 1 ];
77
72
uuid_unparse (xpc_uuid_get_bytes (value ), uuid_str );
78
- printf ("* %s: %s\n " , key , uuid_str );
73
+ INFOF ("* %s: %s" , key , uuid_str );
79
74
} else
80
- printf ("* %s: (unknown type)\n " , key );
75
+ INFOF ("* %s: (unknown type)" , key );
81
76
return true;
82
77
});
83
78
}
@@ -136,29 +131,28 @@ static void _on_vmnet_packets_available(interface_ref iface, int64_t buf_count,
136
131
// TODO: use prealloced pool
137
132
struct vmpktdesc * pdv = calloc (buf_count , sizeof (struct vmpktdesc ));
138
133
if (pdv == NULL ) {
139
- perror ("calloc(estim_count, sizeof(struct vmpktdesc)" );
134
+ ERRORN ("calloc(estim_count, sizeof(struct vmpktdesc)" );
140
135
goto done ;
141
136
}
142
137
for (int i = 0 ; i < buf_count ; i ++ ) {
143
138
pdv [i ].vm_flags = 0 ;
144
139
pdv [i ].vm_pkt_size = max_bytes ;
145
140
pdv [i ].vm_pkt_iovcnt = 1 , pdv [i ].vm_pkt_iov = malloc (sizeof (struct iovec ));
146
141
if (pdv [i ].vm_pkt_iov == NULL ) {
147
- perror ("malloc(sizeof(struct iovec))" );
142
+ ERRORN ("malloc(sizeof(struct iovec))" );
148
143
goto done ;
149
144
}
150
145
pdv [i ].vm_pkt_iov -> iov_base = malloc (max_bytes );
151
146
if (pdv [i ].vm_pkt_iov -> iov_base == NULL ) {
152
- perror ("malloc(max_bytes)" );
147
+ ERRORN ("malloc(max_bytes)" );
153
148
goto done ;
154
149
}
155
150
pdv [i ].vm_pkt_iov -> iov_len = max_bytes ;
156
151
}
157
152
int received_count = buf_count ;
158
153
vmnet_return_t read_status = vmnet_read (iface , pdv , & received_count );
159
- print_vmnet_status (__FUNCTION__ , read_status );
160
154
if (read_status != VMNET_SUCCESS ) {
161
- perror ("vmnet_read" );
155
+ ERRORF ("vmnet_read: [%d] %s" , read_status , vmnet_strerror ( read_status ) );
162
156
goto done ;
163
157
}
164
158
@@ -200,7 +194,7 @@ static void _on_vmnet_packets_available(interface_ref iface, int64_t buf_count,
200
194
"header)" ,
201
195
i , written );
202
196
if (written < 0 ) {
203
- perror ("writev" );
197
+ ERRORN ("writev" );
204
198
goto done ;
205
199
}
206
200
}
@@ -235,11 +229,11 @@ static void on_vmnet_packets_available(interface_ref iface, int64_t estim_count,
235
229
}
236
230
237
231
static interface_ref start (struct state * state , struct cli_options * cliopt ) {
238
- printf ("Initializing vmnet.framework (mode %d)\n " , cliopt -> vmnet_mode );
232
+ INFOF ("Initializing vmnet.framework (mode %d)" , cliopt -> vmnet_mode );
239
233
xpc_object_t dict = xpc_dictionary_create (NULL , NULL , 0 );
240
234
xpc_dictionary_set_uint64 (dict , vmnet_operation_mode_key , cliopt -> vmnet_mode );
241
235
if (cliopt -> vmnet_interface != NULL ) {
242
- printf ("Using network interface \"%s\"\n " , cliopt -> vmnet_interface );
236
+ INFOF ("Using network interface \"%s\"" , cliopt -> vmnet_interface );
243
237
xpc_dictionary_set_string (dict , vmnet_shared_interface_name_key ,
244
238
cliopt -> vmnet_interface );
245
239
}
@@ -278,10 +272,10 @@ static interface_ref start(struct state *state, struct cli_options *cliopt) {
278
272
dispatch_semaphore_signal (sem );
279
273
});
280
274
dispatch_semaphore_wait (sem , DISPATCH_TIME_FOREVER );
281
- print_vmnet_status (__FUNCTION__ , status );
282
275
dispatch_release (q );
283
276
xpc_release (dict );
284
277
if (status != VMNET_SUCCESS ) {
278
+ ERRORF ("vmnet_start_interface: [%d] %s" , status , vmnet_strerror (status ));
285
279
return NULL ;
286
280
}
287
281
@@ -301,7 +295,7 @@ static interface_ref start(struct state *state, struct cli_options *cliopt) {
301
295
302
296
static sigjmp_buf jmpbuf ;
303
297
static void signalhandler (int signal ) {
304
- printf ( "\nReceived signal %d\n " , signal );
298
+ INFOF ( "Received signal: %s " , strsignal ( signal ) );
305
299
siglongjmp (jmpbuf , 1 );
306
300
}
307
301
@@ -318,9 +312,11 @@ static void stop(interface_ref iface) {
318
312
dispatch_semaphore_signal (sem );
319
313
});
320
314
dispatch_semaphore_wait (sem , DISPATCH_TIME_FOREVER );
321
- print_vmnet_status (__FUNCTION__ , status );
322
315
dispatch_release (q );
323
316
// TODO: release event_q ?
317
+ if (status != VMNET_SUCCESS ) {
318
+ ERRORF ("vmnet_stop_interface: [%d] %s" , status , vmnet_strerror (status ));
319
+ }
324
320
}
325
321
326
322
static int socket_bindlisten (const char * socket_path ,
@@ -330,40 +326,41 @@ static int socket_bindlisten(const char *socket_path,
330
326
memset (& addr , 0 , sizeof (addr ));
331
327
unlink (socket_path ); /* avoid EADDRINUSE */
332
328
if ((fd = socket (PF_LOCAL , SOCK_STREAM , 0 )) < 0 ) {
333
- perror ("socket" );
329
+ ERRORN ("socket" );
334
330
goto err ;
335
331
}
336
332
addr .sun_family = PF_LOCAL ;
337
- if (strlen (socket_path ) + 1 > sizeof (addr .sun_path )) {
338
- fprintf (stderr , "the socket path is too long\n" );
333
+ size_t socket_len = strlen (socket_path );
334
+ if (socket_len + 1 > sizeof (addr .sun_path )) {
335
+ ERRORF ("the socket path is too long: %zu" , socket_len );
339
336
goto err ;
340
337
}
341
338
strncpy (addr .sun_path , socket_path , sizeof (addr .sun_path ) - 1 );
342
339
if (bind (fd , (struct sockaddr * )& addr , sizeof (addr )) < 0 ) {
343
- perror ("bind" );
340
+ ERRORN ("bind" );
344
341
goto err ;
345
342
}
346
343
if (listen (fd , 0 ) < 0 ) {
347
- perror ("listen" );
344
+ ERRORN ("listen" );
348
345
goto err ;
349
346
}
350
347
if (socket_group != NULL ) {
351
348
errno = 0 ;
352
349
struct group * grp = getgrnam (socket_group ); /* Do not free */
353
350
if (grp == NULL ) {
354
351
if (errno != 0 )
355
- perror ("getgrnam" );
352
+ ERRORN ("getgrnam" );
356
353
else
357
- fprintf ( stderr , "unknown group name \"%s\"\n " , socket_group );
354
+ ERRORF ( "unknown group name \"%s\"" , socket_group );
358
355
goto err ;
359
356
}
360
357
/* fchown can't be used (EINVAL) */
361
358
if (chown (socket_path , -1 , grp -> gr_gid ) < 0 ) {
362
- perror ("chown" );
359
+ ERRORN ("chown" );
363
360
goto err ;
364
361
}
365
362
if (chmod (socket_path , 0770 ) < 0 ) {
366
- perror ("chmod" );
363
+ ERRORN ("chmod" );
367
364
goto err ;
368
365
}
369
366
}
@@ -386,12 +383,12 @@ int main(int argc, char *argv[]) {
386
383
struct cli_options * cliopt = cli_options_parse (argc , argv );
387
384
assert (cliopt != NULL );
388
385
if (geteuid () != 0 ) {
389
- fprintf ( stderr , "WARNING: Running without root. This is very unlikely to "
390
- "work. See README.md .\n " );
386
+ ERROR ( "WARNING: Running without root. This is very unlikely to "
387
+ "work: See README.md" );
391
388
}
392
389
if (geteuid () != getuid ()) {
393
- fprintf ( stderr , "WARNING: Seems running with SETUID. This is insecure and "
394
- "highly discouraged. See README.md .\n " );
390
+ ERROR ( "WARNING: Seems running with SETUID. This is insecure and "
391
+ "highly discouraged: See README.md" );
395
392
}
396
393
397
394
if (sigsetjmp (jmpbuf , 1 ) != 0 ) {
@@ -409,15 +406,15 @@ int main(int argc, char *argv[]) {
409
406
pid_fd = open (cliopt -> pidfile ,
410
407
O_WRONLY | O_CREAT | O_EXLOCK | O_TRUNC | O_NONBLOCK , 0644 );
411
408
if (pid_fd == -1 ) {
412
- perror ("pidfile_open" );
409
+ ERRORN ("pidfile_open" );
413
410
goto done ;
414
411
}
415
412
}
416
413
DEBUGF ("Opening socket \"%s\" (for UNIX group \"%s\")" , cliopt -> socket_path ,
417
414
cliopt -> socket_group );
418
415
listen_fd = socket_bindlisten (cliopt -> socket_path , cliopt -> socket_group );
419
416
if (listen_fd < 0 ) {
420
- perror ("socket_bindlisten" );
417
+ ERRORN ("socket_bindlisten" );
421
418
goto done ;
422
419
}
423
420
@@ -426,23 +423,23 @@ int main(int argc, char *argv[]) {
426
423
state .sem = dispatch_semaphore_create (1 );
427
424
iface = start (& state , cliopt );
428
425
if (iface == NULL ) {
429
- perror ( "start" );
426
+ // Error already logged.
430
427
goto done ;
431
428
}
432
429
433
430
if (pid_fd != -1 ) {
434
431
char pid [20 ];
435
432
snprintf (pid , sizeof (pid ), "%u" , getpid ());
436
433
if (write (pid_fd , pid , strlen (pid )) != (ssize_t )strlen (pid )) {
437
- perror ( "pidfile_write " );
434
+ ERRORN ( "write " );
438
435
goto done ;
439
436
}
440
437
}
441
438
442
439
while (1 ) {
443
440
int accept_fd = accept (listen_fd , NULL , NULL );
444
441
if (accept_fd < 0 ) {
445
- perror ("accept" );
442
+ ERRORN ("accept" );
446
443
goto done ;
447
444
}
448
445
struct state * state_p = & state ;
@@ -469,12 +466,12 @@ int main(int argc, char *argv[]) {
469
466
}
470
467
471
468
static void on_accept (struct state * state , int accept_fd , interface_ref iface ) {
472
- printf ("Accepted a connection (fd %d)\n " , accept_fd );
469
+ INFOF ("Accepted a connection (fd %d)" , accept_fd );
473
470
state_add_socket_fd (state , accept_fd );
474
471
size_t buf_len = 64 * 1024 ;
475
472
void * buf = malloc (buf_len );
476
473
if (buf == NULL ) {
477
- perror ("malloc" );
474
+ ERRORN ("malloc" );
478
475
goto done ;
479
476
}
480
477
for (uint64_t i = 0 ;; i ++ ) {
@@ -483,24 +480,24 @@ static void on_accept(struct state *state, int accept_fd, interface_ref iface) {
483
480
uint32_t header_be = 0 ;
484
481
ssize_t header_received = read (accept_fd , & header_be , 4 );
485
482
if (header_received < 0 ) {
486
- perror ("read[header]" );
483
+ ERRORN ("read[header]" );
487
484
goto done ;
488
485
}
489
486
if (header_received == 0 ) {
490
487
// EOF according to man page of read.
491
- fprintf ( stderr , "Connection closed by peer (fd %d)\n " , accept_fd );
488
+ INFOF ( "Connection closed by peer (fd %d)" , accept_fd );
492
489
goto done ;
493
490
}
494
491
uint32_t header = ntohl (header_be );
495
492
assert (header <= buf_len );
496
493
ssize_t received = read (accept_fd , buf , header );
497
494
if (received < 0 ) {
498
- perror ("read" );
495
+ ERRORN ("read[body] " );
499
496
goto done ;
500
497
}
501
498
if (received == 0 ) {
502
499
// EOF according to man page of read.
503
- fprintf ( stderr , "Connection closed by peer (fd %d)\n " , accept_fd );
500
+ INFOF ( "Connection closed by peer (fd %d)" , accept_fd );
504
501
goto done ;
505
502
}
506
503
assert (received == header );
@@ -520,9 +517,8 @@ static void on_accept(struct state *state, int accept_fd, interface_ref iface) {
520
517
DEBUGF ("[Socket-to-VMNET i=%lld] Sending to VMNET: %ld bytes" , i ,
521
518
pd .vm_pkt_size );
522
519
vmnet_return_t write_status = vmnet_write (iface , & pd , & written_count );
523
- print_vmnet_status (__FUNCTION__ , write_status );
524
520
if (write_status != VMNET_SUCCESS ) {
525
- perror ("vmnet_write" );
521
+ ERRORF ("vmnet_write: [%d] %s" , write_status , vmnet_strerror ( write_status ) );
526
522
goto done ;
527
523
}
528
524
DEBUGF ("[Socket-to-VMNET i=%lld] Sent to VMNET: %ld bytes" , i ,
@@ -555,13 +551,13 @@ static void on_accept(struct state *state, int accept_fd, interface_ref iface) {
555
551
"bytes (including uint32be header)" ,
556
552
i , accept_fd , conn -> socket_fd , written );
557
553
if (written < 0 ) {
558
- perror ("writev" );
554
+ ERRORN ("writev" );
559
555
continue ;
560
556
}
561
557
}
562
558
}
563
559
done :
564
- printf ("Closing a connection (fd %d)\n " , accept_fd );
560
+ INFOF ("Closing a connection (fd %d)" , accept_fd );
565
561
state_remove_socket_fd (state , accept_fd );
566
562
close (accept_fd );
567
563
if (buf != NULL ) {
0 commit comments