2 #include <sys/socket.h>
4 #include <netinet/in.h>
9 #include "shotgun/lib/shotgun.h"
10 #include "shotgun/lib/symbol.h"
11 #include "shotgun/lib/object.h"
12 #include "shotgun/lib/tuple.h"
13 #include "shotgun/lib/hash.h"
14 #include "shotgun/lib/string.h"
15 #include "shotgun/lib/primitive_indexes.h"
17 int ffi_errno() { return errno
; }
19 void ffi_set_errno(int n
) {
23 time_t ffi_timezone() {
27 char* ffi_tzname(int dst
) {
41 OBJECT
ffi_new_pointer(STATE
, void *ptr
) {
45 NEW_STRUCT(obj
, code_start
, BASIC_CLASS(ffi_ptr
), void*);
46 *code_start
= (void*)ptr
;
51 void ffi_autorelease(OBJECT ptr
, int ar
) {
52 type_assert(ptr
, MemPtrType
, "passing a pointer");
53 ptr
->RequiresCleanup
= (ar
? 1 : 0);
56 void ffi_set_address(OBJECT ptr
, void *addr
) {
57 type_assert(ptr
, MemPtrType
, "passing a pointer");
58 *DATA_STRUCT(ptr
, void**) = addr
;
61 uintptr_t ffi_address(void *ptr
) {
62 return (uintptr_t)ptr
;
65 int ffi_write_int(int *ptr
, int val
) {
70 int ffi_read_int(int *ptr
) {
74 long ffi_write_long(long *ptr
, long val
) {
79 long ffi_read_long(long *ptr
) {
83 double ffi_write_float(double *ptr
, double val
) {
88 double ffi_read_float(double *ptr
) {
92 char *ffi_read_string(char *ptr
) {
96 OBJECT
ffi_read_string_length(STATE
, void *ptr
, int len
) {
97 OBJECT str
= string_new2(state
, NULL
, len
);
99 memcpy(rbx_string_as_cstr(state
, str
), ptr
, len
);
104 int ffi_write_string_length(STATE
, void *ptr
, void* str
, int len
) {
105 void *src
= rbx_string_as_cstr(state
, str
);
107 memcpy(ptr
, src
, len
);
112 void *ffi_read_pointer(void **ptr
) {
116 char *ffi_sprintf_f(double value
, int size
, char *fmt
) {
117 char *str
= ALLOC_N(char, size
);
118 snprintf(str
, size
, fmt
, value
);
122 char *ffi_sprintf_d(int value
, int size
, char *fmt
) {
123 char *str
= ALLOC_N(char, size
);
124 snprintf(str
, size
, fmt
, value
);
128 OBJECT
ffi_pack_sockaddr_un(STATE
, char *path
) {
129 struct sockaddr_un
*sa
;
131 sa
= ALLOC(struct sockaddr_un
);
132 memset(sa
, 0, sizeof(struct sockaddr_un
));
134 strncpy(sa
->sun_path
, path
, sizeof(sa
->sun_path
) - 1);
136 return string_new2(state
, (char*) sa
, sizeof(struct sockaddr_un
) );
139 OBJECT
ffi_getnameinfo(STATE
, struct sockaddr
*sockaddr
, socklen_t sockaddr_len
,
141 char node
[NI_MAXHOST
], service
[NI_MAXSERV
];
142 OBJECT value
, host
, port
, ip
;
146 if(!(flags
& NI_NUMERICHOST
)) {
147 err
= getnameinfo(sockaddr
, sockaddr_len
, node
, NI_MAXHOST
, NULL
, 0, 0);
150 return tuple_new2(state
, 2, Qfalse
,
151 string_new(state
, gai_strerror(err
)));
153 host
= string_new2(state
, node
, strlen(node
));
156 err
= getnameinfo(sockaddr
, sockaddr_len
, node
, NI_MAXHOST
,
157 service
, NI_MAXSERV
, flags
| NI_NUMERICHOST
| NI_NUMERICSERV
);
160 return tuple_new2(state
, 2, Qfalse
,
161 string_new(state
, gai_strerror(err
)));
164 ip
= string_new2(state
, node
, strlen(node
));
165 port
= I2N(atoi(service
));
168 value
= array_new(state
, 0);
169 array_append(state
, value
, I2N(sockaddr
->sa_family
));
170 array_append(state
, value
, port
);
171 array_append(state
, value
, host
);
172 array_append(state
, value
, ip
);
174 return tuple_new2(state
, 2, Qtrue
, value
);
177 void *ffi_add_ptr(char *ptr
, int offset
) {
178 return (void*)(ptr
+ offset
);
181 unsigned int ffi_cast(unsigned int val
) {
185 long ffi_major(dev_t n
) {
193 long ffi_minor(dev_t n
) {
201 /* FIXME: these are TEMPORARY until we determine how to
202 * have FFI resolve symbols that may be macros. This is
203 * used rather than a primitive so that it is easier to
204 * replace (unlike primitives).
206 int ffi_stat(const char *path
, struct stat
*buf
) {
207 return stat(path
, buf
);
210 int ffi_lstat(const char *path
, struct stat
*buf
) {
211 return lstat(path
, buf
);