Actual source code: openport.c

  1: /*$Id: openport.c,v 1.24 2001/03/23 23:19:53 balay Exp $*/
  2: /* 
  3:   Usage: A = openport(portnumber);  [ 5000 < portnumber < 5010 ]
  4:  
  5:         Written by Barry Smith, bsmith@mcs.anl.gov 4/14/92
  6:          Updated by Ridhard Katz, katz@ldeo.columbia.edu 9/28/03

  8:    This code has not been tested on all machines, the function prototypes may not
  9: exist for certain systems. Only compiles as C code.
 10: */

 12:  #include petsc.h
 13:  #include petscsys.h

 15: #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS)
 16: /* Some systems have inconsistent include files that use but don't
 17:    ensure that the following definitions are made */
 18: typedef unsigned char   u_char;
 19: typedef unsigned short  u_short;
 20: typedef unsigned int    u_int;
 21: typedef unsigned long   u_long;
 22: #endif

 24: #include <errno.h>
 25: #if defined(PETSC_HAVE_STDLIB_H)
 26: #include <stdlib.h>
 27: #endif
 28: #include <sys/types.h>
 29: #include <ctype.h>
 30: #if defined(PETSC_HAVE_MACHINE_ENDIAN_H)
 31: #include <machine/endian.h>
 32: #endif
 33: #if defined(PETSC_HAVE_UNISTD_H)
 34: #include <unistd.h>
 35: #endif
 36: #if !defined(PARCH_win32)
 37: #include <sys/socket.h>
 38: #include <sys/wait.h>
 39: #include <netinet/in.h>
 40: #include <netdb.h>
 41: #include <fcntl.h>
 42: #if defined(PETSC_HAVE_STROPTS_H)
 43: #include <stropts.h>
 44: #endif
 45: #if defined (PETSC_HAVE_IO_H)
 46: #include <io.h>
 47: #endif
 48: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
 49: #include <sys/utsname.h>
 50: #endif
 51: #if defined(PETSC_HAVE_STRINGS_H)
 52: #include <strings.h>
 53: #endif

 55:  #include src/sys/src/viewer/impls/socket/socket.h
 56: #include "petscfix.h"
 57: #include "mex.h"

 59: EXTERN int SOCKConnect_Private(int);
 60: #define ERROR(a) {fprintf(stdout,"OPENPORT: %s \n",a); return ;}
 61: /*-----------------------------------------------------------------*/
 62: /*                                                                 */
 63: /*-----------------------------------------------------------------*/
 66: void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
 67: {
 68:   int t,portnumber;

 70:   /* check output parameters */
 71:   if (nlhs != 1) ERROR("Open requires one output argument.");

 73:   /* figure out portnumber user wants to use; default to 5005 */
 74:   if (!nrhs) {
 75:     char *str;
 76:     str = getenv("PETSC_VIEWER_SOCKET_PORT");
 77:     if (str) portnumber = atoi(str);
 78:     else portnumber = DEFAULTPORT;
 79:   } else {
 80:     portnumber = (int)*mxGetPr(prhs[0]);
 81:   }

 83:   /* open connection */
 84:   t = SOCKConnect_Private(portnumber); if (t == -1)  ERROR("opening socket");

 86:   plhs[0]  = mxCreateDoubleMatrix(1,1,mxREAL);
 87: 
 88:   *mxGetPr(plhs[0]) = t;
 89:   return;
 90: }

 92: /*-----------------------------------------------------------------*/
 93: /* The listenport variable is an ugly hack. If the user hits a         */
 94: /* control c while we are listening then we stop listening         */
 95: /* but do not close the listen. Therefore if we try to bind again  */
 96: /* and get an address in use, close the listen which was left      */
 97: /* hanging; the problem is if the user uses several portnumbers    */
 98: /* and control c we may not be able to close the correct listener. */
 99: static int listenport;
100: /*-----------------------------------------------------------------*/
101: extern int establish(u_short);
104: int SOCKConnect_Private(int portnumber)
105: {
106:   struct sockaddr_in isa;
107: #if defined(PETSC_HAVE_ACCEPT_SIZE_T)
108:   size_t             i;
109: #else
110:   int                i;
111: #endif
112:   int                t;

114: /* open port*/
115:   listenport = establish((u_short) portnumber);
116:   if (listenport == -1) {
117:        fprintf(stdout,"RECEIVE: unable to establish port\n");
118:        return -1;
119:   }

121: /* wait for someone to try to connect */
122:   i = sizeof(struct sockaddr_in);
123:   if ((t = accept(listenport,(struct sockaddr *)&isa,(socklen_t *)&i)) < 0) {
124:      fprintf(stdout,"RECEIVE: error from accept\n");
125:      return(-1);
126:   }
127:   close(listenport);
128:   return(t);
129: }
130: /*-----------------------------------------------------------------*/
131: #define MAXHOSTNAME 100
134: int establish(u_short portnum)
135: {
136:   char               myname[MAXHOSTNAME+1];
137:   int                s,ierr;
138:   struct sockaddr_in sa;
139:   struct hostent     *hp;
140:   struct utsname     utname;

142:   /* Note we do not use gethostname since that is not POSIX */
143:   uname(&utname); strncpy(myname,utname.nodename,MAXHOSTNAME);
144:   bzero(&sa,sizeof(struct sockaddr_in));
145:   hp = gethostbyname(myname);
146:   if (hp == NULL) {
147:      fprintf(stdout,"RECEIVE: error from gethostbyname\n");
148:      return(-1);
149:   }

151:   sa.sin_family = hp->h_addrtype;
152:   sa.sin_port = htons(portnum);

154:   if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
155:      fprintf(stdout,"RECEIVE: error from socket\n");
156:      return(-1);
157:   }
158:   {
159:   int optval = 1; /* Turn on the option */
160:   setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&optval,sizeof(optval));
161:   }

163:   while (bind(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) {
164:      if (errno != EADDRINUSE) {
165:         close(s);
166:         fprintf(stdout,"RECEIVE: error from bind\n");
167:         return(-1);
168:      }
169:      close(listenport);
170:   }
171:   listen(s,0);
172:   return(s);
173: }
174: #endif    
175: