1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter#include "apr_network_io.h" 18251875Speter#include "apr_poll.h" 19251875Speter 20251875SpeterAPR_DECLARE(apr_status_t) apr_socket_atreadeof(apr_socket_t *sock, int *atreadeof) 21251875Speter{ 22251875Speter apr_pollfd_t pfds[1]; 23251875Speter apr_status_t rv; 24251875Speter apr_int32_t nfds; 25251875Speter 26251875Speter /* The purpose here is to return APR_SUCCESS only in cases in 27251875Speter * which it can be unambiguously determined whether or not the 28251875Speter * socket will return EOF on next read. In case of an unexpected 29251875Speter * error, return that. */ 30251875Speter 31251875Speter pfds[0].reqevents = APR_POLLIN; 32251875Speter pfds[0].desc_type = APR_POLL_SOCKET; 33251875Speter pfds[0].desc.s = sock; 34251875Speter 35251875Speter do { 36251875Speter rv = apr_poll(&pfds[0], 1, &nfds, 0); 37251875Speter } while (APR_STATUS_IS_EINTR(rv)); 38251875Speter 39251875Speter if (APR_STATUS_IS_TIMEUP(rv)) { 40251875Speter /* Read buffer empty -> subsequent reads would block, so, 41251875Speter * definitely not at EOF. */ 42251875Speter *atreadeof = 0; 43251875Speter return APR_SUCCESS; 44251875Speter } 45251875Speter else if (rv) { 46251875Speter /* Some other error -> unexpected error. */ 47251875Speter return rv; 48251875Speter } 49266735Speter /* Many platforms return only APR_POLLIN; OS X returns APR_POLLHUP|APR_POLLIN */ 50266735Speter else if (nfds == 1 && (pfds[0].rtnevents & APR_POLLIN) == APR_POLLIN) { 51251875Speter apr_sockaddr_t unused; 52251875Speter apr_size_t len = 1; 53251875Speter char buf; 54251875Speter 55251875Speter /* The socket is readable - peek to see whether it returns EOF 56251875Speter * without consuming bytes from the socket buffer. */ 57251875Speter rv = apr_socket_recvfrom(&unused, sock, MSG_PEEK, &buf, &len); 58251875Speter if (rv == APR_EOF) { 59251875Speter *atreadeof = 1; 60251875Speter return APR_SUCCESS; 61251875Speter } 62251875Speter else if (rv) { 63251875Speter /* Read error -> unexpected error. */ 64251875Speter return rv; 65251875Speter } 66251875Speter else { 67251875Speter *atreadeof = 0; 68251875Speter return APR_SUCCESS; 69251875Speter } 70251875Speter } 71251875Speter 72251875Speter /* Should not fall through here. */ 73251875Speter return APR_EGENERAL; 74251875Speter} 75251875Speter 76