Created
March 26, 2021 08:58
-
-
Save jgke/5b1840a9047fb8e5e61c55684db8185f to your computer and use it in GitHub Desktop.
Disable USB device autosuspend with setuid C binary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <dirent.h> | |
#include <unistd.h> | |
/* | |
Throw into Makefile & compile with sudo make: | |
no_mouse_sleep: no-mouse-sleep.c | |
gcc no-mouse-sleep.c -o no_mouse_sleep -Wall -Wextra -Werror | |
sudo chown root:root no_mouse_sleep | |
sudo chmod +s no_mouse_sleep | |
*/ | |
const char *dev_path = "/sys/bus/usb/devices/"; | |
// Find your device with `lsusb` | |
const char *devices[] = { | |
"046d", "c31c", // Logitech, Inc. Keyboard K120 | |
"8564", "4000", // Transcend Information, Inc. RDF8 | |
"046d", "c069", // Logitech, Inc. M-U0007 [Corded Mouse M500] | |
}; | |
int main() { | |
if(setuid(0)) { | |
perror("Couldn't set uid to root"); | |
return 1; | |
} | |
if(setgid(0)) { | |
perror("Couldn't set gid to root"); | |
return 1; | |
} | |
DIR *dp; | |
struct dirent *ep; | |
dp = opendir(dev_path); | |
if (!dp) { | |
perror("Couldn't open usb device list"); | |
return 1; | |
} | |
while ((ep = readdir(dp))) { | |
if(ep->d_name && ep->d_name[0] != '.') { | |
char product[5] = {0}, vendor[5] = {0}; | |
size_t path_len = sizeof(char) * (strlen(dev_path) + strlen(ep->d_name) + strlen("/power/control") + 1); | |
char *path = calloc(path_len + 1, 1); | |
snprintf(path, path_len, "%s%s/idProduct", dev_path, ep->d_name); | |
FILE *fp = fopen(path, "r"); | |
if (!fp) { | |
free(path); | |
continue; | |
} | |
fread(product, 4, sizeof(char), fp); | |
fclose(fp); | |
snprintf(path, path_len, "%s%s/idVendor", dev_path, ep->d_name); | |
fp = fopen(path, "r"); | |
if (!fp) { | |
free(path); | |
continue; | |
} | |
fread(vendor, 4, sizeof(char), fp); | |
fclose(fp); | |
for (unsigned int i = 0; i < sizeof(devices)/sizeof(devices[0])/2; i++) { | |
if (!strcmp(vendor, devices[i*2]) && !strcmp(product, devices[i*2+1])) { | |
snprintf(path, path_len, "%s%s/power/control", dev_path, ep->d_name); | |
fp = fopen(path, "w"); | |
if (!fp) { | |
perror("Couldn't open power control file for writing"); | |
continue; | |
} | |
printf("Disabling autosuspend for %s:%s\n", vendor, product); | |
fwrite("on\n", 4, sizeof(char), fp); | |
fclose(fp); | |
} | |
} | |
free(path); | |
} | |
} | |
closedir(dp); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment