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