📄 select.c
字号:
//==========================================================================
//
// select.c
//
// Test select implementation
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-05-25
// Purpose: Test select implementation
// Description:
//
//
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/isoinfra.h>
#ifndef CYGINT_ISO_PTHREAD_IMPL
# define NA_MSG "POSIX threads needed to run test"
#endif
#include <cyg/infra/testcase.h>
#ifndef NA_MSG
#include <pkgconf/hal.h>
#include <pkgconf/kernel.h>
#include <pkgconf/io_fileio.h>
#ifdef CYGPKG_IO_SERIAL
#include <pkgconf/io_serial.h>
#endif
#define __ECOS 1 // dont like this at all
#include <cyg/kernel/ktypes.h> // base kernel types
#include <cyg/infra/cyg_trac.h> // tracing macros
#include <cyg/infra/cyg_ass.h> // assertion macros
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <errno.h>
#include <string.h>
#ifdef CYGPKG_NET
#include <network.h>
#include <arpa/inet.h>
#define TEST_NET
#endif
#ifdef CYGPKG_IO_SERIAL_LOOP
#define TEST_DEV
#endif
#include <pthread.h>
#include <signal.h>
#include <cyg/infra/diag.h> // HAL polled output
//--------------------------------------------------------------------------
#define SHOW_RESULT( _fn, _res ) \
diag_printf("INFO: " #_fn "() returned %ld %s\n", (long)_res, _res<0?strerror(errno):"");
//--------------------------------------------------------------------------
// Thread stack.
char thread1_stack[PTHREAD_STACK_MIN*2];
char thread2_stack[PTHREAD_STACK_MIN*2];
//--------------------------------------------------------------------------
// Local variables
// Thread IDs
pthread_t thread1;
pthread_t thread2;
#ifdef TEST_NET
struct sockaddr_in sa;
#endif
//--------------------------------------------------------------------------
// Test buffers
// The buffer size here must be less that the size of the serial device
// buffers since the serial devices do not currently implement flow
// control.
#define TEST_BUFSIZE 100
#ifdef TEST_NET
static char buf1[TEST_BUFSIZE];
static char buf2[TEST_BUFSIZE];
static char buf3[TEST_BUFSIZE];
#endif
#ifdef TEST_DEV
static char sbuf1[TEST_BUFSIZE];
static char sbuf2[TEST_BUFSIZE];
static char sbuf3[TEST_BUFSIZE];
#endif
//--------------------------------------------------------------------------
void show_fdsets( char *s, int nfd, fd_set *rd, fd_set *wr, fd_set *ex )
{
int i;
diag_printf("INFO:<%s nfd %d ",s,nfd);
if( rd )
{
diag_printf("rd: [");
for( i = 0; i < nfd ; i++ )
if( FD_ISSET( i, rd ) ) diag_printf("%d ",i);
diag_printf("] ");
}
if( wr )
{
diag_printf("wr: [");
for( i = 0; i < nfd ; i++ )
if( FD_ISSET( i, wr ) ) diag_printf("%d ",i);
diag_printf("] ");
}
if( ex )
{
diag_printf("ex: [");
for( i = 0; i < nfd ; i++ )
if( FD_ISSET( i, ex ) ) diag_printf("%d ",i);
diag_printf("] ");
}
diag_printf(">\n");
}
//--------------------------------------------------------------------------
void *pthread_entry1( void *arg)
{
#ifdef TEST_NET
int fd = 0, fd2 = -1;
struct sockaddr_in accsa;
socklen_t accsa_len = sizeof(accsa);
int netstate = 0;
#endif
#ifdef TEST_DEV
int ser0;
int serstate = 0;
#endif
#if defined(TEST_DEV) || defined(TEST_NET)
int i;
ssize_t done;
#endif
int netdone = 0;
int serdone = 0;
int err;
fd_set rd, wr;
CYG_TEST_INFO( "Thread 1 running" );
FD_ZERO( &rd );
FD_ZERO( &wr );
#ifdef TEST_DEV
CYG_TEST_INFO( "Thread1: calling open()");
ser0 = open("/dev/ser0", O_RDWR );
if( ser0 < 0 ) SHOW_RESULT( open, ser0 );
CYG_TEST_CHECK( ser0 >= 0, "open(/dev/ser0) returned error");
FD_SET( ser0, &rd );
#else
serdone = 1;
#endif
#ifdef TEST_NET
for( i = 0; i < TEST_BUFSIZE; i++ ) buf1[i] = i;
CYG_TEST_INFO( "Thread1: calling socket()");
fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( fd < 0 ) SHOW_RESULT( socket, fd );
CYG_TEST_CHECK( fd >= 0, "socket() returned error");
CYG_TEST_INFO( "Thread1: calling bind()");
err = bind( fd, (struct sockaddr *)&sa, sizeof(sa));
if( err < 0 ) SHOW_RESULT( bind, err );
CYG_TEST_CHECK( err == 0, "bind() returned error");
CYG_TEST_INFO( "Thread1: calling listen()");
err = listen( fd, 3);
if( err < 0 ) SHOW_RESULT( listen, err );
CYG_TEST_CHECK( err == 0, "listen() returned error");
FD_SET( fd, &rd );
#else
netdone = 1;
#endif
while(!(netdone && serdone))
{
fd_set rd_res = rd;
fd_set wr_res = wr;
CYG_TEST_INFO( "Thread1: calling select()");
show_fdsets( "Thread1 request: ", 8, &rd_res, &wr_res, NULL );
err = select( 8, &rd_res, &wr_res, NULL, NULL );
if( err < 0 ) SHOW_RESULT( select, err );
CYG_TEST_CHECK( err >= 0, "select() returned error");
show_fdsets( "Thread1 result: ", 8, &rd_res, &wr_res, NULL );
#ifdef TEST_NET
switch( netstate )
{
case 0:
CYG_TEST_INFO( "Thread1: netstate 0");
if( FD_ISSET( fd, &rd_res ) )
{
CYG_TEST_INFO( "Thread1: calling accept(fd)");
fd2 = accept( fd, (struct sockaddr *)&accsa, &accsa_len );
if( fd2 < 0 ) SHOW_RESULT( accept, fd2 );
CYG_TEST_CHECK( fd2 >= 0, "accept() returned error");
FD_CLR( fd, &rd );
FD_SET( fd2, &wr );
netstate++;
}
break;
case 1:
CYG_TEST_INFO( "Thread1: netstate 1");
if( FD_ISSET( fd2, &wr_res ) )
{
CYG_TEST_INFO( "Thread1: calling write(fd2)");
done = write( fd2, buf1, TEST_BUFSIZE);
if( done != TEST_BUFSIZE ) SHOW_RESULT( write, done );
CYG_TEST_CHECK( done == TEST_BUFSIZE, "write() returned bad size");
FD_CLR( fd2, &wr );
FD_SET( fd2, &rd );
netstate++;
}
break;
case 2:
CYG_TEST_INFO( "Thread1: netstate 2");
if( FD_ISSET( fd2, &rd_res ) )
{
CYG_TEST_INFO( "Thread1: calling read(fd2)");
done = read( fd2, buf3, TEST_BUFSIZE);
if( done != TEST_BUFSIZE ) SHOW_RESULT( read, done );
CYG_TEST_CHECK( done == TEST_BUFSIZE, "read() returned bad size");
for( i = 0; i < TEST_BUFSIZE; i++ )
if( buf1[i] != buf3[i] )
diag_printf("buf1[%d](%02x) != buf3[%d](%02x)\n",i,buf1[i],i,buf3[i]);
FD_CLR( fd2, &rd );
netstate++;
netdone = 1;
CYG_TEST_INFO( "Thread1: netdone");
}
break;
}
#endif
#ifdef TEST_DEV
switch( serstate )
{
case 0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -