I'm playing with luaposix module (using luajit) trying to learn how to fork process and demonize it. Here is the code that create a new process and try to set up a msg queue for communication with the child. I use the function msgget(key) to create the queue but the function goes in error with "No such file or directory", please can someone help me to understand where is the mistake ?
local psx = require("posix");
local os = require("os");
--daemon sleep before die
local DAEMON_SLEEP_BD = 20;
--sleep seconds in write
local SLEEP_SEC = 1;
--message que key
local MSGQ_KEY = 1000;
function main()
local ppid = nil;
local pid = nil;
local sid = nil;
--clear screen
os.execute("clear");
--get process pid - this is the parent
ppid = psx.getpid ("pid");
psx.sleep(SLEEP_SEC);
io.write("proces started with pid : "..ppid.."\n");
psx.sleep(SLEEP_SEC);
--create a msq queque
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." is going to create a msg queue...\n");
psx.sleep(SLEEP_SEC);
local msgqid = psx.msgget(MSGQ_KEY,psx.IPC_CREATE);
if msgqid==nil then
psx.sleep(SLEEP_SEC);
io.write(psx.errno().."\n");
io.write("process "..ppid.." failed to create msg queue...stopping execution\n") ;
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." created msg que with identifier "..msgqid.."\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." is going to fork\n");
psx.sleep(SLEEP_SEC);
pid = psx.fork();
if pid < 0 then
psx.sleep(SLEEP_SEC);
io.write("process " ..ppid.." failed to fork...stopping execution\n")
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
if pid > 0 then
--##################################################
--here put the code of parent process after the fork
--##################################################
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." is going to wait msg from forked child\n");
psx.sleep(SLEEP_SEC);
while true do
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." waiting for msg from forked process.\n");
psx.sleep(SLEEP_SEC);
local msg_type, msg_text = psx.msgrcv(msgqid,1,100)
if msg_type == nil then
psx.sleep(SLEEP_SEC);
io.write("process " ..ppid.." raised error receiving msg...stopping execution\n");
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
if msg_text == "ok" then
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." received mesg from forked "..msg_text.." stopping execution to demonaze\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." die letting fork to demonize\n");
psx.sleep(SLEEP_SEC);
psx._exit(0);
end
end --while
end --if
--#################################################################
--here write the code of child process that will setup it as daemon
--#################################################################
pid = psx.getpid("pid");
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." born from fork is the candidate daemon...\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write(str.format("process "..pid.." eredited db env %s \n",envv));
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write(str.format("process "..pid.." eredited db connection %s \n",con));
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." changing umask\n");
psx.sleep(SLEEP_SEC);
psx.umask(0);
--open log for writing --to_do
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." changing setsid...\n");
psx.sleep(SLEEP_SEC);
sid = psx.setpid("s");
if sid ==nill then
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." setsid failed\n");
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." candidate daemon sid :"..sid.."\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." changing working directory.\n");
psx.sleep(SLEEP_SEC);
if psx.chdir("/")==nill then
psx.sleep(SLEEP_SEC);
io.write(".....can't change the dir\n");
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
psx.sleep(SLEEP_SEC);
io.write("process " ..pid.." changed directory to "..psx.getcwd().."\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." attaching parent message queue with msgq_key "..MSGQ_KEY.."\n");
psx.sleep(SLEEP_SEC);
--attach the msg que using the same key
msgqid = psx.msgget(MSGQ_KEY);
if msgqid == nill then
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." attaching msgq failed...stopping execution\n");
psx.sleep(SLEEP_SEC);
psx._exit(-1);
end
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." has attached msq queue with msgid "..msgqid.."\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." going to close all file descriptor now is a daemon\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." entering in while loop.\n");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." sending msg to parent telling him to die\n");
psx.sleep(SLEEP_SEC);
if psx.msgsnd(msgqid,1,"ok")==nil then
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." raised error sending msg...stopping execution.\n");
psx.sleep(SLEEP_SEC);
end
psx.sleep(SLEEP_SEC);
io.write("process "..pid.." msg sent\n");
psx.sleep(SLEEP_SEC);
psx.close(0);
psx.close(1);
psx.close(2);
while true do
--here write the code of daemon
--you can't use io.write/print because fd are closed
psx.sleep(DAEMON_SLEEP_BD)
psx._exit(0);
end --while
end --main
main()