我正在玩luaposix模块(使用luajit)试图学习如何分叉进程并将其妖魔化。以下是创建新进程并尝试设置msg队列以与子进行通信的代码。我使用函数msgget(key)来创建队列但是函数出错了“没有这样的文件或目录”,请有人帮我理解错误在哪里?
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()