From 15f42220856460f67c375c1e64de4ffc4bdf6f47 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 13 Jul 2014 19:48:56 +0300 Subject: [PATCH] priv drop, hide on USR1 signal --- main.c | 194 ++++++++++++++++++++++++++++++++------------------ update_pnd.sh | 5 ++ 2 files changed, 128 insertions(+), 71 deletions(-) diff --git a/main.c b/main.c index 75082eb..75799b4 100644 --- a/main.c +++ b/main.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -37,33 +38,29 @@ static struct fb_var_screeninfo g_vi; static uint16_t *g_screen_base, *g_screen; static unsigned int g_old_mem; -static int g_fd, g_exit; +static int g_flip_id; +static int g_exit, g_hide; +static pthread_cond_t g_cond; #define IS_START(buf, str) \ !strncmp(buf, str, sizeof(str) - 1) -static int setup_layer(void) +static void clear_bytes(void *mem, int bytes); + +static int setup_layer(int fd) { - static const char fbname[] = "/dev/fb2"; struct omapfb_plane_info pi; struct omapfb_mem_info mi; struct omapfb_color_key key; int ret; - g_fd = open(fbname, O_RDWR); - if (g_fd == -1) { - fprintf(stderr, "open %s: ", fbname); - perror(NULL); - return 1; - } - - ret = ioctl(g_fd, OMAPFB_QUERY_PLANE, &pi); + ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_QUERY_PLANE"); return 1; } - ret = ioctl(g_fd, OMAPFB_QUERY_MEM, &mi); + ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi); if (ret < 0) { perror("ioctl OMAPFB_QUERY_MEM"); return 1; @@ -72,7 +69,7 @@ static int setup_layer(void) /* must disable when changing stuff */ if (pi.enabled) { pi.enabled = 0; - ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_SETUP_PLANE (d)"); return 1; @@ -82,7 +79,7 @@ static int setup_layer(void) g_old_mem = mi.size; if (mi.size < MEM_SIZE) { mi.size = MEM_SIZE; - ret = ioctl(g_fd, OMAPFB_SETUP_MEM, &mi); + ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); if (ret < 0) { perror("ioctl SETUP_MEM"); return 1; @@ -93,13 +90,13 @@ static int setup_layer(void) pi.pos_y = 0; pi.out_width = WIDTH; pi.out_height = HEIGHT; - ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_SETUP_PLANE (e1)"); return 1; } - ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_vi); + ret = ioctl(fd, FBIOGET_VSCREENINFO, &g_vi); if (ret < 0) { perror("ioctl FBIOGET_VSCREENINFO"); return 1; @@ -110,14 +107,14 @@ static int setup_layer(void) g_vi.yres_virtual = HEIGHT * 2; g_vi.bits_per_pixel = 16; - ret = ioctl(g_fd, FBIOPUT_VSCREENINFO, &g_vi); + ret = ioctl(fd, FBIOPUT_VSCREENINFO, &g_vi); if (ret < 0) { perror("ioctl FBIOPUT_VSCREENINFO"); return 1; } pi.enabled = 1; - ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_SETUP_PLANE (e2)"); return 1; @@ -127,21 +124,32 @@ static int setup_layer(void) key.key_type = OMAPFB_COLOR_KEY_VID_SRC; key.trans_key = 0x07e0; - ret = ioctl(g_fd, OMAPFB_SET_COLOR_KEY, &key); - if (ret < 0) { - perror("ioctl OMAPFB_SET_COLOR_KEY"); + ret = ioctl(fd, OMAPFB_SET_COLOR_KEY, &key); + if (ret < 0) { + perror("ioctl OMAPFB_SET_COLOR_KEY"); return 1; - } + } + + g_screen_base = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (g_screen_base == MAP_FAILED) { + perror("mmap"); + g_screen = g_screen_base = NULL; + return 1; + } + clear_bytes(g_screen_base, MEM_SIZE); + g_screen = g_screen_base; + g_flip_id = 0; return 0; } -static int check_layer(void) +static int check_layer(int fd) { struct omapfb_plane_info pi; int ret; - ret = ioctl(g_fd, OMAPFB_QUERY_PLANE, &pi); + ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi); if (ret < 0) { perror("ioctl OMAPFB_QUERY_PLANE"); return 1; @@ -155,19 +163,24 @@ static int check_layer(void) return 0; } -static void remove_layer(void) +static void remove_layer(int fd) { struct omapfb_plane_info pi; struct omapfb_mem_info mi; int ret; + if (g_screen_base != NULL) { + munmap(g_screen_base, MEM_SIZE); + g_screen = g_screen_base = NULL; + } + memset(&pi, 0, sizeof(pi)); pi.enabled = 0; - ret = ioctl(g_fd, OMAPFB_SETUP_PLANE, &pi); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi); if (ret < 0) perror("ioctl OMAPFB_SETUP_PLANE (c)"); - ret = ioctl(g_fd, OMAPFB_QUERY_MEM, &mi); + ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi); if (ret < 0) { perror("ioctl OMAPFB_QUERY_MEM"); goto out; @@ -175,31 +188,34 @@ static void remove_layer(void) if (mi.size != g_old_mem) { mi.size = g_old_mem; - ret = ioctl(g_fd, OMAPFB_SETUP_MEM, &mi); + ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi); if (ret < 0) { perror("ioctl SETUP_MEM"); goto out; } } -out: - close(g_fd); - g_fd = -1; +out:; } -static void handle_signal(int num) +static void flip_fb(int fd) { - g_exit = 1; + g_vi.yoffset = g_flip_id * HEIGHT; + ioctl(fd, FBIOPAN_DISPLAY, &g_vi); + g_flip_id ^= 1; + g_screen = g_screen_base + g_flip_id * WIDTH * HEIGHT; } -static void flip_fb(void) +static void handle_term(int num) { - static int id; + g_exit = 1; + pthread_cond_signal(&g_cond); +} - g_vi.yoffset = id * HEIGHT; - ioctl(g_fd, FBIOPAN_DISPLAY, &g_vi); - id ^= 1; - g_screen = g_screen_base + id * WIDTH * HEIGHT; +static void handle_usr1(int num) +{ + g_hide = !g_hide; + pthread_cond_signal(&g_cond); } #define s_printf(x, y, fmt, ...) \ @@ -222,10 +238,10 @@ static int read_int_file(const char *fn, int *val) return 0; } -static void clear(int h) +static void clear_bytes(void *mem, int bytes) { - int *p = (int *)g_screen; - int l = WIDTH * h / 2; + int *p = mem; + int l = bytes / 4; for (; l >= 4; l -= 4, p += 4) p[0] = p[1] = p[2] = p[3] = 0x07e007e0; @@ -233,6 +249,11 @@ static void clear(int h) *p = 0x07e007e0; } +static void clear(int h) +{ + clear_bytes(g_screen, WIDTH * h * 2); +} + struct proc_stat { unsigned long idlesum; unsigned long sys; @@ -645,14 +666,17 @@ static void get_netsgnl(int x, int y) int main(int argc, char *argv[]) { - static const char socket_name[] = "\0livestats"; + static const char socket_name[] = "\0liveinfo"; + static const char fbname[] = "/dev/fb2"; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_cond_t cond; pthread_condattr_t condattr; struct sockaddr_un sun; struct timespec ts; struct pollfd pfd; + const char *p; + int is_hidden = 0; int y = 0, y_max = 0; + int fd = -1; int sock; int ret; @@ -669,15 +693,35 @@ int main(int argc, char *argv[]) ret = connect(sock, (struct sockaddr *)&sun, sizeof(sun)); if (ret == 0) { - printf("other instance detected, sending quit command\n"); - ret = send(sock, "quit", 4, 0); - if (ret != 4) + printf("other instance detected, sending poke command\n"); + ret = send(sock, "poke", 5, 0); + if (ret != 5) perror("send"); close(sock); - return 0; + return ret == 5 ? 0 : 1; + } + + fd = open(fbname, O_RDWR); + if (fd == -1) { + fprintf(stderr, "open %s: ", fbname); + perror(NULL); + return 1; } - // bind/listen for quit command + nice(-1); + + // no need for privileges any more + p = getenv("SUDO_UID"); + if (p != NULL) { + ret = atoi(p); + if (ret != 0) { + ret = setuid(ret); + if (ret) + perror("setuid"); + } + } + + // bind/listen for commands ret = bind(sock, (struct sockaddr *)&sun, sizeof(sun)); if (ret != 0) { perror("bind"); @@ -696,32 +740,22 @@ int main(int argc, char *argv[]) pfd.events = POLLIN | POLLPRI; pfd.revents = 0; - // clean up on kill too - signal(SIGTERM, handle_signal); - ret = pthread_condattr_init(&condattr); ret |= pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); - ret |= pthread_cond_init(&cond, &condattr); + ret |= pthread_cond_init(&g_cond, &condattr); pthread_condattr_destroy(&condattr); if (ret != 0) { fprintf(stderr, "cond init failed\n"); return 1; } - ret = setup_layer(); + ret = setup_layer(fd); if (ret) return ret; - g_screen_base = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, g_fd, 0); - if (g_screen_base == MAP_FAILED) { - perror("mmap"); - return 1; - } - g_screen = g_screen_base; - clear(HEIGHT); - flip_fb(); - clear(HEIGHT); + // clean up on kill too + signal(SIGTERM, handle_term); + signal(SIGUSR1, handle_usr1); pthread_mutex_lock(&mutex); ret = clock_gettime(CLOCK_MONOTONIC, &ts); @@ -730,10 +764,25 @@ int main(int argc, char *argv[]) return 1; } - nice(-1); init_stats(); - while (!g_exit) { + while (!g_exit) + { + // handle hiding + if (g_hide) { + if (!is_hidden) { + remove_layer(fd); + is_hidden = 1; + } + goto do_sleep; + } + else if (is_hidden) { + ret = setup_layer(fd); + if (ret) + break; + is_hidden = 0; + } + collect_stats(); y += Y_STEP; @@ -774,22 +823,25 @@ int main(int argc, char *argv[]) get_bwatts (0, y += Y_STEP); get_btemp (0, y += Y_STEP); - flip_fb(); + flip_fb(fd); - if (check_layer() != 0) + if (check_layer(fd) != 0) break; + + // anything on unix socket? ret = poll(&pfd, 1, 0); if (ret != 0) { printf("poll returned %d\n", ret); break; } +do_sleep: ts.tv_sec++; - pthread_cond_timedwait(&cond, &mutex, &ts); + pthread_cond_timedwait(&g_cond, &mutex, &ts); } - munmap(g_screen_base, MEM_SIZE); - remove_layer(); + remove_layer(fd); + close(fd); close(sock); return 0; diff --git a/update_pnd.sh b/update_pnd.sh index f6be786..1281ce7 100755 --- a/update_pnd.sh +++ b/update_pnd.sh @@ -1,8 +1,13 @@ #!/bin/sh +set -e + if test -z "$PND_MAKE"; then PND_MAKE=$HOME/dev/pnd/src/pandora-libraries/testdata/scripts/pnd_make.sh fi rm -f *.o +mkdir -p /tmp/liveinfo_git +mv .git /tmp/liveinfo_git/ $PND_MAKE -p /tmp/liveinfo.pnd -d . -x liveinfo.pxml -i liveinfo.png -c +mv /tmp/liveinfo_git/.git . -- 2.39.2