ksgi
/
wrappers.c
631 строка · 13.4 Кб
1/* $Id$ */
2/*
3* Copyright (c) 2012, 2014--2017 Kristaps Dzonsons <kristaps@bsd.lv>
4*
5* Permission to use, copy, modify, and distribute this software for any
6* purpose with or without fee is hereby granted, provided that the above
7* copyright notice and this permission notice appear in all copies.
8*
9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*/
17#include "config.h"18
19#include <sys/stat.h>20#include <sys/socket.h>21#include <sys/uio.h>22#include <sys/wait.h>23
24#include <assert.h>25#include <errno.h>26#include <fcntl.h>27#include <poll.h>28#include <signal.h>29#include <stdarg.h>30#include <stdio.h>31#include <stdint.h>32#include <stdlib.h>33#include <string.h>34#include <unistd.h>35
36#include "kcgi.h"37#include "extern.h"38
39int
40kxvasprintf(char **p, const char *fmt, va_list ap)41{
42int len;43
44if ((len = vasprintf(p, fmt, ap)) >= 0)45return len;46
47kutil_warn(NULL, NULL, "vasprintf");48*p = NULL;49return -1;50}
51
52int
53kxasprintf(char **p, const char *fmt, ...)54{
55va_list ap;56int ret;57
58va_start(ap, fmt);59ret = kxvasprintf(p, fmt, ap);60va_end(ap);61return ret;62}
63
64void *65kxcalloc(size_t nm, size_t sz)66{
67void *p;68
69if (nm == 0 || sz == 0) {70kutil_warnx(NULL, NULL, "calloc: zero length");71return NULL;72} else if ((p = calloc(nm, sz)) != NULL)73return p;74
75kutil_warn(NULL, NULL, "calloc: %zu, %zu", nm, sz);76return NULL;77}
78
79void *80kxmalloc(size_t sz)81{
82void *p;83
84if (sz == 0) {85kutil_warnx(NULL, NULL, "malloc: zero length");86return NULL;87} else if ((p = malloc(sz)) != NULL)88return p;89
90kutil_warn(NULL, NULL, "malloc: %zu", sz);91return NULL;92}
93
94void *95kxrealloc(void *pp, size_t sz)96{
97void *p;98
99if (sz == 0) {100kutil_warnx(NULL, NULL, "realloc: zero length");101return NULL;102} else if ((p = realloc(pp, sz)) != NULL)103return p;104
105kutil_warn(NULL, NULL, "realloc: %zu", sz);106return NULL;107}
108
109void *110kxreallocarray(void *pp, size_t nm, size_t sz)111{
112void *p;113
114if (sz == 0 || nm == 0) {115kutil_warnx(NULL, NULL, "reallocarray: zero length");116return NULL;117} else if ((p = reallocarray(pp, nm, sz)) != NULL)118return p;119
120kutil_warn(NULL, NULL, "reallocarray: %zu, %zu", nm, sz);121return NULL;122}
123
124char *125kxstrdup(const char *cp)126{
127char *p;128
129if (cp == NULL) {130kutil_warnx(NULL, NULL, "strdup: NULL string");131return NULL;132} else if ((p = strdup(cp)) != NULL)133return p;134
135kutil_warn(NULL, NULL, "strdup");136return NULL;137}
138
139/*
140* waitpid() and logging anything but a return with EXIT_SUCCESS.
141* Returns KCGI_OK on EXIT_SUCCESS, KCGI_SYSTEM on waitpid() error,
142* KCGI_FORM on child process failure.
143*/
144enum kcgi_err145kxwaitpid(pid_t pid)146{
147int st;148
149if (waitpid(pid, &st, 0) == -1) {150kutil_warn(NULL, NULL, "waitpid");151return KCGI_SYSTEM;152} else if (WIFEXITED(st) && WEXITSTATUS(st) == EXIT_SUCCESS)153return KCGI_OK;154
155if (WIFEXITED(st))156kutil_warnx(NULL, NULL, "waitpid: child failure");157else158kutil_warnx(NULL, NULL, "waitpid: child signal");159
160return KCGI_FORM;161}
162
163/*
164* Set a file-descriptor as being non-blocking.
165* Returns KCGI_SYSTEM on error, KCGI_OK on success.
166*/
167enum kcgi_err168kxsocketprep(int sock)169{
170int fl;171
172if ((fl = fcntl(sock, F_GETFL, 0)) == -1) {173kutil_warn(NULL, NULL, "fcntl");174return KCGI_SYSTEM;175} else if (fcntl(sock, F_SETFL, fl | O_NONBLOCK) == -1) {176kutil_warn(NULL, NULL, "fcntl");177return KCGI_SYSTEM;178}179
180return KCGI_OK;181}
182
183/*
184* Create a non-blocking socketpair (AF_UNIX, SOCK_STREAM, protocol 0).
185* Return KCGI_ENFILE on temporary failure, KCGI_SYSTEM on fatal error,
186* KCGI_OK on success.
187* The input socket pair is only valid on success.
188*/
189enum kcgi_err190kxsocketpair(int sock[2])191{
192int rc;193enum kcgi_err er;194
195rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);196if (rc == -1 && (EMFILE == errno || ENFILE == errno)) {197kutil_warn(NULL, NULL, "socketpair");198return KCGI_ENFILE;199} else if (rc == -1) {200kutil_warn(NULL, NULL, "socketpair");201return KCGI_SYSTEM;202}203
204if ((er = kxsocketprep(sock[0])) == KCGI_OK &&205((er = kxsocketprep(sock[1])) == KCGI_OK))206return KCGI_OK;207
208close(sock[0]);209close(sock[1]);210return er;211}
212
213/*
214* Write a string "buf".
215* If "buf" is NULL, then write a zero-length string.
216* See fullreadword().
217* On error (which shouldn't happen), this will exit the process with
218* the exit code EXIT_FAILURE.
219*/
220void
221fullwriteword(int fd, const char *buf)222{
223size_t sz;224
225if (buf != NULL) {226sz = strlen(buf);227fullwrite(fd, &sz, sizeof(size_t));228fullwrite(fd, buf, sz);229} else {230sz = 0;231fullwrite(fd, &sz, sizeof(size_t));232}233}
234
235/*
236* This is like fullwrite() but it does not bail out on errors.
237* We need this for writing our response to a socket that may be closed
238* at any time, like the FastCGI one.
239* Returns KCGI_SYSTEM, KCGI_HUP, or KCGI_OK.
240* Ignores SIGPIPE, restoring it on exit.
241*/
242enum kcgi_err243fullwritenoerr(int fd, const void *buf, size_t bufsz)244{
245ssize_t ssz;246size_t sz;247struct pollfd pfd;248int rc;249enum kcgi_err er = KCGI_OK;250void (*sig)(int);251
252pfd.fd = fd;253pfd.events = POLLOUT;254
255if ((sig = signal(SIGPIPE, SIG_IGN)) == SIG_ERR) {256kutil_warn(NULL, NULL, "signal");257return KCGI_SYSTEM;258}259
260for (sz = 0; sz < bufsz; sz += (size_t)ssz) {261if ((rc = poll(&pfd, 1, -1)) < 0) {262kutil_warn(NULL, NULL, "poll");263er = KCGI_SYSTEM;264break;265} else if (rc == 0) {266kutil_warnx(NULL, NULL, "poll: timeout!?");267ssz = 0;268continue;269}270
271if (pfd.revents & POLLHUP) {272kutil_warnx(NULL, NULL, "poll: hangup");273er = KCGI_HUP;274break;275} else if (pfd.revents & POLLERR) {276kutil_warnx(NULL, NULL, "poll: error");277er = KCGI_SYSTEM;278break;279}280
281/* See note in fullwrite(). */282
283#ifdef __APPLE__284if (!(pfd.revents & POLLOUT) &&285!(pfd.revents & POLLNVAL)) {286kutil_warnx(NULL, NULL, "poll: no output");287er = KCGI_SYSTEM;288break;289}290#else291if (!(pfd.revents & POLLOUT)) {292kutil_warnx(NULL, NULL, "poll: no output");293er = KCGI_SYSTEM;294break;295}296#endif297
298if ((ssz = write(fd, buf + sz, bufsz - sz)) < 0) {299er = errno == EPIPE ? KCGI_HUP : KCGI_SYSTEM;300kutil_warn(NULL, NULL, "write");301break;302} else if (sz > SIZE_MAX - (size_t)ssz) {303kutil_warnx(NULL, NULL, "write: overflow");304er = KCGI_SYSTEM;305break;306}307}308
309if (signal(SIGPIPE, sig) == SIG_ERR) {310kutil_warn(NULL, NULL, "signal");311er = KCGI_SYSTEM;312}313
314return er;315}
316
317/*
318* Write "buf", which can be NULL so long as bufsz is zero in which case
319* it's a noop.
320* On error (which shouldn't happen), this will exit the process with
321* the exit code EXIT_FAILURE.
322*/
323void
324fullwrite(int fd, const void *buf, size_t bufsz)325{
326ssize_t ssz;327size_t sz;328struct pollfd pfd;329int rc;330
331if (bufsz == 0)332return;333
334assert(buf != NULL);335pfd.fd = fd;336pfd.events = POLLOUT;337
338for (sz = 0; sz < bufsz; sz += (size_t)ssz) {339if ((rc = poll(&pfd, 1, INFTIM)) == 0) {340kutil_warnx(NULL, NULL, "poll: timeout!?");341ssz = 0;342continue;343} else if (rc < 0)344kutil_err(NULL, NULL, "poll");345
346if (pfd.revents & POLLHUP)347kutil_errx(NULL, NULL, "poll: hangup");348else if (pfd.revents & POLLERR)349kutil_errx(NULL, NULL, "poll: error");350
351/*352* This CPP exists because testing on Mac OS X will have
353* "fd" point to a device and poll(2) returns POLLNVAL
354* if the descriptor is to a device.
355* This is documented in the BUGS section of poll(2).
356*/
357#ifdef __APPLE__358if (!(pfd.revents & POLLOUT) &&359!(pfd.revents & POLLNVAL))360kutil_errx(NULL, NULL, "poll: no output");361#else362if (!(pfd.revents & POLLOUT))363kutil_errx(NULL, NULL, "poll: no output");364#endif365
366if ((ssz = write(fd, buf + sz, bufsz - sz)) < 0)367kutil_err(NULL, NULL, "write");368else if (sz > SIZE_MAX - (size_t)ssz)369kutil_errx(NULL, NULL, "write: overflow");370}371}
372
373/*
374* Read the contents of "buf" of size "bufsz".
375* If "eofok" is set, return zero if there is no data to read.
376* If it's not set, this condition returns <0.
377* Returns <0 on errors and >0 on success.
378*/
379int
380fullread(int fd, void *buf, size_t bufsz, int eofok, enum kcgi_err *er)381{
382ssize_t ssz;383size_t sz;384struct pollfd pfd;385int rc;386
387pfd.fd = fd;388pfd.events = POLLIN;389
390for (sz = 0; sz < bufsz; sz += (size_t)ssz) {391if ((rc = poll(&pfd, 1, INFTIM)) < 0) {392kutil_warn(NULL, NULL, "poll");393*er = KCGI_SYSTEM;394return (-1);395} else if (rc == 0) {396kutil_warnx(NULL, NULL, "poll: timeout!?");397ssz = 0;398continue;399}400
401if (!(pfd.revents & POLLIN)) {402if (eofok && sz == 0) {403*er = KCGI_OK;404return 0;405}406kutil_warnx(NULL, NULL, "poll: no input");407*er = KCGI_FORM;408return (-1);409}410
411if ((ssz = read(fd, buf + sz, bufsz - sz)) < 0) {412kutil_warn(NULL, NULL, "read");413*er = KCGI_SYSTEM;414return (-1);415} else if (ssz == 0 && sz > 0) {416kutil_warnx(NULL, NULL, "read: short read");417*er = KCGI_FORM;418return (-1);419} else if (ssz == 0 && sz == 0 && !eofok) {420kutil_warnx(NULL, NULL, "read: end of file");421*er = KCGI_FORM;422return (-1);423} else if (ssz == 0 && sz == 0 && eofok) {424*er = KCGI_OK;425return 0;426} else if (sz > SIZE_MAX - (size_t)ssz) {427kutil_warnx(NULL, NULL, "read: overflow");428*er = KCGI_FORM;429return (-1);430}431}432
433*er = KCGI_OK;434return 1;435}
436
437/*
438* Read a string from the stream.
439* Return KCGI_OK on success or another on error.
440* This will set cp to NULL and sz to zero on failure.
441* The cp array (on success) is always NUL-terminated, although the
442* buffer it reads is opaque.
443* On success, "sz" may legit be zero.
444*/
445enum kcgi_err446fullreadwordsz(int fd, char **cp, size_t *sz)447{
448enum kcgi_err ke;449int rc;450
451*cp = NULL;452*sz = 0;453
454if (fullread(fd, sz, sizeof(size_t), 0, &ke) < 0)455return ke;456
457/* TODO: check additive overflow of "sz + 1". */458
459if ((*cp = kxmalloc(*sz + 1)) == NULL) {460*sz = 0;461return KCGI_ENOMEM;462}463(*cp)[*sz] = '\0';464
465if (*sz == 0)466return KCGI_OK;467
468/* Because we don't set "eofok", never returns zero. */469
470if ((rc = fullread(fd, *cp, *sz, 0, &ke)) > 0) {471assert(ke == KCGI_OK);472return ke;473}474
475assert(rc < 0);476assert(ke != KCGI_OK);477free(*cp);478*cp = NULL;479*sz = 0;480return ke;481}
482
483/*
484* See fullreadwordsz() with a discarded size.
485*/
486enum kcgi_err487fullreadword(int fd, char **cp)488{
489size_t sz;490
491return fullreadwordsz(fd, cp, &sz);492}
493
494/*
495* Write a file-descriptor "sendfd" and a buffer "b" of length "bsz",
496* which must be 256 bytes or fewer, but not zero.
497* See fullwritefd().
498* Returns zero on failure (any kind), non-zero on success.
499*/
500int
501fullwritefd(int fd, int sendfd, void *b, size_t bsz)502{
503struct msghdr msg;504int rc;505char buf[CMSG_SPACE(sizeof(fd))];506struct iovec io;507struct cmsghdr *cmsg;508struct pollfd pfd;509
510assert(bsz <= 256 && bsz > 0);511
512memset(buf, 0, sizeof(buf));513memset(&msg, 0, sizeof(struct msghdr));514memset(&io, 0, sizeof(struct iovec));515
516io.iov_base = b;517io.iov_len = bsz;518
519msg.msg_iov = &io;520msg.msg_iovlen = 1;521msg.msg_control = buf;522msg.msg_controllen = sizeof(buf);523
524cmsg = CMSG_FIRSTHDR(&msg);525cmsg->cmsg_level = SOL_SOCKET;526cmsg->cmsg_type = SCM_RIGHTS;527cmsg->cmsg_len = CMSG_LEN(sizeof(fd));528
529*((int *)CMSG_DATA(cmsg)) = sendfd;530
531msg.msg_controllen = cmsg->cmsg_len;532
533pfd.fd = fd;534pfd.events = POLLOUT;535
536again:537if ((rc = poll(&pfd, 1, INFTIM)) < 0) {538kutil_warn(NULL, NULL, "poll");539return 0;540} else if (rc == 0) {541kutil_warnx(NULL, NULL, "poll: timeout!?");542goto again;543}544
545if (!(pfd.revents & POLLOUT)) {546kutil_warnx(NULL, NULL, "poll: no output");547return 0;548}549
550if ((rc = sendmsg(fd, &msg, 0)) < 0) {551kutil_warn(NULL, NULL, "sendmsg");552return 0;553} else if (rc == 0) {554kutil_warnx(NULL, NULL, "sendmsg: short write");555return 0;556}557
558return 1;559}
560
561/*
562* Read a file-descriptor into "recvfd" and a buffer "b" of length
563* "bsz", which must be 256 bytes or fewer, but not zero.
564* See fullwritefd().
565* Returns <0 on system failure, 0 on hangup (remote end closed), and >0
566* on success.
567* The output pointers are only set on success.
568*/
569int570fullreadfd(int fd, int *recvfd, void *b, size_t bsz)571{
572struct msghdr msg;573char m_buffer[256];574char c_buffer[256];575struct iovec io;576struct cmsghdr *cmsg;577int rc;578struct pollfd pfd;579
580assert(bsz <= 256 && bsz > 0);581
582memset(&msg, 0, sizeof(struct msghdr));583memset(&io, 0, sizeof(struct iovec));584
585io.iov_base = m_buffer;586io.iov_len = sizeof(m_buffer);587msg.msg_iov = &io;588msg.msg_iovlen = 1;589
590msg.msg_control = c_buffer;591msg.msg_controllen = sizeof(c_buffer);592
593pfd.fd = fd;594pfd.events = POLLIN;595
596again:597if ((rc = poll(&pfd, 1, INFTIM)) < 0) {598kutil_warn(NULL, NULL, "poll");599return (-1);600} else if (rc == 0) {601kutil_warnx(NULL, NULL, "poll timeout!?!?");602goto again;603}604
605if (!(pfd.revents & POLLIN)) {606kutil_warnx(NULL, NULL, "poll: no input");607return 0;608}609
610if ((rc = recvmsg(fd, &msg, 0)) < 0) {611kutil_warn(NULL, NULL, "recvmsg");612return (-1);613} else if (rc == 0) {614kutil_warnx(NULL, NULL, "recvmsg: short read");615return 0;616}617
618memcpy(b, m_buffer, bsz);619for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;620cmsg = CMSG_NXTHDR(&msg, cmsg)) {621if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&622cmsg->cmsg_level == SOL_SOCKET &&623cmsg->cmsg_type == SCM_RIGHTS) {624*recvfd = *(int *)CMSG_DATA(cmsg);625return 1;626}627}628
629kutil_warnx(NULL, NULL, "recvmsg: no SCM_RIGHTS");630return (-1);631}
632