diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | main.c | 86 |
2 files changed, 90 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d1eb8b1 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +CFLAGS=-g -Wall `pkg-config --cflags --libs libudev` + +all: + gcc main.c ${CFLAGS} -o poll-phone @@ -0,0 +1,86 @@ +#include <libudev.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> +#include <sys/epoll.h> +#include <stdbool.h> +#include <unistd.h> +#include <sys/types.h> +#include <string.h> +#include <sys/wait.h> +#include <signal.h> +#include <errno.h> + + +#define EPOLL_EVENTS 8 + +/*Open a connection with the current wayland compositor if it exists + * A fd is provided which can be polled. When polling the fd returns an error + * send a signal to any children and terminate. + */ + +bool TERMINATE = false; + +int fork_and_wait() { + pid_t pid = fork(); + assert(pid != -1); + if(pid == 0) { + /*There's a race condition with adb...*/ + sleep(2); + return execlp("scrcpy", "scrcpy", (char *) 0); + } + int status; + pid_t _pid; + do { + _pid = waitpid(pid, &status, WNOHANG); + } while (pid != _pid && !TERMINATE); + int exit_status = WEXITSTATUS(status); + return exit_status; +} + +void handle_hup(int sig) { + printf("poll-phone: %d\n", sig); + signal(sig, SIG_IGN); + kill(0, SIGHUP); + TERMINATE = true; +} + +/*Refactor this so we poll the signal handlers*/ + +int main(int argc, char **argv) { + + struct epoll_event events[EPOLL_EVENTS]; + int epfd = epoll_create(EPOLL_EVENTS); + struct udev *_udev = udev_new(); + assert(_udev != NULL); + struct udev_monitor *_monitor = udev_monitor_new_from_netlink(_udev, "udev"); + assert(_monitor != NULL); + udev_monitor_enable_receiving(_monitor); + int fd = udev_monitor_get_fd(_monitor); + + struct epoll_event event; + event.events = EPOLLIN; + epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); + + signal(SIGTERM, handle_hup); + signal(SIGINT, handle_hup); + + fork_and_wait(); + while(!TERMINATE) { + int state = epoll_wait(epfd, &events[0], EPOLL_EVENTS, -1); + if(state == EINTR) { break; } + else { exit(-1); } + + struct udev_device *device = udev_monitor_receive_device(_monitor); + const char *action = udev_device_get_action(device); + udev_device_unref(device); + + if(!strcmp(action, "bind")) { + fork_and_wait(); + } + } + + udev_monitor_unref(_monitor); + udev_unref(_udev); + return 0; +} |