/* chsel - example program providing simple command-line interface for * manipulation with the kernel selection buffer. */ /* Note that in the output of chsel get, newlines are returned as ^M (\x0d). * This is just how it's stored in the kernel. Should we translate it? */ /* You currently need a kernel patch available at * http://pasky.ji.cz/~pasky/dev/kernel/selection.patch */ /* [GPL'd] (c) 2002 Petr Baudis */ #define VERSION "0.1" /* This is really not coded nicely, it's rather a dirty hack. Its goal for * now is to be as simple and short as possible, so that people can get the * general idea. */ #include #include #include #include #include int main(int argc, char *argv[]) { enum { MODE_GET, MODE_SET } mode; char *buffer; int len; int fd = 0; if (argc < 2) { usage: fprintf(stderr, "chsel %s\nUsage: %s {get|set }\n", VERSION, argv[0]); return 1; } if (!strcmp(argv[1], "get")) mode = MODE_GET; else if (!strcmp(argv[1], "set")) mode = MODE_SET; else goto usage; if (mode == MODE_SET && argc != 3) goto usage; switch (mode) { case MODE_SET: len = strlen(argv[2]); buffer = malloc(len + 1 + sizeof(unsigned int)); buffer[0] = 13; memcpy(buffer + 1, &len, sizeof(unsigned int)); memcpy(buffer + 1 + sizeof(unsigned int), argv[2], len); if (ioctl(fd, TIOCLINUX, buffer) < 0) { ioctl_error: perror("chsel - ioctl()"); free(buffer); return 2; } break; case MODE_GET: /* I could do this by simply going directly for 65536, but this limit * can change in future and it wouldn't be so demonstrational and * educational ;-). --pasky */ len = 128; get_loop: buffer = malloc(len + 1 + sizeof(unsigned int)); buffer[0] = 14; memcpy(buffer + 1, &len, sizeof(unsigned int)); if ((len = ioctl(fd, TIOCLINUX, buffer)) < 0) goto ioctl_error; if (len > *((unsigned int *) (buffer + 1))) { free(buffer); goto get_loop; /* and now with the right buffer len */ } if (*((unsigned int *) (buffer + 1))) printf("%*s", *((unsigned int *) (buffer + 1)), buffer + 1 + sizeof(unsigned int)); free(buffer); break; } return 0; }