ssize_t Freadall(FD_t fd, void * buf, ssize_t size) { ssize_t total = 0; ssize_t nb = 0; char * bufp = buf; while (total < size) { nb = Fread(bufp, 1, size - total, fd); if (nb == 0 || (nb < 0 && !RETRY_ERROR(errno))) { total = nb; break; } if (nb > 0) { bufp += nb; total += nb; } } return total; }
int main(int argc, char **argv) { unsigned long devt; int ldisc; struct input_types *type = NULL; const char *device = NULL; int daemon_mode = 0; int need_device = 0; unsigned long id, extra; int fd; int i; unsigned char c; int retval; int baud = -1; int ignore_init_res = 0; int no_init = 0; for (i = 1; i < argc; i++) { if (!strcasecmp(argv[i], "--help")) { show_help(); return EXIT_SUCCESS; } else if (!strcasecmp(argv[i], "--daemon")) { daemon_mode = 1; } else if (!strcasecmp(argv[i], "--always")) { ignore_init_res = 1; } else if (!strcasecmp(argv[i], "--noinit")) { no_init = 1; } else if (need_device) { device = argv[i]; need_device = 0; } else if (!strcasecmp(argv[i], "--baud")) { if (argc <= i + 1) { show_help(); fprintf(stderr, "inputattach: require baud rate\n"); return EXIT_FAILURE; } baud = atoi(argv[++i]); } else { if (type && type->name) { fprintf(stderr, "inputattach: '%s' - " "only one mode allowed\n", argv[i]); return EXIT_FAILURE; } for (type = input_types; type->name; type++) { if (!strcasecmp(argv[i], type->name) || !strcasecmp(argv[i], type->name2)) { break; } } if (!type->name) { fprintf(stderr, "inputattach: invalid mode '%s'\n", argv[i]); return EXIT_FAILURE; } need_device = 1; } } if (!type || !type->name) { fprintf(stderr, "inputattach: must specify mode\n"); return EXIT_FAILURE; } if (need_device) { fprintf(stderr, "inputattach: must specify device\n"); return EXIT_FAILURE; } fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { fprintf(stderr, "inputattach: '%s' - %s\n", device, strerror(errno)); return 1; } switch(baud) { case -1: break; case 2400: type->speed = B2400; break; case 4800: type->speed = B4800; break; case 9600: type->speed = B9600; break; case 19200: type->speed = B19200; break; case 38400: type->speed = B38400; break; default: fprintf(stderr, "inputattach: invalid baud rate '%d'\n", baud); return EXIT_FAILURE; } setline(fd, type->flags, type->speed); if (type->flush) while (!readchar(fd, &c, 100)) /* empty */; id = type->id; extra = type->extra; if (type->init && !no_init) { if (type->init(fd, &id, &extra)) { if (ignore_init_res) { fprintf(stderr, "inputattach: ignored device initialization failure\n"); } else { fprintf(stderr, "inputattach: device initialization failed\n"); return EXIT_FAILURE; } } } ldisc = N_MOUSE; if (ioctl(fd, TIOCSETD, &ldisc) < 0) { fprintf(stderr, "inputattach: can't set line discipline\n"); return EXIT_FAILURE; } devt = type->type | (id << 8) | (extra << 16); if (ioctl(fd, SPIOCSTYPE, &devt) < 0) { fprintf(stderr, "inputattach: can't set device type\n"); return EXIT_FAILURE; } retval = EXIT_SUCCESS; if (daemon_mode && daemon(0, 0) < 0) { perror("inputattach"); retval = EXIT_FAILURE; } do { i = read(fd, NULL, 0); if (i == -1) { if (RETRY_ERROR(errno)) continue; } } while (!i); ldisc = 0; ioctl(fd, TIOCSETD, &ldisc); close(fd); return retval; }