1. gcc -o qustion-daemon qustion-daemon.c
2. sudo ./qustion-daemon
3. sudo ./qustion-daemon hi
4. cat /var/log/syslog | tail
5. pkill -n qustion-daemon
該例子我是參考sysvinit所寫成的。
//qustion-daemon.c
#include <&sys/stat.h&>
#include <&sys/wait.h&>
#include <&stdlib.h&>
#include <&unistd.h&>
#include <&errno.h&>
#include <&stdio.h&>
#include <&time.h&>
#include <&fcntl.h&>
#include <&string.h&>
#include <&signal.h&>
#include <&sys/syslog.h&>
#define PIPE_FD 10
int pipe_fd = -1;
int count=1;
int daemon_init(void);
void sig_term(int signo);
void check_init_fifo(void);
int tellme(int argc, char **argv);
struct my_request {
int id;
char data[128];
};
int main(int argc, char *argv[]){
if (argc==2) exit(tellme(argc, argv));
if(daemon_init() == -1){
printf("can't fork self\n");
exit(0);
}
openlog("qustion-daemon", LOG_PID, LOG_USER);
syslog(LOG_INFO, "program started.");
signal(SIGTERM, sig_term);
while(1) {
sleep(1);
check_init_fifo();
}
}
int tellme(int argc, char **argv){
struct my_request request;
int fd;
memset(&request, 0, sizeof(request));
request.id=count;
strcpy(request.data,argv[1]);
if ((fd = open("/dev/myfifo", O_WRONLY)) >= 0 &&
write(fd, &request, sizeof(request)) == sizeof(request)) {
close(fd);
return 0;
}
count++;
}
int daemon_init(void)
{
pid_t pid;
if((pid = fork()) < 0) return(-1);
else if(pid != 0) exit(0); /* parent exit */
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
close(0); /* close stdin */
close(1); /* close stdout */
close(2); /* close stderr */
return(0);
}
void sig_term(int signo)
{
if(signo == SIGTERM){
syslog(LOG_INFO, "program terminated.");
if(pipe_fd != -1)
close(pipe_fd );
closelog();
exit(0);
}
}
void check_init_fifo(void){
struct stat st, st2;
fd_set fds;
int n;
struct timeval tv;
FILE *fp;
char buf[256];
struct my_request request;
int quit = 0;
if (stat("/dev/myfifo", &st2) < 0 && errno == ENOENT)
mkfifo("/dev/myfifo", 0600);
/*
* If /dev/initctl is open, stat the file to see if it
* is still the _same_ inode.
*/
if (pipe_fd >= 0) {
fstat(pipe_fd, &st);
if (stat("/dev/myfifo", &st2) < 0 ||
st.st_dev != st2.st_dev ||
st.st_ino != st2.st_ino) {
close(pipe_fd);
pipe_fd = -1;
}
}
/*
* Now finally try to open /dev/initctl
*/
if (pipe_fd < 0) {
if ((pipe_fd = open("/dev/myfifo", O_RDWR|O_NONBLOCK)) >= 0) {
fstat(pipe_fd, &st);
if (!S_ISFIFO(st.st_mode)) {
syslog(LOG_INFO, "%s is not a fifo","/dev/myfifo");
close(pipe_fd);
pipe_fd = -1;
}
}
if (pipe_fd >= 0) {
/*
* Don't use fd's 0, 1 or 2.
*/
(void) dup2(pipe_fd, PIPE_FD);
close(pipe_fd);
pipe_fd = PIPE_FD;
/*
* Return to caller - we'll be back later.
*/
}
}
/* Wait for data to appear, _if_ the pipe was opened. */
if (pipe_fd >= 0) while(!quit) {
/* Do select, return on EINTR. */
FD_ZERO(&fds);
FD_SET(pipe_fd, &fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
n = select(pipe_fd + 1, &fds, NULL, NULL, &tv);
if (n <= 0) {
if (n == 0 || errno == EINTR) return;
continue;
}
/* Read the data, return on EINTR. */
n = read(pipe_fd, &request, sizeof(request));
sprintf(buf,"rquest=> request.id=%d,request.data=%s",request.id,request.data);
syslog(LOG_INFO, buf);
if (n <= 0) {
if (errno == EINTR) return;
syslog(LOG_INFO, "error reading initrequest");
continue;
}
}
if (pipe_fd < 0) pause();
}
1 則留言:
Yet another technique of scaling down the maturing in our epidermis is consuming a healthy diet plan [url=http://lfcream.com]lifecell[/url] intricate called Useful Keratin and the antioxidant coenzyme q10 supplement. lifecell This http://ywashst.com emphasis a lot on their own face.
張貼留言