Beispiel #1
0
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);
}
Beispiel #2
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;
}
Beispiel #3
0
/* 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;
}
Beispiel #4
0
/* 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, &notifyPortRef, PowerCallBack, &notifierObject);                         /* 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;
}