I wrote a C program/LaunchDaemon that checks if my MacBook is at home (connected to my WLAN). If so, it disables my password protection; if not, it enables it.
Easy. But the problem is that when I take my MacBook anywhere else and password protection is disabled, it will wake up without a password protection.
My fix for this would be: enable the password protection every time just before it goes to sleep.
QUESTION: is there any way find out when my Mac is preparing for sleep? Some interupt I can let my program listen to?
Helpful answers. Option–Command–Power button* or Option–Command–Media Eject: Put your Mac to sleep. Option–Command–Power button* or Option–Command–Media Eject: Put your Mac to sleep. You can tell Siri 'go to sleep'.
Sleep mode stops system processes on your Mac without needing to shut it down. When you close your MacBook, it automatically goes to sleep. Also, you can manually enable the sleep mode any time you need it. In this mode, all your unsaved documents, data, and running processes are stored in the RAM.
I attach below the contents of my C file beforesleep.c
which executes some command line commands (in my case shell commands and AppleScript scripts) when a "will sleep" notification is received.
In order to run your code when the mac is going to sleep, just replace the system(...)
calls with the code you wish to run.
In my case, I use system()
as it allows me to run shell commands passed as strings, but if you prefer to run just C code instead, you can just put your C code there.
In order to build this file, I run:
gcc -framework IOKit -framework Cocoa beforesleep.c
If you are going to use this code, make sure it is always running in background. For example, I have a Cron job which makes sure that this code is always running, and it launches it again in case it is accidentally killed for any reason (although it never happened to me so far). If you are experienced enough, you can find smarter ways to ensure this.
See this link (already suggested by sidyll) for more details about how this works.
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/mach_interface.h>
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
io_connect_t root_port; // a reference to the Root Power Domain IOService
void
MySleepCallBack( void * refCon, io_service_t service, natural_t messageType, void * messageArgument )
{
switch ( messageType )
{
case kIOMessageCanSystemSleep:
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillSleep:
system("/Users/andrea/bin/mylogger.sh");
system("osascript /Users/andrea/bin/pause_clockwork.scpt");
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillPowerOn:
//System has started the wake up process...
break;
case kIOMessageSystemHasPoweredOn:
//System has finished waking up...
break;
default:
break;
}
}
int main( int argc, char **argv )
{
// notification port allocated by IORegisterForSystemPower
IONotificationPortRef notifyPortRef;
// notifier object, used to deregister later
io_object_t notifierObject;
// this parameter is passed to the callback
void* refCon;
// register to receive system sleep notifications
root_port = IORegisterForSystemPower( refCon, ¬ifyPortRef, MySleepCallBack, ¬ifierObject );
if ( root_port == 0 )
{
printf("IORegisterForSystemPower failed\n");
return 1;
}
// add the notification port to the application runloop
CFRunLoopAddSource( CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes );
/* Start the run loop to receive sleep notifications. Don't call CFRunLoopRun if this code
is running on the main thread of a Cocoa or Carbon application. Cocoa and Carbon
manage the main thread's run loop for you as part of their event handling
mechanisms.
*/
CFRunLoopRun();
//Not reached, CFRunLoopRun doesn't return in this case.
return (0);
}
You can do it using I/O Kit, check Apple's QA1340: Registering and unregistering for sleep and wake notifications. You may also want to analyze the SleepWatcher utility sources or use/integrate for your needs. From the homepage:
SleepWatcher 2.2 (running with Mac OS X 10.5 to 10.8, source code included) is a command line tool (daemon) for Mac OS X that monitors sleep, wakeup and idleness of a Mac. It can be used to execute a Unix command when the Mac or the display of the Mac goes to sleep mode or wakes up, after a given time without user interaction or when the user resumes activity after a break or when the power supply of a Mac notebook is attached or detached. It also can send the Mac to sleep mode or retrieve the time since last user activity. A little bit knowledge of the Unix command line is required to benefit from this software.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With