1*0afa8e06SEd Maste /* 2*0afa8e06SEd Maste * Copyright (c) 2020 Yubico AB. All rights reserved. 3*0afa8e06SEd Maste * Use of this source code is governed by a BSD-style 4*0afa8e06SEd Maste * license that can be found in the LICENSE file. 5*0afa8e06SEd Maste */ 6*0afa8e06SEd Maste 7*0afa8e06SEd Maste #include <sys/stat.h> 8*0afa8e06SEd Maste 9*0afa8e06SEd Maste #include <errno.h> 10*0afa8e06SEd Maste #include <fcntl.h> 11*0afa8e06SEd Maste #include <poll.h> 12*0afa8e06SEd Maste #include <unistd.h> 13*0afa8e06SEd Maste 14*0afa8e06SEd Maste #include "fido.h" 15*0afa8e06SEd Maste 16*0afa8e06SEd Maste #ifdef __NetBSD__ 17*0afa8e06SEd Maste #define ppoll pollts 18*0afa8e06SEd Maste #endif 19*0afa8e06SEd Maste 20*0afa8e06SEd Maste int 21*0afa8e06SEd Maste fido_hid_unix_open(const char *path) 22*0afa8e06SEd Maste { 23*0afa8e06SEd Maste int fd; 24*0afa8e06SEd Maste struct stat st; 25*0afa8e06SEd Maste 26*0afa8e06SEd Maste if ((fd = open(path, O_RDWR)) == -1) { 27*0afa8e06SEd Maste if (errno != ENOENT && errno != ENXIO) 28*0afa8e06SEd Maste fido_log_error(errno, "%s: open %s", __func__, path); 29*0afa8e06SEd Maste return (-1); 30*0afa8e06SEd Maste } 31*0afa8e06SEd Maste 32*0afa8e06SEd Maste if (fstat(fd, &st) == -1) { 33*0afa8e06SEd Maste fido_log_error(errno, "%s: fstat %s", __func__, path); 34*0afa8e06SEd Maste if (close(fd) == -1) 35*0afa8e06SEd Maste fido_log_error(errno, "%s: close", __func__); 36*0afa8e06SEd Maste return (-1); 37*0afa8e06SEd Maste } 38*0afa8e06SEd Maste 39*0afa8e06SEd Maste if (S_ISCHR(st.st_mode) == 0) { 40*0afa8e06SEd Maste fido_log_debug("%s: S_ISCHR %s", __func__, path); 41*0afa8e06SEd Maste if (close(fd) == -1) 42*0afa8e06SEd Maste fido_log_error(errno, "%s: close", __func__); 43*0afa8e06SEd Maste return (-1); 44*0afa8e06SEd Maste } 45*0afa8e06SEd Maste 46*0afa8e06SEd Maste return (fd); 47*0afa8e06SEd Maste } 48*0afa8e06SEd Maste 49*0afa8e06SEd Maste int 50*0afa8e06SEd Maste fido_hid_unix_wait(int fd, int ms, const fido_sigset_t *sigmask) 51*0afa8e06SEd Maste { 52*0afa8e06SEd Maste struct timespec ts; 53*0afa8e06SEd Maste struct pollfd pfd; 54*0afa8e06SEd Maste int r; 55*0afa8e06SEd Maste 56*0afa8e06SEd Maste memset(&pfd, 0, sizeof(pfd)); 57*0afa8e06SEd Maste pfd.events = POLLIN; 58*0afa8e06SEd Maste pfd.fd = fd; 59*0afa8e06SEd Maste 60*0afa8e06SEd Maste #ifdef FIDO_FUZZ 61*0afa8e06SEd Maste if (ms < 0) 62*0afa8e06SEd Maste return (0); 63*0afa8e06SEd Maste #endif 64*0afa8e06SEd Maste if (ms > -1) { 65*0afa8e06SEd Maste ts.tv_sec = ms / 1000; 66*0afa8e06SEd Maste ts.tv_nsec = (ms % 1000) * 1000000; 67*0afa8e06SEd Maste } 68*0afa8e06SEd Maste 69*0afa8e06SEd Maste if ((r = ppoll(&pfd, 1, ms > -1 ? &ts : NULL, sigmask)) < 1) { 70*0afa8e06SEd Maste if (r == -1) 71*0afa8e06SEd Maste fido_log_error(errno, "%s: ppoll", __func__); 72*0afa8e06SEd Maste return (-1); 73*0afa8e06SEd Maste } 74*0afa8e06SEd Maste 75*0afa8e06SEd Maste return (0); 76*0afa8e06SEd Maste } 77