📄 taccept.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/socktest/taccept.c,v 1.1.1.1 2001/11/05 17:49:13 tneale Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1998-1999 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: taccept.c,v $ * Revision 1.1.1.1 2001/11/05 17:49:13 tneale * Tornado shuffle * * Revision 1.2 2001/01/19 22:24:53 paul * Update copyright. * * Revision 1.1 2000/10/16 19:22:17 paul * Renamed from test_accept.c * * Revision 1.11 2000/03/17 00:14:46 meister * Update copyright message * * Revision 1.10 1999/07/30 21:29:40 paul * enhanced test_fail, test_pass * * Revision 1.9 1999/05/21 19:33:58 niqbal * PNA isn;t exactly like BSD, atleast in returning the error * numbers. So removing the TEST_PNA flag from code that should be tested * on BSD only. * * Revision 1.7 1999/05/12 19:03:26 paul * Tweaks for greater-than-backlog test. * * Revision 1.6 1999/05/03 19:22:44 paul * Check for select timeout. * * Revision 1.5 1999/03/04 15:44:24 paul * fleshed out * * Revision 1.4 1999/02/18 04:15:58 wes * Socket Merge: new code (socket tests). * * Revision 1.3.2.3 1998/11/06 23:36:49 paul * rototill to support tcp * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*/#include "test.h"/* This test suite is different from the others because it needs a * cooperating program to initiate connections to it. We trigger a * foreign connection attempt by sending a datagram with the tcp port * number that we're listening on. */ #define BACKLOG 5#define UDP_PORT 49374unsigned short port; /* in network byte order */static void test_accept_1(int type, char *proto);static void trigger(char *proto, char *name);static int new_sock(int do_bind, int do_listen, int do_nonblocking);/* send a datagram to tell the other side we're ready */static voidtrigger(char *proto, char *name){ int s; struct sockaddr_in si; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { test_fail(proto, name, "trigger: socket"); return; } memset(&si, 0, sizeof(si)); si.sin_family = AF_INET; si.sin_port = htons(UDP_PORT); si.sin_addr.s_addr = server; /* tell the other side which port we're listening on */ if (sendto(s, (const void *)&port, sizeof(port), 0, (struct sockaddr *) &si, sizeof(si)) != sizeof(port)) test_fail(proto, name, "trigger: sendto"); close(s);}static intnew_sock(int do_bind, int do_listen, int do_nonblocking){ int s, opt; struct sockaddr_in si; /* set up the listening socket */ if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { test_fail(0, "accept: new_sock", "socket"); return -1; } if (do_bind) { memset(&si, 0, sizeof(si)); si.sin_family = AF_INET; si.sin_port = htons(0); if (bind(s, (struct sockaddr *) &si, sizeof(si)) != 0) { test_fail(0, "accept: new_sock", "bind"); close(s); return -1; } opt = sizeof(si); if (getsockname(s, (struct sockaddr *) &si, &opt) != 0) test_fail(0, "accept: new_sock", "getsockname"); port = si.sin_port; } if (do_listen) { if (listen(s, BACKLOG) != 0) { test_fail(0, "accept: new_sock", "listen"); close(s); return -1; } } if (do_nonblocking) { opt = -1; if (ioctl(s, FIONBIO, (char *) &opt) == -1) test_fail(0, "accept: new_sock", "nonblocking"); } return s;}static voidtest_ac(char *proto, char *name, int s, struct sockaddr_in *addr, int *addrlen, int do_trigger, int do_select, int expected, int expected_errno){ int s2, i; fd_set rfds; struct timeval tv; if (do_trigger) trigger(proto, name); if (do_select && (s >= 0)) { /* don't try select -1 fd */ FD_ZERO(&rfds); FD_SET(s, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; i = select(s+1, &rfds, 0, 0, &tv); if (i == 0) { test_fail(proto, name, "accept: select timed out"); return; } } s2 = accept(s, (struct sockaddr *) addr, addrlen); if (name) test(proto, name, s2, expected, expected_errno); if (s2 >= 0) { if (addr && addrlen && (*addrlen >= sizeof(struct sockaddr_in))) pr_sockaddr_in(addr); close(s2); }}voidtest_accept(int flags){ int s; test_ac(0, "accept invalid descriptor", -1, 0, 0, 0, 0, -1, EBADF);#ifdef TEST_BSD test_ac(0, "accept file descriptor", 1, 0, 0, 0, 0, -1, ENOTSOCK);#endif if (flags & TEST_UDP) { s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { test_fail(0, "accept", "socket(SOCK_DGRAM)"); return; } /* BSD returns EINVAL in the following case, in contradiction to * both the man page and the Posix spec */ test_ac(0, "accept non-STREAM socket", s, 0, 0, 0, 0, -1, EOPNOTSUPP); close(s); } if (flags & TEST_TCP) test_accept_1(SOCK_STREAM, "tcp");}static voidtest_accept_1(int type, char *proto){ int s, s2, si_len, i; struct sockaddr_in si; fd_set rfds; struct timeval tv; si_len = sizeof(si); s = new_sock(1, 0, 0); test_ac(0, "accept non-listening socket", s, 0, 0, 0, 0, -1, EINVAL); if (listen(s, BACKLOG) != 0) test_fail(0, "accept", "listen"); test_ac(0, "blocking accept", s, 0, 0, 1, 0, 17, 0); close(s); s = new_sock(1, 1, 1); trigger(proto, "nonblocking accept"); while (((s2 = accept(s, 0, 0)) == -1) && (errno == EWOULDBLOCK)) { /* loop */ } test(0, "nonblocking accept", s2, 17, 0); if (s2 >= 0) close(s2); test_ac(0, "select accept", s, 0, 0, 1, 1, 17, 0); /* close a socket with pending connections. this is not a test in * the usual sense; it is to see if we have any memory leaks with * purify. */ FD_ZERO(&rfds); FD_SET(s, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; trigger(proto, "accept: pending connections"); if (select(s+1, &rfds, 0, 0, &tv) == 0) test_fail(0, "accept", "select"); close(s); test_pass(0, "accept", "closed socket with pending connections"); /* get a bunch of pending connections before accepting any */ s = new_sock(1, 1, 1); for (i = 0; i < BACKLOG + 1; ++i) trigger(proto, "accept: backlog"); /* there's no equivalent to FIONREAD for number of connections, so * delay a bit for all the connections to come in */ sleep(10); for (i = 0; i < BACKLOG; ++i) test_ac(0, 0, s, 0, 0, 0, 1, 0, 0); test_ac(0, "accept > backlog", s, 0, 0, 0, 0, -1, EWOULDBLOCK); test_ac(0, "accept addrlen=null", s, &si, 0, 1, 1, -1, EFAULT); si_len = 0; test_ac(0, "accept addrlen=0", s, &si, &si_len, 1, 1, 17, 0); si_len = sizeof(si); test_ac(0, "accept addrlen=sizeof(sockaddr_in)", s, &si, &si_len, 1, 1, 17, 0);/*- remote open, write data, close before accepting (trigger, pause?, accept)- dfq test: multiple connections with data before processing dfq (may be hard to induce)*/ close(s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -