CUBRID Engine  latest
jsp_comm.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * jsp_comm.c - Functions to communicate with Java Stored Procedure Server
22  *
23  * Note:
24  */
25 
26 #include "config.h"
27 
28 #include <assert.h>
29 #if !defined(WINDOWS)
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <netinet/tcp.h>
35 #include <arpa/inet.h>
36 #include <errno.h>
37 #include <unistd.h>
38 #include <netdb.h>
39 #else /* not WINDOWS */
40 #include <winsock2.h>
41 #include <windows.h>
42 #endif /* not WINDOWS */
43 
44 #include "jsp_comm.h"
45 
46 #include "porting.h"
47 #include "error_manager.h"
48 
49 /*
50  * jsp_connect_server
51  * return: connect fail - return Error Code
52  * connection success - return socket fd
53  *
54  * Note:
55  */
56 
57 SOCKET
59 {
60  struct sockaddr_in tcp_srv_addr;
61  SOCKET sockfd = INVALID_SOCKET;
62  int success = -1;
63  unsigned int inaddr;
64  int b;
65  char *server_host = (char *) "127.0.0.1"; /* assume as local host */
66 
67  union
68  {
69  struct sockaddr_in in;
70  } saddr_buf;
71  struct sockaddr *saddr = (struct sockaddr *) &saddr_buf;
72  socklen_t slen;
73 
74  if (server_port < 0)
75  {
76  return sockfd; /* INVALID_SOCKET (-1) */
77  }
78 
79  inaddr = inet_addr (server_host);
80  memset ((void *) &tcp_srv_addr, 0, sizeof (tcp_srv_addr));
81  tcp_srv_addr.sin_family = AF_INET;
82  tcp_srv_addr.sin_port = htons (server_port);
83 
84  if (inaddr != INADDR_NONE)
85  {
86  memcpy ((void *) &tcp_srv_addr.sin_addr, (void *) &inaddr, sizeof (inaddr));
87  }
88  else
89  {
90  struct hostent *hp;
91  hp = gethostbyname (server_host);
92 
93  if (hp == NULL)
94  {
96  return INVALID_SOCKET;
97  }
98  memcpy ((void *) &tcp_srv_addr.sin_addr, (void *) hp->h_addr, hp->h_length);
99  }
100  slen = sizeof (tcp_srv_addr);
101  memcpy ((void *) saddr, (void *) &tcp_srv_addr, slen);
102 
103  sockfd = socket (saddr->sa_family, SOCK_STREAM, 0);
104  if (IS_INVALID_SOCKET (sockfd))
105  {
107  return INVALID_SOCKET;
108  }
109  else
110  {
111  b = 1;
112  setsockopt (sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &b, sizeof (b));
113  }
114 
115  success = connect (sockfd, saddr, slen);
116  if (success < 0)
117  {
119  return INVALID_SOCKET;
120  }
121 
122  return sockfd;
123 }
124 
125 
126 /*
127  * jsp_disconnect_server -
128  * return: none
129  * sockfd(in) : close connection
130  *
131  * Note:
132  */
133 
134 void
136 {
137  struct linger linger_buffer;
138 
139  linger_buffer.l_onoff = 1;
140  linger_buffer.l_linger = 0;
141  setsockopt (sockfd, SOL_SOCKET, SO_LINGER, (char *) &linger_buffer, sizeof (linger_buffer));
142 #if defined(WINDOWS)
143  closesocket (sockfd);
144 #else /* not WINDOWS */
145  close (sockfd);
146 #endif /* not WINDOWS */
147 }
148 
149 /*
150  * jsp_writen
151  * return: fail return -1,
152  * fd(in): Specifies the socket file descriptor.
153  * vptr(in): Points to the buffer containing the message to send.
154  * n(in): Specifies the length of the message in bytes
155  *
156  * Note:
157  */
158 
159 int
160 jsp_writen (SOCKET fd, const void *vptr, int n)
161 {
162  int nleft;
163  int nwritten;
164  const char *ptr;
165 
166  ptr = (const char *) vptr;
167  nleft = n;
168 
169  while (nleft > 0)
170  {
171 #if defined(WINDOWS)
172  nwritten = send (fd, ptr, nleft, 0);
173 #else
174  nwritten = send (fd, ptr, (size_t) nleft, 0);
175 #endif
176 
177  if (nwritten <= 0)
178  {
179 #if defined(WINDOWS)
180  if (nwritten < 0 && errno == WSAEINTR)
181 #else /* not WINDOWS */
182  if (nwritten < 0 && errno == EINTR)
183 #endif /* not WINDOWS */
184  {
185  nwritten = 0; /* and call write() again */
186  }
187  else
188  {
189  return (-1); /* error */
190  }
191  }
192 
193  nleft -= nwritten;
194  ptr += nwritten;
195  }
196 
197  return (n - nleft);
198 }
199 
200 /*
201  * jsp_readn
202  * return: read size
203  * fd(in): Specifies the socket file descriptor.
204  * vptr(in/out): Points to a buffer where the message should be stored.
205  * n(in): Specifies the length in bytes of the buffer pointed
206  * to by the buffer argument.
207  *
208  * Note:
209  */
210 
211 int
212 jsp_readn (SOCKET fd, void *vptr, int n)
213 {
214  int nleft;
215  int nread;
216  char *ptr;
217 
218  ptr = (char *) vptr;
219  nleft = n;
220 
221  while (nleft > 0)
222  {
223 #if defined(WINDOWS)
224  nread = recv (fd, ptr, nleft, 0);
225 #else
226  nread = recv (fd, ptr, (size_t) nleft, 0);
227 #endif
228 
229  if (nread < 0)
230  {
231 
232 #if defined(WINDOWS)
233  if (errno == WSAEINTR)
234 #else /* not WINDOWS */
235  if (errno == EINTR)
236 #endif /* not WINDOWS */
237  {
238  nread = 0; /* and call read() again */
239  }
240  else
241  {
242  return (-1);
243  }
244  }
245  else if (nread == 0)
246  {
247  break; /* EOF */
248  }
249 
250  nleft -= nread;
251  ptr += nread;
252  }
253 
254  return (n - nleft); /* return >= 0 */
255 }
256 
257 #if defined(WINDOWS)
258 /*
259  * windows_blocking_hook() -
260  * return: false
261  *
262  * Note: WINDOWS Code
263  */
264 
265 BOOL
266 windows_blocking_hook ()
267 {
268  return false;
269 }
270 
271 /*
272  * windows_socket_startup() -
273  * return: return -1 on error otherwise return 1
274  *
275  * Note:
276  */
277 
278 int
279 windows_socket_startup (FARPROC hook)
280 {
281  WORD wVersionRequested;
282  WSADATA wsaData;
283  int err;
284 
285  hook = NULL;
286  wVersionRequested = 0x101;
287  err = WSAStartup (wVersionRequested, &wsaData);
288  if (err != 0)
289  {
291  return (-1);
292  }
293 
294  /* Establish a blocking "hook" function to prevent Windows messages from being dispatched when we block on reads. */
295  hook = WSASetBlockingHook ((FARPROC) windows_blocking_hook);
296  if (hook == NULL)
297  {
298  /* couldn't set up our hook */
299  err = WSAGetLastError ();
301  (void) WSACleanup ();
302  return -1;
303  }
304 
305  return 1;
306 }
307 
308 /*
309  * windows_socket_shutdown() -
310  * return:
311  *
312  * Note:
313  */
314 
315 void
316 windows_socket_shutdown (FARPROC hook)
317 {
318  int err;
319 
320  if (hook != NULL)
321  {
322  (void) WSASetBlockingHook (hook);
323  }
324 
325  err = WSACleanup ();
326 }
327 #endif /* WINDOWS */
int SOCKET
Definition: porting.h:482
#define INVALID_SOCKET
Definition: porting.h:483
#define ERR_CSS_TCP_HOST_NAME_ERROR
Definition: error_code.h:426
#define INADDR_NONE
Definition: tcp.c:89
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
static int server_port
Definition: jsp_cl.c:109
#define IS_INVALID_SOCKET(socket)
Definition: porting.h:484
#define NULL
Definition: freelistheap.h:34
unsigned short htons(unsigned short from)
static int success()
#define err(fd,...)
Definition: porting.h:431
void jsp_disconnect_server(const SOCKET sockfd)
Definition: jsp_comm.c:135
void er_set_with_oserror(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define ER_CSS_WINSOCK_STARTUP
Definition: error_code.h:738
int jsp_writen(SOCKET fd, const void *vptr, int n)
Definition: jsp_comm.c:160
#define ARG_FILE_LINE
Definition: error_manager.h:44
SOCKET jsp_connect_server(int server_port)
Definition: jsp_comm.c:58
int jsp_readn(SOCKET fd, void *vptr, int n)
Definition: jsp_comm.c:212
#define ER_SP_CANNOT_CONNECT_JVM
Definition: error_code.h:1128