--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/libc/test/testselect/src/tselectblocks.cpp Fri Jun 04 16:20:51 2010 +0100
@@ -0,0 +1,1118 @@
+/*
+* 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;
+ }
+