SCDNotifierInformViaFD.c [plain text]
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
#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)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
int sc_status;
struct sockaddr_un un;
int sock;
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyFileDescriptor:"));
if (!store) {
_SCErrorSet(kSCStatusNoStoreSession);
return FALSE;
}
if (storePrivate->server == MACH_PORT_NULL) {
_SCErrorSet(kSCStatusNoStoreServer);
return FALSE;
}
if (storePrivate->notifyStatus != NotifierNotRegistered) {
_SCErrorSet(kSCStatusNotifierActive);
return FALSE;
}
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_NOTICE, CFSTR("socket: %s"), strerror(errno));
return FALSE;
}
bzero(&un, sizeof(un));
un.sun_family = AF_UNIX;
snprintf(un.sun_path,
sizeof(un.sun_path)-1,
"%s%s-%d",
_PATH_VARTMP,
"SCDynamicStoreNotifyFileDescriptor",
storePrivate->server);
if (bind(sock, (struct sockaddr *)&un, sizeof(un)) == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_NOTICE, CFSTR("bind: %s"), strerror(errno));
(void) close(sock);
return FALSE;
}
if (listen(sock, 0) == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_NOTICE, CFSTR("listen: %s"), strerror(errno));
(void) close(sock);
return FALSE;
}
status = notifyviafd(storePrivate->server,
un.sun_path,
strlen(un.sun_path),
identifier,
(int *)&sc_status);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviafd(): %s"), mach_error_string(status));
(void) mach_port_destroy(mach_task_self(), storePrivate->server);
storePrivate->server = MACH_PORT_NULL;
_SCErrorSet(status);
return FALSE;
}
*fd = accept(sock, 0, 0);
if (*fd == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_NOTICE, CFSTR("accept: %s"), strerror(errno));
(void) close(sock);
return FALSE;
}
(void) close(sock);
storePrivate->notifyStatus = Using_NotifierInformViaFD;
return TRUE;
}