#include <unistd.h>
#include <sys/fileport.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "configd.h"
#include "session.h"
__private_extern__
int
__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store)
{
serverSessionRef mySession;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
if (storePrivate->notifyStatus != NotifierNotRegistered) {
return kSCStatusNotifierActive;
}
mySession = getSession(storePrivate->server);
if (mySession->changedKeys != NULL) {
CFNumberRef sessionNum;
if (needsNotification == NULL)
needsNotification = CFSetCreateMutable(NULL,
0,
&kCFTypeSetCallBacks);
sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
CFSetAddValue(needsNotification, sessionNum);
CFRelease(sessionNum);
}
return kSCStatusOK;
}
__private_extern__
kern_return_t
_notifyviafd(mach_port_t server,
fileport_t fileport,
int identifier,
int *sc_status
)
{
int fd = -1;
int flags;
serverSessionRef mySession = getSession(server);
SCDynamicStorePrivateRef storePrivate;
fd = fileport_makefd(fileport);
mach_port_deallocate(mach_task_self(), fileport);
if (fd < 0) {
*sc_status = errno;
return KERN_SUCCESS;
}
flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
*sc_status = errno;
goto fail;
}
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1) {
*sc_status = errno;
goto fail;
}
if (mySession == NULL) {
*sc_status = kSCStatusNoStoreSession;
goto fail;
}
storePrivate = (SCDynamicStorePrivateRef)mySession->store;
*sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store);
if (*sc_status != kSCStatusOK) {
goto fail;
}
storePrivate->notifyStatus = Using_NotifierInformViaFD;
storePrivate->notifyFile = fd;
storePrivate->notifyFileIdentifier = identifier;
return KERN_SUCCESS;
fail :
if (fd >= 0) close(fd);
return KERN_SUCCESS;
}