ISIS Logo
UTILITIES
EPICS Utilities
freeIPPort.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <errno.h>
5 #include <math.h>
6 #include <exception>
7 #include <algorithm>
8 #include <stdexcept>
9 #include <iostream>
10 #include <map>
11 #include <list>
12 #include <string>
13 #include <time.h>
14 #include <sstream>
15 #include <fstream>
16 
17 #ifdef _WIN32
18 # include <winsock2.h>
19 # include <ws2tcpip.h>
20 #else
21 # include <sys/socket.h>
22 # include <netinet/in.h>
23 # include <unistd.h>
24 # define closesocket close
25 # define SOCKET int
26 #endif
27 
28 #include "epicsStdlib.h"
29 #include "epicsString.h"
30 #include "dbDefs.h"
31 #include "epicsMutex.h"
32 #include "dbBase.h"
33 #include "dbStaticLib.h"
34 #include "dbFldTypes.h"
35 #include "dbCommon.h"
36 #include "dbAccessDefs.h"
37 #include <epicsTypes.h>
38 #include <epicsTime.h>
39 #include <epicsThread.h>
40 #include <epicsString.h>
41 #include <epicsTimer.h>
42 #include <epicsMutex.h>
43 #include <iocsh.h>
44 #include "envDefs.h"
45 #include "macLib.h"
46 #include "errlog.h"
47 
48 #include <string.h>
49 #include <registryFunction.h>
50 
51 #include <epicsExport.h>
52 
53 #include "utilities.h"
54 
55 static int getFreeIPPort()
56 {
57  struct sockaddr_in serv_addr;
58  socklen_t len;
59  int enable = 1;
60  SOCKET sock;
61  int port = 0;
62 // EPICS should already have done this
63 //#ifdef _WIN32
64 // WORD versionWanted = MAKEWORD(1, 1);
65 // WSADATA wsaData;
66 // WSAStartup(versionWanted, &wsaData);
67 //#endif
68  sock = socket(AF_INET, SOCK_STREAM, 0);
69  if(sock < 0) {
70  errlogPrintf("freeIPPort: socket error\n");
71  return port;
72  }
73 #ifdef _WIN32
74  if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE , (char*)&enable, sizeof(enable)) < 0 ) {
75  errlogPrintf("freeIPPort: setsockopt error\n");
76  return port;
77  }
78 #else
79  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(enable)) < 0) {
80  errlogPrintf("freeIPPort: setsockopt error\n");
81  return port;
82  }
83 #endif /* _WIN32 */
84  memset((char *) &serv_addr, 0, sizeof(serv_addr));
85  serv_addr.sin_family = AF_INET;
86  serv_addr.sin_addr.s_addr = INADDR_ANY;
87  serv_addr.sin_port = 0;
88  if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
89  errlogPrintf("freeIPPort: bind error\n");
90  return port;
91  }
92  len = sizeof(serv_addr);
93  if (getsockname(sock, (struct sockaddr *)&serv_addr, &len) == -1) {
94  errlogPrintf("freeIPPort: getsockname error\n");
95  return port;
96  }
97  if (closesocket (sock) == 0 ) {
98  port = ntohs(serv_addr.sin_port);
99  }
100  return port;
101 }
102 
103 epicsShareFunc int freeIPPort(const char* macro)
104 {
105  std::stringstream oss;
106  if (macro != NULL)
107  {
108  oss << getFreeIPPort();
109  epicsEnvSet(macro, oss.str().c_str());
110  }
111  else
112  {
113  errlogPrintf("freeIPPort: please specify a macro to set\n");
114  }
115  return 0;
116 }
117 
118 extern "C" {
119 
120 // EPICS iocsh shell commands
121 
122 static const iocshArg freeIPPortArg0 = { "macro", iocshArgString };
123 static const iocshArg * const freeIPPortArgs[] = { &freeIPPortArg0 };
124 
125 static const iocshFuncDef freeIPPortFuncDef = {"freeIPPort", sizeof(freeIPPortArgs) / sizeof(iocshArg*), freeIPPortArgs};
126 
127 static void freeIPPortCallFunc(const iocshArgBuf *args)
128 {
129  freeIPPort(args[0].sval);
130 }
131 
132 static void freeIPPortRegister(void)
133 {
134  iocshRegister(&freeIPPortFuncDef, freeIPPortCallFunc);
135 }
136 
137 epicsExportRegistrar(freeIPPortRegister); // need to be declared via registrar() in utilities.dbd too
138 
139 }
140 
static void freeIPPortRegister(void)
Definition: freeIPPort.cpp:132
static const iocshArg *const freeIPPortArgs[]
Definition: freeIPPort.cpp:123
epicsShareFunc int freeIPPort(const char *macro)
Definition: freeIPPort.cpp:103
static int getFreeIPPort()
Definition: freeIPPort.cpp:55
static void freeIPPortCallFunc(const iocshArgBuf *args)
Definition: freeIPPort.cpp:127
static const iocshArg freeIPPortArg0
macro to set
Definition: freeIPPort.cpp:122
#define closesocket
Definition: freeIPPort.cpp:24
static const iocshFuncDef freeIPPortFuncDef
Definition: freeIPPort.cpp:125
#define SOCKET
Definition: freeIPPort.cpp:25
epicsExportRegistrar(dbLoadRecordsFuncsRegister)
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5