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