SCDNotifierInformViaFD.c [plain text]
#include "SCDynamicStoreInternal.h"
#include "config.h"
#include <paths.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
Boolean
SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store,
int32_t identifier,
int *fd)
{
int fildes[2] = { -1, -1 };
fileport_t fileport = MACH_PORT_NULL;
int ret;
int sc_status;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
if (store == NULL) {
_SCErrorSet(kSCStatusNoStoreSession);
return FALSE;
}
if (storePrivate->server == MACH_PORT_NULL) {
_SCErrorSet(kSCStatusNoStoreServer);
return FALSE;
}
if (storePrivate->notifyStatus != NotifierNotRegistered) {
_SCErrorSet(kSCStatusNotifierActive);
return FALSE;
}
ret = pipe(fildes);
if (ret == -1) {
_SCErrorSet(errno);
SC_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
goto fail;
}
fileport = MACH_PORT_NULL;
ret = fileport_makeport(fildes[1], &fileport);
if (ret < 0) {
_SCErrorSet(errno);
SC_log(LOG_ERR, "fileport_makeport() failed: %s", strerror(errno));
goto fail;
}
retry :
status = notifyviafd(storePrivate->server,
fileport,
identifier,
(int *)&sc_status);
if (__SCDynamicStoreCheckRetryAndHandleError(store,
status,
&sc_status,
"SCDynamicStoreNotifyFileDescriptor notifyviafd()")) {
goto retry;
}
if (status != KERN_SUCCESS) {
_SCErrorSet(status);
goto fail;
}
if (sc_status != kSCStatusOK) {
_SCErrorSet(sc_status);
goto fail;
}
(void) close(fildes[1]);
*fd = fildes[0];
storePrivate->notifyStatus = Using_NotifierInformViaFD;
return TRUE;
fail :
if (fildes[0] != -1) close(fildes[0]);
if (fildes[1] != -1) close(fildes[1]);
return FALSE;
}