Line data Source code
1 : /*
2 : Authors:
3 : Jan Cholasta <jcholast@redhat.com>
4 :
5 : Copyright (C) 2012 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "util/atomic_io.h"
22 :
23 : /* based on code from libssh <http://www.libssh.org> */
24 960 : ssize_t sss_atomic_io_s(int fd, void *buf, size_t n, bool do_read)
25 : {
26 960 : char *b = buf;
27 960 : size_t pos = 0;
28 : ssize_t res;
29 : struct pollfd pfd;
30 :
31 960 : pfd.fd = fd;
32 960 : pfd.events = do_read ? POLLIN : POLLOUT;
33 :
34 2871 : while (n > pos) {
35 1858 : if (do_read) {
36 1845 : res = read(fd, b + pos, n - pos);
37 : } else {
38 13 : res = write(fd, b + pos, n - pos);
39 : }
40 1858 : switch (res) {
41 : case -1:
42 8 : if (errno == EINTR) {
43 0 : continue;
44 : }
45 8 : if (errno == EAGAIN || errno == EWOULDBLOCK) {
46 8 : (void) poll(&pfd, 1, -1);
47 8 : continue;
48 : }
49 0 : return -1;
50 : case 0:
51 : /* read returns 0 on end-of-file */
52 907 : errno = do_read ? 0 : EPIPE;
53 907 : return pos;
54 : default:
55 943 : pos += (size_t) res;
56 : }
57 : }
58 :
59 53 : return pos;
60 : }
|