UNIX程式設計 13 守護程序

2021-08-31 15:20:27 字數 3069 閱讀 6248

1.守護程序的程式設計規則

1)用umask將檔案模式建立遮蔽字設定為0

2)呼叫fork,然後使父程序退出

3)呼叫setsid建立乙個新會話

4)將當前工作目錄更改為根目錄

5)關閉不再需要的的檔案描述符

6)某些守護程序開啟/dev/null使其具有檔案描述符0,1,2,

例:初始化乙個守護程序

#include "apue.h"

#include #include #include void

daemonize(const char *cmd)

}

2.出錯記錄

使用syslog設施產生日誌

有三種方法產生日誌資訊:

1)核心呼叫log函式

2)呼叫syslog函式以產生日誌訊息

3)用網路程式傳送到其他主機的514埠

syslogd守護程序讀取三種格式的日誌資訊,此守護程序在啟動時讀乙個配置檔案,/etc/syslog.conf,該檔案決定了不同種類的訊息送向何處。

#include void openlog(const char *ident, int option, int

facility);

void syslog(int priority, const char *format, ...);

void closelog(void);

int setlogmask(int maskpri);

returns: previous log priority mask value

3.單例項守護程序

使用檔案和記錄鎖保證只執行守護程序的乙個副本

#include #include #include #include #include #include #include #include #define lockfile "/var/run/daemon.pid"

#define lockmode (s_irusr|s_iwusr|s_irgrp|s_iroth)

extern int lockfile(int);

intalready_running(void)

if (lockfile(fd) < 0)

syslog(log_err, "can't lock %s: %s", lockfile, strerror(errno));

exit(1);

}ftruncate(fd, 0);

sprintf(buf, "%ld", (long)getpid());

write(fd, buf, strlen(buf)+1);

return(0);

}

4.守護程序的慣例

例:守護程序重新讀配置檔案

#include "apue.h"

#include #include sigset_t mask;

extern int already_running(void);

void

reread(void)

void *

thr_fn(void *arg)

switch (signo)

}return(0);

}int

main(int argc, char *argv)

/** restore sighup default and block all signals.

*/sa.sa_handler = sig_dfl;

sigemptyset(&sa.sa_mask);

sa.sa_flags = 0;

if (sigaction(sighup, &sa, null) < 0)

err_quit("%s: can't restore sighup default");

sigfillset(&mask);

if ((err = pthread_sigmask(sig_block, &mask, null)) != 0)

err_exit(err, "sig_block error");

/** create a thread to handle sighup and sigterm.

*/err = pthread_create(&tid, null, thr_fn, 0);

if (err != 0)

err_exit(err, "can't create thread");

/** proceed with the rest of the daemon.

*//* ... */

exit(0);

}

另外一種實現

#include "apue.h"

#include #include extern int lockfile(int);

extern int already_running(void);

void

reread(void)

void

sigterm(int signo)

void

sighup(int signo)

intmain(int argc, char *argv)

/** handle signals of interest.

*/sa.sa_handler = sigterm;

sigemptyset(&sa.sa_mask);

sigaddset(&sa.sa_mask, sighup);

sa.sa_flags = 0;

if (sigaction(sigterm, &sa, null) < 0)

sa.sa_handler = sighup;

sigemptyset(&sa.sa_mask);

sigaddset(&sa.sa_mask, sigterm);

sa.sa_flags = 0;

if (sigaction(sighup, &sa, null) < 0)

/** proceed with the rest of the daemon.

*//* ... */

exit(0);

}

UNIX高階程式設計 第13章 守護程序

請移步到這 13.2 守護程序的特徵 注意,大多數守護程序都以超級使用者 root 特權執行。所有的守護程序都沒有控制終端,其終端名設定為問號。核心守護程序以無控制終端方式啟動。使用者層守護程序缺少控制終端可能是守護程序呼叫了setsid的結果。大多數使用者層守護程序都是程序組的組長程序以及會話的首...

UNIX高階環境程式設計 第13章 守護程序

守護程序 沒有控制終端,長期執行在後台的程序 void daemonize const char cmd else if pid 0 呼叫setsid以建立乙個新會話 使呼叫程序 a.成為新會話的首程序,b.成為乙個新程序組的組長程序,c.沒有控制終端。setsid struct sigaction...

unix環境高階程式設計 守護程序

守護程序 daemon 是生存期長的一種程序,常常在系統引導裝入時啟動,僅在系統關閉時終止,因為它們沒有控制終端,unix有很多守護程序,它們執行日常事務活動。守護程序的特徵 執行指令 ps zxj a顯示其他使用者擁有的程序狀態,x顯示沒有終端控制的程序狀態,j顯示與作業有關的資訊 會話id 程序...