/////////////////////////////////////////////////////////////////////////////////// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>//// See accompanying file COPYING.TXT file for licensing details./////////////////////////////////////////////////////////////////////////////////#define CPPCMS_SOURCE#include "daemonize.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/resource.h>#include <fcntl.h>#include <pwd.h>#include <grp.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <sstream>#include <vector>#include <locale>#include <cppcms/json.h>#include <cppcms/cppcms_error.h>namespace cppcms {namespace impl {int daemonizer::global_urandom_fd = -1;daemonizer::daemonizer(json::value const &conf){real_pid = getpid();try {daemonize(conf);}catch(...) {cleanup();throw;}}daemonizer::~daemonizer(){cleanup();}void daemonizer::cleanup(){if(!unlink_file.empty() && real_pid == getpid())unlink(unlink_file.c_str());}void daemonizer::daemonize(json::value const &conf){if(getppid() == 1)return;if(!conf.get("daemon.enable",false))return;int gid = -1;int uid = -1;int devnull_fd = -1;int lock_fd = -1;try {devnull_fd = open("/dev/null",O_RDWR);if(devnull_fd < 0) {int err = errno;throw cppcms_error(err,"Failed to open /dev/null");}std::string group = conf.get("daemon.group","");if(!group.empty()) {struct group *gr = getgrnam(group.c_str());if(!gr)throw cppcms_error("Invalid group " + group);gid = gr->gr_gid;}std::string user = conf.get("daemon.user","");if(!user.empty()) {struct passwd *pw = getpwnam(user.c_str());if(!pw)throw cppcms_error("Invalid user " + user);uid = pw->pw_uid;if(gid==-1)gid = pw->pw_gid;}std::string chroot_dir = conf.get("daemon.chroot","");if(!chroot_dir.empty()) {global_urandom_fd = open("/dev/urandom",O_RDONLY);if(global_urandom_fd < 0) {int err = errno;throw cppcms_error(err,"Failed to open /dev/urandom");}if(chdir(chroot_dir.c_str()) < 0) {int err = errno;throw cppcms_error(err,"Failed to chdir to " + chroot_dir);}if(chroot(chroot_dir.c_str()) < 0) {int err = errno;throw cppcms_error(err,"Failed to chroot to " + chroot_dir);}}int fd_limit = conf.get("daemon.fdlimit",-1);if(fd_limit != -1) {struct rlimit lm;lm.rlim_cur = fd_limit;lm.rlim_max = fd_limit;if(setrlimit(RLIMIT_NOFILE,&lm) < 0) {int err = errno;throw cppcms_error(err,"Failed to change daemon.fdlimit");}}if(gid!=-1) {if(setgid(gid) < 0) {int err = errno;throw cppcms_error(err,"Failed setgid to group " + group);}}if(uid!=-1) {if(setuid(uid) < 0) {int err = errno;throw cppcms_error(err,"Failed setuid to user " + user);}}std::string lock_file = conf.get("daemon.lock","");if(!lock_file.empty()) {if(lock_file[0]!='/') {char *wd = 0;std::vector<char> buf(256);while((wd=getcwd(&buf.front(),buf.size()))==0 && errno==ERANGE)buf.resize(buf.size()*2);if(!wd) {int err=errno;throw cppcms_error(err,"getcwd failed");}lock_file=wd + ("/" + lock_file);}lock_fd = ::open(lock_file.c_str(),O_RDWR | O_CREAT | O_EXCL,0666);if(lock_fd < 0) {int err = errno;throw cppcms_error(err,"Failed to create a lock file");}unlink_file = lock_file;}// forking twiceint chid = fork();if(chid < 0) {int err = errno;throw cppcms_error(err,"Fork failed");}if(chid != 0)exit(0);real_pid = getpid();if(setsid() < 0) {int err = errno;throw cppcms_error(err,"setsid failed");}chid = fork();if(chid < 0) {int err = errno;throw cppcms_error(err,"2nd fork failed");}if(chid != 0)exit(0);real_pid = getpid();dup2(devnull_fd,0);dup2(devnull_fd,1);dup2(devnull_fd,2);close(devnull_fd);devnull_fd = -1;int chdir_r = chdir("/");(void)(chdir_r); // shut up GCCif(lock_fd!=-1) {std::ostringstream ss;ss.imbue(std::locale::classic());ss << real_pid;std::string pid = ss.str();int v = write(lock_fd,pid.c_str(),pid.size());if(v!=int(pid.size())) {throw cppcms_error("Failed to write to lock file");}close(lock_fd);lock_fd = -1;}}catch(...) {if(lock_fd >= 0)close(lock_fd);if(devnull_fd >=0)close(devnull_fd);if(global_urandom_fd >= 0)close(global_urandom_fd);throw;}}} // impl} // cppcms
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。