~mil/sxmo-devel

sxmo-utils: sxmo_timer.sh: allow suspension while running v1 PROPOSED

Little patchset that (1) add a sxmo_sleep command that give us more
possibilities to control our workflows, arround features to manage
suspensions. This sxmo_timer.sh change is an example of how we can
use it. But it can be used in a variety of situation, and some patches
are planned.
#1178158 test.yml success
sxmo-utils/patches/test.yml: SUCCESS in 1m4s

[sxmo_timer.sh: allow suspension while running][0] from [Willow Barraco][1]

[0]: https://lists.sr.ht/~mil/sxmo-devel/patches/50442
[1]: mailto:contact@willowbarraco.fr

✓ #1178158 SUCCESS sxmo-utils/patches/test.yml https://builds.sr.ht/~mil/job/1178158
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mil/sxmo-devel/patches/50442/mbox | git am -3
Learn more about email & git

[PATCH sxmo-utils 1/3] sxmo_timer.sh: allow suspension while running Export this patch

To do this, we implement a new sxmo_sleep program that is a sleep
but that can wake the device from suspension when the timer expires.

Also, stopwatch can perfectly survive a suspension. So we don't have to
wakelock on this.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
---
 Makefile                         |  5 ++-
 programs/sxmo_sleep.c            | 70 ++++++++++++++++++++++++++++++++
 scripts/appscripts/sxmo_timer.sh | 31 ++++++++++----
 3 files changed, 97 insertions(+), 9 deletions(-)
 create mode 100644 programs/sxmo_sleep.c

diff --git a/Makefile b/Makefile
index 7480facc..2058fcee 100644
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,7 @@ OPENRC:=1
CC ?= $(CROSS_COMPILE)gcc
PROGRAMS = \
	programs/sxmo_aligned_sleep \
	programs/sxmo_sleep \
	programs/sxmo_vibrate

DOCS = \
@@ -51,7 +52,7 @@ programs/%: programs/%.c
	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<

clean:
	rm -f programs/sxmo_aligned_sleep programs/sxmo_vibrate
	rm -f programs/sxmo_aligned_sleep programs/sxmo_sleep programs/sxmo_vibrate

install: install-sway install-dwm install-scripts install-docs

@@ -97,6 +98,8 @@ install-scripts: $(PROGRAMS)

	install -D programs/sxmo_aligned_sleep $(DESTDIR)$(PREFIX)/bin/
	install -D programs/sxmo_vibrate $(DESTDIR)$(PREFIX)/bin/
	install -D programs/sxmo_sleep $(DESTDIR)$(PREFIX)/bin/
	setcap 'cap_wake_alarm=ep' $(DESTDIR)$(PREFIX)/bin/sxmo_sleep

	find $(DESTDIR)$(PREFIX)/share/sxmo/default_hooks/ -type f -exec ./setup_config_version.sh "{}" \;
	find $(DESTDIR)$(PREFIX)/share/sxmo/appcfg/ -type f -exec ./setup_config_version.sh "{}" \;
diff --git a/programs/sxmo_sleep.c b/programs/sxmo_sleep.c
new file mode 100644
index 00000000..0da4af39
--- /dev/null
+++ b/programs/sxmo_sleep.c
@@ -0,0 +1,70 @@
#include <errno.h>       // error handling
#include <stdint.h>      // uint64_t type
#include <stdio.h>       // dprintf
#include <stdlib.h>      // strtol, exit
#include <string.h>      // strerror, strcmp
#include <sys/timerfd.h> // timers
#include <unistd.h>      // read

static void error(char *message, int err) {
	dprintf(2, "%s: %s\n", message, strerror(err));
	exit(1);
}

static void usage(char *cmd, char *msg) {
	dprintf(2, "Usage: %s [-c <clock-name>] <seconds>\n", cmd);
	dprintf(2, "%s\n", msg);
	exit(1);
}

int main(int argc, char **argv) {
	uint64_t buf;
	long duration = -1;
	int time_fd;
	int clockid = CLOCK_REALTIME;

	struct itimerspec time = {
		.it_value = { .tv_sec = 0, .tv_nsec = 0 },
		.it_interval = { .tv_sec = 0, .tv_nsec = 0 }
	};

	for (int i = 1; i < argc; i += 1) {
		if (0 == strcmp(argv[i], "-c")) {
			if (argc <= i + 1) {
				usage(argv[0], "You must pass a clock name.");
			}
			if (0 == strcmp(argv[i+1], "realtime")) {
				clockid = CLOCK_REALTIME;
			} else if (0 == strcmp(argv[i+1], "monotonic")) {
				clockid = CLOCK_MONOTONIC;
			} else if (0 == strcmp(argv[i+1], "boottime")) {
				clockid = CLOCK_BOOTTIME;
			} else if (0 == strcmp(argv[i+1], "realtime_alarm")) {
				clockid = CLOCK_REALTIME_ALARM;
			} else if (0 == strcmp(argv[i+1], "boottime_alarm")) {
				clockid = CLOCK_BOOTTIME_ALARM;
			} else {
				usage(argv[0], "Unknown clock name.");
			}
			i += 1;
			continue;
		}
		duration = strtol(argv[i], NULL, 0);;
	}

	if (duration <= 0) {
		usage(argv[0], "You must pass a duration in second.");
	}

	// Setup timer
	if ((time_fd = timerfd_create(clockid, TFD_CLOEXEC)) == -1)
		error("Failed to create timerfd", errno);

	time.it_value.tv_sec = duration;

	if (timerfd_settime(time_fd, 0, &time, NULL) == -1)
		error("Failed to set timer",errno);

	// Wait for timer
	read(time_fd, &buf, sizeof(uint64_t));
}
diff --git a/scripts/appscripts/sxmo_timer.sh b/scripts/appscripts/sxmo_timer.sh
index facbe7a0..89f0b9fa 100755
--- a/scripts/appscripts/sxmo_timer.sh
+++ b/scripts/appscripts/sxmo_timer.sh
@@ -6,13 +6,34 @@
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh

_finish_timerrun() {
	_releasealarm
	exit
}

_setupalarm() {
	sxmo_sleep -c boottime_alarm "$1" &
	alarmpid=$!
}

_releasealarm() {
	if [ -n "$alarmpid" ]; then
		kill "$alarmpid" 2> /dev/null
		unset alarmpid
	fi
}

timerrun() {
	trap '_finish_timerrun' INT TERM EXIT

	TIME="$(
		echo "$@" |
		sed 's/\([^0-9]\)\([0-9]\)/\1+\2/g; s/h/*60m/g; s/m/*60s/g; s/s//g' |
		bc
	)"

	_setupalarm "$TIME"

	DATE1="$(($(date +%s) + TIME))";
	while [ "$DATE1" -ge "$(date +%s)" ]; do
		printf "%s\r" "$(date -u --date @$((DATE1 - $(date +%s))) +%H:%M:%S)";
@@ -20,6 +41,8 @@ timerrun() {
	done
	echo "Done with $*"

	_releasealarm

	while : ;
		do notify-send  "Done with $*";
		sxmo_vibrate 1000 "${SXMO_VIBRATE_STRENGTH:-1}"
@@ -27,10 +50,6 @@ timerrun() {
	done
}

cleanwakelock() {
	sxmo_wakelock.sh unlock sxmo_"$(basename "$0")"
}

stopwatchrun() {
	start="$(date +%s)"
	while : ; do
@@ -63,13 +82,9 @@ EOF
			exit 0
			;;
		"Stopwatch")
			sxmo_wakelock.sh lock sxmo_"$(basename "$0")" infinite
			trap 'cleanwakelock' INT TERM EXIT
			sxmo_terminal.sh "$0" stopwatchrun
			;;
		*)
			sxmo_wakelock.sh lock sxmo_"$(basename "$0")" infinite
			trap 'cleanwakelock' INT TERM EXIT
			sxmo_terminal.sh "$0" timerrun "$TIMEINPUT"
			;;
	esac
-- 
2.44.0

[PATCH sxmo-utils 2/3] sxmo_timer.sh: stop at precise second Export this patch

-ge means that we wait one additional second. Sleep 5s should actually
wait 5s, no more.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
---
 scripts/appscripts/sxmo_timer.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/appscripts/sxmo_timer.sh b/scripts/appscripts/sxmo_timer.sh
index 89f0b9fa..9dbf3f15 100755
--- a/scripts/appscripts/sxmo_timer.sh
+++ b/scripts/appscripts/sxmo_timer.sh
@@ -35,7 +35,7 @@ timerrun() {
	_setupalarm "$TIME"

	DATE1="$(($(date +%s) + TIME))";
	while [ "$DATE1" -ge "$(date +%s)" ]; do
	while [ "$DATE1" -gt "$(date +%s)" ]; do
		printf "%s\r" "$(date -u --date @$((DATE1 - $(date +%s))) +%H:%M:%S)";
		sxmo_aligned_sleep 1
	done
-- 
2.44.0

[PATCH sxmo-utils 3/3] sxmo_timer.sh: finish as soon as it get killed Export this patch

Without this, the script will wait the full second before handling the
kill signal.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
---
 scripts/appscripts/sxmo_timer.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/appscripts/sxmo_timer.sh b/scripts/appscripts/sxmo_timer.sh
index 9dbf3f15..2f212901 100755
--- a/scripts/appscripts/sxmo_timer.sh
+++ b/scripts/appscripts/sxmo_timer.sh
@@ -37,7 +37,8 @@ timerrun() {
	DATE1="$(($(date +%s) + TIME))";
	while [ "$DATE1" -gt "$(date +%s)" ]; do
		printf "%s\r" "$(date -u --date @$((DATE1 - $(date +%s))) +%H:%M:%S)";
		sxmo_aligned_sleep 1
		sxmo_aligned_sleep 1 &
		wait $!
	done
	echo "Done with $*"

-- 
2.44.0
sxmo-utils/patches/test.yml: SUCCESS in 1m4s

[sxmo_timer.sh: allow suspension while running][0] from [Willow Barraco][1]

[0]: https://lists.sr.ht/~mil/sxmo-devel/patches/50442
[1]: mailto:contact@willowbarraco.fr

✓ #1178158 SUCCESS sxmo-utils/patches/test.yml https://builds.sr.ht/~mil/job/1178158