1150043Smaxim/*- 2150043Smaxim * Copyright (C) 2005 The FreeBSD Project. All rights reserved. 3150043Smaxim * 4150043Smaxim * Redistribution and use in source and binary forms, with or without 5150043Smaxim * modification, are permitted provided that the following conditions 6150043Smaxim * are met: 7150043Smaxim * 1. Redistributions of source code must retain the above copyright 8150043Smaxim * notice, this list of conditions and the following disclaimer. 9150043Smaxim * 2. Redistributions in binary form must reproduce the above copyright 10150043Smaxim * notice, this list of conditions and the following disclaimer in the 11150043Smaxim * documentation and/or other materials provided with the distribution. 12150043Smaxim * 13150043Smaxim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14150043Smaxim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15150043Smaxim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16150043Smaxim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17150043Smaxim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18150043Smaxim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19150043Smaxim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20150043Smaxim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21150043Smaxim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22150043Smaxim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23150043Smaxim * SUCH DAMAGE. 24150043Smaxim * 25150043Smaxim * $FreeBSD: releng/11.0/tools/regression/sockets/shutdown/shutdown.c 281395 2015-04-11 03:19:48Z ngie $ 26150043Smaxim */ 27150043Smaxim 28150043Smaxim#include <sys/types.h> 29150043Smaxim#include <sys/socket.h> 30150043Smaxim 31150043Smaxim#include <netinet/in.h> 32150043Smaxim#include <arpa/inet.h> 33150043Smaxim 34150043Smaxim#include <err.h> 35150043Smaxim#include <errno.h> 36150043Smaxim#include <stdio.h> 37150043Smaxim#include <string.h> 38150043Smaxim#include <unistd.h> 39150043Smaxim 40150043Smaximint 41150043Smaximmain(void) 42150043Smaxim{ 43150043Smaxim struct sockaddr_in sock; 44150043Smaxim socklen_t len; 45150043Smaxim int listen_sock, connect_sock; 46150043Smaxim u_short port; 47150043Smaxim 48281395Sngie listen_sock = -1; 49281395Sngie 50150043Smaxim /* Shutdown(2) on an invalid file descriptor has to return EBADF. */ 51150043Smaxim if ((shutdown(listen_sock, SHUT_RDWR) != -1) && (errno != EBADF)) 52150043Smaxim errx(-1, "shutdown() for invalid file descriptor does not " 53150043Smaxim "return EBADF"); 54150043Smaxim 55150043Smaxim listen_sock = socket(PF_INET, SOCK_STREAM, 0); 56150043Smaxim if (listen_sock == -1) 57150043Smaxim errx(-1, 58150043Smaxim "socket(PF_INET, SOCK_STREAM, 0) for listen socket: %s", 59150043Smaxim strerror(errno)); 60150043Smaxim 61150043Smaxim bzero(&sock, sizeof(sock)); 62150043Smaxim sock.sin_len = sizeof(sock); 63150043Smaxim sock.sin_family = AF_INET; 64150043Smaxim sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 65150043Smaxim sock.sin_port = 0; 66150043Smaxim 67150043Smaxim if (bind(listen_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0) 68150043Smaxim errx(-1, "bind(%s, %d) for listen socket: %s", 69150043Smaxim inet_ntoa(sock.sin_addr), sock.sin_port, strerror(errno)); 70150043Smaxim 71150043Smaxim len = sizeof(sock); 72150043Smaxim if (getsockname(listen_sock, (struct sockaddr *)&sock, &len) < 0) 73150043Smaxim errx(-1, "getsockname() for listen socket: %s", 74150043Smaxim strerror(errno)); 75150043Smaxim port = sock.sin_port; 76150043Smaxim 77150043Smaxim if (listen(listen_sock, -1) < 0) 78150043Smaxim errx(-1, "listen() for listen socket: %s", strerror(errno)); 79150043Smaxim 80150043Smaxim connect_sock = socket(PF_INET, SOCK_STREAM, 0); 81150043Smaxim if (connect_sock == -1) 82150043Smaxim errx(-1, "socket(PF_INET, SOCK_STREAM, 0) for connect " 83150043Smaxim "socket: %s", strerror(errno)); 84150043Smaxim 85150043Smaxim bzero(&sock, sizeof(sock)); 86150043Smaxim sock.sin_len = sizeof(sock); 87150043Smaxim sock.sin_family = AF_INET; 88150043Smaxim sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 89150043Smaxim sock.sin_port = port; 90150043Smaxim 91150043Smaxim if (connect(connect_sock, (struct sockaddr *)&sock, sizeof(sock)) < 0) 92150043Smaxim errx(-1, "connect() for connect socket: %s", strerror(errno)); 93150043Smaxim /* Try to pass an invalid flags. */ 94150043Smaxim if ((shutdown(connect_sock, SHUT_RD - 1) != -1) && (errno != EINVAL)) 95150043Smaxim errx(-1, "shutdown(SHUT_RD - 1) does not return EINVAL"); 96150043Smaxim if ((shutdown(connect_sock, SHUT_RDWR + 1) != -1) && (errno != EINVAL)) 97150043Smaxim errx(-1, "shutdown(SHUT_RDWR + 1) does not return EINVAL"); 98150043Smaxim 99150043Smaxim if (shutdown(connect_sock, SHUT_RD) < 0) 100150043Smaxim errx(-1, "shutdown(SHUT_RD) for connect socket: %s", 101150043Smaxim strerror(errno)); 102150043Smaxim if (shutdown(connect_sock, SHUT_WR) < 0) 103150043Smaxim errx(-1, "shutdown(SHUT_WR) for connect socket: %s", 104150043Smaxim strerror(errno)); 105150043Smaxim 106150043Smaxim close(connect_sock); 107150043Smaxim close(listen_sock); 108150043Smaxim 109150043Smaxim return (0); 110150043Smaxim} 111