int uf_create_pidfile() { char pidtxt[128]; size_t l; int fd; if(!uf_return_running() && (fd = open(G15DAEMON_PIDFILE, O_CREAT|O_RDWR|O_EXCL, 0644)) < 0) { g15daemon_log(LOG_ERR,"previous G15Daemon process died. removing pidfile"); unlink(G15DAEMON_PIDFILE); } if ((fd = open(G15DAEMON_PIDFILE, O_CREAT|O_RDWR|O_EXCL, 0644)) < 0) { return 1; } snprintf(pidtxt, sizeof(pidtxt), "%lu\n", (unsigned long) getpid()); if (write(fd, pidtxt, l = strlen(pidtxt)) != l) { g15daemon_log(LOG_WARNING, "write(): %s", strerror(errno)); unlink(G15DAEMON_PIDFILE); } if(fd>0) { close(fd); return 0; } return 1; }
int uf_return_running(){ int fd; char pidtxt[128]; int pid; int l; if ((fd = open(G15DAEMON_PIDFILE, O_RDWR, 0644)) < 0) { return -1; } if((l = read(fd,pidtxt,sizeof(pidtxt)-1)) < 0) { unlink (G15DAEMON_PIDFILE); close(fd); return -1; } if((pid = atoi(pidtxt)) <= 0) { g15daemon_log(LOG_ERR,"pidfile corrupt"); unlink(G15DAEMON_PIDFILE); close(fd); return -1; } if((kill(pid,0) != 0) && errno != EPERM ) { g15daemon_log(LOG_ERR,"Process died - removing pidfile"); unlink(G15DAEMON_PIDFILE); close(fd); return -1; } return pid; }
static int g15_init_uinput(void *plugin_args) { int i=0; char *custom_filename; g15daemon_t *masterlist = (g15daemon_t*) plugin_args; struct uinput_user_dev uinp; static const char *uinput_device_fn[] = { "/dev/uinput", "/dev/input/uinput","/dev/misc/uinput",0}; uinput_cfg = g15daemon_cfg_load_section(masterlist,"Keyboard OS Mapping (uinput)"); custom_filename = g15daemon_cfg_read_string(uinput_cfg, "device",(char*)uinput_device_fn[1]); map_Lkeys=g15daemon_cfg_read_int(uinput_cfg, "Lkeys.mapped",0); seteuid(0); setegid(0); while (uinput_device_fn[i] && (uinp_fd = open(uinput_device_fn[i],O_RDWR))<0){ ++i; } if(uinp_fd<0) { /* try reading the users preference in the config */ uinp_fd = open(custom_filename,O_RDWR); } if(uinp_fd<0){ g15daemon_log(LOG_ERR,"Unable to open UINPUT device. Please ensure the uinput driver is loaded into the kernel and that you have permission to open the device."); return -1; } /* all other processes/threads should be seteuid nobody */ seteuid(masterlist->nobody->pw_uid); setegid(masterlist->nobody->pw_gid); memset(&uinp,0,sizeof(uinp)); strncpy(uinp.name, "G15 Extra Keys", UINPUT_MAX_NAME_SIZE); uinp.id.version = 4; uinp.id.bustype = BUS_USB; ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY); for (i=0; i<256; ++i) ioctl(uinp_fd, UI_SET_KEYBIT, i); write(uinp_fd, &uinp, sizeof(uinp)); if (ioctl(uinp_fd, UI_DEV_CREATE)) { g15daemon_log(LOG_ERR,"Unable to create UINPUT device."); return -1; } return 0; }
/* handy function from xine_utils.c */ void *g15daemon_xmalloc(size_t size) { void *ptr; /* prevent xmalloc(0) of possibly returning NULL */ if( !size ) size++; if((ptr = calloc(1, size)) == NULL) { g15daemon_log(LOG_WARNING, "g15_xmalloc() failed: %s.\n", strerror(errno)); return NULL; } return ptr; }