This commit changes setup_serve() to report its errors via GError object to its caller. It also add resource deallocation code to return points to free all local resources correctly. Note that, the previous version of the setup_serve() did not free its resources properly on error, but just called functions which terminated the process. This was techincally a leak, but without any practical significance due to immediate process termination. However, now that error handling (process termination) is separeted from error reporting, we must deallocate/free all locally allocated resources correctly on errors.
Signed-off-by: Tuomas Jorma Juhani Räsänen <[email protected]> --- nbd-server.c | 73 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/nbd-server.c b/nbd-server.c index 87f63fc..be65ebb 100644 --- a/nbd-server.c +++ b/nbd-server.c @@ -2392,12 +2392,11 @@ int dosockopts(const int socket, GError **const gerror) { * * @param serve the server we want to connect. **/ -int setup_serve(SERVER *serve) { +int setup_serve(SERVER *const serve, GError **const gerror) { struct addrinfo hints; struct addrinfo *ai = NULL; gchar *port = NULL; int e; - GError *gerror = NULL; /* Without this, it's possible that socket == 0, even if it's * not initialized at all. And that would be wrong because 0 is @@ -2432,10 +2431,12 @@ int setup_serve(SERVER *serve) { g_free(port); if(e != 0) { - fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(e)); - serve->socket = -1; - freeaddrinfo(ai); - exit(EXIT_FAILURE); + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_GAI, + "failed to open an export socket: " + "failed to get address info: %s", + gai_strerror(e)); + freeaddrinfo(ai); + return -1; } if(serve->socket_family == AF_UNSPEC) @@ -2449,23 +2450,46 @@ int setup_serve(SERVER *serve) { ai->ai_family = AF_INET6_SDP; } #endif - if ((serve->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) - err("socket: %m"); - - if (dosockopts(serve->socket, &gerror) == -1) { - msg(LOG_ERR, "failed to open export-specific socket: %s", - gerror->message); - g_clear_error(&gerror); - exit(EXIT_FAILURE); + if ((serve->socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_SOCKET, + "failed to open an export socket: " + "failed to create a socket: %s", + strerror(errno)); + freeaddrinfo(ai); + return -1; + } + + if (dosockopts(serve->socket, gerror) == -1) { + g_prefix_error(gerror, "failed to open an export socket: "); + close(serve->socket); + serve->socket = -1; + freeaddrinfo(ai); + return -1; } DEBUG("Waiting for connections... bind, "); e = bind(serve->socket, ai->ai_addr, ai->ai_addrlen); - if (e != 0 && errno != EADDRINUSE) - err("bind: %m"); + if (e != 0 && errno != EADDRINUSE) { + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_BIND, + "failed to open an export socket: " + "failed to bind an address to a socket: %s", + strerror(errno)); + close(serve->socket); + serve->socket = -1; + freeaddrinfo(ai); + return -1; + } DEBUG("listen, "); - if (listen(serve->socket, 1) < 0) - err("listen: %m"); + if (listen(serve->socket, 1) < 0) { + g_set_error(gerror, SETUP_ERROR, SETUP_ERROR_BIND, + "failed to open an export socket: " + "failed to start listening on a socket: %s", + strerror(errno)); + close(serve->socket); + serve->socket = -1; + freeaddrinfo(ai); + return -1; + } freeaddrinfo (ai); if(serve->servename) { @@ -2551,7 +2575,18 @@ void setup_servers(GArray *const servers, const gchar *const modernaddr, int want_modern=0; for(i=0;i<servers->len;i++) { - want_modern |= setup_serve(&(g_array_index(servers, SERVER, i))); + GError *gerror = NULL; + SERVER *server = &g_array_index(servers, SERVER, i); + int ret; + + ret = setup_serve(server, &gerror); + if (ret == -1) { + msg(LOG_ERR, "failed to setup servers: %s", + gerror->message); + g_clear_error(&gerror); + exit(EXIT_FAILURE); + } + want_modern |= ret; } if(want_modern) { GError *gerror = NULL; -- 1.7.10.4 ------------------------------------------------------------------------------ Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and much more. Get web development skills now with LearnDevNow - 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122812 _______________________________________________ Nbd-general mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/nbd-general
