# HG changeset patch # User jbe # Date 1474157961 -7200 # Node ID 77a7ca00ad34870ad9c0f85749ed336a0be9a180 # Parent ff7eea59be93e496d3651a1ead6b9d56a71d0fca Simplified error handling with new macro(s) diff -r ff7eea59be93 -r 77a7ca00ad34 moonbridge_io.c --- a/moonbridge_io.c Sun Sep 18 00:59:31 2016 +0200 +++ b/moonbridge_io.c Sun Sep 18 02:19:21 2016 +0200 @@ -42,9 +42,18 @@ #define MOONBR_IO_LISTEN_BACKLOG 1024 #define MOONBR_IO_STRERROR_R_MSG "Error detail unavailable due to noncompliant strerror_r() implementation" -#define moonbr_io_errmsg() \ +#define moonbr_io_prepare_errmsg() \ char errmsg[MOONBR_IO_MAXSTRERRORLEN] = MOONBR_IO_STRERROR_R_MSG; \ strerror_r(errno, errmsg, MOONBR_IO_MAXSTRERRORLEN) +#define moonbr_io_return_prepared_errmsg() \ + lua_pushnil(L); \ + lua_pushstring(L, errmsg); \ + return 2 +#define moonbr_io_return_errmsg() \ + do { \ + moonbr_io_prepare_errmsg(); \ + moonbr_io_return_prepared_errmsg(); \ + } while (0) #define MOONBR_IO_HANDLE_MT_REGKEY "moonbridge_io_handle" #define MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY "moonbridge_io_handle_public" @@ -202,12 +211,7 @@ return 2; } handle->readerr = 1; - if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) moonbr_io_return_errmsg(); if (!drain) luaL_buffinit(L, &luabuf); while (1) { remaining = -1; @@ -311,12 +315,7 @@ handle->readerr = 0; return 2; } - if (bytesread < 0) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (bytesread < 0) moonbr_io_return_errmsg(); handle->readbufin = bytesread; } } @@ -508,12 +507,7 @@ return 2; } handle->writeerr = 1; - if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nonblocking(L, handle, nonblocking)) moonbr_io_return_errmsg(); top = lua_gettop(L); lua_getuservalue(L, 1); lua_getfield(L, -1, "writequeue"); @@ -548,12 +542,7 @@ handle->writeqoff += MOONBR_IO_WRITEBUFLEN - handle->writebufin; handle->writebufin = MOONBR_IO_WRITEBUFLEN; while (handle->writebufout < MOONBR_IO_WRITEBUFLEN) { - if (moonbr_io_handle_set_nopush(L, handle, 1)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nopush(L, handle, 1)) moonbr_io_return_errmsg(); #ifdef MOONBR_IO_USE_TLS moonbr_io_write_tls( handle->writebuf + handle->writebufout, @@ -568,24 +557,14 @@ if (written < 0) { if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { goto moonbr_io_write_impl_block; - } else if (errno != EINTR) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + } else if (errno != EINTR) moonbr_io_return_errmsg(); } else { handle->writebufout += written; handle->writeleft -= written; if (handle->flushedleft) { if (written >= handle->flushedleft) { handle->flushedleft = 0; - if (moonbr_io_handle_set_nopush(L, handle, 0)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nopush(L, handle, 0)) moonbr_io_return_errmsg(); } else { handle->flushedleft -= written; } @@ -602,12 +581,7 @@ lua_rawseti(L, -2, handle->writeqout++); } while (handle->flushedleft) { - if (moonbr_io_handle_set_nopush(L, handle, 1)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nopush(L, handle, 1)) moonbr_io_return_errmsg(); #ifdef MOONBR_IO_USE_TLS moonbr_io_write_tls( handle->writebuf + handle->writebufout, @@ -622,24 +596,14 @@ if (written < 0) { if (nonblocking && (errno == EAGAIN || errno == EWOULDBLOCK)) { goto moonbr_io_write_impl_block; - } else if (errno != EINTR) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + } else if (errno != EINTR) moonbr_io_return_errmsg(); } else { handle->writebufout += written; handle->writeleft -= written; if (handle->flushedleft) { if (written >= handle->flushedleft) { handle->flushedleft = 0; - if (moonbr_io_handle_set_nopush(L, handle, 0)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (moonbr_io_handle_set_nopush(L, handle, 0)) moonbr_io_return_errmsg(); } else { handle->flushedleft -= written; } @@ -755,22 +719,14 @@ } handle->finished = 1; if (handle->addrfam == AF_INET6 || handle->addrfam == AF_INET) { - if (shutdown(handle->fd, SHUT_WR)) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (shutdown(handle->fd, SHUT_WR)) moonbr_io_return_errmsg(); } else { #ifdef MOONBR_IO_USE_TLS if (handle->tls) tls_close(handle->tls); #endif if (close(handle->fd)) { - moonbr_io_errmsg(); handle->fd = -1; - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_errmsg(); } handle->fd = -1; /* fake EOF on read */ } @@ -802,12 +758,10 @@ handle->closed = 1; } if (moonbr_io_handle_set_linger(L, handle, -1)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(handle->fd); handle->fd = -1; - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } } else { handle->closed = 1; @@ -817,11 +771,8 @@ if (handle->tls) tls_close(handle->tls); #endif if (close(handle->fd)) { - moonbr_io_errmsg(); handle->fd = -1; - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_errmsg(); } handle->fd = -1; } @@ -881,7 +832,7 @@ addrlen = sizeof(addr); if (getsockname(*fd, &addr, &addrlen)) { if (errno != ENOTSOCK) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Unexpected error when examining socket: %s", errmsg); } handle->issock = 0; @@ -911,7 +862,7 @@ #endif handle->fd = *fd; /* required for set_linger call */ if (moonbr_io_handle_set_linger(L, handle, 0)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); handle->fd = -1; luaL_error(L, "Unexpected error while setting SO_LINGER with setsockopt: %s", errmsg); } @@ -927,7 +878,7 @@ const char *addrstr; addrlen = sizeof(addr_in6); if (getsockname(*fd, (struct sockaddr *)&addr_in6, &addrlen)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not determine local IP address/port: %s", errmsg); } if (addrlen > sizeof(addr_in6)) { @@ -935,7 +886,7 @@ } addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); if (!addrstr) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not format local IP address: %s", errmsg); } else { lua_pushstring(L, addrstr); @@ -944,7 +895,7 @@ lua_pushinteger(L, ntohs(addr_in6.sin6_port)); lua_setfield(L, -2, "local_tcpport"); if (getpeername(*fd, (struct sockaddr *)&addr_in6, &addrlen)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); } if (addrlen > sizeof(addr_in6)) { @@ -952,7 +903,7 @@ } addrstr = inet_ntop(AF_INET6, addr_in6.sin6_addr.s6_addr, addrstrbuf, sizeof(addrstrbuf)); if (!addrstr) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not format remote IP address: %s", errmsg); } else { lua_pushstring(L, addrstr); @@ -966,7 +917,7 @@ const char *addrstr; addrlen = sizeof(addr_in); if (getsockname(*fd, (struct sockaddr *)&addr_in, &addrlen)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not determine local IP address/port: %s", errmsg); } if (addrlen > sizeof(addr_in)) { @@ -974,7 +925,7 @@ } addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); if (!addrstr) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not format local IP address: %s", errmsg); } else { lua_pushstring(L, addrstr); @@ -983,7 +934,7 @@ lua_pushinteger(L, ntohs(addr_in.sin_port)); lua_setfield(L, -2, "local_tcpport"); if (getpeername(*fd, (struct sockaddr *)&addr_in, &addrlen)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not determine remote IP address/port: %s", errmsg); } if (addrlen > sizeof(addr_in)) { @@ -991,7 +942,7 @@ } addrstr = inet_ntop(AF_INET, &addr_in.sin_addr.s_addr, addrstrbuf, sizeof(addrstrbuf)); if (!addrstr) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Could not format remote IP address: %s", errmsg); } else { lua_pushstring(L, addrstr); @@ -1054,25 +1005,13 @@ SOCK_STREAM | SOCK_CLOEXEC | (nonblocking ? SOCK_NONBLOCK : 0), 0 ); - if (sock < 0) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (sock < 0) moonbr_io_return_errmsg(); if (connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) { if (!nonblocking && errno == EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + moonbr_io_return_prepared_errmsg(); + } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) moonbr_io_return_errmsg(); } moonbr_io_pushhandle(L, sock); return 1; @@ -1102,7 +1041,7 @@ if (errcode) { freeaddrinfo(res); if (errcode == EAI_SYSTEM) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); lua_pushnil(L); lua_pushfstring(L, "%s: %s", gai_strerror(errcode), errmsg); } else { @@ -1125,26 +1064,17 @@ addrinfo->ai_protocol ); if (sock < 0) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); freeaddrinfo(res); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } if (connect(sock, addrinfo->ai_addr, addrinfo->ai_addrlen)) { freeaddrinfo(res); if (!nonblocking && errno == EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + moonbr_io_return_prepared_errmsg(); + } else if (!(nonblocking && (errno == EINPROGRESS || errno == EINTR))) moonbr_io_return_errmsg(); } else { freeaddrinfo(res); } @@ -1183,25 +1113,16 @@ SOCK_STREAM | SOCK_CLOEXEC, 0 ); - if (sock < 0) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + if (sock < 0) moonbr_io_return_errmsg(); if (bind(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } if (listen(sock, MOONBR_IO_LISTEN_BACKLOG)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } listener->fd = sock; listener->addrfam = AF_LOCAL; @@ -1229,7 +1150,7 @@ if (errcode) { freeaddrinfo(res); if (errcode == EAI_SYSTEM) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); lua_pushnil(L); lua_pushfstring(L, "%s: %s", gai_strerror(errcode), errmsg); } else { @@ -1253,16 +1174,14 @@ addrinfo->ai_protocol ); if (sock < 0) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); freeaddrinfo(res); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } { static const int reuseval = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseval, sizeof(reuseval))) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); freeaddrinfo(res); close(sock); lua_pushnil(L); @@ -1271,20 +1190,16 @@ } } if (bind(sock, addrinfo->ai_addr, addrinfo->ai_addrlen)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); freeaddrinfo(res); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } freeaddrinfo(res); if (listen(sock, MOONBR_IO_LISTEN_BACKLOG)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sock); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } listener->fd = sock; listener->nonblocking = -1; @@ -1300,7 +1215,7 @@ int flags; flags = fcntl(listener->fd, F_GETFL, 0); if (flags == -1) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(listener->fd); listener->fd = -1; luaL_error(L, "Unexpected error in fcntl call: %s", errmsg); @@ -1308,7 +1223,7 @@ if (nonblocking) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; if (fcntl(listener->fd, F_SETFL, flags) == -1) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(listener->fd); listener->fd = -1; luaL_error(L, "Unexpected error in fcntl call: %s", errmsg); @@ -1320,7 +1235,7 @@ fd = accept(listener->fd, NULL, NULL); if (fd != -1) { if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(listener->fd); listener->fd = -1; close(fd); @@ -1335,12 +1250,7 @@ lua_pushboolean(L, 0); lua_pushliteral(L, "No incoming connection pending"); return 2; - } else if (errno != EINTR) { - moonbr_io_errmsg(); - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; - } + } else if (errno != EINTR) moonbr_io_return_errmsg(); } else { moonbr_io_pushhandle(L, fd); return 1; @@ -1366,16 +1276,14 @@ addrlen = sizeof(addr); if (getsockname(listener->fd, (struct sockaddr *)&addr, &addrlen)) addrlen = 0; if (close(listener->fd)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); listener->fd = -1; if (addrlen && addrlen <= sizeof(addr)) { if (stat(addr.sun_path, &sb) == 0) { if (S_ISSOCK(sb.st_mode)) unlink(addr.sun_path); } } - lua_pushnil(L); - lua_pushstring(L, errmsg); - return 2; + moonbr_io_return_prepared_errmsg(); } listener->fd = -1; if (addrlen && addrlen <= sizeof(addr)) { @@ -1412,13 +1320,13 @@ lua_setuservalue(L, -2); luaL_setmetatable(L, MOONBR_IO_CHILD_MT_REGKEY); if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sockin)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); lua_pushnil(L); lua_pushfstring(L, "Could not create socket pair: %s", errmsg); return 2; } if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sockout)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sockin[0]); close(sockin[1]); lua_pushnil(L); @@ -1426,7 +1334,7 @@ return 2; } if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sockerr)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sockin[0]); close(sockin[1]); close(sockout[0]); @@ -1437,7 +1345,7 @@ } child->pid = vfork(); if (child->pid == -1) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); close(sockin[0]); close(sockin[1]); close(sockout[0]); @@ -1476,7 +1384,7 @@ close(sockerr[0]); while (waitpid(child->pid, &status, 0) == -1) { if (errno != EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in waitpid call after unsuccessful exec: %s", errmsg); } } @@ -1516,7 +1424,7 @@ int status; while (waitpid(child->pid, &status, 0) == -1) { if (errno != EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in waitpid call after error creating socket handles: %s", errmsg); } } @@ -1556,12 +1464,12 @@ if (child->pid) { int status; if (kill(child->pid, SIGKILL)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in kill call during garbage collection: %s", errmsg); } while (waitpid(child->pid, &status, 0) == -1) { if (errno != EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in waitpid call during garbage collection: %s", errmsg); } } @@ -1576,7 +1484,7 @@ sig = luaL_optinteger(L, 2, SIGTERM); if (!child->pid) luaL_error(L, "Attempt to kill an already collected child process"); if (kill(child->pid, sig)) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in kill call: %s", errmsg); } lua_settop(L, 1); @@ -1591,7 +1499,7 @@ if (!child->pid) luaL_error(L, "Attempt to wait for an already collected child process"); while ((waitedpid = waitpid(child->pid, &status, nonblocking ? WNOHANG : 0)) == -1) { if (errno != EINTR) { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); luaL_error(L, "Error in waitpid call: %s", errmsg); } } @@ -1770,7 +1678,7 @@ lua_pushliteral(L, "Signal received while polling file descriptors"); return 2; } else { - moonbr_io_errmsg(); + moonbr_io_prepare_errmsg(); return luaL_error(L, "Unexpected error during \"select\" system call: %s", errmsg); } } else if (status == 0) {