4 -- |
4 -- |
5 -- This project is MIT/X11 licensed. Please see the |
5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. |
6 -- COPYING file in the source package for more information. |
7 -- |
7 -- |
8 |
8 |
9 |
|
10 local want_pposix_version = "0.4.0"; |
|
11 |
|
12 local pposix = assert(require "prosody.util.pposix"); |
|
13 if pposix._VERSION ~= want_pposix_version then |
|
14 module:log("warn", "Unknown version (%s) of binary pposix module, expected %s." |
|
15 .. "Perhaps you need to recompile?", tostring(pposix._VERSION), want_pposix_version); |
|
16 end |
|
17 |
|
18 |
|
19 local lfs = require "lfs"; |
|
20 local stat = lfs.attributes; |
|
21 |
|
22 local prosody = _G.prosody; |
|
23 |
|
24 module:set_global(); -- we're a global module |
9 module:set_global(); -- we're a global module |
25 |
10 |
26 local umask = module:get_option_string("umask", "027"); |
11 -- TODO delete this whole concept |
27 pposix.umask(umask); |
|
28 |
|
29 -- Don't even think about it! |
|
30 if not prosody.start_time then -- server-starting |
|
31 if pposix.getuid() == 0 and not module:get_option_boolean("run_as_root") then |
|
32 module:log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!"); |
|
33 module:log("error", "For more information on running Prosody as root, see https://prosody.im/doc/root"); |
|
34 prosody.shutdown("Refusing to run as root", 1); |
|
35 end |
|
36 end |
|
37 |
|
38 local pidfile; |
|
39 local pidfile_handle; |
|
40 |
|
41 local function remove_pidfile() |
|
42 if pidfile_handle then |
|
43 pidfile_handle:close(); |
|
44 os.remove(pidfile); |
|
45 pidfile, pidfile_handle = nil, nil; |
|
46 end |
|
47 end |
|
48 |
|
49 local function write_pidfile() |
|
50 if pidfile_handle then |
|
51 remove_pidfile(); |
|
52 end |
|
53 pidfile = module:get_option_path("pidfile", nil, "data"); |
|
54 if pidfile then |
|
55 local err; |
|
56 local mode = stat(pidfile) and "r+" or "w+"; |
|
57 pidfile_handle, err = io.open(pidfile, mode); |
|
58 if not pidfile_handle then |
|
59 module:log("error", "Couldn't write pidfile at %s; %s", pidfile, err); |
|
60 prosody.shutdown("Couldn't write pidfile", 1); |
|
61 else |
|
62 if not lfs.lock(pidfile_handle, "w") then -- Exclusive lock |
|
63 local other_pid = pidfile_handle:read("*a"); |
|
64 module:log("error", "Another Prosody instance seems to be running with PID %s, quitting", other_pid); |
|
65 pidfile_handle = nil; |
|
66 prosody.shutdown("Prosody already running", 1); |
|
67 else |
|
68 pidfile_handle:close(); |
|
69 pidfile_handle, err = io.open(pidfile, "w+"); |
|
70 if not pidfile_handle then |
|
71 module:log("error", "Couldn't write pidfile at %s; %s", pidfile, err); |
|
72 prosody.shutdown("Couldn't write pidfile", 1); |
|
73 else |
|
74 if lfs.lock(pidfile_handle, "w") then |
|
75 pidfile_handle:write(tostring(pposix.getpid())); |
|
76 pidfile_handle:flush(); |
|
77 end |
|
78 end |
|
79 end |
|
80 end |
|
81 end |
|
82 end |
|
83 |
|
84 local daemonize = prosody.opts.daemonize; |
|
85 |
|
86 if daemonize == nil then |
|
87 -- Fall back to config file if not specified on command-line |
|
88 daemonize = module:get_option_boolean("daemonize", nil); |
|
89 if daemonize ~= nil then |
|
90 module:log("warn", "The 'daemonize' option has been deprecated, specify -D or -F on the command line instead."); |
|
91 -- TODO: Write some docs and include a link in the warning. |
|
92 end |
|
93 end |
|
94 |
|
95 local function remove_log_sinks() |
|
96 local lm = require "prosody.core.loggingmanager"; |
|
97 lm.register_sink_type("console", nil); |
|
98 lm.register_sink_type("stdout", nil); |
|
99 lm.reload_logging(); |
|
100 end |
|
101 |
|
102 if daemonize then |
|
103 local function daemonize_server() |
|
104 module:log("info", "Prosody is about to detach from the console, disabling further console output"); |
|
105 remove_log_sinks(); |
|
106 local ok, ret = pposix.daemonize(); |
|
107 if not ok then |
|
108 module:log("error", "Failed to daemonize: %s", ret); |
|
109 elseif ret and ret > 0 then |
|
110 os.exit(0); |
|
111 else |
|
112 module:log("info", "Successfully daemonized to PID %d", pposix.getpid()); |
|
113 write_pidfile(); |
|
114 end |
|
115 end |
|
116 module:hook("server-started", daemonize_server) |
|
117 else |
|
118 -- Not going to daemonize, so write the pid of this process |
|
119 write_pidfile(); |
|
120 end |
|
121 |
|
122 module:hook("server-stopped", remove_pidfile); |
|