generated from Comet/Comet-C-External-Lib
bug fixes, added shutdown method, resolve hostnames as well as ips
This commit is contained in:
112
src/socket.c
112
src/socket.c
@@ -19,18 +19,37 @@ ResultType(int64_t, objectPtr) impl_Socket_INIT(int64_t* args, CometVM* vm) {
|
|||||||
|
|
||||||
self->fields[0] = fd;
|
self->fields[0] = fd;
|
||||||
self->fields[1] = family;
|
self->fields[1] = family;
|
||||||
|
self->fields[2] = type;
|
||||||
|
|
||||||
return Success(int64_t, objectPtr, (int64_t)self);
|
return Success(int64_t, objectPtr, (int64_t)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in createIPV4Address(int family, char* ip, int port) {
|
typedef struct sockaddr_in SocketAddress;
|
||||||
struct sockaddr_in address;
|
|
||||||
|
|
||||||
inet_pton(family, ip, &address.sin_addr.s_addr);
|
Result(SocketAddress, objectPtr);
|
||||||
address.sin_family = family;
|
ResultType(SocketAddress, objectPtr) createIPV4Address(CometVM* vm, int family, int type, char* host, int port) {
|
||||||
address.sin_port = htons(port);
|
struct sockaddr_in address = {};
|
||||||
|
|
||||||
return address;
|
struct addrinfo hints = {};
|
||||||
|
struct addrinfo* result;
|
||||||
|
|
||||||
|
hints.ai_family = family;
|
||||||
|
hints.ai_socktype = type;
|
||||||
|
|
||||||
|
char portString[16];
|
||||||
|
snprintf(portString, sizeof(portString), "%d", port);
|
||||||
|
|
||||||
|
int status = getaddrinfo(host, portString, &hints, &result);
|
||||||
|
if (status < 0) {
|
||||||
|
char* errMsg = strerror(errno);
|
||||||
|
ResultType(int64_t, objectPtr) error = cometError(vm, "SocketError", errMsg);
|
||||||
|
return Error(SocketAddress, objectPtr, error.as.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&address, result->ai_addr, sizeof(address));
|
||||||
|
freeaddrinfo(result);
|
||||||
|
|
||||||
|
return Success(SocketAddress, objectPtr, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) {
|
ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) {
|
||||||
@@ -40,11 +59,14 @@ ResultType(int64_t, objectPtr) impl_connect(int64_t* args, CometVM* vm) {
|
|||||||
|
|
||||||
int fd = self->fields[0];
|
int fd = self->fields[0];
|
||||||
int family = self->fields[1];
|
int family = self->fields[1];
|
||||||
|
int type = self->fields[2];
|
||||||
|
|
||||||
struct sockaddr_in address = createIPV4Address(family, ip, port);
|
ResultType(SocketAddress, objectPtr) address = createIPV4Address(vm, family, type, ip, port);
|
||||||
|
if (address.error)
|
||||||
|
return Error(int64_t, objectPtr, address.as.error);
|
||||||
|
|
||||||
// then connect
|
// then connect
|
||||||
int result = connect(fd, (struct sockaddr*)&address, sizeof(address));
|
int result = connect(fd, (struct sockaddr*)&address.as.success, sizeof(address));
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
char* errMsg = strerror(errno);
|
char* errMsg = strerror(errno);
|
||||||
@@ -61,11 +83,13 @@ ResultType(int64_t, objectPtr) impl_bind(int64_t* args, CometVM* vm) {
|
|||||||
|
|
||||||
int fd = self->fields[0];
|
int fd = self->fields[0];
|
||||||
int family = self->fields[1];
|
int family = self->fields[1];
|
||||||
|
int type = self->fields[2];
|
||||||
|
|
||||||
struct sockaddr_in address = createIPV4Address(family, ip, port);
|
ResultType(SocketAddress, objectPtr) address = createIPV4Address(vm, family, type, ip, port);
|
||||||
|
if (address.error)
|
||||||
|
return Error(int64_t, objectPtr, address.as.error);
|
||||||
|
|
||||||
|
int result = bind(fd, (struct sockaddr*)&address.as.success, sizeof(address));
|
||||||
int result = bind(fd, (struct sockaddr*)&address, sizeof(address));
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
char* errMsg = strerror(errno);
|
char* errMsg = strerror(errno);
|
||||||
return cometError(vm, "SocketError", errMsg);
|
return cometError(vm, "SocketError", errMsg);
|
||||||
@@ -107,7 +131,9 @@ ResultType(int64_t, objectPtr) impl_accept(int64_t* args, CometVM* vm) {
|
|||||||
CometObject* clientCometSocket = cometCreateObject(socketStruct);
|
CometObject* clientCometSocket = cometCreateObject(socketStruct);
|
||||||
|
|
||||||
clientCometSocket->fields[0] = clientSocket;
|
clientCometSocket->fields[0] = clientSocket;
|
||||||
clientCometSocket->fields[1] = clientAddr.sin_port;
|
clientCometSocket->fields[1] = self->fields[1];
|
||||||
|
clientCometSocket->fields[2] = self->fields[2];
|
||||||
|
clientCometSocket->fields[3] = clientAddr.sin_port;
|
||||||
|
|
||||||
return Success(int64_t, objectPtr, (int64_t)clientCometSocket);
|
return Success(int64_t, objectPtr, (int64_t)clientCometSocket);
|
||||||
}
|
}
|
||||||
@@ -148,17 +174,22 @@ ResultType(int64_t, objectPtr) impl_readExact(int64_t* args, CometVM* vm) {
|
|||||||
return cometError(vm, "MemoryAllocFail", "Failed to allocate memory for buffer (readExact)");
|
return cometError(vm, "MemoryAllocFail", "Failed to allocate memory for buffer (readExact)");
|
||||||
|
|
||||||
ssize_t amountReceived = recv(fd, buffer, amount, 0);
|
ssize_t amountReceived = recv(fd, buffer, amount, 0);
|
||||||
if (amountReceived != amount) {
|
|
||||||
char* buffer = malloc(128);
|
if (amountReceived < 0) { // connection closed by peer
|
||||||
snprintf(buffer, 128, "Expected to read %d bytes but only got %zu", amount, amountReceived);
|
|
||||||
return cometError(vm, "UnexpectedEOF", buffer);
|
|
||||||
} else if (amountReceived == -1) { // connection closed by peer
|
|
||||||
char* errMsg = strerror(errno);
|
char* errMsg = strerror(errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return cometError(vm, "SocketError", errMsg);
|
return cometError(vm, "SocketError", errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (amountReceived != amount) {
|
||||||
|
char* buffer = malloc(128);
|
||||||
|
snprintf(buffer, 128, "Expected to read %d bytes but only got %zu", amount, amountReceived);
|
||||||
|
return cometError(vm, "UnexpectedEOF", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
buffer[amountReceived] = 0;
|
buffer[amountReceived] = 0;
|
||||||
|
|
||||||
int64_t serializedString = cometSerializeString(buffer);
|
int64_t serializedString = cometSerializeString(buffer);
|
||||||
@@ -238,7 +269,28 @@ ResultType(int64_t, objectPtr) impl_send(int64_t* args, CometVM* vm) {
|
|||||||
return cometError(vm, "SocketError", errMsg);
|
return cometError(vm, "SocketError", errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success(int64_t, objectPtr, 0);
|
return Success(int64_t, objectPtr, bytesSent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_sendAll(int64_t* args, CometVM* vm) {
|
||||||
|
char* buffer = cometArgString(args[0]);
|
||||||
|
CometObject* self = (CometObject*)args[1];
|
||||||
|
|
||||||
|
int fd = self->fields[0];
|
||||||
|
|
||||||
|
size_t length = strlen(buffer);
|
||||||
|
|
||||||
|
ssize_t bytesSent = 0;
|
||||||
|
while (bytesSent < length) {
|
||||||
|
bytesSent += send(fd, buffer + bytesSent, length - bytesSent, MSG_NOSIGNAL);
|
||||||
|
|
||||||
|
if (bytesSent < 0) {
|
||||||
|
char* errMsg = strerror(errno);
|
||||||
|
return cometError(vm, "SocketError", errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, bytesSent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultType(int64_t, objectPtr) impl_sendByte(int64_t* args, CometVM* vm) {
|
ResultType(int64_t, objectPtr) impl_sendByte(int64_t* args, CometVM* vm) {
|
||||||
@@ -262,13 +314,28 @@ ResultType(int64_t, objectPtr) impl_close(int64_t* args, CometVM* vm) {
|
|||||||
CometObject* self = (CometObject*)args[0];
|
CometObject* self = (CometObject*)args[0];
|
||||||
|
|
||||||
int fd = self->fields[0];
|
int fd = self->fields[0];
|
||||||
|
|
||||||
int result = close(fd);
|
int result = close(fd);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
char* errMsg = strerror(errno);
|
char* errMsg = strerror(errno);
|
||||||
return cometError(vm, "IOError", errMsg);
|
return cometError(vm, "IOError", errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->fields[0] = -1;
|
||||||
|
|
||||||
|
return Success(int64_t, objectPtr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(int64_t, objectPtr) impl_shutdown(int64_t* args, CometVM* vm) {
|
||||||
|
int method = mapLanguageShutdownToOS(cometArgSmall(args[0]));
|
||||||
|
CometObject* self = (CometObject*)args[1];
|
||||||
|
|
||||||
|
int fd = self->fields[0];
|
||||||
|
int result = shutdown(fd, method);
|
||||||
|
if (result != 0) {
|
||||||
|
char* errMsg = strerror(errno);
|
||||||
|
return cometError(vm, "SocketError", errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
return Success(int64_t, objectPtr, 0);
|
return Success(int64_t, objectPtr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,6 +494,7 @@ ResultType(int64_t, objectPtr) impl_waitWriteable(int64_t* args, CometVM* vm) {
|
|||||||
void defineSocketStruct(CometEnvironment* env, CometTypeMap* typeMap) {
|
void defineSocketStruct(CometEnvironment* env, CometTypeMap* typeMap) {
|
||||||
CometType familyEnum = defineFamilyEnum(env, typeMap);
|
CometType familyEnum = defineFamilyEnum(env, typeMap);
|
||||||
CometType typeEnum = defineTypeEnum(env, typeMap);
|
CometType typeEnum = defineTypeEnum(env, typeMap);
|
||||||
|
CometType shutdownEnum = defineShutdownEnum(env, typeMap);
|
||||||
|
|
||||||
CometStruct* socketStruct = cometDefineStruct(env, "Socket", NULL);
|
CometStruct* socketStruct = cometDefineStruct(env, "Socket", NULL);
|
||||||
|
|
||||||
@@ -438,6 +506,8 @@ void defineSocketStruct(CometEnvironment* env, CometTypeMap* typeMap) {
|
|||||||
List(StructField) fields = newList(StructField);
|
List(StructField) fields = newList(StructField);
|
||||||
append(fields, cometCreateField("fd", cometTypeInt, FIELD_PRIVATE));
|
append(fields, cometCreateField("fd", cometTypeInt, FIELD_PRIVATE));
|
||||||
append(fields, cometCreateField("family", cometTypeSmall, FIELD_READ_ONLY));
|
append(fields, cometCreateField("family", cometTypeSmall, FIELD_READ_ONLY));
|
||||||
|
append(fields, cometCreateField("type", cometTypeSmall, FIELD_READ_ONLY));
|
||||||
|
append(fields, cometCreateField("port", cometTypeInt, FIELD_READ_ONLY));
|
||||||
|
|
||||||
/// METHODS ///
|
/// METHODS ///
|
||||||
List(externalMethodPtr) methods = newList(externalMethodPtr);
|
List(externalMethodPtr) methods = newList(externalMethodPtr);
|
||||||
@@ -454,8 +524,10 @@ void defineSocketStruct(CometEnvironment* env, CometTypeMap* typeMap) {
|
|||||||
append(methods, cometDefineMethod(env, "readAll", socketStruct, FIELD_PUBLIC, cometTypeString, 0, false));
|
append(methods, cometDefineMethod(env, "readAll", socketStruct, FIELD_PUBLIC, cometTypeString, 0, false));
|
||||||
append(methods, cometDefineMethod(env, "readExact", socketStruct, FIELD_PUBLIC, cometTypeString, 1, false, cometTypeInt));
|
append(methods, cometDefineMethod(env, "readExact", socketStruct, FIELD_PUBLIC, cometTypeString, 1, false, cometTypeInt));
|
||||||
append(methods, cometDefineMethod(env, "readByte", socketStruct, FIELD_PUBLIC, cometTypeSmall, 0, false));
|
append(methods, cometDefineMethod(env, "readByte", socketStruct, FIELD_PUBLIC, cometTypeSmall, 0, false));
|
||||||
append(methods, cometDefineMethod(env, "send", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeString));
|
append(methods, cometDefineMethod(env, "send", socketStruct, FIELD_PUBLIC, cometTypeInt, 1, false, cometTypeString));
|
||||||
|
append(methods, cometDefineMethod(env, "sendAll", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeString));
|
||||||
append(methods, cometDefineMethod(env, "sendByte", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeSmall));
|
append(methods, cometDefineMethod(env, "sendByte", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, cometTypeSmall));
|
||||||
|
append(methods, cometDefineMethod(env, "shutdown", socketStruct, FIELD_PUBLIC, cometTypeVoid, 1, false, shutdownEnum));
|
||||||
append(methods, cometDefineMethod(env, "close", socketStruct, FIELD_PUBLIC, cometTypeVoid, 0, false));
|
append(methods, cometDefineMethod(env, "close", socketStruct, FIELD_PUBLIC, cometTypeVoid, 0, false));
|
||||||
|
|
||||||
// options
|
// options
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -74,6 +74,18 @@ CometType defineTypeEnum(CometEnvironment* env, CometTypeMap* typeMap) {
|
|||||||
return domainEnum;
|
return domainEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CometType defineShutdownEnum(CometEnvironment* env, CometTypeMap* typeMap) {
|
||||||
|
char* items[] = {
|
||||||
|
"Read",
|
||||||
|
"Write",
|
||||||
|
"ReadWrite"
|
||||||
|
};
|
||||||
|
|
||||||
|
CometType shutdownEnum = cometDefineEnum(env, typeMap, "Shutdown", items, sizeof(items)/sizeof(items[0]));
|
||||||
|
|
||||||
|
return shutdownEnum;
|
||||||
|
}
|
||||||
|
|
||||||
int mapLanguageTypeToOS(int cometType) {
|
int mapLanguageTypeToOS(int cometType) {
|
||||||
/*
|
/*
|
||||||
ughhhh...
|
ughhhh...
|
||||||
@@ -149,3 +161,12 @@ int mapLanguageFamilyToOS(int cometFamily) {
|
|||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mapLanguageShutdownToOS(int cometShutdown) {
|
||||||
|
switch (cometShutdown) {
|
||||||
|
case 0: return SHUT_RD;
|
||||||
|
case 1: return SHUT_WR;
|
||||||
|
case 2: return SHUT_RDWR;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
CometType defineFamilyEnum(CometEnvironment* env, CometTypeMap* typeMap);
|
CometType defineFamilyEnum(CometEnvironment* env, CometTypeMap* typeMap);
|
||||||
CometType defineTypeEnum(CometEnvironment* env, CometTypeMap* typeMap);
|
CometType defineTypeEnum(CometEnvironment* env, CometTypeMap* typeMap);
|
||||||
|
CometType defineShutdownEnum(CometEnvironment* env, CometTypeMap* typeMap);
|
||||||
int mapLanguageFamilyToOS(int cometFamily);
|
int mapLanguageFamilyToOS(int cometFamily);
|
||||||
int mapLanguageTypeToOS(int cometFamily);
|
int mapLanguageTypeToOS(int cometFamily);
|
||||||
|
int mapLanguageShutdownToOS(int cometShutdown);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user