static int sleepImmediately (void) { mach_port_t masterPort; io_connect_t rootPort; IOReturn err; if (IOPMSleepEnabled()) { if ((err = IOMasterPort(MACH_PORT_NULL, &masterPort))) { fprintf (stderr, "%s: can't get mach master port: %ld\n", args.progname, (long) err); return (1); } rootPort = IOPMFindPowerManagement(masterPort); if (rootPort) { err = IOPMSleepSystem(rootPort); if (err) { fprintf (stderr, "%s: IOPMSleepSystem failed: %ld\n", args.progname, (long) err); return (1); } } else { fprintf (stderr, "%s: IOPMFindPowerManagement failed\n", args.progname); return (1); } } else { fprintf (stderr, "%s: sleep mode is disabled\n", args.progname); return (1); } return (0); }
static OSStatus SleepSystem( AuthorizationRef auth, const void * userData, CFDictionaryRef request, CFMutableDictionaryRef response, aslclient asl, aslmsg aslMsg ) { io_connect_t fb = IOPMFindPowerManagement(MACH_PORT_NULL); IOPMSleepSystem(fb); return noErr; }
/* Private call for Apple Internal use only */ IOReturn IOPMSleepSystemWithOptions ( io_connect_t fb, CFDictionaryRef options ) { uint64_t rtn = 0; size_t len = sizeof(uint32_t); kern_return_t err; CFDataRef serializedOptions = NULL; if( !options ) { return IOPMSleepSystem( fb ); } serializedOptions = IOCFSerialize( options, 0 ); if (!serializedOptions) { return kIOReturnInternalError; } /* kPMSleepSystemOptions * in: serialized CFDictionary of options * out: IOReturn code returned from sleepSystem */ err = IOConnectCallStructMethod( fb, kPMSleepSystemOptions, CFDataGetBytePtr(serializedOptions), /* inputStruct */ CFDataGetLength(serializedOptions), /* inputStructCnt */ &rtn, /* outputStruct */ &len); /* outputStructCnt */ CFRelease(serializedOptions); if (kIOReturnSuccess != err) return err; else return (IOReturn) rtn; }
/* Main program */ int main (int argc, const char * argv[]) { enum suspend_type {soft, dump, hard}; int vmmib[2] = {CTL_VM, VM_SWAPUSAGE}; int osmib[2] = {CTL_KERN, KERN_OSRELEASE}; int original_mode; int target_mode; int default_mode; int original_profile; int target_profile = -1; void *refCon; struct xsw_usage swap; size_t swlen = sizeof(swap); size_t oslen; char *kernel_version; int major_version = 0; int minor_version = 0; struct stat sleepimage; /* By default, */ int do_sleep = 1; /* send the sleep call, */ int repair = 0; /* do not check the validity of the original hibernation mode, */ int check_hibernation = 1; /* check if the hibernation file is present, */ int check_os = 1; /* check if the operating system is supported, */ enum suspend_type target_suspend = soft; /* send computer to software suspend mode, */ int restore = 1; /* restore the original mode, */ if (argc >= 2) { if (!strcmp(argv[1], "-v")) { /* Display version number if invoked with -v */ printf("deepsleep build %s\n", VERSION); return 0; } else if (!strcmp(argv[1], "-h")) { printf("deepsleep usage: deepsleep [-bdhrvsu] [hard|dump|soft]\n"); printf(" -b : bypass the hibernation file check\n"); printf(" -d : debug mode - be verbose\n"); printf(" -h : display this help screen\n"); printf(" -m : mute - be silent\n"); printf(" -o : do not restore the original hibernation mode\n"); printf(" -r : repair the default hibernation mode if needed\n"); printf(" -s : simulation - do not send the computer to sleep\n"); printf(" -v : display version number\n"); printf(" -u : perform operations even on unsupported OS revisions\n"); printf(" hard : send computer to hardware suspend mode\n"); printf(" dump : send computer to safe hardware suspend mode\n"); printf(" soft : send computer to software suspend mode (by default)\n"); return 0; } else { if (argc >= 3) { if (strstr(argv[1], "b")) /* Do not check the existence of the hibernation file if invoked with -b */ check_hibernation = 0; if (strstr(argv[1], "d")) /* Print debug information if invoked with -d */ debug = 1; if (strstr(argv[1], "o")) /* Do not restore the original hibernation mode if invoked with -o */ restore = 0; if (strstr(argv[1], "r")) /* Check for the validity of the original hibernation mode if invoked with -r*/ repair = 1; if (strstr(argv[1], "s")) /* Do not send the sleep call if invoked with -s */ do_sleep = 0; if (strstr(argv[1], "u")) /* Do not care about OS revision if invoked with -u */ check_os = 0; if (strstr(argv[1], "m")) mute = 1; } if (strstr(argv[argc-1], "hard")) /* Send computer to hardware suspend mode instead of software suspend mode if the hard argument is present */ target_suspend = hard; else if (strstr(argv[argc-1], "dump")) /* Send computer to safe hardware suspend mode instead of software suspend mode if the safe argument is present */ target_suspend = dump; } } if (sysctl(osmib, 2, NULL, &oslen, NULL, 0) == -1) { /* Get the operating system revision length */ printf("Failed to get the operating system revision\n"); /* On failure: quit */ return 1; } else { kernel_version = malloc(oslen * sizeof(char)); sysctl(osmib, 2, kernel_version, &oslen, NULL, 0); /* Get the operating system revision length */ sscanf(kernel_version, "%d.%d", &major_version, &minor_version); free(kernel_version); } if (debug) { printf("OS revision: %d.%d", major_version, minor_version); if (!check_os) printf(" (ignored)"); printf("\n"); } if (check_os && (major_version != 8 || minor_version < 3) && (major_version <= 8)) { /* If needed, check if major version is 8 (Mac OS X 10.4) and minor version is greater or equal than 3. Mac OS X 10.5 is also supported.*/ printf("This operating system is not supported\n"); /* On failure: quit */ return 1; } if (check_hibernation && stat("/private/var/vm/sleepimage", &sleepimage)) { /* If needed, check if the hibernation file (/private/var/vm/sleepimage) exists */ printf("Hibernation file is missing\n"); /* On failure: quit */ return 1; } if (sysctl(vmmib, 2, &swap, &swlen, NULL, 0) == -1) { /* Get the current virtual memory parameters */ printf("Failed to get the virtual memory information\n"); /* On failure: quit */ return 1; } else { default_mode = 3; if (target_suspend == dump) { target_mode = default_mode; /* we will use the regular mode 3 for safe hardware suspsend */ } else /*if (target_suspend == soft)*/ { target_mode = 25; /* or the regular mode 25 for software suspsend */ } if (target_suspend == hard) /* If we only want to perform basic hardware suspend */ target_mode = 0; /* we will sleep with hibernate mode 0 */ if (debug) printf("target mode: %d\n", target_mode); } ps_info = IOPSCopyPowerSourcesInfo(); /* Get the power source information */ if (ps_info) { current_ps = IOPSGetProvidingPowerSourceType(ps_info); /* On success, store the active power source */ } else { printf("Failed to get the power source information\n"); /* On failure: quit */ return 1; } if (debug) printf("target power source: %s\n", CFStringGetCStringPtr(current_ps, kCFStringEncodingMacRoman)); active_prof = IOPMCopyActivePowerProfiles(); /* Get the power profiles */ if (!active_prof) { printf("Failed to get the active profile\n"); CFCleanup(); return 1; } if (CFDictionaryContainsKey(active_prof, current_ps)) { /* Get the active profile corresponding to the current power source */ profile_ref = (CFNumberRef) CFDictionaryGetValue(active_prof, current_ps); profile_type = CFNumberGetType(profile_ref); CFNumberGetValue(profile_ref, profile_type, &original_profile); /* On succes, store its value */ if (debug) printf("original profile: %d\n", original_profile); } else { printf("Failed to get the power management settings\n"); /* On failure: quit */ CFCleanup(); return 1; } ds = SCDynamicStoreCreate(NULL, CFSTR("deepsleep"), NULL, NULL); /* Create a new dynamic store */ live_settings = SCDynamicStoreCopyValue(ds, CFSTR(kIOPMDynamicStoreSettingsKey)); /* Read current settings */ if(!isA_CFDictionary(live_settings)) { /* We did not get the settings: quit */ printf("Failed to get the power management settings\n"); CFCleanup(); return 1; } if (CFDictionaryContainsKey(live_settings, CFSTR("Hibernate Mode"))) { /* Check if the hibernate mode key exists */ hm_ref = (CFNumberRef) CFDictionaryGetValue(live_settings, CFSTR("Hibernate Mode")); /* On success, get its value */ hm_type = CFNumberGetType(hm_ref); CFNumberGetValue(hm_ref, hm_type, &original_mode); if (debug) printf("original mode: %d\n", original_mode); } else { /* On failure, cleanup and quit */ printf("Failed to get the hibernation mode\n"); CFCleanup(); return 1; } if (repair && original_mode == target_mode) { /* If the original mode is the same as the target mode */ original_mode = default_mode; /* A crash has probably happened during hibernation: we will set back the hibernation mode to its default value after wakeup */ if (debug) printf("repair mode to: %d\n", default_mode); } root_power_port = IORegisterForSystemPower(refCon, ¬ifyPortRef, PowerCallBack, ¬ifierObject); /* Register to the Root Power Domain IOService: notifications will be handled by the PowerCallBack functions */ if (!root_power_port) { /* Registering failed: quit */ printf("Failed to register to the Root Power Domain IOService\n"); CFCleanup(); return 1; } CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes); /* Add the notification port to the run loop */ if (SetActiveProfile(target_profile, current_ps, active_prof)) { /* Set the active power profile to custom (-1) */ printf("Failed to set the active profile\n"); PortsCleanup(); CFCleanup(); return 1; } if (SetHibernateMode(target_mode, current_ps)) { /* Set the hibernate mode to target mode */ printf("Failed to set the hibernation mode\n"); SetActiveProfile(original_profile, current_ps, active_prof); PortsCleanup(); CFCleanup(); return 1; } if (do_sleep) { /* If we are not in simulation mode */ sleep(3); /* Wait for 3s to allow settings to settle down */ if (IOPMSleepSystem(root_power_port) == kIOReturnSuccess) /* Request the system to sleep */ CFRunLoopRun(); /* On success, start the run loop */ else perror("Failed to send the sleep request\n"); /* On failure, do not start it */ } /* The run loop has stopped: system has woken up */ if (restore) { /* If we are asked to restore the original hibernate mode */ if (SetHibernateMode(original_mode, current_ps)) { /* Restore the original hibernate mode */ printf("Failed to set the hibernation mode\n"); SetActiveProfile(original_profile, current_ps, active_prof); PortsCleanup(); CFCleanup(); return 1; } if (SetActiveProfile(original_profile, current_ps, active_prof)) { /* Restore the original power profile */ printf("Failed to set the active profile\n"); PortsCleanup(); CFCleanup(); return 1; } } PortsCleanup(); /* Cleanup */ CFCleanup(); return 0; }