⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daemonmgr.c

📁 linux下的FTP服务器。支持现在主流的FTP客户端软件。增加了一些额外的功能。
💻 C
字号:
#include "Public.h"
#include "DaemonMgr.h"

//2 实现守护进程,要求实现start,stop,restart功能
//守护进程的初始化
/*
void init_daemon(void)
{
	pid_t  pid;
	int i;
	if(pid=fork())
	{
		// 父进程
		exit(0);
	}
	else if(pid<0)
	{
		// fork 失败
		printf("call fork function failure! exit program!\n");
		exit(EXIT_FAILURE);
	}
	// 子进程
	setsid(); // 第一个进程的子进程成为新的会话组长,与终端脱离

	if (pid=fork())
	{
		exit(0);
	}
	else if(pid<0)
	{
		printf("call fork function failure! exit program!\n");
		exit(EXIT_FAILURE);
	}
	// 子子进程   子子进程不在是会话组长。是一个 无会话组长,与终端无关的进程
	// 禁止进程重新打开控制终端
	for(i=0;i<OPEN_MAX;i++)
	{
		close(1);
	}
	// 更改文件目录
	chdir("/root");
	// 重新设置文件掩码
	umask(0);
}
*/


//得到thisApp应用程序的进程号
int GetThisAppPid(const char * ThisApp,char *pidstring,int bufflen)
{

	int pipes[2];
	if(pipe(pipes)==-1)
	{
		printf("GetThisAppPid Call pipe function failure! Exit program!\n");
		exit(EXIT_FAILURE);
	}
	
	switch(fork())
	{
		case 0:
			close(1); // 重定义标准输入
			if (dup(pipes[1])==-1)
			{
				printf("Dup error");
			}
			execlp("pidof","pidof",ThisApp,0); //得到的结构输入到 管道里
			// DUP是把SEHLL 输出保存到文件里面一种很好的方法
			return -1;
		break;

		case -1:
			printf("GetThisAppPid Call pipe function failure! Exit program!\n");
			exit(EXIT_FAILURE);
			break;
		default:
			close(pipes[1]);
			read(pipes[0],pidstring,bufflen); // 从管道里面读存在pidstring 缓冲区中
			return 0;
			break;
	}

}


// 结束守护进程
int daemon_stop(char * ThisApp)
{
	int thisid=0;
	thisid=getpid();
	char buff[MAX_BUFF_LEN]={0};
	GetThisAppPid(ThisApp,buff,MAX_BUFF_LEN);

	char temppid[SHORT_STR_LEN]={0};
	char *p=buff;

	int tempintid,i=0;

	if (!strchr(buff,' ')) // 当前只有一个进程
	{
		printf( "[ Services are not running  ]\n");
		return -1;
	}

     char * strtmp="Ftp Server stop.";
	 write(1,strtmp,strlen(strtmp));

	// 杀死进程
	 while (*p)
	{
		while (*p&&isspace(*p))p++;
		i=0;
		while (*p&&!isspace(*p))
			temppid[i++]=*p++;
			
		tempintid=atoi(temppid);
		if (tempintid!=0&&thisid!=tempintid) 
		{
			kill(tempintid,SIGTERM);		//杀死进程
		}

		//memset(tempintid,0,SHORT_STR_LEN);
		//if(*p=='\0')	break;
	}


	int pointcount=10;
	for (;pointcount>0;pointcount--) {
		write(1,".",1);
		usleep(10000);		
	}
	write(1,"[  OK  ]\n",strlen("[  OK  ]\n"));
	Del_shm();
	return 0;
}

//开始ThisApp 守护进程
int daemon_start(char * ThisApp,void (*start)(void))
{
	if (getuid()!=0)
	{
		printf("Please root user to start %s\n",ThisApp);
		exit(1);
	}
	
	int thisid=0; //这个进程的ID
	thisid=getpid(); // 得到这个进程的ID
	char buff[MAX_BUFF_LEN]={0};
	
	GetThisAppPid(ThisApp,buff,MAX_BUFF_LEN); // 得到ThisApp的进程号存在buff里面
	char temppid[SHORT_STR_LEN]={0};

	char *p=buff; // 字符指针
	int i=0;
	int  tempintid;
	while (*p)
	{
		while (*p && isspace(*p)) // 去除ID号前面的空格
			p++;
		i=0;

		while (*p && !isspace(*p))
		{
			temppid[i++]=*p++;
		}
		if(*p=='\0')break;

		tempintid=atoi(temppid);

		if (tempintid!=thisid)
		{
			printf( "Service has been launched\n");
			return -1;
		}
	}
	
	char *strtmp="Ftp Server Start.";
//	printf("%s",strtmp);
	write(1,strtmp,strlen(strtmp));
	int pointcount=30;
	//write(1,ThisApp,strlen(ThisApp));

	for (;pointcount>0;pointcount--) {
		write(1,".",1);
		usleep(10000);		
	}

	daemon(1,1); // 作为一个守护进程

	write(1,"[  OK  ]\n",strlen("[  OK  ]\n"));
	//printf("[OK]");
	start(); // 启动服务开始进程
}


//重启ThisApp 守护进程
int daemon_restart(char * ThisApp,void (*start)(void))
{
	daemon_stop(ThisApp);
	//usleep(100000);
	return daemon_start(ThisApp,start);
}


//控制守护进程
int daemon_ctrl(int argc, char *argv[],void(*start)(void))
{
	signal(SIGCHLD, SIG_IGN); //  防止挂起
	if (argc!=2)
	{
		printf("Usage:daemon {start|stop|restart}\n"); 
		return -1;
	}
	
	if (strcmp(argv[1],"start")==0)
	{
		return daemon_start(argv[0],start);
	}

	if (strcmp(argv[1],"stop")==0)
	{
		return daemon_stop(argv[0]);
	}

	if (strcmp(argv[1],"restart")==0)
	{	
		return daemon_restart(argv[0],start);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -