守护进程(服务器端):daemon.h daemon.c daemon_mod.c
/****************daemon.h***************/
#ifndef _DAEMON_H_
#define _DAEMON_H_
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#ifdef __cpluscplus
extern "C" {
#endif
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define VANSTOR_DAEMON_PORT 6686
int printf_cgi(int sockfd,char*fmt,...);
/*
** 服务器端添加一个代理功能,只需在此添加一个函数名声明,并在结构体数组中加入对应的一项
**
*/
void* nas_resouce_create_func(int sockfd,char*s);
/**********msg struct [modename,func_name ,args]
*/
typedef void* Func_point(int n,char*s);
static const struct msg_par{
char * name;
int func_num;
Func_point *vanstor_function;
}vanstor_daemon_array[]={
{"samba",1,nas_resouce_create_func},//calling nas_resouce_create(device,fstype,path)
};
#ifdef __cplusplus
}
#endif
#endif
/*************daemon.c********************/
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<syslog.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/mount.h>
#include <netinet/in.h>
#include "vanstor_daemon.h"
int printf_cgi(int fd,char*fmt,...){
va_list args;
char buf[1024];
int n=0;
va_start(args,fmt);
n=vsprintf(buf,fmt,args);
va_end(args);
write(fd,buf,n);
return n;
};
/***** in:src 按数据结构分解
***** out: modename,
***** func_num,
*****
*/
int msg_parse_dispatch(char *src,char *modename,int *func_num){
char c=' ';
char *result=strtok(src,&c);
strcpy(modename,result);// modename<24
result=strtok(NULL,&c);
*func_num=atoi(result);
return strlen(modename)+strlen(result);
}
int vanstor_recv(int fd){
char recv_buf[1024];
int num;
char modename[24]={0};
int func_num,i;
memset(recv_buf,0,1024);
num=read(fd,recv_buf,sizeof(recv_buf));
//printf("vanstor_recv:%s\n",recv_buf);
//syslog(LOG_INFO,"recv message:[%s]\n",recv_buf);
int n=msg_parse_dispatch(recv_buf,modename,&func_num);
for(i=0;i<ARRAY_SIZE(vanstor_daemon_array);i++){
if((0==strcmp(modename,vanstor_daemon_array[i].name))&&(func_num==vanstor_daemon_array[i].func_num)){
vanstor_daemon_array[i].vanstor_function(fd,recv_buf+n+2);
break;
}
}
close(fd);
return 0;
}
int ipc_daemon()
{
int fd,connect_fd,err;
struct sockaddr_in local_addr,client_addr;
socklen_t len;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
syslog(LOG_ERR,"can't create a listen socket!\n");
return -1;
}
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr=htonl(INADDR_ANY);
local_addr.sin_port=htons(VANSTOR_DAEMON_PORT);
err = bind(fd, (struct sockaddr *) &local_addr, sizeof(local_addr));
if (err) {
syslog(LOG_ERR,"can't bind local socket!\n");
return -1;
}
err = listen(fd, 32);
if (err) {
syslog(LOG_ERR,"can't listen in local socket !\n");
return -1;
}
while(1){
len = sizeof(client_addr);
connect_fd = accept(fd, (struct sockaddr *) &client_addr, &len);
if(connect_fd>0){
pid_t pid;
pid=fork();
if(pid<0){
syslog(LOG_ERR,"fork failed!");
}
else if(pid==0){
vanstor_recv(connect_fd);
exit(0);
}
}
}
close(fd);
return 0;
}
void handler(int num){
int status;
//int pid=
waitpid(-1,&status,WNOHANG);
/*
if(WIFEXITED(status)){
printf("the child %d exit with %d \n",pid,WIFEXITED(status));
}
*/
}
int main()
{
int pid;
if((pid=fork()))
exit(0);
if(pid<0){
printf("vanstor_daemon start failed!\n");
exit(1);
}
signal(SIGCHLD,handler);
openlog("vanstor_daemon",LOG_PID|LOG_CONS,LOG_USER);
ipc_daemon();
closelog();
return 0;
}
/*************daemon_mod.c*****************************
*****例:数据结构数组 第一项 的实现,其它代理功能可以在此文件中实现添加,也可以新建文件
********************************/
#include "daemon.h"
//args=device+fstype+path
void* nas_resouce_create_func(int sockfd,char*s){
char *device,*fstype,*path;
int ret=0;
char *res=strtok(s," ");
device=res;
res=strtok(NULL," ");
fstype=res;
res=strtok(NULL," ");
path=res;
ret=nas_resource_create(device,fstype,path); //此为库函数
if(ret){
printf_cgi(sockfd,"%s mount %s seccess!",device,path);
}else{
printf_cgi(sockfd,"%s mount %s failed!",device,path);
}
return 0;
}
/**********客户端:daemon_client.h
********想要与守护进程通信只需调用此函数
*********/
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<errno.h>
#include<netinet/in.h>
#define VANSTOR_IPC_CONNECTION "/var/vanstor.ipc" // 本地通信AF_LOCAL
//sendmsg必需与守护进程定义的数据结构格式一样 sendmsg= "modename func_num args"
int daemon_send(char*sendmsg,char*recv_msg){
int connect_fd;
int ret;
char snd_buf[1024];
int i;
//static struct sockaddr_un srv_addr;
static struct sockaddr_in srv_addr;
connect_fd=socket(AF_INET,SOCK_STREAM,0);
if(connect_fd<0)
{
printf("cannot create communication socket!\n");
return -1;
}
memset(&srv_addr,0,sizeof(srv_addr));
//srv_addr.sun_family=AF_UNIX;
//strcpy(srv_addr.sun_path,VANSTOR_IPC_CONNECTION);
srv_addr.sin_family=AF_INET;
srv_addr.sin_port=htons(6686);
if(inet_pton(AF_INET,"127.0.0.1",&srv_addr.sin_addr)<0){
printf("inet_pton error !\n");
return 0;
}
ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
if(ret==-1)
{
printf("cannot connect to the server!%d,%d:%s\n",connect_fd,errno,strerror(errno));
close(connect_fd);
return -1;
}
memset(snd_buf,0,1024);
strcpy(snd_buf,sendmsg);
write(connect_fd,snd_buf,sizeof(snd_buf));
i=read(connect_fd,recv_msg,1024);
close(connect_fd);
return i;
}