コード例 #1
0
ファイル: misc.c プロジェクト: BurntBrunch/rockbox-fft
static bool clean_shutdown(void (*callback)(void *), void *parameter)
{
#ifdef SIMULATOR
    (void)callback;
    (void)parameter;
    bookmark_autobookmark();
    call_storage_idle_notifys(true);
    exit(0);
#else
    long msg_id = -1;
    int i;

    scrobbler_poweroff();

#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
    if(!charger_inserted())
#endif
    {
        bool batt_safe = battery_level_safe();
        int audio_stat = audio_status();

        FOR_NB_SCREENS(i)
        {
            screens[i].clear_display();
            screens[i].update();
        }

        if (batt_safe)
        {
#ifdef HAVE_TAGCACHE
            if (!tagcache_prepare_shutdown())
            {
                cancel_shutdown();
                splash(HZ, ID2P(LANG_TAGCACHE_BUSY));
                return false;
            }
#endif
            if (battery_level() > 10)
                splash(0, str(LANG_SHUTTINGDOWN));
            else
            {
                msg_id = LANG_WARNING_BATTERY_LOW;
                splashf(0, "%s %s", str(LANG_WARNING_BATTERY_LOW),
                                    str(LANG_SHUTTINGDOWN));
            }
        }
        else
        {
            msg_id = LANG_WARNING_BATTERY_EMPTY;
            splashf(0, "%s %s", str(LANG_WARNING_BATTERY_EMPTY),
                                str(LANG_SHUTTINGDOWN));
        }

        if (global_settings.fade_on_stop
            && (audio_stat & AUDIO_STATUS_PLAY))
        {
            fade(false, false);
        }

        if (batt_safe) /* do not save on critical battery */
        {
#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            if (audio_stat & AUDIO_STATUS_RECORD)
            {
                rec_command(RECORDING_CMD_STOP);
                /* wait for stop to complete */
                while (audio_status() & AUDIO_STATUS_RECORD)
                    sleep(1);
            }
#endif
            bookmark_autobookmark();

            /* audio_stop_recording == audio_stop for HWCODEC */
            audio_stop();

            if (callback != NULL)
                callback(parameter);

#if CONFIG_CODEC != SWCODEC
            /* wait for audio_stop or audio_stop_recording to complete */
            while (audio_status())
                sleep(1);
#endif

#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
            audio_close_recording();
#endif

            if(global_settings.talk_menu)
            {
                bool enqueue = false;
                if(msg_id != -1)
                {
                    talk_id(msg_id, enqueue);
                    enqueue = true;
                }
                talk_id(LANG_SHUTTINGDOWN, enqueue);
#if CONFIG_CODEC == SWCODEC
                voice_wait();
#endif
            }

            system_flush();
#ifdef HAVE_EEPROM_SETTINGS
            if (firmware_settings.initialized)
            {
                firmware_settings.disk_clean = true;
                firmware_settings.bl_version = 0;
                eeprom_settings_store();
            }
#endif
        }
#ifdef HAVE_DIRCACHE
        else
            dircache_disable();
#endif

        shutdown_hw();
    }
コード例 #2
0
ファイル: openrc-shutdown.c プロジェクト: dwfreed/openrc
int main(int argc, char **argv)
{
	char *ch = NULL;
	int opt;
	int cmd_count = 0;
	int hour = 0;
	int min = 0;
	int shutdown_delay = 0;
	struct sigaction sa;
	struct tm *lt;
	time_t tv;
	bool need_warning = false;
	char *msg = NULL;
	char *state = NULL;
	char *time_arg = NULL;
	FILE *fp;

	applet = basename_c(argv[0]);
	while ((opt = getopt_long(argc, argv, getoptstring,
		    longopts, (int *) 0)) != -1)
	{
		switch (opt) {
			case 'c':
				do_cancel = true;
			cmd_count++;
				break;
			case 'd':
				do_wtmp = false;
				break;
		case 'D':
			do_dryrun = true;
			break;
		case 'H':
			do_halt = true;
			xasprintf(&state, "%s", "halt");
			cmd_count++;
			break;
		case 'K':
			do_kexec = true;
			xasprintf(&state, "%s", "reboot");
			cmd_count++;
			break;
		case 'p':
			do_poweroff = true;
			xasprintf(&state, "%s", "power off");
			cmd_count++;
			break;
		case 'R':
			do_reexec = true;
			cmd_count++;
			break;
		case 'r':
			do_reboot = true;
			xasprintf(&state, "%s", "reboot");
			cmd_count++;
			break;
		case 's':
			do_single = true;
			xasprintf(&state, "%s", "go down for maintenance");
			cmd_count++;
			break;
		case 'w':
			do_wtmp_only = true;
			cmd_count++;
			break;
		case_RC_COMMON_GETOPT
		}
	}
	if (geteuid() != 0)
		eerrorx("%s: you must be root\n", applet);
	if (cmd_count != 1) {
		eerror("%s: %s\n", applet, exclusive);
		usage(EXIT_FAILURE);
	}

	if (do_cancel) {
		cancel_shutdown();
		exit(EXIT_SUCCESS);
	} else if (do_reexec) {
		send_cmd("reexec");
		exit(EXIT_SUCCESS);
	} else if (do_wtmp_only) {
		log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
		exit(EXIT_SUCCESS);
	}

	if (optind >= argc) {
		eerror("%s: No shutdown time specified", applet);
		usage(EXIT_FAILURE);
	}
	time_arg = argv[optind];
	if (*time_arg == '+')
		time_arg++;
	if (strcasecmp(time_arg, "now") == 0)
		strcpy(time_arg, "0");
	for (ch=time_arg; *ch; ch++)
		if ((*ch < '0' || *ch > '9') && *ch != ':') {
			eerror("%s: invalid time %s", applet, time_arg);
			usage(EXIT_FAILURE);
		}
	if (strchr(time_arg, ':')) {
		if ((sscanf(time_arg, "%2d:%2d", &hour, &min) != 2) ||
				(hour > 23) || (min > 59)) {
			eerror("%s: invalid time %s", applet, time_arg);
			usage(EXIT_FAILURE);
		}
		time(&tv);
		lt = localtime(&tv);
		shutdown_delay = (hour * 60 + min) - (lt->tm_hour * 60 + lt->tm_min);
		if (shutdown_delay < 0)
			shutdown_delay += 1440;
	} else {
		shutdown_delay = atoi(time_arg);
	}

	fp = fopen(shutdown_pid, "w");
	if (!fp)
		eerrorx("%s: fopen `%s': %s", applet, shutdown_pid, strerror(errno));
	fprintf(fp, "%d\n", getpid());
	fclose(fp);

	openlog(applet, LOG_PID, LOG_DAEMON);
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = stop_shutdown;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	while (shutdown_delay > 0) {
		need_warning = false;
		if (shutdown_delay > 180)
			need_warning = (shutdown_delay % 60 == 0);
		else if (shutdown_delay > 60)
			need_warning = (shutdown_delay % 30 == 0);
		else if	(shutdown_delay > 10)
			need_warning = (shutdown_delay % 15 == 0);
		else
			need_warning = true;
		if (shutdown_delay <= 5)
			create_nologin(shutdown_delay);
		if (need_warning) {
		xasprintf(&msg, "\rThe system will %s in %d minutes\r\n",
		          state, shutdown_delay);
			broadcast(msg);
			free(msg);
		}
		sleep_no_interrupt(60);
		shutdown_delay--;
	}
	xasprintf(&msg, "\rThe system will %s now\r\n", state);
	broadcast(msg);
	syslog(LOG_NOTICE, "The system will %s now", state);
	unlink(nologin_file);
	unlink(shutdown_pid);
	if (do_halt)
		send_cmd("halt");
	else if (do_kexec)
		send_cmd("kexec");
	else if (do_poweroff)
		send_cmd("poweroff");
	else if (do_reboot)
		send_cmd("reboot");
	else if (do_single)
		send_cmd("single");
	return 0;
}