os.execute без наследования fds родителя

У меня проблема, аналогичная описанной здесь: Запретить fork() копировать сокеты

По сути, внутри моего Lua скрипта я порождаю другой скрипт, который:

  • не требует общения с моим скриптом в любом случае
  • продолжает работать после завершения моего скрипта
  • это сторонняя программа, код которой я не контролирую

Проблема в том, что мой Lua скрипт открывает TCP сокет для прослушивания на определенном порту и после выхода из него и несмотря на явное server: close() дочерняя программа (точнее, ее дочерние программы) удерживает сокет и держит порт открытым (в состоянии LISTEN), не позволяя моему скрипту запуститься снова.

Вот пример кода, который демонстрирует проблему:

require('socket')

print('listening')
s = socket.bind("*", 9999)
s:settimeout(1)

while true do
    print('accepting connection')
    local c = s:accept()
    if c then
            c:settimeout(1)
            local rec = c:receive()
            print('received ' .. rec)
            c:close()
            if rec == "quit" then break end
            if rec == "exec" then 
                    print('running ping in background')
                    os.execute('sleep 10s &')
                    break
            end     
    end
end
print('closing server')
s:close()

Если я запускаю вышеприведенный скрипт и echo quit | nc localhost 9999, все работает хорошо - программа завершается и порт закрывается.

Однако если я делаю echo exec | nc localhost 9999, программа завершается, но порт блокируется порожденным sleep (что подтверждается netstat -lpn), пока программа не выйдет.

Как мне решить эту проблему наиболее простым способом, желательно без добавления дополнительных зависимостей.

5
задан Community 23 May 2017 в 12:31
поделиться