Skip to content

Instantly share code, notes, and snippets.

@neogeographica
Created January 26, 2023 16:26
Show Gist options
  • Save neogeographica/d5e1b318ed61af29e41496ec093c7940 to your computer and use it in GitHub Desktop.
Save neogeographica/d5e1b318ed61af29e41496ec093c7940 to your computer and use it in GitHub Desktop.
mouse bouncer
// SPDX-License-Identifier: GPL-2.0-or-later
//
// looooosely based on usbip_unbind.c and sysfs_utils.c from the Linux source
// This C code is for replicating this kind of behavior from the shell:
// sudo sh -c 'echo 8-1 > /sys/bus/usb/drivers/usb/unbind'
// sleep 30
// sudo sh -c 'echo 8-1 > /sys/bus/usb/drivers/usb/bind'
// I use that to bounce my wireless mouse to the receiver on another computer.
// Building this as an executable rather than a shell script means that I can
// give it root ownership and setuid so that I don't need to enter the root
// password, therefore I can bind it to a keyboard shortcut.
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static const char usage_string[] =
"usb-pause <id> [<seconds>]\n"
" <id> is bus and device in format such as \"8-1\"\n"
" <seconds> is number of seconds to pause; 30 if not specified\n";
void usage(void)
{
printf("usage: %s", usage_string);
}
int write_sysfs(const char *attr_path, const char *new_value, size_t len)
{
int fd;
int length;
fd = open(attr_path, O_WRONLY);
if (fd < 0) {
//fprintf(stderr, "error opening %s\n", attr_path);
return -1;
}
length = write(fd, new_value, len);
if (length < 0) {
//fprintf(stderr, "error writing to %s\n", attr_path);
close(fd);
return -1;
}
close(fd);
return 0;
}
int pause_device(char *id, int seconds)
{
int rc;
rc = write_sysfs("/sys/bus/usb/drivers/usb/unbind", id, strlen(id));
if (rc < 0) {
fprintf(stderr, "error pausing device %s\n", id);
return -1;
}
printf("pausing device for %d seconds...\n", seconds);
sleep(seconds);
rc = write_sysfs("/sys/bus/usb/drivers/usb/bind", id, strlen(id));
if (rc < 0) {
fprintf(stderr, "error unpausing device %s\n", id);
return -1;
}
printf("...done\n");
return 0;
}
int main(int argc, char *argv[])
{
int seconds = 30;
if (argc < 2 || argc > 3) {
usage();
return -1;
}
if (argc == 3) {
seconds = atoi(argv[2]);
}
return pause_device(argv[1], seconds);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment