/*
* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include "tselect.h"
// CONSTANTS
const TUint KTestPort = 2080;
TInt CTestSelect::TestTimeout()
{
// Create temporary variables in stack
TInt timesecs;
TInt timemicrosecs;
timemicrosecs = 0;
timesecs = 10;
struct timeval tv;
tv.tv_sec = timesecs;
tv.tv_usec = timemicrosecs;
time_t time1,time2;
int err = time(&time1);
int fd = select(1, NULL, NULL,NULL, &tv);
err = time(&time2);
if ( ((time2 - time1) >= timesecs) && fd != -1 )
{
return KErrNone;
}
else
{
return KErrGeneral;
}
}
TInt CTestSelect::TestReadFileDesc()
{
TInt timesecs = 5;
TInt timemicrosecs = 0;
struct timeval tv;
tv.tv_sec = timesecs;
tv.tv_usec = timemicrosecs;
// read only
int fd = open("c:\\tselect.cfg", O_RDONLY|O_CREAT);
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
int maxfd = fd + 1;
int ret = select(maxfd, &readfds, NULL, NULL,&tv);
if ( ret != -1 && FD_ISSET(fd, &readfds))
{
_LIT(KMsg1, "Read on file fd Test Passed");
INFO_PRINTF1(KMsg1);
return KErrNone;
}
else
{
_LIT(KMsg1, "Read on file fd Test Failed");
INFO_PRINTF1(KMsg1);
return KErrGeneral;
}
}
TInt CTestSelect::TestWriteFileDesc()
{
TInt timesecs = 2;
TInt timemicrosecs = 0;
struct timeval tv;
tv.tv_sec = timesecs;
tv.tv_usec = timemicrosecs;
// write check
int fd = open("c:\\tselect.cfg", O_RDONLY);
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(fd, &writefds);
int maxfd = fd + 1;
int ret = select(maxfd, NULL,&writefds, NULL,&tv);
if ( ret != -1 && FD_ISSET(fd, &writefds))
{
_LIT(KMsg1, "Write on file fd Test Passed");
INFO_PRINTF1(KMsg1);
return KErrNone;
}
else
{
_LIT(KMsg1, "Write on file fd Test failed");
INFO_PRINTF1(KMsg1);
return KErrGeneral;
}
}
TInt CTestSelect::TestReadWriteFileDesc()
{
// both read and write
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int fd = open("c:\\tselect.cfg", O_RDONLY);
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(fd, &writefds);
int maxfd = fd + 1;
int ret = select(maxfd, &readfds, &writefds, NULL,&tv);
if ( ret != -1 && FD_ISSET(fd, &readfds) && FD_ISSET(fd, &writefds) )
{
_LIT(KMsg1, "R/W on file fd Test passed");
INFO_PRINTF1(KMsg1);
return KErrNone;
}
else
{
_LIT(KMsg1, "R/W on file fd Test failed");
INFO_PRINTF1(KMsg1);
return KErrGeneral;
}
}
TInt CTestSelect::TestPipeReadDesc()
{
int fd[2];
INFO_PRINTF1(_L("Before Pipe "));
if ( pipe(fd) < 0 )
{
return -1;
}
char a = 's';
write(fd[1],&a,1);
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd[0], &readfds);
int ret = select(fd[0] +1, &readfds, NULL, NULL, NULL );
if ( ret != -1 && FD_ISSET(fd[0], &readfds))
{
_LIT(KMsg1, "Read on pipe fd Test passed");
INFO_PRINTF1(KMsg1);
ret = KErrNone;
}
else
{
_LIT(KMsg1, "Read on pipe fd Test failed");
INFO_PRINTF1(KMsg1);
ret = KErrGeneral;
}
close(fd[0]);
close(fd[1]);
return ret;
}
//Test case added to check when write end of a pipe is closed
TInt CTestSelect::TestPipeReadDesc1()
{
int fd[2];
INFO_PRINTF1(_L("Before Pipe "));
if ( pipe(fd) < 0 )
{
return -1;
}
char a = 's';
write(fd[1],&a,0);
fd_set readfds,exceptfds;
FD_ZERO(&readfds);
FD_ZERO(&exceptfds);
FD_SET(fd[0], &readfds);
FD_SET(fd[0], &exceptfds);
FD_SET(fd[1], &exceptfds);
close(fd[1]);
int ret = select(fd[0] +1, &readfds, NULL, &exceptfds, NULL );
if ( ret != -1 && FD_ISSET(fd[0], &exceptfds))
{
_LIT(KMsg1, "Read on pipe fd Test passed and passed to set EAnyException on write end of a pipe being closed\n");
INFO_PRINTF1(KMsg1);
ret = KErrNone;
}
else
{
_LIT(KMsg1, "Failed to set EAnyException on write end being closed\n");
INFO_PRINTF1(KMsg1);
ret = KErrGeneral;
}
close(fd[0]);
return ret;
}
TInt CTestSelect::TestPipeWriteDesc()
{
int fd[2];
INFO_PRINTF1(_L("Before Pipe "));
if ( pipe(fd) < 0 )
{
return -1;
}
INFO_PRINTF1(_L("Pipe Created"));
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(fd[1], &writefds);
int ret = select(fd[1] +1, NULL, &writefds, NULL, NULL );
iSelectflag = 1;
if ( ret != -1 && FD_ISSET(fd[1], &writefds))
{
_LIT(KMsg1, "Write on pipe fd Test passed");
INFO_PRINTF1(KMsg1);
ret = KErrNone;
}
else
{
_LIT(KMsg1, "Write on pipe fd Test failed");
INFO_PRINTF1(KMsg1);
ret = KErrGeneral;
}
close(fd[0]);
close(fd[1]);
return ret;
}
void* CTestSelect::ServerThread(TAny* ptr)
{
CTestSelect* thisptr = (CTestSelect*)ptr;
int sock_fd,newsock_fd;
unsigned int addr_len;
sockaddr_in serv_addr,new_socket;
sock_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (sock_fd < 0)
{
return NULL;//KErrGeneral;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(KTestPort);
if (bind(sock_fd,(sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
{
shutdown(sock_fd,SHUT_RDWR); // 2 -> SHUT_RDWT
close(sock_fd);
return NULL;//KErrBind;
}
if (listen(sock_fd,1) < 0)
{
shutdown(sock_fd,SHUT_RDWR); // 2 -> SHUT_RDWT
close(sock_fd);
return NULL;//KErrListen;
}
addr_len = sizeof(new_socket);
thisptr->iAcceptflag = 1;
newsock_fd = accept(sock_fd,(sockaddr*)&new_socket,&addr_len); // Code blocks here
char a = 'S';
write(newsock_fd, &a, 1);
thisptr->iWriteflag = 1;
while(!thisptr->iSelectflag)
{
usleep(10000);
}
close(sock_fd);
close(newsock_fd);
return NULL;//KErrNone;
}
TInt CTestSelect::TestSocketDesc()
{
struct timeval tv;
struct sockaddr_in testaddr;
tv.tv_sec = 1;
tv.tv_usec = 0;
memset( &testaddr,0, sizeof( testaddr));
// now connect to the server
int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
INFO_PRINTF1(_L("socket in client called"));
pthread_t testThread;
pthread_create(&testThread, NULL, &ServerThread, (void*)this);
testaddr.sin_family = AF_INET;
testaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
testaddr.sin_port = htons(KTestPort);
while ( !iAcceptflag )
{
usleep(10000);
}
INFO_PRINTF1(_L("connect called"));
TInt err=connect(fd,(struct sockaddr*)&testaddr, sizeof(testaddr));
fd_set readfds,writefds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(fd, &readfds);
FD_SET(fd, &writefds);
int maxfd = fd + 1;
while ( !iWriteflag )
{
usleep(10000);
}
INFO_PRINTF1(_L("before select "));
int ret = select(maxfd, &readfds, NULL, NULL,&tv);
INFO_PRINTF1(_L("after select"));
iSelectflag = 1;
if ( ret != -1 && FD_ISSET(fd, &readfds))
{
ret = KErrNone;
}
else
{
ret = KErrGeneral;
}
close(fd);
int *p;
pthread_join(testThread,(void**)&p);
return ret;
}
//Test case added for select not hanging for zero timeout- DEF122924
TInt CTestSelect::TestSocketDesc2()
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int fd = socket(AF_INET, SOCK_STREAM, 0);
INFO_PRINTF1(_L("socket in client called"));
fd_set readfds,writefds,errfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&errfds);
FD_SET(fd, &readfds);
int maxfd = fd + 1;
INFO_PRINTF1(_L("before select "));
int ret = select(maxfd, &readfds, &writefds, &errfds,&tv);
INFO_PRINTF1(_L("select passes, does not hang."));
close(fd);
return ret;
}
int FlgReadWrite = 0;
int FlgRead = 0;
#define ReadWriteErr2 7
#define ReadWriteErr1 6
#define Write2Err 5
#define Write1Err 4
#define Read1Err 3
#define PipeReadDesc 8
#define PipeWriteDesc 9
void* CreateConnection(void* /*aParam*/)
{
// Only make a write on the sock_fd
int ret;
struct sockaddr_in host;
int dest_fd;
char buf[50];
host.sin_port = htons(5002);
host.sin_family = AF_INET;
host.sin_addr.s_addr = inet_addr("127.0.0.1");
dest_fd = socket(AF_INET,SOCK_STREAM,0);
ret = connect(dest_fd,(struct sockaddr*)&host,sizeof(host));
ret = read(dest_fd,buf,sizeof(buf));
ret = write(dest_fd,buf,ret);
close(dest_fd);
return NULL;
}
void* SocketReadWrite(void* aSock)
{
// Note, here "aSock" is being treated as an array of FDs.
// The FD at the 0th index is the write-fd, and the FD at
// the 1st index is the read-fd.
int sock_fd = *((int*)aSock);
fd_set fds;
int ret;
char buf[] = "Write from third thread";
char buf2[50];
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
// Setting the write-fd.
FD_ZERO(&fds);
FD_SET(sock_fd,&fds);
fd_set readfds;
FD_ZERO(&readfds);
//FD_SET(((int*)aSock)[0],&readfds);
FD_SET(((int*)aSock)[1],&readfds);
FD_SET(((int*)aSock)[PipeReadDesc],&readfds);
((int*)aSock)[ReadWriteErr1] = 0;
((int*)aSock)[ReadWriteErr2] = 0;
//while(FlgReadWrite == 0)
//while(FlgRead == 0)
{
}
ret = select(((int*)aSock)[PipeReadDesc] + 1,&readfds,NULL,NULL,&timeout);
//ret = select(((int*)aSock)[PipeReadDesc] + 1,&readfds,&fds,NULL,&timeout);
//ret = select(((int*)aSock)[1] + 1,&readfds,NULL,NULL,&timeout);
#if 0
if (ret && FD_ISSET(sock_fd,&fds))
{
ret = write(sock_fd,buf,sizeof(buf));
fprintf( (FILE*)(((int*)aSock)[2]), "WRITING SocketReadWrite END - have written = %d and %s\n",ret,buf);
if (ret < 0)
((int*)aSock)[ReadWriteErr1] = ret;
}
#endif
if(ret && FD_ISSET(((int*)aSock)[1],&readfds))
{
ret = read(((int*)aSock)[1],buf2,sizeof(buf2));
fprintf( (FILE*)(((int*)aSock)[2]), "READING SocketReadWrite END - have read = %d and %s\n",ret,buf2);
if(ret < 0)
((int*)aSock)[ReadWriteErr2] = ret;
}
if(ret && FD_ISSET(((int*)aSock)[PipeReadDesc],&readfds))
{
ret = read(((int*)aSock)[PipeReadDesc],buf,sizeof(buf));
fprintf( (FILE*)(((int*)aSock)[2]), "READING SocketReadWrite END - have read = %d and %s\n",ret,buf);
if(ret < 0)
((int*)aSock)[ReadWriteErr2] = ret;
}
if(ret == -1)
{
fprintf( (FILE*)(((int*)aSock)[2]), "WRITING SocketReadWrite ERROR END - have written = %d \n",ret);
((int*)aSock)[ReadWriteErr1] = ret;
}
return aSock;
}
void* SocketWrite1(void* aSock)
{
int *sock_fd = (int*)aSock;
((int*)aSock)[Write1Err] = KErrNone;
char buf[] = "Write from first thread";
int ret = 0;
// sleep(3);
ret = write(*sock_fd,buf,sizeof(buf));
FlgRead = 1;
if (ret < 0)
((int*)aSock)[Write1Err] = ret;
else
((int*)aSock)[Write1Err] = KErrNone;
return aSock;
}
void* SocketWrite2(void* aSock)
{
// int *sock_fd = (int*)aSock;
((int*)aSock)[Write2Err] = KErrNone;
char buf[] = "Write from second thread";
// sleep(2);
int ret = write(((int*)aSock)[1],buf,sizeof(buf));
FlgReadWrite = 1;
if (ret < 0)
((int*)aSock)[Write2Err] = ret;
else
((int*)aSock)[Write2Err] = KErrNone;
return aSock;
}
void* PipeWrite(void* aPipe)
{
//int *pipe_fd = (int*)aPipe;
char buf[] = "Pipe Write";
sleep(1);
int ret = write(((int*)aPipe)[PipeWriteDesc],buf,sizeof(buf));
FlgReadWrite = 1;
if (ret < 0)
((int*)aPipe)[Write2Err] = ret;
else
((int*)aPipe)[Write2Err] = KErrNone;
return aPipe;
}
void* SocketRead1(void* aSock)
{
int sock_fd = *((int*)aSock);
fd_set fds;
char buf[50];
int ret;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
((int*)aSock)[Read1Err] = KErrNone;
FD_ZERO(&fds);
FD_SET(sock_fd,&fds);
//while(FlgRead == 0)
{
}
ret = select(sock_fd+1,&fds,NULL,NULL,&timeout);
if (ret && FD_ISSET(sock_fd,&fds))
{
ret = read(sock_fd,buf,sizeof(buf));
if(ret <= 0)
{
((int*)aSock)[Read1Err] = ret;
fprintf( (FILE*)(((int*)aSock)[2]), "READING SocketRead END - have read = %d \n",ret);
}
else
{
fprintf( (FILE*)(((int*)aSock)[2]), "READING SocketRead END - have read = %d and %s\n",ret,buf);
}
}
else if(ret == -1)
{
fprintf( (FILE*)(((int*)aSock)[2]), "READING SocketRead ERROR END - have read = %d \n",ret);
((int*)aSock)[Read1Err] = ret;
}
return aSock;
}
TInt CTestSelect::TestSocketDesc3()
{
// __UHEAP_MARK;
int ret;
char buf[50];
fd_set fds;
FD_ZERO(&fds);
int sock_fds[10];
int listen_sock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in host,dest;
pthread_t client1, client2, sockwrite1, sockwrite2, sockread1, pipewrite, sockreadwrite;
int err = KErrNone;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FILE* outFile = fopen("c:\\logs\\TestSocketDesc3.txt", "w+");
sock_fds[2] = (int)outFile;
host.sin_port = htons(5002);
host.sin_family = AF_INET;
host.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(listen_sock,(struct sockaddr*)&host,sizeof(host));
if(ret<0)
{
INFO_PRINTF1(_L("Error in bind\n"));
return KErrGeneral ;
}
ret = listen(listen_sock,1);
if(ret<0)
{
INFO_PRINTF1(_L("Error in listen\n"));
return KErrGeneral ;
}
unsigned size = sizeof(host);
/*************************** First Client Connection ***************************/
ret = pthread_create(&client1,(pthread_attr_t*)NULL,&CreateConnection,NULL);
if(ret<0)
{
INFO_PRINTF2(_L("Error creating thread for client1:%d\n"),errno);
return KErrGeneral ;
}
// This socket monitored by 4 threads - two for read, and two for write.
sock_fds[0] = accept(listen_sock,(struct sockaddr*)&dest,&size);
/********************************************************************************/
/*************************** Second Client Connection ***************************/
ret = pthread_create(&client2,(pthread_attr_t*)NULL,&CreateConnection,NULL);
if(ret<0)
{
INFO_PRINTF2(_L("Error creating thread for client2:%d\n"),errno);
return KErrGeneral ;
}
// This socket monitored by 2 threads - one for read, and one for write.
sock_fds[1] = accept(listen_sock,(struct sockaddr*)&dest,&size);
/********************************************************************************/
/*************************** Pipe Creation and Writing **************************/
int fd[2];
//char buf1[50]= "Write from main thread";
INFO_PRINTF1(_L("Before Pipe "));
if ( pipe(fd) < 0 )
{
return KErrGeneral;
}
// write(fd[1],buf1,sizeof(buf1));
sock_fds[PipeReadDesc] = fd[0];
sock_fds[PipeWriteDesc]= fd[1];
/********************************************************************************/
// Creating the 1st Read thread.
ret = pthread_create(&sockread1,(pthread_attr_t*)NULL,&SocketRead1,sock_fds);
// sleep(3);
// Creating the Read/Write thread.
ret = pthread_create(&sockreadwrite,(pthread_attr_t*)NULL,&SocketReadWrite,sock_fds);
// Creating the 1st Write thread.
ret = pthread_create(&sockwrite1,(pthread_attr_t*)NULL,&SocketWrite1,sock_fds);
if(ret<0)
{
INFO_PRINTF2(_L("Error creating thread for Write1:%d\n"),errno);
return KErrGeneral ;
}
// Creating the 2nd Write thread.
ret = pthread_create(&sockwrite2,(pthread_attr_t*)NULL,&SocketWrite2,sock_fds);
// Creating the 3rd Write thread.
ret = pthread_create(&pipewrite,(pthread_attr_t*)NULL,&PipeWrite,sock_fds);
// The 2nd Read thread.
FD_SET(sock_fds[0],&fds);
ret = select(sock_fds[0]+1,&fds,NULL,NULL,&timeout);
if (ret && FD_ISSET(sock_fds[0],&fds))
{
ret = read(sock_fds[0],buf,sizeof(buf));
if(ret > 0)
{
fprintf(outFile,"READING socket main END - have read = %d and %s\n",ret,buf);
//INFO_PRINTF3(_L("READING socket main END - have read = %d and %s\n"),ret,buf);
}
else
{
fprintf(outFile,"READING socket main END - have read = %d \n",ret);
//INFO_PRINTF2(_L("READING socket main END - have read = %d \n"),ret);
}
}
else
{
fprintf(outFile,"READING socket main ERROR END - have read = %d \n",ret);
//INFO_PRINTF2(_L("READING socket main ERROR END - have read = %d \n"),ret);
}
pthread_join(sockwrite1,(void**)&sock_fds);
if(KErrNone != sock_fds[Write1Err])
{
err = KErrGeneral ;
}
pthread_join(sockread1,(void**)&sock_fds);
if(KErrNone != sock_fds[Read1Err] && KErrNone == err)
{
err = KErrGeneral ;
}
pthread_join(client1,(void**)NULL);
pthread_join(sockreadwrite,(void**)&sock_fds);
if((KErrNone != sock_fds[ReadWriteErr1] || KErrNone != sock_fds[ReadWriteErr2]) && KErrNone == err)
{
err = KErrGeneral ;
}
pthread_join(sockwrite2,(void**)&sock_fds);
if(KErrNone != sock_fds[Write2Err] && KErrNone == err)
{
err = KErrGeneral ;
}
pthread_join(client2,(void**)NULL);
pthread_join(pipewrite,(void**)&sock_fds);
if(KErrNone != sock_fds[Write2Err] && KErrNone == err)
{
err = KErrGeneral ;
}
close(sock_fds[0]);
close(sock_fds[1]);
fclose(outFile);
close(fd[0]);
close(fd[1]);
close(listen_sock);
// __UHEAP_MARKEND;
return err;
}
TInt CTestSelect::TestMultipleDesc()
{
return KErrNone;
}
TInt CTestSelect::TestConnectErrorDesc()
{
TInt ret = KErrGeneral;
struct sockaddr_in host;
int dest_fd;
host.sin_port = htons(122);
host.sin_family = AF_INET;
host.sin_addr.s_addr = inet_addr("127.0.0.1");
dest_fd = socket(AF_INET,SOCK_STREAM,0);
TInt blocking;
if(!GetIntFromConfig(ConfigSection(), _L("blocking"),blocking ))
{
ERR_PRINTF1(_L("Reading case from .ini fails"));
return ret;
}
if(blocking == 0)
{
fcntl( dest_fd, F_SETFL, O_NONBLOCK );
}
ret = connect(dest_fd,(struct sockaddr*)&host,sizeof(host));
if(ret == -1)
{
INFO_PRINTF2(_L("Connect errno value is %d\n"), errno);
if((blocking == 0) && (errno != EINPROGRESS))
return KErrGeneral;
}
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
FD_ZERO(&writefds);
FD_SET(dest_fd, &writefds);
FD_ZERO(&readfds);
FD_SET(dest_fd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(dest_fd, &exceptfds);
int maxfd = dest_fd + 1;
ret = select(maxfd, &readfds, &writefds, NULL,NULL);
if(ret == -1)
{
INFO_PRINTF2(_L("select errno value is %d\n"), errno);
return KErrGeneral;
}
else
{
INFO_PRINTF2(_L("select ret value is %d\n"), ret);
}
FD_ZERO(&writefds);
FD_SET(dest_fd, &writefds);
FD_ZERO(&readfds);
FD_SET(dest_fd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(dest_fd, &exceptfds);
ret = select(maxfd, &readfds, NULL, &exceptfds, NULL);
if(ret == -1)
{
INFO_PRINTF2(_L("select errno value is %d\n"), errno);
return KErrGeneral;
}
else
{
INFO_PRINTF2(_L("select ret value is %d\n"), ret);
}
FD_ZERO(&writefds);
FD_SET(dest_fd, &writefds);
FD_ZERO(&readfds);
FD_SET(dest_fd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(dest_fd, &exceptfds);
ret = select(maxfd, NULL, &writefds, &exceptfds, NULL);
if(ret == -1)
{
INFO_PRINTF2(_L("select errno value is %d\n"), errno);
return KErrGeneral;
}
else
{
INFO_PRINTF2(_L("select ret value is %d\n"), ret);
}
FD_ZERO(&writefds);
FD_SET(dest_fd, &writefds);
FD_ZERO(&readfds);
FD_SET(dest_fd, &readfds);
FD_ZERO(&exceptfds);
FD_SET(dest_fd, &exceptfds);
ret = select(maxfd, NULL, NULL, &exceptfds, NULL);
if(ret == -1)
{
INFO_PRINTF2(_L("select errno value is %d\n"), errno);
return KErrGeneral;
}
else
{
INFO_PRINTF2(_L("select ret value is %d\n"), ret);
}
ret = connect(dest_fd,(struct sockaddr*)&host,sizeof(host));
if(ret == -1)
{
INFO_PRINTF2(_L("Connect errno value is %d\n"), errno);
}
close(dest_fd);
return 0;
}
TInt CTestSelect::TestSelectOnBadPipeEnd1()
{
int fds[2],rc,max;
fd_set readfds,writefds;
if (pipe(fds) == -1)
{
INFO_PRINTF1(_L("Pipe creation failed!\n")) ;
}
/* fds[0] - opened for read */
/* fds[1] - opened for write */
write(fds[1],"hello",5); // Writing data onto the pipe, thus setting the read event bit
if(fds[0] > fds[1])
max = fds[0] + 1;
else
max = fds[1] + 1;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(fds[0],&readfds);
FD_SET(fds[0],&writefds); // issue here is:-- trying to set the write operation bit on the fixed read end of the pipe
// OR.. FD_SET(fds[1],&writefds); FD_SET(fds[1],&readfds); //similar issue here is:-- trying to set the read operation bit on the fixed write end of the pipe
rc = select(max,&readfds,&writefds, NULL, NULL);
if (rc == -1)
{
INFO_PRINTF1(_L("select failed\n")) ;
return KErrGeneral ;
}
else
{
if(FD_ISSET(fds[0],&readfds))
INFO_PRINTF1(_L("ready for reading\n\n")) ;
}
INFO_PRINTF2(_L("Return value from select is %d\n"), rc);
close(fds[0]);
close(fds[1]);
return 0;
}
////One more Test case added to check for writability at the read end of the pipe or readability for the write end of the pipe while notifying the event
void *WritingToPipe(void * p)
{
int *fd;
fd = (int *)p;
sleep(3);
write( *(fd + 1),"hello",5);
return 0;
}
TInt CTestSelect::TestSelectOnBadPipeEnd2()
{
int fds[2],rc, max, *p,t;
fd_set readfds,writefds;
pthread_t threads1;
int threadRetVal = 0;
if (pipe(fds) == -1)
{
INFO_PRINTF1(_L("Pipe creation failed!\n")) ;
}
p = &fds[0];
/* fds[0] - opened for read */
/* fds[1] - opened for write */
// creating the new thread for writing data onto the pipe when select is actually waiting for someone to write into the pipe
t = pthread_create(&threads1, NULL, WritingToPipe, (void *)p);
if (t)
{
INFO_PRINTF2(_L("ERROR; return code from pthread_create() is %d\n"), t);
}
if(fds[0] > fds[1])
max = fds[0] + 1;
else
max = fds[1] + 1;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(fds[0],&readfds);
FD_SET(fds[0],&writefds); // issue here is:-- trying to set the write operation bit on the fixed read end of the pipe
// OR.. FD_SET(fds[1],&writefds); FD_SET(fds[1],&readfds); // similar issue here is:-- trying to set the read operation bit on the fixed write end of the pipe
const int timeout = 5000; // 5 seconds
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
rc = select(max,&readfds,&writefds, NULL, &tv);
if (rc == -1)
{
INFO_PRINTF1(_L("select failed\n")) ;
return KErrGeneral ;
}
else
{
if(FD_ISSET(fds[0],&readfds))
INFO_PRINTF1(_L("ready for reading\n\n")) ;
}
INFO_PRINTF2(_L("Return value from select is %d\n"), rc);
pthread_join(threads1, (void**)threadRetVal);
close(fds[0]);
close(fds[1]);
return 0;
}
/* -----------------------------------------------------------------------------
*Function Name :TestSelectLargeFd
*API Tested :select()
*TestCase Description:Testing the behaviour of select with nfds set to FD_SETSIZE.
*(FD_SETSIZE is macro whose value is the maximum number of file descriptors that a fd_set object can hold information about.)
* -----------------------------------------------------------------------------
*/
TInt CTestSelect::TestSelectLargeFd()
{
struct timeval to;
to.tv_sec = 0;
to.tv_usec = 100;
fd_set readfds;
FD_ZERO(&readfds);
TInt ret = KErrGeneral;
TInt fd;
if(!GetIntFromConfig(ConfigSection(), _L("fd"),fd ))
{
ERR_PRINTF1(_L("Reading case from .ini fails"));
return ret;
}
TInt retVal = select(fd, &readfds, NULL, NULL, &to);
TInt expVal;
if(!GetIntFromConfig(ConfigSection(), _L("expVal"),expVal ))
{
ERR_PRINTF1(_L("Reading case from .ini fails"));
return ret;
}
TInt err;
if(!GetIntFromConfig(ConfigSection(), _L("err"),err ))
{
ERR_PRINTF1(_L("Reading case from .ini fails"));
return ret;
}
if(retVal != expVal && errno != err)
{
ERR_PRINTF4(_L("Expected: %d and Result: %d ,errno: %d"),expVal, retVal,errno);
return ret;
}
ret = KErrNone ;
return ret ;
}
/* -----------------------------------------------------------------------------
*Function Name :TestSelectRedirDescWrite
*API Tested :select()
*TestCase Description:Testing the behaviour of select with redir desc as the fd
* -----------------------------------------------------------------------------
*/
TInt CTestSelect::TestSelectRedirDescWrite()
{
TBool stdinpass = EFalse;
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
int maxfd = STDIN_FILENO;
// int select_ret = 0;
maxfd = STDIN_FILENO;
FD_ZERO(&writefds);
FD_SET(STDIN_FILENO,&writefds);
/*select_ret =*/ select(maxfd+1,&readfds,&writefds,&exceptfds,NULL);
if( FD_ISSET(STDIN_FILENO,&writefds) )
{
stdinpass = ETrue;
INFO_PRINTF1(_L("select on writefds of STDIN passed\n")) ;
}
else
{
INFO_PRINTF1(_L("select on writefds of STDIN failed\n")) ;
return KErrGeneral;
}
maxfd = STDOUT_FILENO;
FD_ZERO(&writefds);
FD_SET(STDOUT_FILENO,&writefds);
/*select_ret = */ select(maxfd+1,NULL,&writefds,NULL,NULL);
if( FD_ISSET(STDOUT_FILENO,&writefds) )
{
if( stdinpass )
{
INFO_PRINTF1(_L("select on writefds of STDOUT passed\n")) ;
return KErrNone;
}
else
{
INFO_PRINTF1(_L("select on writefds of STDOUT failed\n")) ;
}
}
return KErrGeneral;
}
/* -----------------------------------------------------------------------------
*Function Name :TestSelectConnectFailure
*API Tested :select()
*TestCase Description:Testing the behaviour of select on non blocking socket
*when connect fails
* -----------------------------------------------------------------------------
*/
TInt CTestSelect::TestSelectConnectFailure()
{
// Loop back
char *addr="127.0.0.1";
int sock_fd;
int check = 0;
int flags;
fd_set writefds;
fd_set readfds;
fd_set exceptfds;
int max;
int select_ret = 0;
// int ret = KErrGeneral;
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(addr);
serv_addr.sin_port = htons(80);
sock_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (-1 == (flags = fcntl(sock_fd, F_GETFL, 0)))
{
flags = 0;
}
check = fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
if ( check != -1 )
{
connect(sock_fd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
}
max = sock_fd + 1;
// readfds,writefds and exceptfds are requested
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(sock_fd, &readfds);
FD_SET(sock_fd, &writefds);
FD_SET(sock_fd, &exceptfds);
select_ret = select(max,&readfds,&writefds,&exceptfds,NULL);
if( !(select_ret == 3 && FD_ISSET(sock_fd,&readfds)
&& FD_ISSET(sock_fd,&writefds) && FD_ISSET(sock_fd,&exceptfds)) )
{
return KErrGeneral;
}
// readfds and writefds are requested
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(sock_fd, &readfds);
FD_SET(sock_fd, &writefds);
select_ret = select(max,&readfds,&writefds,NULL,NULL);
if(!(select_ret == 2 && FD_ISSET(sock_fd,&readfds)
&& FD_ISSET(sock_fd,&writefds)))
{
return KErrGeneral;
}
// Only readfds is requested
FD_ZERO(&readfds);
FD_SET(sock_fd, &readfds);
select_ret = select(max,&readfds,NULL,NULL,NULL);
if(!(select_ret == 1 && FD_ISSET(sock_fd,&readfds)))
{
return KErrGeneral;
}
// Only writefds is requested
FD_ZERO(&writefds);
FD_SET(sock_fd, &writefds);
select_ret = select(max,NULL,&writefds,NULL,NULL);
if(!(select_ret == 1 && FD_ISSET(sock_fd,&writefds)))
{
return KErrGeneral;
}
return KErrNone;
}