#lua #posix #luajit
#lua #posix #luajit
Вопрос:
Я играю с модулем luaposix (используя luajit), пытаясь узнать, как разветвлять процесс и демонизировать его. Вот код, который создает новый процесс и пытается настроить очередь сообщений для связи с дочерним процессом. Я использую функцию msgget (ключ) для создания очереди, но функция выдает ошибку «Нет такого файла или каталога», пожалуйста, может кто-нибудь помочь мне понять, в чем ошибка?
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 executionn") ;
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 forkn");
psx.sleep(SLEEP_SEC);
pid = psx.fork();
if pid < 0 then
psx.sleep(SLEEP_SEC);
io.write("process " ..ppid.." failed to fork...stopping executionn")
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 childn");
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 executionn");
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 demonazen");
psx.sleep(SLEEP_SEC);
psx.sleep(SLEEP_SEC);
io.write("process "..ppid.." die letting fork to demonizen");
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 umaskn");
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 failedn");
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 dirn");
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 executionn");
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 daemonn");
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 dien");
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 sentn");
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()
Комментарии:
1. Флаг есть
psx.IPC_CREAT
и нетpsx.IPC_CREATE
.2. Извините, моя ошибка при вводе, да, это psx.IPC_CREAT, теперь очередь создана, но когда дочерний процесс отправляет сообщение, родительский процесс его не получает.
3. Теперь работает нормально, я инвертировал аргументы в msgrcv, psx.msgrcv(msgqid,1,100) => psx.msgrcv(msgqid,100,1)