2012-07-24 37 views
4

我的進程作爲守護進程運行。 我想用信號重新加載配置。 問題是,如果配置錯誤,它應該以tty形式發送信號的錯誤消息。在發送信號的終端顯示一條消息

  1. 有沒有辦法做到這一點?
  2. 它是推薦的方式嗎?

如果沒有推薦的方式。什麼是更合適的方法來檢查它是否成功?

+1

我覺得更堅實的做法是寫你的包裝,人們可以用它來做事喜歡重啓,重裝配置等東西就像一個「遙控器」程序Apache Web服務器的「apachectl」。 – 2012-07-24 07:54:07

回答

2

我猜你的東西像抓住SIGUSR1,然後重新加載配置?

你應該記住,信號處理程序應儘可能小,見效快的可能,而不是做一些事情,可能會導致另一個信號。所以基本上你應該儘可能避免I/O。可能最好的辦法是設置一個非常簡單的信號處理程序,只設置一個標誌,然後在主循環中檢查此標誌,然後在主線程的上下文中重新加載配置。在那裏你可以輸出到控制檯所有你想要的。

+0

該循環檢查應該有什麼閒置睡眠時間? – 2012-07-24 07:58:34

+0

@VivekGoel這完全取決於你。如果你的程序是事件驅動的,那麼你可以使用適合你所使用的事件框架而不是標誌(例如條件變量,管道)的東西。 – 2012-07-24 08:07:44

1

你可以這樣做,但沒有瑣碎的方式來做到這一點。您需要爲守護進程安排一種機制來反饋發送信號的進程。

包括做着一些可能的方式:

  • 寫(時間戳)導致在預定位置的文件。
  • 守護進程是否保持與已知結構中的信息共享的內存段。
  • 有後臺監聽某種形式的命名管道/插座並給出反饋意見的方式。 (您也可以通過該頻道發送重新載入命令)。
  • 具有將信號和守護進程鏈接發送到共享庫的事情,以便兩者都能夠驗證配置文件。提升信號之前驗證文件。

在那些命名管道將是我的第一選擇,我認爲 - 你可以限制對它的訪問與正常的權限,這是最簡單的做出健全和正確的。

0

我懷疑,你可以確定信號源,甚至如果可以的話,它不一定是終端。使用簡單的tcp/ip協議怎麼樣?接受特殊端口上的tcp/ip連接。閱讀命令,直到第一個新行。如果該命令是「重新配置」,則執行重新配置並通過建立的TCP/IP連接發送消息。

6

爲獲得信號源的PID,您需要在設置信號處理程序使用sa_sigaction代替sa_handler

static pid_t g_killer_pid = 0; 

static void signal_handler(int num, siginfo_t *info, void* blabla) 
{ 
    g_killer_pid = info->si_pid; 
} 

int main(void) 
{  
    struct sigaction sa; 

    memset(&sa, 0, sizeof(sa)); 
    sa.sa_sigaction = &signal_handler; 
    sa.sa_flags = SA_SIGINFO; 
    sigaction(SIGTERM, &sa, NULL); 
    sigaction(SIGINT, &sa, NULL); 

    pause(); 
    hello_killer(g_killer_pid); 

    return 0; 
} 

現在你的PID源的過程。

獲取源進程的終端ID並不那麼簡單。 一種方法是從proc/<pid>/stat文件中讀取它。文件中的一個數字是tty_nrtty_nr對我來說有點奇怪,所以我不知道這是甚至便攜的東西。 但它擁有次要號碼,可用於打開正確的端子寫作:

static void hello_killer(pid_t killer) 
{ 
    char filename[200]; 
    FILE* fil; 
    FILE* out; 
    int tty_nr; 

    sprintf(filename, "/proc/%ld/stat", (long int)killer); 
    fil = fopen(filename, "r"); 
    if(fil) 
    { 
     if(fscanf(fil, "%*s %*s %*s %*s %*s %*s %d ", &tty_nr) == 1) 
     { 
      sprintf(filename, "/dev/pts/%d", (tty_nr & 0xF) | ((tty_nr >> 20) & 0xFFF)); 

      out = fopen(filename, "a"); 
      if(out) 
      { 
       fprintf(out, "Hello!\n"); 
       fclose(out); 
      } 
     } 
     fclose(fil); 
    } 
} 

我不知道的是,/dev/pts招正確的/最好的方式做到這一點。但似乎在我的Linux機器的工作:

~ # killall temp_test 
Hello! 
~ #