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
7: This code has not been tested on all machines, the function prototypes may not
8: exist for certain systems. Only compiles as C code.
9: */
11: #include petsc.h
12: #include petscsys.h
14: #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS)
15: /* Some systems have inconsistent include files that use but don't
16: ensure that the following definitions are made */
17: typedef unsigned char u_char;
18: typedef unsigned short u_short;
19: typedef unsigned int u_int;
20: typedef unsigned long u_long;
21: #endif
23: #include <errno.h>
24: #if defined(PETSC_HAVE_STDLIB_H)
25: #include <stdlib.h>
26: #endif
27: #include <sys/types.h>
28: #include <ctype.h>
29: #if defined(PETSC_HAVE_MACHINE_ENDIAN_H)
30: #include <machine/endian.h>
31: #endif
32: #if defined(PETSC_HAVE_UNISTD_H)
33: #include <unistd.h>
34: #endif
35: #if !defined(PARCH_win32)
36: #include <sys/socket.h>
37: #include <sys/wait.h>
38: #include <netinet/in.h>
39: #include <netdb.h>
40: #include <fcntl.h>
41: #if defined(PETSC_HAVE_STROPTS_H)
42: #include <stropts.h>
43: #endif
44: #if defined (PETSC_HAVE_IO_H)
45: #include <io.h>
46: #endif
47: #if defined(PETSC_HAVE_SYS_UTSNAME_H)
48: #include <sys/utsname.h>
49: #endif
50: #if defined(PETSC_HAVE_STRINGS_H)
51: #include <strings.h>
52: #endif
54: #include src/sys/src/viewer/impls/socket/socket.h
55: #include "petscfix.h"
56: #include "mex.h"
58: EXTERN int SOCKConnect_Private(int);
59: #define ERROR(a) {fprintf(stdout,"OPENPORT: %s n",a); return ;}
60: /*-----------------------------------------------------------------*/
61: /* */
62: /*-----------------------------------------------------------------*/
63: #undef __FUNCT__
65: void mexFunction(int nlhs,Matrix *plhs[],int nrhs,Matrix *prhs[])
66: {
67: int t,portnumber;
69: /* check output parameters */
70: if (nlhs != 1) ERROR("Open requires one output argument.");
72: /* figure out portnumber user wants to use; default to 5005 */
73: if (!nrhs) {
74: char *str;
75: str = getenv("PETSC_VIEWER_SOCKET_PORT");
76: if (str) portnumber = atoi(str);
77: else portnumber = DEFAULTPORT;
78: } else {
79: portnumber = (int)*mxGetPr(prhs[0]);
80: }
82: /* open connection */
83: t = SOCKConnect_Private(portnumber); if (t == -1) ERROR("opening socket");
85: plhs[0] = mxCreateFull(1,1,mxREAL);
86:
87: *mxGetPr(plhs[0]) = t;
88: return;
89: }
91: /*-----------------------------------------------------------------*/
92: /* The listenport variable is an ugly hack. If the user hits a */
93: /* control c while we are listening then we stop listening */
94: /* but do not close the listen. Therefore if we try to bind again */
95: /* and get an address in use, close the listen which was left */
96: /* hanging; the problem is if the user uses several portnumbers */
97: /* and control c we may not be able to close the correct listener. */
98: static int listenport;
99: /*-----------------------------------------------------------------*/
100: extern int establish(u_short);
101: #undef __FUNCT__
103: int SOCKConnect_Private(int portnumber)
104: {
105: struct sockaddr_in isa;
106: #if defined(PETSC_HAVE_ACCEPT_SIZE_T)
107: size_t i;
108: #else
109: int i;
110: #endif
111: int t;
113: /* open port*/
114: listenport = establish((u_short) portnumber);
115: if (listenport == -1) {
116: fprintf(stdout,"RECEIVE: unable to establish portn");
117: return -1;
118: }
120: /* wait for someone to try to connect */
121: i = sizeof(struct sockaddr_in);
122: if ((t = accept(listenport,(struct sockaddr *)&isa,&i)) < 0) {
123: fprintf(stdout,"RECEIVE: error from acceptn");
124: return(-1);
125: }
126: close(listenport);
127: return(t);
128: }
129: /*-----------------------------------------------------------------*/
130: #define MAXHOSTNAME 100
131: #undef __FUNCT__
133: int establish(u_short portnum)
134: {
135: char myname[MAXHOSTNAME+1];
136: int s,ierr;
137: struct sockaddr_in sa;
138: struct hostent *hp;
139: struct utsname utname;
141: /* Note we do not use gethostname since that is not POSIX */
142: uname(&utname); strncpy(myname,utname.nodename,MAXHOSTNAME);
143: bzero(&sa,sizeof(struct sockaddr_in));
144: hp = gethostbyname(myname);
145: if (hp == NULL) {
146: fprintf(stdout,"RECEIVE: error from gethostbynamen");
147: return(-1);
148: }
150: sa.sin_family = hp->h_addrtype;
151: sa.sin_port = htons(portnum);
153: if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
154: fprintf(stdout,"RECEIVE: error from socketn");
155: return(-1);
156: }
157: {
158: int optval = 1; /* Turn on the option */
159: setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&optval,sizeof(optval));
160: }
162: while (bind(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) {
163: if (errno != EADDRINUSE) {
164: close(s);
165: fprintf(stdout,"RECEIVE: error from bindn");
166: return(-1);
167: }
168: close(listenport);
169: }
170: listen(s,0);
171: return(s);
172: }
173: #endif
174: