moonbridge

changeset 303:477456cea361

Avoid using WNOWAIT in moonbridge_io.poll(...) for Linux compatibility
author jbe
date Wed Nov 15 15:35:42 2017 +0100 (21 months ago)
parents b2282fb8553b
children e18589f22314
files moonbridge_io.c
line diff
     1.1 --- a/moonbridge_io.c	Fri Jun 23 15:49:43 2017 +0200
     1.2 +++ b/moonbridge_io.c	Wed Nov 15 15:35:42 2017 +0100
     1.3 @@ -114,6 +114,8 @@
     1.4  
     1.5  typedef struct {
     1.6    pid_t pid;
     1.7 +  int status;
     1.8 +  int status_valid;
     1.9  } moonbr_io_child_t;
    1.10  
    1.11  volatile sig_atomic_t moonbr_io_sigterm_flag = 0;
    1.12 @@ -1367,6 +1369,7 @@
    1.13    argv[argc] = NULL;
    1.14    child = lua_newuserdata(L, sizeof(moonbr_io_child_t));
    1.15    child->pid = 0;
    1.16 +  child->status_valid = 0;
    1.17    lua_newtable(L);
    1.18    lua_setuservalue(L, -2);
    1.19    luaL_setmetatable(L, MOONBR_IO_CHILD_MT_REGKEY);
    1.20 @@ -1535,10 +1538,13 @@
    1.21    int sig;
    1.22    child = luaL_checkudata(L, 1, MOONBR_IO_CHILD_MT_REGKEY);
    1.23    sig = luaL_optinteger(L, 2, SIGKILL);
    1.24 -  if (!child->pid) luaL_error(L, "Attempt to kill an already collected child process");
    1.25 -  if (kill(child->pid, sig)) {
    1.26 -    moonbr_io_prepare_errmsg();
    1.27 -    luaL_error(L, "Error in kill call: %s", errmsg);
    1.28 +  if (!child->pid) {
    1.29 +    if (!child->status_valid) luaL_error(L, "Attempt to kill an already collected child process");
    1.30 +  } else {
    1.31 +    if (kill(child->pid, sig)) {
    1.32 +      moonbr_io_prepare_errmsg();
    1.33 +      luaL_error(L, "Error in kill call: %s", errmsg);
    1.34 +    }
    1.35    }
    1.36    lua_settop(L, 1);
    1.37    return 1;
    1.38 @@ -1546,31 +1552,35 @@
    1.39  
    1.40  static int moonbr_io_wait_impl(lua_State *L, int nonblocking) {
    1.41    moonbr_io_child_t *child;
    1.42 -  pid_t waitedpid;
    1.43    int status;
    1.44    child = luaL_checkudata(L, 1, MOONBR_IO_CHILD_MT_REGKEY);
    1.45 -  if (!child->pid) luaL_error(L, "Attempt to wait for an already collected child process");
    1.46 -  while ((waitedpid = waitpid(child->pid, &status, nonblocking ? WNOHANG : 0)) == -1) {
    1.47 -    if (errno != EINTR) {
    1.48 -      moonbr_io_prepare_errmsg();
    1.49 -      luaL_error(L, "Error in waitpid call: %s", errmsg);
    1.50 +  if (!child->pid) {
    1.51 +    if (!child->status_valid) luaL_error(L, "Attempt to wait for an already collected child process");
    1.52 +    status = child->status;
    1.53 +    child->status_valid = 0;
    1.54 +  } else {
    1.55 +    pid_t waitedpid;
    1.56 +    while ((waitedpid = waitpid(child->pid, &status, nonblocking ? WNOHANG : 0)) == -1) {
    1.57 +      if (errno != EINTR) {
    1.58 +        moonbr_io_prepare_errmsg();
    1.59 +        luaL_error(L, "Error in waitpid call: %s", errmsg);
    1.60 +      }
    1.61      }
    1.62 +    if (!waitedpid) {
    1.63 +      lua_pushboolean(L, 0);
    1.64 +      lua_pushliteral(L, "Process is still running");
    1.65 +      return 2;
    1.66 +    }
    1.67 +    child->pid = 0;
    1.68    }
    1.69 -  if (!waitedpid) {
    1.70 -    lua_pushboolean(L, 0);
    1.71 -    lua_pushliteral(L, "Process is still running");
    1.72 -    return 2;
    1.73 +  if (WIFEXITED(status)) {
    1.74 +    lua_pushinteger(L, WEXITSTATUS(status));
    1.75 +  } else if (WIFSIGNALED(status)) {
    1.76 +    lua_pushinteger(L, -WTERMSIG(status));
    1.77    } else {
    1.78 -    child->pid = 0;
    1.79 -    if (WIFEXITED(status)) {
    1.80 -      lua_pushinteger(L, WEXITSTATUS(status));
    1.81 -    } else if (WIFSIGNALED(status)) {
    1.82 -      lua_pushinteger(L, -WTERMSIG(status));
    1.83 -    } else {
    1.84 -      luaL_error(L, "Unexpected status value returned by waitpid call");
    1.85 -    }
    1.86 -    return 1;
    1.87 +    luaL_error(L, "Unexpected status value returned by waitpid call");
    1.88    }
    1.89 +  return 1;
    1.90  }
    1.91  
    1.92  static int moonbr_io_wait(lua_State *L) {
    1.93 @@ -1709,13 +1719,22 @@
    1.94                  moonbr_io_sigchld_flag = 0;
    1.95                  signal(SIGCHLD, moonbr_io_sigchld_handler);
    1.96                }
    1.97 -              while ((waitedpid = waitpid(child->pid, &status, WNOHANG|WNOWAIT)) == -1) {
    1.98 -                if (errno != EINTR) {
    1.99 -                  moonbr_io_prepare_errmsg();
   1.100 -                  luaL_error(L, "Error in waitpid call: %s", errmsg);
   1.101 +              if (child->status_valid) {
   1.102 +                force_wakeup = 1;
   1.103 +              } else {
   1.104 +                while ((waitedpid = waitpid(child->pid, &status, WNOHANG)) == -1) {
   1.105 +                  if (errno != EINTR) {
   1.106 +                    moonbr_io_prepare_errmsg();
   1.107 +                    luaL_error(L, "Error in waitpid call: %s", errmsg);
   1.108 +                  }
   1.109 +                }
   1.110 +                if (waitedpid) {
   1.111 +                  child->pid = 0;
   1.112 +                  child->status = status;
   1.113 +                  child->status_valid = 1;
   1.114 +                  force_wakeup = 1;
   1.115                  }
   1.116                }
   1.117 -              if (waitedpid) force_wakeup = 1;
   1.118                continue;
   1.119              } else {
   1.120                fd = lua_tointegerx(L, -2, &isnum);

Impressum / About Us