9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek/*
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek Authors:
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek Jan Cholasta <jcholast@redhat.com>
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek Copyright (C) 2012 Red Hat
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek This program is free software; you can redistribute it and/or modify
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek it under the terms of the GNU General Public License as published by
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek the Free Software Foundation; either version 3 of the License, or
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek (at your option) any later version.
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek This program is distributed in the hope that it will be useful,
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek GNU General Public License for more details.
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek You should have received a copy of the GNU General Public License
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek*/
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek#include "util/atomic_io.h"
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek/* based on code from libssh <http://www.libssh.org> */
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozekssize_t sss_atomic_io_s(int fd, void *buf, size_t n, bool do_read)
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek{
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek char *b = buf;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek size_t pos = 0;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek ssize_t res;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek struct pollfd pfd;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek pfd.fd = fd;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek pfd.events = do_read ? POLLIN : POLLOUT;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek while (n > pos) {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek if (do_read) {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek res = read(fd, b + pos, n - pos);
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek } else {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek res = write(fd, b + pos, n - pos);
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek }
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek switch (res) {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek case -1:
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek if (errno == EINTR) {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek continue;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek }
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek if (errno == EAGAIN || errno == EWOULDBLOCK) {
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek (void) poll(&pfd, 1, -1);
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek continue;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek }
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek return -1;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek case 0:
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek /* read returns 0 on end-of-file */
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek errno = do_read ? 0 : EPIPE;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek return pos;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek default:
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek pos += (size_t) res;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek }
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek }
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek return pos;
9959c512ac3ba36f7a0db7614f0357ce0bae748fJakub Hrozek}