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: