1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2017 Sebastian Wiedenroth
14  */
15 
16 /*
17  * Test for MSG_NOSIGNAL flag.
18  */
19 
20 
21 #include <unistd.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <arpa/inet.h>
27 #include <errno.h>
28 #include <assert.h>
29 
30 /* allow the test to build and fail */
31 #ifndef MSG_NOSIGNAL
32 #define	MSG_NOSIGNAL 0
33 #endif
34 
35 volatile sig_atomic_t sigcount = 0;
36 
37 void
sigpipe_h(int sig0)38 sigpipe_h(int sig0)
39 {
40 	sigcount++;
41 	signal(SIGPIPE, sigpipe_h);
42 }
43 
44 int
main()45 main()
46 {
47 	signal(SIGPIPE, sigpipe_h);
48 
49 	int len = 0;
50 	const char *msg = "hello illumos";
51 
52 	struct sockaddr_in sin;
53 	sin.sin_family = AF_INET;
54 	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
55 	sin.sin_port = htons(4242);
56 
57 	int s = socket(PF_INET, SOCK_STREAM, 0);
58 	int c = socket(PF_INET, SOCK_STREAM, 0);
59 	assert(s >= 0 && c >= 0);
60 
61 	assert(bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0);
62 	assert(listen(s, 3) >= 0);
63 	assert(connect(c, (struct sockaddr *)&sin, sizeof (sin)) >= 0);
64 	assert(close(s) == 0);
65 
66 	assert(MSG_NOSIGNAL > 0);
67 	assert(sigcount == 0);
68 
69 	/* test failure with signal */
70 	len = send(c, msg, strlen(msg), 0);
71 	assert(len == -1 && errno == EPIPE);
72 	sleep(1);
73 	assert(sigcount == 1);
74 
75 	/* test failure without signal */
76 	len = send(c, msg, strlen(msg), MSG_NOSIGNAL);
77 	assert(len == -1 && errno == EPIPE);
78 	sleep(1);
79 	assert(sigcount == 1);
80 
81 	assert(close(c) == 0);
82 	return (0);
83 }
84