2012-12-13 40 views
0

我有一個啓動守護進程,我想從用戶應用程序請求狀態信息。我實現了使用Unix套接字客戶端 - 服務器模型(與守護程序服務器),如下所述:OS X - Communication between launch daemon and launch agent守護進程 - 使用Unix套接字的客戶端IPC

事實上它工作得很好,當我運行的後臺程序作爲一個用戶進程(用於調試),但它會失敗當它實際上以root身份啓動時。

我看了TN on Daemons and AgentsDaemon & Services Programming Guide。但是,我無法找到像啓動守護進程中必須使用套接字的體面信息。

我很困惑的幾件事情:

  • 我必須指定在啓動守護進程plist文件的插座?如何?

  • 如果plist中指定了插座,這是否改變我需要在代碼中創建插座的方式嗎?

  • 什麼路徑將是很好的Unix套接字?技術說明建議/var/run,但我猜用戶進程可能不寫在那裏,或可以嗎?

  • 是否有可能是更容易的方法程序和客戶端之間做IPC?

  • 什麼是登錄守護進程輸出的最佳途徑。我試過的NSLog,但它似乎沒有工作...


我也不能確定,如果我的插座碼是正確的。也許更有經驗的人可以告訴我我是否在正確的軌道上。在守護我有以下代碼初始化Unix套接字:

#define SOCKETNAME "/var/run/com.company.myApp.socket" 

- (void) startServer { 
    //remove any prev socket 
    unlink(SOCKETNAME); 
    CFSocketContext CTX = { 0, (__bridge void *)(self), NULL, NULL, NULL }; 

    CFSocketRef unixSocket = CFSocketCreate(NULL, PF_UNIX, SOCK_STREAM, 0, 
           kCFSocketAcceptCallBack, (CFSocketCallBack)AcceptCallBack, &CTX); 
    if (unixSocket == NULL) {/*log and return*/} 

    struct sockaddr_un addr; 
    memset(&addr, 0, sizeof(addr)); 
    addr.sun_family = AF_UNIX; 
    strcpy(addr.sun_path, SOCKETNAME); 
    addr.sun_len = strlen(addr.sun_path) + sizeof (addr.sun_family); 

    NSData *address = [ NSData dataWithBytes: &addr length: sizeof(addr) ]; 
    if (CFSocketSetAddress(unixSocket, (__bridge CFDataRef) address) != kCFSocketSuccess) { 
     NSLog(@"CFSocketSetAddress() failed\n"); 
     CFRelease(unixSocket); 
    } 

    CFRunLoopSourceRef sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault, unixSocket, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes); 
    CFRelease(sourceRef);  
    CFRunLoopRun(); 
} 


void AcceptCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { 
    CTServerController* selfServerController = (__bridge CTServerController*) info; 
    //NSLog(@"acceptCallBack"); 
    //... 
} 

回答

1
  • 你不應該指定plist中的插座,你知道具體地點,服務器知道,客戶知道,這應該是足夠多的
  • 在plist中規定的用於啓動後臺程序/代理點播,你並不需要在基本情況下,插座
  • 你可以使用任何路徑,如果你的守護進程啓動第一個(通常情況下),它擁有所有有權在套接字上設置正確的權限以讓任何人(或給定的用戶,組)讀取,讀取或寫入任何給定的權利,我相信y ou只是忘了讓客戶端寫/讀unix插座
  • 我想在OSX上unix socket IPC是一個完美的,簡單的解決方案(當然還有很多其他選擇,xpc,mach消息等)
  • 你可以定義哪裏去守護程序的輸出和錯誤在它的plist(StandardOutPath,StandardErrorPath鍵)
+0

謝謝,這幫助了我。 – codingFriend1