Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/sockets/shutdown/shutdown.c
48254 views
1
/*-
2
* Copyright (C) 2005 The FreeBSD Project. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
* SUCH DAMAGE.
24
*/
25
26
#include <sys/types.h>
27
#include <sys/socket.h>
28
29
#include <netinet/in.h>
30
#include <arpa/inet.h>
31
32
#include <err.h>
33
#include <errno.h>
34
#include <stdio.h>
35
#include <string.h>
36
#include <unistd.h>
37
38
int
39
main(void)
40
{
41
struct sockaddr_in sock;
42
socklen_t len;
43
int listen_sock, connect_sock;
44
u_short port;
45
46
listen_sock = -1;
47
48
/* Shutdown(2) on an invalid file descriptor has to return EBADF. */
49
if ((shutdown(listen_sock, SHUT_RDWR) != -1) && (errno != EBADF))
50
errx(-1, "shutdown() for invalid file descriptor does not "
51
"return EBADF");
52
53
listen_sock = socket(PF_INET, SOCK_STREAM, 0);
54
if (listen_sock == -1)
55
errx(-1,
56
"socket(PF_INET, SOCK_STREAM, 0) for listen socket: %s",
57
strerror(errno));
58
59
bzero(&sock, sizeof(sock));
60
sock.sin_len = sizeof(sock);
61
sock.sin_family = AF_INET;
62
sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
63
sock.sin_port = 0;
64
65
if (bind(listen_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0)
66
errx(-1, "bind(%s, %d) for listen socket: %s",
67
inet_ntoa(sock.sin_addr), sock.sin_port, strerror(errno));
68
69
len = sizeof(sock);
70
if (getsockname(listen_sock, (struct sockaddr *)&sock, &len) < 0)
71
errx(-1, "getsockname() for listen socket: %s",
72
strerror(errno));
73
port = sock.sin_port;
74
75
if (listen(listen_sock, -1) < 0)
76
errx(-1, "listen() for listen socket: %s", strerror(errno));
77
78
connect_sock = socket(PF_INET, SOCK_STREAM, 0);
79
if (connect_sock == -1)
80
errx(-1, "socket(PF_INET, SOCK_STREAM, 0) for connect "
81
"socket: %s", strerror(errno));
82
83
bzero(&sock, sizeof(sock));
84
sock.sin_len = sizeof(sock);
85
sock.sin_family = AF_INET;
86
sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
87
sock.sin_port = port;
88
89
if (connect(connect_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0)
90
errx(-1, "connect() for connect socket: %s", strerror(errno));
91
/* Try to pass an invalid flags. */
92
if ((shutdown(connect_sock, SHUT_RD - 1) != -1) && (errno != EINVAL))
93
errx(-1, "shutdown(SHUT_RD - 1) does not return EINVAL");
94
if ((shutdown(connect_sock, SHUT_RDWR + 1) != -1) && (errno != EINVAL))
95
errx(-1, "shutdown(SHUT_RDWR + 1) does not return EINVAL");
96
97
if (shutdown(connect_sock, SHUT_RD) < 0)
98
errx(-1, "shutdown(SHUT_RD) for connect socket: %s",
99
strerror(errno));
100
if (shutdown(connect_sock, SHUT_WR) < 0)
101
errx(-1, "shutdown(SHUT_WR) for connect socket: %s",
102
strerror(errno));
103
104
close(connect_sock);
105
close(listen_sock);
106
107
return (0);
108
}
109
110