Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
socket.c File Reference
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include "duktape.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 
#define ERROR_FROM_ERRNO(ctx)
 

Functions

static void set_nonblocking (duk_context *ctx, int fd)
 
static void set_reuseaddr (duk_context *ctx, int fd)
 
static int socket_create_server_socket (duk_context *ctx)
 
static int socket_close (duk_context *ctx)
 
static int socket_accept (duk_context *ctx)
 
static int socket_connect (duk_context *ctx)
 
static int socket_read (duk_context *ctx)
 
static int socket_write (duk_context *ctx)
 
void socket_register (duk_context *ctx)
 

Variables

static duk_function_list_entry socket_funcs []
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 5 of file duktape-1.5.2/examples/eventloop/socket.c.

◆ ERROR_FROM_ERRNO

#define ERROR_FROM_ERRNO ( ctx)
Value:
do { \
duk_error(ctx, DUK_ERR_ERROR, "%s (errno=%d)", strerror(errno), errno); \
} while (0)

Definition at line 19 of file duktape-1.5.2/examples/eventloop/socket.c.

19#define ERROR_FROM_ERRNO(ctx) do { \
20 duk_error(ctx, DUK_ERR_ERROR, "%s (errno=%d)", strerror(errno), errno); \
21 } while (0)

Referenced by set_nonblocking(), set_reuseaddr(), socket_accept(), socket_close(), socket_connect(), socket_create_server_socket(), socket_read(), and socket_write().

Function Documentation

◆ set_nonblocking()

static void set_nonblocking ( duk_context * ctx,
int fd )
static

Definition at line 23 of file duktape-1.5.2/examples/eventloop/socket.c.

23 {
24 int rc;
25 int flags;
26
27 rc = fcntl(fd, F_GETFL);
28 if (rc < 0) {
30 }
31 flags = rc;
32
33 flags |= O_NONBLOCK;
34
35 rc = fcntl(fd, F_SETFL, flags);
36 if (rc < 0) {
38 }
39}
#define ERROR_FROM_ERRNO(ctx)

References ERROR_FROM_ERRNO.

Referenced by socket_accept(), socket_connect(), and socket_create_server_socket().

◆ set_reuseaddr()

static void set_reuseaddr ( duk_context * ctx,
int fd )
static

Definition at line 41 of file duktape-1.5.2/examples/eventloop/socket.c.

41 {
42 int val;
43 int rc;
44
45 val = 1;
46 rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &val, sizeof(val));
47 if (rc != 0) {
49 }
50}

References ERROR_FROM_ERRNO.

Referenced by socket_create_server_socket().

◆ socket_accept()

static int socket_accept ( duk_context * ctx)
static

Definition at line 133 of file duktape-1.5.2/examples/eventloop/socket.c.

133 {
134 int sock = duk_to_int(ctx, 0);
135 int rc;
136 struct sockaddr_in addr;
137 socklen_t addrlen;
138
139 memset(&addr, 0, sizeof(addr));
140 addr.sin_family = AF_INET;
141 addrlen = sizeof(addr);
142
143 rc = accept(sock, (struct sockaddr *) &addr, &addrlen);
144 if (rc < 0) {
145 ERROR_FROM_ERRNO(ctx);
146 }
147
148 set_nonblocking(ctx, sock);
149#ifdef __APPLE__
150 set_nosigpipe(ctx, sock);
151#endif
152
153 if (addrlen == sizeof(addr)) {
154 uint32_t tmp = ntohl(addr.sin_addr.s_addr);
155
156 duk_push_object(ctx);
157
158 duk_push_string(ctx, "fd");
159 duk_push_int(ctx, rc);
160 duk_put_prop(ctx, -3);
161 duk_push_string(ctx, "addr");
162 duk_push_sprintf(ctx, "%d.%d.%d.%d", ((tmp >> 24) & 0xff), ((tmp >> 16) & 0xff), ((tmp >> 8) & 0xff), (tmp & 0xff));
163 duk_put_prop(ctx, -3);
164 duk_push_string(ctx, "port");
165 duk_push_int(ctx, ntohs(addr.sin_port));
166 duk_put_prop(ctx, -3);
167
168 return 1;
169 }
170
171 return 0;
172}
static void set_nonblocking(duk_context *ctx, int fd)
DUK_EXTERNAL const char * duk_push_string(duk_context *ctx, const char *str)
DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val)
DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx)
DUK_EXTERNAL const char * duk_push_sprintf(duk_context *ctx, const char *fmt,...)
DUK_EXTERNAL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx)

References duk_push_int(), duk_push_object(), duk_push_sprintf(), duk_push_string(), duk_put_prop(), duk_to_int(), ERROR_FROM_ERRNO, and set_nonblocking().

◆ socket_close()

static int socket_close ( duk_context * ctx)
static

Definition at line 122 of file duktape-1.5.2/examples/eventloop/socket.c.

122 {
123 int sock = duk_to_int(ctx, 0);
124 int rc;
125
126 rc = close(sock);
127 if (rc < 0) {
128 ERROR_FROM_ERRNO(ctx);
129 }
130 return 0;
131}

References duk_to_int(), and ERROR_FROM_ERRNO.

◆ socket_connect()

static int socket_connect ( duk_context * ctx)
static

Definition at line 174 of file duktape-1.5.2/examples/eventloop/socket.c.

174 {
175 const char *addr = duk_to_string(ctx, 0);
176 int port = duk_to_int(ctx, 1);
177 int sock;
178 struct sockaddr_in sockaddr;
179 struct hostent *ent;
180 struct in_addr **addr_list;
181 struct in_addr *addr_inet;
182 int i;
183 int rc;
184
185 sock = socket(AF_INET, SOCK_STREAM, 0);
186 if (sock < 0) {
187 ERROR_FROM_ERRNO(ctx);
188 }
189
190 set_nonblocking(ctx, sock);
191#ifdef __APPLE__
192 set_nosigpipe(ctx, sock);
193#endif
194
195 ent = gethostbyname(addr);
196 if (!ent) {
197 ERROR_FROM_ERRNO(ctx);
198 }
199
200 addr_list = (struct in_addr **) ent->h_addr_list;
201 addr_inet = NULL;
202 for (i = 0; addr_list[i]; i++) {
203 addr_inet = addr_list[i];
204 break;
205 }
206 if (!addr_inet) {
207 duk_error(ctx, DUK_ERR_ERROR, "cannot resolve %s", addr);
208 }
209
210 memset(&sockaddr, 0, sizeof(sockaddr));
211 sockaddr.sin_family = AF_INET;
212 sockaddr.sin_port = htons(port);
213 sockaddr.sin_addr = *addr_inet;
214
215 rc = connect(sock, (const struct sockaddr *) &sockaddr, (socklen_t) sizeof(sockaddr));
216 if (rc < 0) {
217 if (errno == EINPROGRESS) {
218#if 0
219 fprintf(stderr, "connect() returned EINPROGRESS as expected, need to poll writability\n");
220 fflush(stderr);
221#endif
222 } else {
223 ERROR_FROM_ERRNO(ctx);
224 }
225 }
226
227 duk_push_int(ctx, sock);
228 return 1;
229}
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)
#define NULL
Definition gmacros.h:924

References DUK_ERR_ERROR, duk_error, duk_push_int(), duk_to_int(), duk_to_string(), ERROR_FROM_ERRNO, NULL, and set_nonblocking().

◆ socket_create_server_socket()

static int socket_create_server_socket ( duk_context * ctx)
static

Definition at line 65 of file duktape-1.5.2/examples/eventloop/socket.c.

65 {
66 const char *addr = duk_to_string(ctx, 0);
67 int port = duk_to_int(ctx, 1);
68 int sock;
69 struct sockaddr_in sockaddr;
70 struct hostent *ent;
71 struct in_addr **addr_list;
72 struct in_addr *addr_inet;
73 int i;
74 int rc;
75
76 sock = socket(AF_INET, SOCK_STREAM, 0);
77 if (sock < 0) {
79 }
80
81 set_nonblocking(ctx, sock);
82 set_reuseaddr(ctx, sock);
83#ifdef __APPLE__
84 set_nosigpipe(ctx, sock);
85#endif
86
87 ent = gethostbyname(addr);
88 if (!ent) {
90 }
91
92 addr_list = (struct in_addr **) ent->h_addr_list;
93 addr_inet = NULL;
94 for (i = 0; addr_list[i]; i++) {
95 addr_inet = addr_list[i];
96 break;
97 }
98 if (!addr_inet) {
99 duk_error(ctx, DUK_ERR_ERROR, "cannot resolve %s", addr);
100 }
101
102 memset(&sockaddr, 0, sizeof(sockaddr));
103 sockaddr.sin_family = AF_INET;
104 sockaddr.sin_port = htons(port);
105 sockaddr.sin_addr = *addr_inet;
106
107 rc = bind(sock, (const struct sockaddr *) &sockaddr, sizeof(sockaddr));
108 if (rc < 0) {
109 ERROR_FROM_ERRNO(ctx);
110 }
111
112 rc = listen(sock, 10 /*backlog*/);
113 if (rc < 0) {
114 (void) close(sock);
115 ERROR_FROM_ERRNO(ctx);
116 }
117
118 duk_push_int(ctx, sock);
119 return 1;
120}
static void set_reuseaddr(duk_context *ctx, int fd)

References DUK_ERR_ERROR, duk_error, duk_push_int(), duk_to_int(), duk_to_string(), ERROR_FROM_ERRNO, NULL, set_nonblocking(), and set_reuseaddr().

◆ socket_read()

static int socket_read ( duk_context * ctx)
static

Definition at line 231 of file duktape-1.5.2/examples/eventloop/socket.c.

231 {
232 int sock = duk_to_int(ctx, 0);
233 char readbuf[1024];
234 int rc;
235 void *data;
236
237 rc = recvfrom(sock, (void *) readbuf, sizeof(readbuf), 0, NULL, NULL);
238 if (rc < 0) {
239 ERROR_FROM_ERRNO(ctx);
240 }
241
242 data = duk_push_fixed_buffer(ctx, rc);
243 memcpy(data, readbuf, rc);
244 return 1;
245}
#define duk_push_fixed_buffer(ctx, size)

References duk_push_fixed_buffer, duk_to_int(), ERROR_FROM_ERRNO, and NULL.

◆ socket_register()

void socket_register ( duk_context * ctx)

Definition at line 279 of file duktape-1.5.2/examples/eventloop/socket.c.

279 {
280 /* Set global 'Socket'. */
282 duk_push_object(ctx);
284 duk_put_prop_string(ctx, -2, "Socket");
285 duk_pop(ctx);
286}
static duk_function_list_entry socket_funcs[]
DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key)
DUK_EXTERNAL void duk_push_global_object(duk_context *ctx)
DUK_EXTERNAL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_index, const duk_function_list_entry *funcs)
DUK_EXTERNAL void duk_pop(duk_context *ctx)

◆ socket_write()

static int socket_write ( duk_context * ctx)
static

Definition at line 247 of file duktape-1.5.2/examples/eventloop/socket.c.

247 {
248 int sock = duk_to_int(ctx, 0);
249 const char *data;
250 size_t len;
251 ssize_t rc;
252
253 data = duk_to_buffer(ctx, 1, &len);
254
255 /* MSG_NOSIGNAL: avoid SIGPIPE */
256#ifdef __APPLE__
257 rc = sendto(sock, (void *) data, len, 0, NULL, 0);
258#else
259 rc = sendto(sock, (void *) data, len, MSG_NOSIGNAL, NULL, 0);
260#endif
261 if (rc < 0) {
262 ERROR_FROM_ERRNO(ctx);
263 }
264
265 duk_push_int(ctx, rc);
266 return 1;
267}
#define MSG_NOSIGNAL
Definition civetweb.c:1735
#define duk_to_buffer(ctx, index, out_size)

References duk_push_int(), duk_to_buffer, duk_to_int(), ERROR_FROM_ERRNO, MSG_NOSIGNAL, and NULL.

Variable Documentation

◆ socket_funcs

duk_function_list_entry socket_funcs[]
static
Initial value:
= {
{ "createServerSocket", socket_create_server_socket, 2 },
{ "close", socket_close, 1 },
{ "accept", socket_accept, 1 },
{ "connect", socket_connect, 2 },
{ "read", socket_read, 1 },
{ "write", socket_write, 2 },
{ NULL, NULL, 0 }
}
static int socket_create_server_socket(duk_context *ctx)
static int socket_connect(duk_context *ctx)
static int socket_read(duk_context *ctx)
static int socket_write(duk_context *ctx)
static int socket_accept(duk_context *ctx)
static int socket_close(duk_context *ctx)

Definition at line 269 of file duktape-1.5.2/examples/eventloop/socket.c.

269 {
270 { "createServerSocket", socket_create_server_socket, 2 },
271 { "close", socket_close, 1 },
272 { "accept", socket_accept, 1 },
273 { "connect", socket_connect, 2 },
274 { "read", socket_read, 1 },
275 { "write", socket_write, 2 },
276 { NULL, NULL, 0 }
277};

Referenced by socket_register().