195dbdf32Schristos /*
295dbdf32Schristos * Copyright (c) 2020 Yubico AB. All rights reserved.
395dbdf32Schristos * Use of this source code is governed by a BSD-style
495dbdf32Schristos * license that can be found in the LICENSE file.
5*2d40c451Schristos * SPDX-License-Identifier: BSD-2-Clause
695dbdf32Schristos */
795dbdf32Schristos
895dbdf32Schristos #include <sys/stat.h>
995dbdf32Schristos
1095dbdf32Schristos #include <errno.h>
1195dbdf32Schristos #include <fcntl.h>
1295dbdf32Schristos #include <poll.h>
1395dbdf32Schristos #include <unistd.h>
1495dbdf32Schristos
1595dbdf32Schristos #include "fido.h"
1695dbdf32Schristos
1795dbdf32Schristos #ifdef __NetBSD__
1895dbdf32Schristos #define ppoll pollts
1995dbdf32Schristos #endif
2095dbdf32Schristos
2195dbdf32Schristos int
fido_hid_unix_open(const char * path)2295dbdf32Schristos fido_hid_unix_open(const char *path)
2395dbdf32Schristos {
2495dbdf32Schristos int fd;
2595dbdf32Schristos struct stat st;
2695dbdf32Schristos
2795dbdf32Schristos if ((fd = open(path, O_RDWR)) == -1) {
2895dbdf32Schristos if (errno != ENOENT && errno != ENXIO)
2995dbdf32Schristos fido_log_error(errno, "%s: open %s", __func__, path);
3095dbdf32Schristos return (-1);
3195dbdf32Schristos }
3295dbdf32Schristos
3395dbdf32Schristos if (fstat(fd, &st) == -1) {
3495dbdf32Schristos fido_log_error(errno, "%s: fstat %s", __func__, path);
3595dbdf32Schristos if (close(fd) == -1)
3695dbdf32Schristos fido_log_error(errno, "%s: close", __func__);
3795dbdf32Schristos return (-1);
3895dbdf32Schristos }
3995dbdf32Schristos
4095dbdf32Schristos if (S_ISCHR(st.st_mode) == 0) {
4195dbdf32Schristos fido_log_debug("%s: S_ISCHR %s", __func__, path);
4295dbdf32Schristos if (close(fd) == -1)
4395dbdf32Schristos fido_log_error(errno, "%s: close", __func__);
4495dbdf32Schristos return (-1);
4595dbdf32Schristos }
4695dbdf32Schristos
4795dbdf32Schristos return (fd);
4895dbdf32Schristos }
4995dbdf32Schristos
5095dbdf32Schristos int
fido_hid_unix_wait(int fd,int ms,const fido_sigset_t * sigmask)5195dbdf32Schristos fido_hid_unix_wait(int fd, int ms, const fido_sigset_t *sigmask)
5295dbdf32Schristos {
5395dbdf32Schristos struct timespec ts;
5495dbdf32Schristos struct pollfd pfd;
5595dbdf32Schristos int r;
5695dbdf32Schristos
5795dbdf32Schristos memset(&pfd, 0, sizeof(pfd));
5895dbdf32Schristos pfd.events = POLLIN;
5995dbdf32Schristos pfd.fd = fd;
6095dbdf32Schristos
6195dbdf32Schristos #ifdef FIDO_FUZZ
6295dbdf32Schristos return (0);
6395dbdf32Schristos #endif
6495dbdf32Schristos if (ms > -1) {
6595dbdf32Schristos ts.tv_sec = ms / 1000;
6695dbdf32Schristos ts.tv_nsec = (ms % 1000) * 1000000;
6795dbdf32Schristos }
6895dbdf32Schristos
6995dbdf32Schristos if ((r = ppoll(&pfd, 1, ms > -1 ? &ts : NULL, sigmask)) < 1) {
7095dbdf32Schristos if (r == -1)
7195dbdf32Schristos fido_log_error(errno, "%s: ppoll", __func__);
7295dbdf32Schristos return (-1);
7395dbdf32Schristos }
7495dbdf32Schristos
7595dbdf32Schristos return (0);
7695dbdf32Schristos }
77