21 #include <sys/types.h>
22 #include <sys/socket.h>
25 #include <netinet/tcp.h>
33 #error Neither SO_NOSIGPIPE nor MSG_NOSIGNAL available!
38 he = gethostbyname(name);
47 name, h_errno, hstrerror(h_errno));
52 static SmartCharPtr hostname;
53 if (hostname.isNull()) {
62 size_t to_read = size;
64 ssize_t read_len = read(socket, ptr, to_read);
76 size_t to_write = size;
82 ssize_t write_len = send(socket, ptr, to_write, MSG_NOSIGNAL);
87 ssize_t write_len = write(socket, ptr, to_write);
91 fputs(
"pipe broken\n", stderr);
98 to_write -= write_len;
128 if (!name || strlen(name) == 0) {
129 error =
"Error opening socket: empty name";
131 else if (name[0] ==
':') {
141 reassign(*filename_out, filename);
148 freenull(*filename_out);
165 sockaddr_un unix_socket;
166 unix_socket.sun_family = AF_UNIX;
167 if (strlen(filename)+1 >
sizeof(unix_socket.sun_path)) {
169 "\"%s\" is longer than the allowed %zu characters",
170 filename,
sizeof(unix_socket.sun_path));
173 strncpy(unix_socket.sun_path, filename,
sizeof(unix_socket.sun_path));
176 *fd = socket(PF_UNIX, SOCK_STREAM, 0);
183 if (connect(*fd, (sockaddr*)&unix_socket,
sizeof(sockaddr_un))) {
184 if (errno == ECONNREFUSED || errno == ENOENT) {
189 filename, strerror(errno), errno);
195 if (!stat(filename, &stt)) {
196 if (!S_ISSOCK(stt.st_mode)) {
198 " and is not a socket", filename);
200 else if (unlink(filename)) {
201 error =
GBS_global_string(
"Failed to create unix socket at \"%s\": cannot remove"
202 " existing socket", filename);
205 if (!error && bind(*fd, (sockaddr*)&unix_socket,
sizeof(sockaddr_un))) {
207 filename, strerror(errno));
216 if (setsockopt(*fd, SOL_SOCKET, SO_NOSIGPIPE, (
const char *)&one,
sizeof(one))){
217 fprintf(stderr,
"Warning: setsockopt(...NOSIGPIPE...) failed: %s", strerror(errno));
236 *fd = socket(PF_INET, SOCK_STREAM, 0);
242 sockaddr_in tcp_socket;
243 tcp_socket.sin_family = AF_INET;
247 char *p = strchr(name,
':');
249 tcp_socket.sin_port = htons(atoi(name));
253 tcp_socket.sin_port = htons(atoi(p+1));
258 if (tcp_socket.sin_port == 0) {
259 error =
"Cannot open tcp socket on port 0. Is the port name malformed?";
262 memcpy(&tcp_socket.sin_addr, he->h_addr_list[0], he->h_length);
266 if (connect(*fd, (sockaddr*)&tcp_socket,
sizeof(tcp_socket))) {
267 if (errno == ECONNREFUSED) {
271 name, strerror(errno));
276 if (setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &one,
sizeof(one))) {
277 fprintf(stderr,
"Warning: setsockopt(...REUSEADDR...) failed: %s", strerror(errno));
279 if (bind(*fd, (sockaddr*)&tcp_socket,
sizeof(tcp_socket))) {
281 name, strerror(errno));
285 if (setsockopt(*fd, IPPROTO_TCP, TCP_NODELAY, &one,
sizeof(one))) {
286 fprintf(stderr,
"Warning: setsockopt(...TCP_NODELAY...) failed: %s", strerror(errno));
305 #include <sys/wait.h>
308 static int echo_server(
const char* portname) {
310 if (mypid)
return mypid;
313 char *filename =
NULp;
324 int cli_fd = accept(fd,
NULp,
NULp);
337 if (strcmp(buf,
"exit") == 0)
break;
354 void TEST_open_socket() {
356 char *filename =
NULp;
357 int server_pid, server_status;
359 const int XTRABUF = 20;
362 char *unix_socket =
arb_shell_expand(
":$ARBHOME/UNIT_TESTER/sok/test.socket");
363 char tcp_socket[
sizeof(
"65536")+XTRABUF], tcp_socket2[
sizeof(
"localhost:65536")+XTRABUF];
367 srand(time(
NULp)+getpid());
369 const int RANGE = 100;
370 const int PORT_MIN = 32039;
371 const int PORT_MAX = PORT_MIN+RANGE-1;
376 for (
int p = 0; p<RANGE; ++p) pos[p] = p;
378 for (
int o = 0; o<RANGE; ++o) {
380 int take = (rand()*double(limit))/RAND_MAX;
382 order[o] = pos[take];
383 for (
int t = take+1; t<limit; ++t) {
390 for (
int o = 0; o<RANGE; o++) {
391 port = PORT_MIN+order[o];
394 snprintf(tcp_socket,
sizeof(tcp_socket),
"%i", port);
399 else if (err[0] ==
'\0') {
408 snprintf(tcp_socket2,
sizeof(tcp_socket2),
"localhost:%i", port);
430 server_pid = echo_server(tcp_socket);
437 while (!maxconnect.passed()) {
439 if (!res || res[0])
break;
454 server_pid = echo_server(unix_socket);
460 while (!maxconnect.passed()) {
462 if (!res || res[0])
break;
470 char send_buf[500], recv_buf[500];
471 for (
unsigned int i=0; i <
sizeof(send_buf); i++) {
472 send_buf[i]=i % 64 +
'0';
474 send_buf[
sizeof(send_buf)-1]=
'\0';
485 strcpy(send_buf,
"exit");
GB_ERROR GB_incur_error()
static GB_ERROR arb_open_tcp_socket(char *name, bool do_connect, int *fd)
#define TEST_REJECT_ZERO(cond)
static GB_ERROR arb_open_unix_socket(char *name, bool do_connect, int *fd)
const char * arb_gethostname()
char * ARB_strdup(const char *str)
GB_ERROR arb_open_socket(const char *name, bool do_connect, int *fd, char **filename_out)
const char * GBS_global_string(const char *templat,...)
int gethostname(char *name, int namelen)
char buffer[MESSAGE_BUFFERSIZE]
#define TEST_PUBLISH(testfunction)
#define TEST_EXPECT(cond)
char * arb_shell_expand(const char *str)
#define TEST_REJECT(cond)
#define TEST_REJECT_NULL(n)
static void error(const char *msg)
void ARB_sleep(int amount, TimeUnit tu)
fputs(TRACE_PREFIX, stderr)
size_t arb_socket_read(int socket, char *ptr, size_t size)
#define TEST_EXPECT_NULL(n)
ssize_t arb_socket_write(int socket, const char *ptr, size_t size)
#define TEST_EXPECT_EQUAL(expr, want)
static void arb_gethostbyname(const char *name, struct hostent *&he, GB_ERROR &err)