static void handle_events(fd_set *rset) { int dev_fd, hotplug_fd; /* handle anything coming through the UNIX socket */ handle_uevents(rset); #ifdef USE_X11 /* handle any X11 events (magellan protocol) */ handle_xevents(rset); #endif /* finally read any pending device input data */ if((dev_fd = get_dev_fd()) != -1) { if(FD_ISSET(dev_fd, rset)) { struct dev_input inp; /* read an event from the device ... */ while(read_dev(&inp) != -1) { /* ... and process it, possibly dispatching a spacenav event to clients */ process_input(&inp); } } } else if((hotplug_fd = get_hotplug_fd()) != -1) { if(FD_ISSET(hotplug_fd, rset)) { handle_hotplug(); } } }
int main(int argc, char **argv) { int i, ret, become_daemon = 1; for(i=1; i<argc; i++) { if(argv[i][0] == '-' && argv[i][2] == 0) { switch(argv[i][1]) { case 'd': become_daemon = !become_daemon; break; case 'v': verbose = 1; break; case 'h': printf("usage: %s [options]\n", argv[0]); printf("options:\n"); printf(" -d\tdo not daemonize\n"); printf(" -v\tverbose output\n"); printf(" -h\tprint this usage information\n"); return 0; default: fprintf(stderr, "unrecognized argument: %s\n", argv[i]); return 1; } } else { fprintf(stderr, "unexpected argument: %s\n", argv[i]); return 1; } } if(become_daemon) { daemonize(); } write_pid_file(); puts("Spacenav daemon " VERSION); read_cfg("/etc/spnavrc", &cfg); if(init_clients() == -1) { return 1; } signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGSEGV, sig_handler); signal(SIGHUP, sig_handler); signal(SIGUSR1, sig_handler); signal(SIGUSR2, sig_handler); if(init_dev() == -1) { init_hotplug(); } init_unix(); #ifdef USE_X11 init_x11(); #endif atexit(cleanup); for(;;) { fd_set rset; int fd, max_fd = 0; struct client *c; FD_ZERO(&rset); /* set the device fd if it's open, otherwise set the hotplug fd */ if((fd = get_dev_fd()) != -1 || (fd = get_hotplug_fd()) != -1) { FD_SET(fd, &rset); if(fd > max_fd) max_fd = fd; } /* the UNIX domain socket listening for connections */ if((fd = get_unix_socket()) != -1) { FD_SET(fd, &rset); if(fd > max_fd) max_fd = fd; } /* all the UNIX socket clients */ c = first_client(); while(c) { if(get_client_type(c) == CLIENT_UNIX) { int s = get_client_socket(c); assert(s >= 0); FD_SET(s, &rset); if(s > max_fd) max_fd = s; } c = next_client(); } /* and the X server socket */ #ifdef USE_X11 if((fd = get_x11_socket()) != -1) { FD_SET(fd, &rset); if(fd > max_fd) max_fd = fd; } #endif do { ret = select(max_fd + 1, &rset, 0, 0, 0); } while(ret == -1 && errno == EINTR); if(ret > 0) { handle_events(&rset); } } return 0; /* unreachable */ }
int main(int argc, char *argv[]) { struct thread_arg arg = { .fd = -1 }; bool daemonize = false; char *dev = NULL; int e; int i; e = pthread_mutex_init(&arg.mutex, NULL); if (e) { EMSG("pthread_mutex_init: %s", strerror(e)); EMSG("terminating..."); exit(EXIT_FAILURE); } if (argc > 3) return usage(EXIT_FAILURE); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d")) daemonize = true; else if (!strcmp(argv[i], "-h")) return usage(EXIT_SUCCESS); else dev = argv[i]; } if (dev) { arg.fd = open_dev(dev, &arg.gen_caps); if (arg.fd < 0) { EMSG("failed to open \"%s\"", argv[1]); exit(EXIT_FAILURE); } } else { arg.fd = get_dev_fd(&arg.gen_caps); if (arg.fd < 0) { EMSG("failed to find an OP-TEE supplicant device"); exit(EXIT_FAILURE); } } if (tee_supp_fs_init() != 0) { EMSG("error tee_supp_fs_init"); exit(EXIT_FAILURE); } if (daemonize && daemon(0, 0) < 0) { EMSG("daemon(): %s", strerror(errno)); exit(EXIT_FAILURE); } while (!arg.abort) { if (!process_one_request(&arg)) arg.abort = true; } close(arg.fd); return EXIT_FAILURE; } bool tee_supp_param_is_memref(struct tee_ioctl_param *param) { switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: return true; default: return false; } } bool tee_supp_param_is_value(struct tee_ioctl_param *param) { switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: return true; default: return false; } } void *tee_supp_param_to_va(struct tee_ioctl_param *param) { struct tee_shm *tshm; size_t end_offs; if (!tee_supp_param_is_memref(param)) return NULL; end_offs = param->u.memref.size + param->u.memref.shm_offs; if (end_offs < param->u.memref.size || end_offs < param->u.memref.shm_offs) return NULL; tshm = find_tshm(param->u.memref.shm_id); if (!tshm) return NULL; if (end_offs > tshm->size) return NULL; return (uint8_t *)tshm->p + param->u.memref.shm_offs; } void tee_supp_mutex_lock(pthread_mutex_t *mu) { int e = pthread_mutex_lock(mu); if (e) { EMSG("pthread_mutex_lock: %s", strerror(e)); EMSG("terminating..."); exit(EXIT_FAILURE); } }