xref: /netbsd-src/external/bsd/libfido2/dist/src/hid_unix.c (revision 2d40c4512a84c0d064ec30a492c5e2a14d230bc3)
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