我有一個啓動守護進程,我想從用戶應用程序請求狀態信息。我實現了使用Unix套接字客戶端 - 服務器模型(與守護程序服務器),如下所述:OS X - Communication between launch daemon and launch agent守護進程 - 使用Unix套接字的客戶端IPC
事實上它工作得很好,當我運行的後臺程序作爲一個用戶進程(用於調試),但它會失敗當它實際上以root身份啓動時。
我看了TN on Daemons and Agents和Daemon & 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");
//...
}
謝謝,這幫助了我。 – codingFriend1