Skip to content

Instantly share code, notes, and snippets.

@cono
Created May 21, 2017 16:56
Show Gist options
  • Save cono/d828120249a08ddf08b71f632d1ec7b5 to your computer and use it in GitHub Desktop.
Save cono/d828120249a08ddf08b71f632d1ec7b5 to your computer and use it in GitHub Desktop.
First unused port
MoarVM:
diff --git a/src/core/interp.c b/src/core/interp.c
index 0057f7b3..129107de 100644
--- a/src/core/interp.c
+++ b/src/core/interp.c
@@ -3598,6 +3598,10 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
GET_REG(cur_op, 0).o = MVM_io_socket_create(tc, GET_REG(cur_op, 2).i64);
cur_op += 4;
goto NEXT;
+ OP(get_port_sk):
+ GET_REG(cur_op, 0).i64 = MVM_io_get_port_sk(tc, GET_REG(cur_op, 2).o);
+ cur_op += 4;
+ goto NEXT;
OP(bind_sk):
MVM_io_bind(tc, GET_REG(cur_op, 0).o,
GET_REG(cur_op, 2).s, GET_REG(cur_op, 4).i64, (int)GET_REG(cur_op, 6).i64);
diff --git a/src/io/syncsocket.c b/src/io/syncsocket.c
index affece99..be51314f 100644
--- a/src/io/syncsocket.c
+++ b/src/io/syncsocket.c
@@ -251,6 +251,31 @@ MVMObject * MVM_io_socket_create(MVMThreadContext *tc, MVMint64 listen) {
return (MVMObject *)result;
}
+MVMint64 MVM_io_get_port_sk(MVMThreadContext *tc, MVMOSHandle *h) {
+ MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data;
+ uv_tcp_t *socket = (uv_tcp_t *) data->ss.handle;
+ struct sockaddr_storage name;
+ int error, len = sizeof(struct sockaddr_storage);
+ MVMint64 port = 0;
+
+ error = uv_tcp_getsockname(socket, (struct sockaddr *) &name, &len);
+
+ if (error != 0) {
+ MVM_exception_throw_adhoc(tc, "Failed to getsockname: %s", uv_strerror(error));
+ }
+
+ switch (name.ss_family) {
+ case AF_INET6:
+ port = ntohs((*( struct sockaddr_in6 *) &name).sin6_port);
+ break;
+ case AF_INET:
+ port = ntohs((*( struct sockaddr_in *) &name).sin_port);
+ break;
+ }
+
+ return port;
+}
+
MVMString * MVM_io_get_hostname(MVMThreadContext *tc) {
char hostname[65];
gethostname(hostname, 65);
NQP:
diff --git a/src/vm/moar/QAST/QASTOperationsMAST.nqp b/src/vm/moar/QAST/QASTOperationsMAST.nqp
index 0765d8561..032da7fb1 100644
--- a/src/vm/moar/QAST/QASTOperationsMAST.nqp
+++ b/src/vm/moar/QAST/QASTOperationsMAST.nqp
@@ -2089,6 +2089,7 @@ QAST::MASTOperations.add_core_moarop_mapping('socket', 'socket');
QAST::MASTOperations.add_core_moarop_mapping('connect', 'connect_sk', 0);
QAST::MASTOperations.add_core_moarop_mapping('bindsock', 'bind_sk', 0);
QAST::MASTOperations.add_core_moarop_mapping('accept', 'accept_sk');
+QAST::MASTOperations.add_core_moarop_mapping('get_port', 'get_port_sk');
QAST::MASTOperations.add_core_moarop_mapping('readcharsfh', 'read_fhs');
QAST::MASTOperations.add_core_moarop_mapping('setinputlinesep', 'setinputlinesep_fh', 0);
QAST::MASTOperations.add_core_moarop_mapping('setinputlineseps', 'setinputlineseps_fh', 0);
Rakudo:
diff --git a/src/core/IO/Socket/INET.pm b/src/core/IO/Socket/INET.pm
index bb0f0c69e..d03d9e61e 100644
--- a/src/core/IO/Socket/INET.pm
+++ b/src/core/IO/Socket/INET.pm
@@ -22,7 +22,7 @@ my class IO::Socket::INET does IO::Socket {
has Str $.host;
has Int $.port;
has Str $.localhost;
- has Int $.localport;
+ has Int $.localport is rw;
has Int $.backlog;
has Bool $.listening;
has $.family = PIO::PF_INET;
@@ -129,6 +129,7 @@ my class IO::Socket::INET does IO::Socket {
}
if $.listening {
+ $.localport = nqp::get_port($PIO);
}
elsif $.type == PIO::SOCK_STREAM {
nqp::connect($PIO, nqp::unbox_s($.host), nqp::unbox_i($.port));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment