diff options
Diffstat (limited to 'compat.h')
-rw-r--r-- | compat.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/compat.h b/compat.h new file mode 100644 index 0000000..55dda53 --- /dev/null +++ b/compat.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2019 C. McEnroe <june@causal.agency> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#ifdef __linux__ + +#define _GNU_SOURCE + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define NO_READPASSPHRASE_H +#define RPP_STDIN 1 +static inline char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { + if (flags) { + if (!fgets(buf, bufsiz, stdin)) return NULL; + return strsep(&buf, "\n"); + } + return getpass(prompt); +} + +typedef int _readfn(void *, char *, int); +typedef int _writefn(void *, const char *, int); +typedef fpos_t _seekfn(void *, fpos_t, int); +typedef int _closefn(void *); + +struct _funopen { + void *cookie; + _readfn *readfn; + _writefn *writefn; + _closefn *closefn; +}; + +static inline ssize_t +_cookie_read(void *cookie, char *buf, size_t size) { + struct _funopen *funopen = cookie; + assert((size_t)(int)size == size); + return funopen->readfn(funopen->cookie, buf, size); +} + +static inline ssize_t +_cookie_write(void *cookie, const char *buf, size_t size) { + struct _funopen *funopen = cookie; + assert((size_t)(int)size == size); + return funopen->writefn(funopen->cookie, buf, size); +} + +static inline int +_cookie_close(void *cookie) { + struct _funopen *funopen = cookie; + int ret = funopen->closefn(funopen->cookie); + free(cookie); + return ret; +} + +static const cookie_io_functions_t _cookie_fns = { + .read = _cookie_read, + .write = _cookie_write, + .close = _cookie_close, +}; + +static inline FILE * +funopen( + const void *cookie, + _readfn *readfn, _writefn *writefn, _seekfn *seekfn, _closefn *closefn +) { + struct _funopen *funopen = malloc(sizeof(*funopen)); + if (!funopen) return NULL; + assert(!seekfn); + *funopen = (struct _funopen) { (void *)cookie, readfn, writefn, closefn }; + return fopencookie(funopen, "r+", _cookie_fns); +} + +#endif /* __linux__ */ |