This is Unofficial EPICS BASE Doxygen Site
osdSock.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE Versions 3.13.7
7 * and higher are distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 /* osdSock.c */
11 /*
12  * Author: Jeff Hill
13  * Date: 04-05-94
14  *
15  */
16 
17 #include <ctype.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 
24 #include "epicsThread.h"
25 #include "epicsEvent.h"
26 #include "epicsMutex.h"
27 #include "osiSock.h"
28 #include "epicsAssert.h"
29 #include "errlog.h"
30 
31 /*
32  * Protect some routines which are not thread-safe
33  */
34 static epicsMutexId infoMutex;
35 static void createInfoMutex (void *unused)
36 {
37  infoMutex = epicsMutexMustCreate ();
38 }
39 static void lockInfo (void)
40 {
41  static epicsThreadOnceId infoMutexOnceFlag = EPICS_THREAD_ONCE_INIT;
42 
43  epicsThreadOnce (&infoMutexOnceFlag, createInfoMutex, NULL);
44  epicsMutexMustLock (infoMutex);
45 }
46 static void unlockInfo (void)
47 {
48  epicsMutexUnlock (infoMutex);
49 }
50 
51 /*
52  * NOOP
53  */
55 {
56  return 1;
57 }
58 
59 /*
60  * NOOP
61  */
63 {
64 }
65 
66 /*
67  * this version sets the file control flags so that
68  * the socket will be closed if the user uses exec()
69  * as is the case with third party tools such as TCL/TK
70  */
71 LIBCOM_API SOCKET epicsStdCall epicsSocketCreate (
72  int domain, int type, int protocol )
73 {
74  SOCKET sock = socket ( domain, type, protocol );
75  if ( sock < 0 ) {
76  sock = INVALID_SOCKET;
77  }
78  else {
79  int status = fcntl ( sock, F_SETFD, FD_CLOEXEC );
80  if ( status < 0 ) {
81  char buf [ 64 ];
82  epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) );
83  errlogPrintf (
84  "epicsSocketCreate: failed to "
85  "fcntl FD_CLOEXEC because \"%s\"\n",
86  buf );
87  close ( sock );
88  sock = INVALID_SOCKET;
89  }
90  }
91  return sock;
92 }
93 
94 LIBCOM_API int epicsStdCall epicsSocketAccept (
95  int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen )
96 {
97  int newSock = accept ( sock, pAddr, addrlen );
98  if ( newSock < 0 ) {
99  newSock = INVALID_SOCKET;
100  }
101  else {
102  int status = fcntl ( newSock, F_SETFD, FD_CLOEXEC );
103  if ( status < 0 ) {
104  char buf [ 64 ];
105  epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) );
106  errlogPrintf (
107  "epicsSocketCreate: failed to "
108  "fcntl FD_CLOEXEC because \"%s\"\n",
109  buf );
110  close ( newSock );
111  newSock = INVALID_SOCKET;
112  }
113  }
114  return newSock;
115 }
116 
117 LIBCOM_API void epicsStdCall epicsSocketDestroy ( SOCKET s )
118 {
119  int status = close ( s );
120  if ( status < 0 ) {
121  char buf [ 64 ];
122  epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) );
123  errlogPrintf (
124  "epicsSocketDestroy: failed to "
125  "close a socket because \"%s\"\n",
126  buf );
127  }
128 }
129 
130 /*
131  * ipAddrToHostName
132  * On many systems, gethostbyaddr must be protected by a
133  * mutex since the routine is not thread-safe.
134  */
135 LIBCOM_API unsigned epicsStdCall ipAddrToHostName
136  (const struct in_addr *pAddr, char *pBuf, unsigned bufSize)
137 {
138  struct hostent *ent;
139  int ret = 0;
140 
141  if (bufSize<1) {
142  return 0;
143  }
144 
145  lockInfo ();
146  ent = gethostbyaddr((const char *) pAddr, sizeof (*pAddr), AF_INET);
147  if (ent) {
148  strncpy (pBuf, ent->h_name, bufSize);
149  pBuf[bufSize-1] = '\0';
150  ret = strlen (pBuf);
151  }
152  unlockInfo ();
153  return ret;
154 }
155 
156 /*
157  * hostToIPAddr ()
158  * On many systems, gethostbyname must be protected by a
159  * mutex since the routine is not thread-safe.
160  */
161 LIBCOM_API int epicsStdCall hostToIPAddr
162  (const char *pHostName, struct in_addr *pIPA)
163 {
164  struct hostent *phe;
165  int ret = -1;
166 
167  lockInfo ();
168  phe = gethostbyname (pHostName);
169  if (phe && phe->h_addr_list[0]) {
170  if (phe->h_addrtype==AF_INET && phe->h_length<=sizeof(struct in_addr)) {
171  struct in_addr *pInAddrIn = (struct in_addr *) phe->h_addr_list[0];
172 
173  *pIPA = *pInAddrIn;
174  ret = 0;
175  }
176  }
177  unlockInfo ();
178  return ret;
179 }
180 
181 
182 
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
#define INVALID_SOCKET
Definition: osdSock.h:32
pvd::Status status
An EPICS-specific replacement for ANSI C&#39;s assert.
int osiSocklen_t
Definition: osdSock.h:36
void osiSockRelease()
Definition: osdSock.c:62
pvd::StructureConstPtr type
LIBCOM_API int epicsStdCall hostToIPAddr(const char *pHostName, struct in_addr *pIPA)
Definition: osdSock.c:162
#define epicsMutexMustCreate()
Create an epicsMutex semaphore for use from C code.
Definition: epicsMutex.h:179
#define NULL
Definition: catime.c:38
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
Definition: osdSock.c:71
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
LIBCOM_API int epicsStdCall epicsSocketAccept(int sock, struct sockaddr *pAddr, osiSocklen_t *addrlen)
Definition: osdSock.c:94
int SOCKET
Definition: osdSock.h:31
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
APIs for the epicsEvent binary semaphore.
int osiSockAttach()
Definition: osdSock.c:54
LIBCOM_API unsigned epicsStdCall ipAddrToHostName(const struct in_addr *pAddr, char *pBuf, unsigned bufSize)
Definition: osdSock.c:136
C++ and C descriptions for a thread.
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214