linux守护进程
#include <iostream>
#include <unistd.h>
//#include "curl/curl.h"
#include "app_curl.h"
#include "youtube_package.h"
#include "CAutoMail.h"
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#define LOCKFILE "./daemon.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
int lockfile(int fd);
int lockfile(int fd)
{
struct flock fl;
fl.l_len=0;
fl.l_type=F_WRLCK;
fl.l_whence=SEEK_SET;
fl.l_start=0;
return (fcntl(fd,F_SETLK,&fl));
}
int already_running(void)
{
int fd;
char buf[16]={0};
int nResult=0;
if(0>(fd=open(LOCKFILE,O_RDWR|O_CREAT,LOCKMODE)))
{
COMM_LOG("youtube",LOG_ERROR,"can't open %s:%s",LOCKFILE,strerror(errno));
exit(1);
}
if(lockfile(fd)<0)
{
if(errno==EACCES || errno==EAGAIN)
{
close(fd);
return 1;
}
COMM_LOG("youtube",LOG_ERROR,"can't lock %s:%s",LOCKFILE,strerror(errno));
exit(1);
}
nResult=ftruncate(fd,0);
snprintf(buf,sizeof(buf),"%ld",(long)getpid());
nResult=write(fd,buf,strlen(buf)+1);
return 0;
}
void daemonize(const char *cmd)
{
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
//umask(0);
if((pid=fork())<0)
{
COMM_LOG("youtube",LOG_ERROR,"%s","pid can't fork");
exit(0);
}else if(pid!=0)
{
exit(0);
}
setsid();
sa.sa_handler=SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags=0;
if(sigaction(SIGHUP,&sa,NULL)<0)
{
COMM_LOG("youtube",LOG_ERROR,"%s","can't ignore SIGHUP");
exit(0);
}
if((pid=fork())<0)
{
COMM_LOG("youtube",LOG_ERROR,"%s","pid can't fork");
exit(0);
}else if(pid!=0)
{
exit(0);
}
//if(chdir("/")<0)
//{
// COMM_LOG("youtube",LOG_ERROR,"%s","can't change directory to /");
// exit(0);
//}
if(rl.rlim_max==RLIM_INFINITY)
rl.rlim_max=1024;
for(i=0;i<rl.rlim_max;i++)
close(i);
fd0=open("/dev/null",O_RDWR);
fd1=dup(0);
fd2=dup(0);
if(fd0!=0 || fd1!=1 || fd2!=2)
{
COMM_LOG("youtube",LOG_ERROR,"%s,%d,%d,%d","unexpected file descriprors",fd0,fd1,fd2);
exit(1);
}
}
int main()
{
int ret=0;
#if 0
daemonize(NULL);
if(already_running())
{
COMM_LOG("youtube",LOG_ERROR,"%s","daemon already running");
exit(1);
}
#endif
//CurlDownLoad("46.51.223.70/script/youtube_rev.ver","youtube_rev.ver",CurlWriteToFile);
// printf("hello world\n");
YtbDecrypt::GetInstance();//解密前置
//CAutoMail::GetInstance()->SendMail("test","this is a test file!");
//CAutoMail::GetInstance()->SendMail("test","你好啊,中文测试!");
//printf("jiexi0--\n");
while(1)
{
sleep(10);
}
return ret;
}
关系所有的文件描述符:
for(i=getdtablesize()-1;i>=0;--i)
close(i);
NAME
getdtablesize - get descriptor table size
SYNOPSIS
#include <unistd.h>
int getdtablesize(void);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
getdtablesize():
Since glibc 2.12:
_BSD_SOURCE ||
!(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
Before glibc 2.12:
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
DESCRIPTION
getdtablesize() returns the maximum number of files a process can have open, one more than the largest possible value for a file
descriptor.
RETURN VALUE
The current limit on the number of open files per process.
ERRORS
On Linux, getdtablesize() can return any of the errors described for getrlimit(2); see NOTES below.
对服务器编程以改变它的控制TTY:
使进程与其控制终端分开:
fd=open("/dev/tty",0_RDWR);
(void)ioctl(fd,TIOCNOTTY,0);
(void)close(fd);
每个进程继承了一个进程组的成员关系,为避免接收其父进程有意义的下信号,服务器必须离开其父进程的进程组。
对服务器编程以设置其进程组:
(void)setpgrp(0,getpid());
相关文章
- Linux下性能监控、守护进程与计划任务管理
- linux系统中,查看当前系统中,都在监听哪些端口
- 关于 Linux 进程的睡眠和唤醒 ,来看这篇就够了~
- linux内核——进程管理
- Linux 进程后台运行的几种方式(screen)
- linux 进程间通信
- 基于Linux进程共享内存&进程共享mutex实现的订票系统
- Linux基础:如何在命令行中查看目录的大小
- 如何在 Ubuntu/Debian/Linux Mint 中编译和安装 wxWidgets
- 关于Linux防火墙'iptables'的面试问答
- MySQL8.0安装教程,在Linux环境安装MySQL8.0教程,最新教程 超详细
- linux内核的0号进程是在哪里创建的?
- 【Linux】ubuntu中的软件包管理器apt和dpkg、apt和apt-get的区别
- Linux:进程和计划任务管理(ps、top、at、crontab)
- Linux - Centos7系统破解root用户密码
- 《操作系统真象还原》——0.14 为什么Linux系统下的应用程序不能在Windows系统下运行
- 《Linux/UNIX OpenLDAP实战指南》——2.6 OpenLDAP目录树规划
- 【Linux】进程控制(详细解析)
- 第7章 Linux上配置RAID
- 【转】学习Linux守护进程详细笔记
- Linux守护进程的编程实现
- Linux 查看占用资源cpu、内存最大的进程命令
- 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---17