/*=========================================================================== Copyright (C) 1995-2005 European Southern Observatory (ESO) This program 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 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME atestosx.c .LANGUAGE C .AUTHOR Carlos Guirao. IPG-ESO Garching .CATEGORY Tests of host operating system interfaces. .COMMENTS Automatic osx test. This test exercises the functions of the module "osx". .REMARKS A hanged condition has been detected for this test. It happens when a procces is waiting for data to come from a socket, and the connection is already stablished with a sender. If the sender, for any reason, denies the data, the procces will hang forever (or CTRL-C). SIGALRM does not work for this porpose because the system call "read" ignores it when there is a stablished connection. .ENVIRONment UNIX .VERSION 1.1 05-Jul-1990 Implementation C. Guirao 051021 last modif ------------------------------------------------------------*/ #include #include #include #include #include #include #include #ifndef S_IFSOCK /* defined in stat.h if Unix domain sockets */ static char socket_name[] = "00"; /* for PC/SCO without local sockets */ # define OSX_OPEN_MODE NETW #else static char socket_name[] = "/tmp/mtape"; # define OSX_OPEN_MODE LOCAL #endif #define LOWER 0 #define UPPER 1 #define PATTERNA '0' #define PATTERNB 'a' #define PATTERNC 'B' #define PATTERND 'b' char *osmsg(); #define PERROR { printf("\tERROR: %s\n",osmsg()); ospexit(1); } #define PRINTF(string) { fflush(stdout); printf(string); fflush(stdout); sleep(1); } #define SIZEBUF 1024 char *buf; int sizebuf; void timeout(k) int k; { printf("(TIMEOUT)\n"); exit(-1); } static int readn(fd, ptr, nbytes) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Read "n" bytest from a descriptor. Use in place of read() when fd is a stream socket .RETURNS If succesful, the number of bytes actaully read is returned. Otherwise, a -1 is returned. .REMARKS System dependencies: -- UNIX: read(2) ------------------------------------------------------------*/ register int fd; register char *ptr; register int nbytes; { int nleft, nread; int st; nleft = nbytes; while (nleft > 0) { /* if ( (st = osxinfo(fd,0,0)) == -1) PERROR if (st == NODATA) break; */ nread = osxread(fd, ptr, nleft); if (nread < 0) /* error, return < 0 */ return(nread); nleft -= nread; ptr += nread; } return(nbytes - nleft); /* return >= 0 */ } main(argc,argv) int argc; int **argv; { char input[80], name[80], *pname; int fdn, fd; int nbytes; static char *channame[2]; static struct stat statbuf; int childpid; int st; channame[1]="localhost"; signal(SIGALRM,timeout); printf("**********************************************\n"); printf("****** AUTOMATIC TEST FOR OSX INTERFACE ******\n"); printf("****** LOCAL MODE. USING SOCKETS. ******\n"); printf("**********************************************\n\n"); printf("Deleting socket files: %s if existing... ", socket_name); if (stat(socket_name,&statbuf) == 0 ) if (unlink(socket_name) < 0) PERROR PRINTF("OK\n"); sizebuf=SIZEBUF; printf("Allocating memory for buffers..."); if ( (buf = (char *)malloc((size_t)(sizebuf+1))) == (char *)0) PERROR else printf("OK\n"); /* First step: open & close mode*/ printf("\n************** Testing open & close\n"); printf("Opening a normal file.... "); if ( (fdn = open(socket_name,O_CREAT,S_IREAD|S_IWRITE)) < 0) PERROR else PRINTF("OK\n"); printf("Opening a socket in READ mode, over a normal file.... "); channame[0]=socket_name; if ( (fd = osxopen(channame,LOCAL|IPC_READ)) != -1) { printf("ERROR: Return code != -1\n"); osxclose(fd); ospexit(1); } else PRINTF("OK\n"); printf("Opening a socket in WRITE mode, over a normal file.... "); channame[0]=socket_name; if ( (fd = osxopen(channame,LOCAL|IPC_WRITE)) != -1) { printf("ERROR: Return code != -1\n"); osxclose(fd); ospexit(1); } else PRINTF("OK\n"); printf("Closing and unlinking the normal file.... "); if ( close(fdn) < 0) PERROR if (unlink(socket_name) < 0) PERROR PRINTF("OK\n"); printf("\nOpening a socket in READ mode.... "); channame[0]=socket_name; if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_READ)) == -1) PERROR else PRINTF("OK\n"); printf("Reading status from socket.... "); if ( (st = osxinfo(fd,0,0)) == -1) PERROR if (st == NOCONN) { PRINTF("OK\n"); } else printf("ERROR: Return code != %d\n",NOCONN); printf("Closing the socket in READ mode.... "); if ( osxclose(fd) == -1) PERROR else PRINTF("OK\n"); printf("\nTrying to open a socket in WRITE mode.... "); channame[0]=socket_name; if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_WRITE)) != -1) { printf("ERROR: Return code != -1\n"); osxclose(fd); ospexit(1); } else PRINTF("OK\n"); printf("\nOpening a socket (once).... "); channame[0]=socket_name; if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_READ)) == -1) PERROR else PRINTF("OK\n"); /* PC/SCO with NETW socket returns -1 Address already in use printf("Trying to open the same socket mode (twice).... "); channame[0]=socket_name; if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_READ)) == -1) PERROR else PRINTF("OK\n"); */ printf("Closing the socket (once).... "); if ( osxclose(fd) == -1) PERROR else PRINTF("OK\n"); printf("Trying to close the same socket (twice).... "); if ( osxclose(fd) != -1) { PRINTF("ERROR: Return code != -1\n"); ospexit(1); } else PRINTF("OK\n"); printf("\nOpening a socket in READ mode.... "); channame[0]=socket_name; if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_READ)) == -1) PERROR else PRINTF("OK\n"); printf("Trying to read something... "); fflush(stdout); alarm(5); if ( osxread(fd,buf,1) != -1) { PRINTF("ERROR: Return code != -1\n"); ospexit(1); } else PRINTF("OK\n"); alarm(0); printf("Trying to write something... "); if ( osxwrite(fd,buf,1) != -1) { PRINTF("ERROR: Return code != -1n"); ospexit(1); } else PRINTF("OK\n"); printf("Closing the socket in READ mode.... "); if ( osxclose(fd) == -1) PERROR else PRINTF("OK\n"); printf("\nDoing a fork for server & client \n"); if ( (childpid = fork()) < 0) PERROR else if (childpid == 0) { child_task(); ospexit(0); } father_task(); printf("**********************************************\n"); printf("****** END OF AUTOMATIC TEST FOR OSX ******\n"); printf("****** LOCAL MODE. USING SOCKETS. ******\n"); printf("**********************************************\n\n"); } father_task() { int fd; int nbytes; char *channame[2]; /* This is the father procces */ printf("I am the father.\n"); channame[0]=socket_name; channame[1]="localhost"; printf("\n************** Using client ---> server transfer\n"); if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_READ)) == -1) { printf("Open socket in read mode... FAILED.\n"); PERROR } else printf("Open socket in read mode... OK\n"); PRINTF("Waiting connection from client\n"); alarm(10); while( osxinfo(fd,0,0) == NOCONN ) ; PRINTF("Connection from client... OK\n"); alarm(0); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNA,LOWER)) != SIZEBUF) { PRINTF("Reading pattern A in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern A in socket... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNB,LOWER)) != SIZEBUF) { PRINTF("Reading pattern B in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern B in socket... OK\n"); if ( (nbytes=testread(fd,buf,SIZEBUF/2,PATTERNC,LOWER)) != SIZEBUF/2) { PRINTF("Reading (1/2) pattern C in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern C (1/2) in socket... OK\n"); if ( (nbytes=testread(fd,buf,SIZEBUF/2,PATTERNC,LOWER)) != SIZEBUF/2) { PRINTF("Reading (2/2) pattern C in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern C (2/2) in socket... OK\n"); if ((nbytes=testwrite(fd,buf,SIZEBUF,PATTERNA,LOWER)) != SIZEBUF) { printf("Writting pattern A in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern A in socket... OK\n"); alarm(10); if ( (nbytes = osxread(fd,buf,SIZEBUF)) != 0) { PRINTF("Reading EOF in socket... FAILED.\n"); if (nbytes != -1) printf("%d bytes read !!!\n",nbytes); else PERROR ospexit(1); } else PRINTF("Reading EOF in socket... OK\n"); alarm(0); printf("\n************** Using server ---> client transfer\n"); PRINTF("Waiting connection from client\n"); alarm(10); while( osxinfo(fd,0,0) == NOCONN ) ; PRINTF("Connection from client... OK\n"); alarm(0); if ((nbytes=testwrite(fd,buf,SIZEBUF/2,PATTERNA,LOWER)) != SIZEBUF/2) { printf("Writting pattern A (1/2) in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern A (1/2) in socket... OK\n"); if ((nbytes=testwrite(fd,buf,SIZEBUF/2,PATTERNA,LOWER)) != SIZEBUF/2) { printf("Writting pattern A (2/2) in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern A (2/2) in socket... OK\n"); if ((nbytes=testwrite(fd,buf,SIZEBUF,PATTERNB,LOWER)) != SIZEBUF) { printf("Writting pattern B in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern B in socket... OK\n"); if ((nbytes=testwrite(fd,buf,SIZEBUF,PATTERNC,LOWER)) != SIZEBUF) { printf("Writting pattern C in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern C in socket... OK\n"); alarm(10); if ( (nbytes = osxread(fd,buf,SIZEBUF)) != 0) { PRINTF("Reading EOF in socket... FAILED.\n"); if (nbytes != -1) printf("%d bytes read !!!\n",nbytes); else PERROR ospexit(1); } else PRINTF("Reading EOF in socket... OK\n"); alarm(0); printf("\n************** Using server <--> client transfer\n"); PRINTF("Waiting connection from client\n"); alarm(10); while (osxinfo(fd,0,0) == NOCONN) ; PRINTF("Connection from client... OK\n"); alarm(0); if ((nbytes=testwrite(fd,buf,SIZEBUF,PATTERNB,UPPER)) != SIZEBUF) { printf("Writting pattern B in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern B in socket... OK\n"); if ( (nbytes=testread(fd,buf,SIZEBUF,PATTERNC,LOWER)) != SIZEBUF) { PRINTF("Reading pattern C in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern C in socket... OK\n"); if ( (nbytes=testread(fd,buf,SIZEBUF,PATTERNA,LOWER)) != SIZEBUF) { PRINTF("Reading pattern A in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: Only %d bytes read !!!\n",nbytes); ospexit(1); } else PRINTF("Reading pattern A in socket... OK\n"); if ((nbytes=testwrite(fd,buf,SIZEBUF,PATTERNC,UPPER)) != SIZEBUF) { printf("Writting pattern C in socket... FAILED.\n"); if (nbytes != -1) printf("\tError: only %d bytes written!!!\n",nbytes); ospexit(1); } else printf("Writting pattern C in socket... OK\n"); alarm(10); if ( (nbytes = osxread(fd,buf,SIZEBUF)) != 0) { PRINTF("Reading EOF in socket... FAILED.\n"); if (nbytes != -1) printf("%d bytes read !!!\n",nbytes); else PERROR ospexit(1); } else PRINTF("Reading EOF in socket... OK\n"); alarm(0); if ( osxclose(fd) == -1) { printf("Closing socket write mode... FAILED.\n"); PERROR } printf("Closing socket write mode... OK\n\n"); sleep(2); /* Wait for child to finish */ printf("****** Waiting for child proccess to die\n"); wait(0); printf("****** End of father proccess\n"); } child_task() { int fd; int nbytes; char *channame[2]; printf("I AM THE CHILD.\n"); channame[0]=socket_name; channame[1]="localhost"; alarm(10); while ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_WRITE)) == -1) ; alarm(0); printf("OPEN SOCKET IN WRITE MODE... OK\n"); if ( (nbytes = testwrite(fd,buf,SIZEBUF,PATTERNA,UPPER)) != SIZEBUF) { printf("WRITTING PATTERN A IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES WRITTEN!!!\n",nbytes); ospexit(1); } else printf("WRITTING PATTERN A IN SOCKET... OK\n"); if ( (nbytes = testwrite(fd,buf,SIZEBUF,PATTERNB,UPPER)) != SIZEBUF) { printf("WRITTING PATTERN B IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES WRITTEN!!!\n",nbytes); ospexit(1); } else printf("WRITTING PATTERN B IN SOCKET... OK\n"); if ( (nbytes = testwrite(fd,buf,SIZEBUF,PATTERNC,UPPER)) != SIZEBUF) { printf("WRITTING PATTERN C IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES WRITTEN!!!\n",nbytes); ospexit(1); } else printf("WRITTING PATTERN C IN SOCKET... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNA,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN A IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN A IN SOCKET... OK\n"); if ( osxclose(fd) == -1) { printf("CLOSING THE SOCKET WRITE MODE ... FAILED.\n"); PERROR } printf("CLOSING THE SOCKET WRITE MODE... OK\n"); alarm(10); while ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_WRITE)) == -1) ; printf("OPEN SOCKET IN WRITE MODE... OK\n"); alarm(0); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNA,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN A IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN A IN SOCKET... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNB,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN B IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN B IN SOCKET... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNC,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN C IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN C IN SOCKET... OK\n"); if ( osxclose(fd) == -1) { printf("CLOSING THE SOCKET WRITE MODE ... FAILED.\n"); PERROR } printf("CLOSING THE SOCKET WRITE MODE... OK\n"); /* alarm(10); PRINTF("WAITING DISCONNECTION FROM SERVER... "); if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_WRITE)) == -1) PERROR while( osxread(fd,buf,1) != -1 ) ; PRINTF("OK\n"); alarm(0); */ sleep(2); if ( (fd = osxopen(channame,OSX_OPEN_MODE|IPC_WRITE)) == -1) { printf("OPEN SOCKET IN WRITE MODE... FAILED.\n"); PERROR } else printf("OPEN SOCKET 0 IN WRITE MODE... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNB,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN B IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN B IN SOCKET... OK\n"); if ( (nbytes = testwrite(fd,buf,SIZEBUF,PATTERNC,UPPER)) != SIZEBUF) { printf("WRITTING PATTERN C IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES WRITTEN!!!\n",nbytes); ospexit(1); } else printf("WRITTING PATTERN C IN SOCKET... OK\n"); if ( (nbytes = testwrite(fd,buf,SIZEBUF,PATTERNA,UPPER)) != SIZEBUF) { printf("WRITTING PATTERN A IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES WRITTEN!!!\n",nbytes); ospexit(1); } else printf("WRITTING PATTERN A IN SOCKET... OK\n"); if ( (nbytes = testread(fd,buf,SIZEBUF,PATTERNC,UPPER)) != SIZEBUF) { PRINTF("READING PATTERN C IN SOCKET... FAILED.\n"); if (nbytes != -1) printf("\tERROR: ONLY %d BYTES READ !!!\n",nbytes); ospexit(1); } else PRINTF("READING PATTERN C IN SOCKET... OK\n"); if ( osxclose(fd) == -1) { printf("CLOSING THE SOCKET WRITE MODE ... FAILED.\n"); PERROR } printf("CLOSING THE SOCKET WRITE MODE... OK\n"); sleep(2); printf("****** END OF CHILD PROCCESS\n"); } testread(fd,buffer,size,pattern,type) int fd; char *buffer; int size; char pattern; int type; { int i, j, nbytes; for(i=0; i