My software installs a privileged daemon using the SMAppService api. After removing the executables and recompiling the software I sometimes find that it needs to be registered again. After doing this, i.e. ensuring the application is properly registered and enabled in Login Items & Extensions the helper is not run when initiated from XPC.
SMAppService.status has returned .enabled, and there is a valid job dictionary for the helper. I check the job dictionary with a function called updatePenaltyBoxStatus() that was given to me by a friend but I think originated from Apple.
If I logoff (or reboot), login again, manually open Login Items & Extensions to check registration, then retry the application, it works. I don't mind doing this but it is probably a bit much for a lot of my users.
Is there a reliable way to do this programatically?
Here is my Swift translation of updatePenaltyBoxStatus. I fetch the job dictionary with SMJobCopyDictionary() prior to calling isInPenaltyBox(). I also had to write C wrapper functions for the WIFEXITED and WIFEXITSTATUS macros.
func isInPenaltyBox(_ dict: Dictionary<String, Any>?) -> Bool
{
guard let jobDict = dict else {
// If the helper was in the penalty box, unregistering it doesn't change that. So don't override a previous helperInPenaltyBox value
return m_penalty_box
}
if let lastExitStatusObj = jobDict["LastExitStatus"] as? NSNumber {
let lastExitStatus = lastExitStatusObj.intValue
if wifexited(Int32(lastExitStatus)) == 0 {
// It might've stopped or exited due to a signal or whatever.
// Regardless, it didn't meet our criteria for winding up in the penalty box.
m_penalty_box = false
}
// Now get the exit status and check for `EX_CONFIG`.
let status = wexitstatus(Int32(lastExitStatus))
let newInPenaltyBox = status == EX_CONFIG
if m_penalty_box != newInPenaltyBox {
Logger.instance.log(
"Penalty box change: "
+ m_ident
+ " old: " + String(m_penalty_box)
+ " new: " + String(newInPenaltyBox))
}
m_penalty_box = newInPenaltyBox
}
return m_penalty_box
}