]> git.saurik.com Git - apple/xnu.git/blame - tools/tests/xnu_quick_test/socket_tests.c
xnu-1504.15.3.tar.gz
[apple/xnu.git] / tools / tests / xnu_quick_test / socket_tests.c
CommitLineData
2d21ac55
A
1/*
2 * socket_tests.c
3 * xnu_quick_test
4 *
5 * Created by Jerry Cottingham on 4/12/05.
6 * Copyright 2005 Apple Computer Inc. All rights reserved.
7 *
8 */
9
10#include "tests.h"
11#include <poll.h>
b0d623f7 12#include <mach/mach.h>
2d21ac55
A
13
14extern char g_target_path[ PATH_MAX ];
b0d623f7 15extern int g_is_under_rosetta;
2d21ac55
A
16
17/* **************************************************************************************************************
18 * Test accept, bind, connect, listen, socket, recvmsg, sendmsg, recvfrom, sendto, getpeername, getsockname
19 * system calls.
20 * WARNING - I don't do networking - this should get a good look from a networking stud.
21 * **************************************************************************************************************
22 */
23int socket_tests( void * the_argp )
24{
25 int my_err, my_status, my_len;
26 pid_t my_pid, my_wait_pid;
27 int my_socket_fd = -1;
28 int my_accepted_socket = -1;
29 char * my_parent_pathp = NULL;
30 char * my_child_pathp = NULL;
31 socklen_t my_accept_len;
32 struct sockaddr *my_sockaddr;
33 ssize_t my_result;
34 off_t my_current_offset;
35 char my_parent_socket_name[sizeof(struct sockaddr) + 64];
36 char my_child_socket_name[sizeof(struct sockaddr) + 64];
37 char my_accept_buffer[sizeof(struct sockaddr) + 64];
b0d623f7 38 kern_return_t my_kr;
2d21ac55
A
39
40 /* generate 2 names for binding to the sockets (one socket in the parent and one in the child) */
b0d623f7
A
41 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_parent_pathp, 128, VM_FLAGS_ANYWHERE);
42 if(my_kr != KERN_SUCCESS){
43 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
44 goto test_failed_exit;
45 }
46
47 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_child_pathp, 128, VM_FLAGS_ANYWHERE);
48 if(my_kr != KERN_SUCCESS){
49 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
50 goto test_failed_exit;
2d21ac55
A
51 }
52
53 *my_parent_pathp = 0x00;
54 strcat( my_parent_pathp, "/tmp/" );
55
56 /* get a unique name for our testing */
57 my_err = create_random_name( my_parent_pathp, 0 );
58 if ( my_err != 0 ) {
59 goto test_failed_exit;
60 }
61 strcpy( my_child_pathp, my_parent_pathp );
62 strcat( my_parent_pathp, "p" ); /* append 'p' to mean "parent" */
63 strcat( my_child_pathp, "c" ); /* append 'c' to mean "child" */
64
65 memset( &my_parent_socket_name[0], 0, sizeof(my_parent_socket_name) );
66 memset( &my_child_socket_name[0], 0, sizeof(my_child_socket_name) );
67
68 /* use unique names we generated in /tmp/ */
69 my_sockaddr = (struct sockaddr *) &my_parent_socket_name[0];
70 my_len = sizeof(*my_sockaddr) - sizeof(my_sockaddr->sa_data) + strlen(my_parent_pathp);
71 my_sockaddr->sa_len = my_len;
72 my_sockaddr->sa_family = AF_UNIX;
73 strcpy( &my_sockaddr->sa_data[0], my_parent_pathp );
74
75 my_sockaddr = (struct sockaddr *) &my_child_socket_name[0];
76 my_len = sizeof(*my_sockaddr) - sizeof(my_sockaddr->sa_data) + strlen(my_child_pathp);
77 my_sockaddr->sa_len = my_len;
78 my_sockaddr->sa_family = AF_UNIX;
79 strcpy( &my_sockaddr->sa_data[0], my_child_pathp );
80
81 /* set up socket for parent side */
82 my_socket_fd = socket( AF_UNIX, SOCK_STREAM, 0 );
83 if ( my_socket_fd == -1 ) {
84 printf( "socket call in parent failed with error %d - \"%s\" \n", errno, strerror( errno) );
85 goto test_failed_exit;
86 }
87 my_sockaddr = (struct sockaddr *) &my_parent_socket_name[0];
88 my_err = bind( my_socket_fd, my_sockaddr, my_sockaddr->sa_len );
89 if ( my_err == -1 ) {
90 printf( "bind call in child failed with error %d - \"%s\" \n", errno, strerror( errno) );
91 goto test_failed_exit;
92 }
93
94 /* test getsockname */
95 my_sockaddr = (struct sockaddr *) &my_accept_buffer[0];
96 my_accept_len = sizeof(my_accept_buffer);
97 my_err = getsockname( my_socket_fd, my_sockaddr, &my_accept_len );
98 if ( my_err == -1 ) {
99 printf( "getsockname call in child failed with error %d - \"%s\" \n", errno, strerror( errno) );
100 goto test_failed_exit;
101 }
102 if ( my_sockaddr->sa_family != SOCK_STREAM ) {
103 printf( "getsockname test failed - did not get correct socket name data \n" );
104 goto test_failed_exit;
105 }
106
107 /* make sure we can't seek on a socket */
108 my_current_offset = lseek( my_socket_fd, 0, SEEK_CUR );
109 if ( my_current_offset != -1 ) {
110 printf( "lseek on socket should fail but did not \n" );
111 goto test_failed_exit;
112 }
113
114 /*
115 * spin off a child process that we communicate with via sockets.
116 */
117 my_pid = fork( );
118 if ( my_pid == -1 ) {
119 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
120 goto test_failed_exit;
121 }
122 if ( my_pid == 0 ) {
123 /*
124 * child process - open a socket and use it to talk to our parent.
125 */
126 int my_child_fd = -1;
127 struct msghdr my_msghdr;
b0d623f7 128 struct iovec my_iov[4];
2d21ac55
A
129 char my_buffer[128];
130
131 my_child_fd = socket( AF_UNIX, SOCK_STREAM, 0 );
132 if ( my_child_fd == -1 ) {
133 printf( "socket call in child failed with error %d - \"%s\" \n", errno, strerror( errno) );
134 exit( -1 );
135 }
136
137 my_sockaddr = (struct sockaddr *) &my_child_socket_name[0];
138 my_err = bind( my_child_fd, my_sockaddr, my_sockaddr->sa_len );
139 if ( my_err == -1 ) {
140 close( my_child_fd );
141 printf( "bind call in child failed with error %d - \"%s\" \n", errno, strerror( errno) );
142 exit( -1 );
143 }
144 sleep(2);
145
146 /* connect to socket in our parent */
147 my_sockaddr = (struct sockaddr *) &my_parent_socket_name[0];
148 my_err = connect( my_child_fd, my_sockaddr, my_sockaddr->sa_len );
149 if ( my_err == -1 ) {
150 close( my_child_fd );
151 printf( "connect call in child failed with error %d - \"%s\" \n", errno, strerror( errno) );
152 exit( -1 );
153 }
154
155 /* get some data from the child via socket and test socket peer data */
156 {
157 socklen_t my_buffer_len;
158 struct sockaddr * my_sockaddr;
159 char my_parent_buffer[256];
160
161 my_sockaddr = (struct sockaddr *) &my_parent_buffer[0];
162 my_buffer_len = sizeof(my_parent_buffer);
163 my_err = getpeername( my_child_fd, my_sockaddr, &my_buffer_len );
164 if ( my_err == -1 ) {
165 printf( "getpeername call in parent failed with error %d - \"%s\" \n", errno, strerror( errno) );
166 goto test_failed_exit;
167 }
168
169 /* test results - should be sa_family == SOCK_STREAM and name should match my_child_pathp */
170 if ( my_sockaddr->sa_family != SOCK_STREAM ) {
171 printf( "getpeername test failed - did not get correct peer data \n" );
172 goto test_failed_exit;
173 }
174 }
175
176 my_buffer[0] = 'j';
b0d623f7
A
177 my_iov[0].iov_base = &my_buffer[0];
178 my_iov[0].iov_len = 1;
2d21ac55
A
179
180 my_sockaddr = (struct sockaddr *) &my_parent_socket_name[0];
181 my_msghdr.msg_name = my_sockaddr;
182 my_msghdr.msg_namelen = my_sockaddr->sa_len;
b0d623f7 183 my_msghdr.msg_iov = &my_iov[0];
2d21ac55
A
184 my_msghdr.msg_iovlen = 1;
185 my_msghdr.msg_control = NULL;
186 my_msghdr.msg_controllen = 0;
187 my_msghdr.msg_flags = 0;
188
189 my_result = sendmsg( my_child_fd, &my_msghdr, 0 );
190 if ( my_result == -1 ) {
191 printf( "sendmsg failed with error %d - \"%s\" \n", errno, strerror( errno) );
192 close( my_child_fd );
193 exit( -1 );
194 }
195
196#if 1
197 /* get data from our parent */
198 my_result = recvfrom( my_child_fd, &my_buffer[0], 1,
199 MSG_WAITALL, NULL, NULL );
200 if ( my_result == -1 ) {
201 printf( "recvfrom failed with error %d - \"%s\" \n", errno, strerror( errno) );
202 close( my_child_fd );
203 exit( -1 );
204 }
205
206 /* verify that we got the correct message from our child */
207 if ( my_buffer[0] != 'e' ) {
208 printf( "test failed - did not get correct data from child \n" );
209 close( my_child_fd );
210 exit( -1 );
211 }
212#endif
213
b0d623f7
A
214#if 1
215 /* sendfile test. Open libsystem, set up some headers, and send it */
216 if (!g_is_under_rosetta) {
217 struct sf_hdtr my_sf_hdtr;
218 int my_libsys_fd;
219 off_t my_libsys_len;
220
221 my_libsys_fd = open("/usr/lib/libSystem.dylib", O_RDONLY, 0644);
222 if (my_libsys_fd < 0) {
223 printf( "test failed - could not open /usr/lib/libSystem.dylib\n" );
224 close ( my_child_fd );
225 exit ( -1 );
226 }
227
228 my_libsys_len = 7+2; /* 2 bytes of header */
229 my_buffer[0] = 's';
230 my_iov[0].iov_base = &my_buffer[0];
231 my_iov[0].iov_len = 1;
232 my_buffer[1] = 'e';
233 my_iov[1].iov_base = &my_buffer[1];
234 my_iov[1].iov_len = 1;
235 my_buffer[2] = 'n';
236 my_iov[2].iov_base = &my_buffer[2];
237 my_iov[2].iov_len = 1;
238 my_buffer[3] = 'd';
239 my_iov[3].iov_base = &my_buffer[3];
240 my_iov[3].iov_len = 1;
241
242 my_sf_hdtr.headers = &my_iov[0];
243 my_sf_hdtr.hdr_cnt = 2;
244 my_sf_hdtr.trailers = &my_iov[2];
245 my_sf_hdtr.trl_cnt = 2;
246
247 my_result = sendfile(my_libsys_fd, my_child_fd, 3, &my_libsys_len, &my_sf_hdtr, 0);
248 if (my_result < 0 || my_libsys_len != 11) {
249 printf( "sendfile failed with error %d - \"%s\" \n", errno, strerror( errno) );
250 close( my_child_fd );
251 exit( -1 );
252 }
253
254 my_result = close ( my_libsys_fd );
255 if ( my_libsys_fd < 0 ) {
256 printf ( "close failed with error %d - \"%s\" \n", errno, strerror( errno) );
257 close ( my_child_fd );
258 exit ( -1 );
259 }
260 }
261#endif
262
2d21ac55
A
263 /* tell parent we're done */
264 my_result = write( my_child_fd, "all done", 8 );
265 if ( my_result == -1 ) {
266 close( my_child_fd );
267 exit( -1 );
268 }
269
270 close( my_child_fd );
271 exit(0);
272 }
273
274 /*
275 * parent process - listen for connection requests
276 */
277 my_err = listen( my_socket_fd, 10 );
278 if ( my_err == -1 ) {
279 printf( "listen call in parent failed with error %d - \"%s\" \n", errno, strerror( errno) );
280 goto test_failed_exit;
281 }
282
283 /* accept connection from child */
284 my_sockaddr = (struct sockaddr *) &my_accept_buffer[0];
285 my_accepted_socket = accept( my_socket_fd, my_sockaddr, &my_accept_len );
286 if ( my_accepted_socket == -1 ) {
287 printf( "accept call in parent failed with error %d - \"%s\" \n", errno, strerror( errno) );
288 goto test_failed_exit;
289 }
290
291 /* get some data from the child via socket and test socket peer data */
292 {
293 //socklen_t my_buffer_len;
294 struct msghdr my_msghdr;
295 struct iovec my_iov;
296 char my_parent_buffer[128];
297
298 my_parent_buffer[0] = 'x';
299 my_iov.iov_base = &my_parent_buffer[0];
300 my_iov.iov_len = 1;
301
302 my_msghdr.msg_name = &my_accept_buffer[0];
303 my_msghdr.msg_namelen = my_accept_len;
304 my_msghdr.msg_iov = &my_iov;
305 my_msghdr.msg_iovlen = 1;
306 my_msghdr.msg_control = NULL;
307 my_msghdr.msg_controllen = 0;
308 my_msghdr.msg_flags = 0;
309
310 my_result = recvmsg( my_accepted_socket, &my_msghdr, MSG_WAITALL );
311 if ( my_result == -1 ) {
312 printf( "recvmsg failed with error %d - \"%s\" \n", errno, strerror( errno) );
313 goto test_failed_exit;
314 }
315
316 /* verify that we got the correct message from our child */
317 if ( my_parent_buffer[0] != 'j' ) {
318 printf( "test failed - did not get correct data from child \n" );
319 goto test_failed_exit;
320 }
321
322#if 1
323 /* now send some data to our child */
324 my_parent_buffer[0] = 'e';
325 my_sockaddr = (struct sockaddr *) &my_child_socket_name[0];
326 my_result = sendto( my_accepted_socket, &my_parent_buffer[0], 1, 0, my_sockaddr,
327 my_sockaddr->sa_len );
328 if ( my_result == -1 ) {
329 printf( "sendto failed with error %d - \"%s\" \n", errno, strerror( errno) );
330 goto test_failed_exit;
331 }
332#endif
333
b0d623f7
A
334#if 1
335 if (!g_is_under_rosetta) {
336 size_t neededBytes = 11;
337
338 /* Check for sendfile output */
339 bzero( (void *)&my_parent_buffer[0], sizeof(my_parent_buffer) );
340 while (neededBytes > 0) {
341 my_result = read( my_accepted_socket, &my_parent_buffer[11-neededBytes], neededBytes );
342 if ( my_result == -1 ) {
343 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
344 goto test_failed_exit;
345 } else if (my_result == 0) {
346 break;
347 }
348 neededBytes -= my_result;
349 }
350
351 if ( neededBytes > 0 ) {
352 printf( "read call returned %ld bytes instead of 11\n", 11 - neededBytes );
353 goto test_failed_exit;
354 }
355
356 if ( ! (my_parent_buffer[0] == 's' && my_parent_buffer[1] == 'e' && my_parent_buffer[9] == 'n' && my_parent_buffer[10] == 'd') ) {
357 printf( "read wrong sendfile message from child \n" );
358 goto test_failed_exit;
359 }
360 }
361
362#endif
363
364 /* see if child is done. bzero so that string is NUL terminated */
2d21ac55
A
365 bzero( (void *)&my_parent_buffer[0], sizeof(my_parent_buffer) );
366 my_result = read( my_accepted_socket, &my_parent_buffer[0], sizeof(my_parent_buffer) );
367 if ( my_result == -1 ) {
368 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
369 goto test_failed_exit;
370 }
371 if ( strcmp( "all done", &my_parent_buffer[0] ) != 0 ) {
372 printf( "read wrong message from child \n" );
373 goto test_failed_exit;
374 }
375 }
376
377 /* wait for child to exit */
378 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
379 if ( my_wait_pid == -1 ) {
380 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
381 goto test_failed_exit;
382 }
383
384 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
385 goto test_failed_exit;
386 }
387
388 my_err = 0;
389 goto test_passed_exit;
390
391test_failed_exit:
392 my_err = -1;
393
394test_passed_exit:
395 if ( my_socket_fd != -1 )
396 close( my_socket_fd );
397 if ( my_accepted_socket != -1 )
398 close( my_accepted_socket );
399 if ( my_parent_pathp != NULL ) {
400 remove( my_parent_pathp );
b0d623f7 401 vm_deallocate(mach_task_self(), (vm_address_t)my_parent_pathp, 128);
2d21ac55
A
402 }
403 if ( my_child_pathp != NULL ) {
404 remove( my_child_pathp );
b0d623f7 405 vm_deallocate(mach_task_self(), (vm_address_t)my_child_pathp, 128);
2d21ac55
A
406 }
407 return( my_err );
408}
409
410/* **************************************************************************************************************
411 * Test fsync, getsockopt, poll, select, setsockopt, socketpair system calls.
412 * **************************************************************************************************************
413 */
414int socket2_tests( void * the_argp )
415{
416 int my_err, my_status;
417 int my_sockets[ 2 ] = {-1, -1};
418 pid_t my_pid, my_wait_pid;
419 ssize_t my_count;
420 socklen_t my_socklen;
421 struct timeval * my_tvp;
422 struct timeval my_orig_tv;
423 char my_buffer[ 32 ];
424
425 my_err = socketpair( AF_UNIX, SOCK_STREAM, 0, &my_sockets[0] );
426 if ( my_err == -1 ) {
427 printf( "socketpair failed with errno %d - %s \n", errno, strerror( errno ) );
428 goto test_failed_exit;
429 }
430
431 /* test getsockopt and setsockopt */
432 my_socklen = sizeof( my_buffer );
433 my_err = getsockopt( my_sockets[0], SOL_SOCKET, SO_TYPE, &my_buffer[0], &my_socklen);
434 if ( my_err == -1 ) {
435 printf( "getsockopt - SO_TYPE - failed with errno %d - %s \n", errno, strerror( errno ) );
436 goto test_failed_exit;
437 }
438 if ( SOCK_STREAM != *((int *)&my_buffer[0]) ) {
439 printf( "getsockopt returned incorrect socket type \n" );
440 goto test_failed_exit;
441 }
442
443 /* get and set receive timeout */
444 my_socklen = sizeof( my_buffer );
445 my_err = getsockopt( my_sockets[0], SOL_SOCKET, SO_RCVTIMEO, &my_buffer[0], &my_socklen);
446 if ( my_err == -1 ) {
447 printf( "getsockopt - SO_RCVTIMEO - failed with errno %d - %s \n", errno, strerror( errno ) );
448 goto test_failed_exit;
449 }
450 my_tvp = (struct timeval *) &my_buffer[0];
451 my_orig_tv.tv_sec = my_tvp->tv_sec;
452 my_orig_tv.tv_usec = my_tvp->tv_usec;
453
454 my_tvp->tv_sec += 60;
455 my_err = setsockopt( my_sockets[0], SOL_SOCKET, SO_RCVTIMEO, &my_buffer[0], sizeof(struct timeval) );
456 if ( my_err == -1 ) {
457 printf( "setsockopt - SO_RCVTIMEO - failed with errno %d - %s \n", errno, strerror( errno ) );
458 goto test_failed_exit;
459 }
460
461 /* verify we set it */
462 my_socklen = sizeof( my_buffer );
463 my_err = getsockopt( my_sockets[0], SOL_SOCKET, SO_RCVTIMEO, &my_buffer[0], &my_socklen);
464 if ( my_err == -1 ) {
465 printf( "getsockopt - SO_RCVTIMEO - failed with errno %d - %s \n", errno, strerror( errno ) );
466 goto test_failed_exit;
467 }
468 my_tvp = (struct timeval *) &my_buffer[0];
469 if ( my_tvp->tv_sec != (my_orig_tv.tv_sec + 60) || my_tvp->tv_usec != my_orig_tv.tv_usec ) {
470 printf( "setsockopt - SO_RCVTIMEO - did not set correct timeval \n" );
471 goto test_failed_exit;
472 }
473
474 /* set back to original receive timeout */
475 my_err = setsockopt( my_sockets[0], SOL_SOCKET, SO_RCVTIMEO, &my_orig_tv, sizeof(struct timeval) );
476 if ( my_err == -1 ) {
477 printf( "setsockopt - SO_RCVTIMEO - failed with errno %d - %s \n", errno, strerror( errno ) );
478 goto test_failed_exit;
479 }
480
481 /* test fsync - should fail when used with a socket fd */
482 errno = 0;
483 my_err = fsync( my_sockets[0] );
484 if ( my_err == -1 && errno != ENOTSUP ) {
485 printf( "fsync failed with errno %d - %s \n", errno, strerror( errno ) );
486 goto test_failed_exit;
487 }
488 else if ( my_err != -1 ) {
489 printf( "fsync should have failed with errno ENOTSUP \n" );
490 goto test_failed_exit;
491 }
492
493 /*
494 * spin off a child process that we will talk to via our socketpair.
495 */
496 my_pid = fork( );
497 if ( my_pid == -1 ) {
498 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
499 goto test_failed_exit;
500 }
501 if ( my_pid == 0 ) {
502 /*
503 * child process - tell parent we are ready to go.
504 */
505 char my_buffer[ 32 ];
506 struct pollfd my_pollfd;
507
508 my_count = write( my_sockets[1], "r", 1 );
509 if ( my_count == -1 ) {
510 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
511 exit( -1 );
512 }
513
514 /* test select by using it to wait for message from parent */
515 for ( ;; ) {
516 fd_set my_read_set;
517 struct timeval my_timeout;
518
519 FD_ZERO( &my_read_set );
520 FD_SET( my_sockets[1], &my_read_set );
521 timerclear( &my_timeout );
522 my_timeout.tv_sec = 1;
523
524 /* check to see if we are done, if no message is ready after a second
525 * return and try again...
526 */
527 my_err = select( (my_sockets[1] + 1), &my_read_set, NULL, NULL, &my_timeout );
528 if ( my_err == -1 ) {
529 printf( "select call failed with error %d - \"%s\" \n", errno, strerror( errno) );
530 exit( -1 );
531 }
532 else if ( my_err > 0 ) {
533 /* we're done */
534 break;
535 }
536 }
537
538 /* test poll too */
539 my_pollfd.fd = my_sockets[1];
540 my_pollfd.events = (POLLIN | POLLPRI);
541 my_pollfd.revents = 0;
542 my_err = poll( &my_pollfd, 1, 500 );
543 if ( my_err == -1 ) {
544 printf( "poll call failed with error %d - \"%s\" \n", errno, strerror( errno) );
545 exit( -1 );
546 }
547 /* should be ready for read */
548 if ( (my_pollfd.revents & POLLIN) == 0 ) {
549 printf( "poll should have returned ready for read \n" );
550 exit( -1 );
551 }
552
553 my_count = read( my_sockets[1], &my_buffer[0], sizeof(my_buffer) );
554 if ( my_count == -1 ) {
555 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
556 exit( -1 );
557 }
558 if ( my_buffer[0] != 'd' ) {
559 printf( "read call on socket failed to get \"all done\" message \n" );
560 exit( -1 );
561 }
562
563 exit(0);
564 }
565
566 /*
567 * parent process - wait for child to spin up
568 */
569 my_count = read( my_sockets[0], &my_buffer[0], sizeof(my_buffer) );
570 if ( my_count == -1 ) {
571 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
572 goto test_failed_exit;
573 }
574 if ( my_buffer[0] != 'r' ) {
575 printf( "read call on socket failed to get \"ready to go message\" \n" );
576 goto test_failed_exit;
577 }
578
579 /* tell child we're done */
580 write( my_sockets[0], "d", 1 );
581
582 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
583 if ( my_wait_pid == -1 ) {
584 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
585 goto test_failed_exit;
586 }
587
588 /* wait4 should return our child's pid when it exits */
589 if ( my_wait_pid != my_pid ) {
590 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
591 goto test_failed_exit;
592 }
593
594 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
595 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
596 goto test_failed_exit;
597 }
598
599 my_err = 0;
600 goto test_passed_exit;
601
602test_failed_exit:
603 my_err = -1;
604
605test_passed_exit:
606 if ( my_sockets[0] != -1 )
607 close( my_sockets[0] );
608 if ( my_sockets[1] != -1 )
609 close( my_sockets[1] );
610 return( my_err );
611}
612