代码拉取完成,页面将自动刷新
/*
* pslash-systemd - systemd integration for psplash
*
* Copyright (c) 2020 Toradex
*
* Author: Stefan Agner <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-event.h>
#include "psplash.h"
#define PSPLASH_UPDATE_USEC 1000000
typedef uint64_t usec_t;
static int pipe_fd;
int get_progress(void)
{
sd_bus_error error = SD_BUS_ERROR_NULL;
static double current_progress = 0;
double progress = 0;
sd_bus *bus = NULL;
int r;
char buffer[20];
int len;
/* Connect to the system bus */
r = sd_bus_new(&bus);
if (r < 0)
goto finish;
r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
if (r < 0)
goto finish;
r = sd_bus_start(bus);
if (r < 0) {
fprintf(stderr, "Failed to connect to systemd private bus: %s\n", strerror(-r));
goto finish;
}
/* Issue the method call and store the respons message in m */
r = sd_bus_get_property_trivial(bus,
"org.freedesktop.systemd1", /* service to contact */
"/org/freedesktop/systemd1", /* object path */
"org.freedesktop.systemd1.Manager", /* interface name */
"Progress", /* method name */
&error, /* object to return error in */
'd', /* return message on success */
&progress); /* value */
if (r < 0) {
fprintf(stderr, "Failed to get progress: %s\n", error.message);
goto finish;
}
/*
* Systemd's progress seems go backwards at times. Prevent that
* progress bar on psplash goes backward by just communicating the
* highest observed progress so far.
*/
if (current_progress < progress)
current_progress = progress;
len = snprintf(buffer, 20, "PROGRESS %d", (int)(current_progress * 100));
write(pipe_fd, buffer, len + 1);
if (progress == 1.0) {
printf("Systemd reported progress of 1.0, quit psplash.\n");
write(pipe_fd, "QUIT", 5);
r = -1;
}
finish:
sd_bus_error_free(&error);
sd_bus_unref(bus);
return r;
}
int psplash_handler(sd_event_source *s,
uint64_t usec,
void *userdata)
{
sd_event *event = userdata;
int r;
r = get_progress();
if (r < 0)
goto err;
r = sd_event_source_set_time(s, usec + PSPLASH_UPDATE_USEC);
if (r < 0)
goto err;
return 0;
err:
sd_event_exit(event, EXIT_FAILURE);
return r;
}
int main()
{
sd_event *event;
sd_event_source *event_source = NULL;
int r;
sigset_t ss;
usec_t time_now;
char *rundir;
/* Open pipe for psplash */
rundir = getenv("PSPLASH_FIFO_DIR");
if (!rundir)
rundir = "/run";
chdir(rundir);
if ((pipe_fd = open (PSPLASH_FIFO,O_WRONLY|O_NONBLOCK)) == -1) {
fprintf(stderr, "Error unable to open fifo");
exit(EXIT_FAILURE);
}
r = sd_event_default(&event);
if (r < 0)
goto finish;
if (sigemptyset(&ss) < 0 ||
sigaddset(&ss, SIGTERM) < 0 ||
sigaddset(&ss, SIGINT) < 0) {
r = -errno;
goto finish;
}
/* Block SIGTERM first, so that the event loop can handle it */
if (sigprocmask(SIG_BLOCK, &ss, NULL) < 0) {
r = -errno;
goto finish;
}
/* Let's make use of the default handler and "floating" reference
* features of sd_event_add_signal() */
r = sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
if (r < 0)
goto finish;
r = sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
if (r < 0)
goto finish;
r = sd_event_now(event, CLOCK_MONOTONIC, &time_now);
if (r < 0)
goto finish;
r = sd_event_add_time(event, &event_source, CLOCK_MONOTONIC,
time_now, 0, psplash_handler, event);
if (r < 0)
goto finish;
r = sd_event_source_set_enabled(event_source, SD_EVENT_ON);
if (r < 0)
goto finish;
r = sd_event_loop(event);
finish:
event = sd_event_unref(event);
close(pipe_fd);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。