#include #include #include #include #include #include #include #include #include #define DEV_PATH "/dev/power" #define BUFFER_SIZE 2 void execute_command(const char *cmd) { pid_t pid = fork(); if (pid == -1) { perror("fork failed"); return; } if (pid == 0) { execl("/bin/sh", "sh", "-c", cmd, NULL); perror("execl failed"); exit(EXIT_FAILURE); } else { int status; waitpid(pid, &status, 0); } } void reboot_system() { printf("reboot command received, system rebooting...\n"); sync(); execute_command("reboot"); } void shutdown_system() { printf("shutdown command received, system shutting down...\n"); sync(); execute_command("shutdown -hP now"); } int main() { int fd; char buf[BUFFER_SIZE]; ssize_t nread; fd = open(DEV_PATH, O_RDONLY); if (fd == -1) { fprintf(stderr, "cannot open device node %s: %s\n", DEV_PATH, strerror(errno)); fprintf(stderr, "please ensure:\n"); fprintf(stderr, "1. device node /dev/power exists\n"); fprintf(stderr, "2. sufficient permissions to access\n"); fprintf(stderr, "3. kernel driver is loaded\n"); return EXIT_FAILURE; } printf("monitoring %s, waiting for commands...\n", DEV_PATH); printf("'r' -> reboot system\n"); printf("'p' -> graceful shutdown\n"); printf("press Ctrl+C to exit\n\n"); while (1) { nread = read(fd, buf, sizeof(buf) - 1); if (nread == -1) { if (errno == EINTR) { continue; } perror("read device node failed"); break; } else if (nread == 0) { printf("device node closed, exiting\n"); break; } buf[nread] = '\0'; for (int i = 0; i < nread; i++) { char ch = buf[i]; switch (ch) { case 'r': case 'R': printf("detected character '%c'\n", ch); reboot_system(); break; case 'p': case 'P': printf("detected character '%c'\n", ch); shutdown_system(); break; default: printf("unknown character: '%c' (ASCII: %d)\n", ch, ch); break; } } } close(fd); return EXIT_SUCCESS; }