~ubuntu-branches/ubuntu/vivid/munge/vivid

« back to all changes in this revision

Viewing changes to src/libcommon/fd.c

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2011-02-28 20:41:12 UTC
  • mfrom: (6.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20110228204112-2lc8ss9geeusv5uo
Tags: 0.5.10-1
* New upstream release 
* Updated copyright, homepage, watch thanks to Chris Dunlap
* Standards version upgraded to 3.9.1.0 (no changes) 
* Switch to dpkg-source 3.0 (quilt) format
* Added explicit dependency by the same version of libmunge for munge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
 
 *  $Id: fd.c 771 2010-03-02 23:14:07Z dun $
 
2
 *  $Id: fd.c 923 2011-02-25 09:47:54Z chris.m.dunlap $
3
3
 *****************************************************************************
4
4
 *  Written by Chris Dunlap <cdunlap@llnl.gov>.
5
 
 *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
 
5
 *  Copyright (C) 2007-2011 Lawrence Livermore National Security, LLC.
6
6
 *  Copyright (C) 2002-2007 The Regents of the University of California.
7
7
 *  UCRL-CODE-155910.
8
8
 *
9
9
 *  This file is part of the MUNGE Uid 'N' Gid Emporium (MUNGE).
10
 
 *  For details, see <http://home.gna.org/munge/>.
 
10
 *  For details, see <http://munge.googlecode.com/>.
11
11
 *
12
12
 *  MUNGE is free software: you can redistribute it and/or modify it under
13
13
 *  the terms of the GNU General Public License as published by the Free
37
37
#include <assert.h>
38
38
#include <errno.h>
39
39
#include <fcntl.h>
 
40
#include <poll.h>
40
41
#include <stdlib.h>
41
42
#include <string.h>
 
43
#include <sys/time.h>
 
44
#include <sys/uio.h>
42
45
#include <unistd.h>
43
46
#include "fd.h"
44
47
 
45
48
 
46
49
/*****************************************************************************
47
 
 *  Static Prototypes
 
50
 *  Private Prototypes
48
51
 *****************************************************************************/
49
52
 
 
53
static int _fd_get_poll_timeout (const struct timeval *when);
 
54
 
50
55
static int _fd_get_lock (int fd, int cmd, int type);
 
56
 
51
57
static pid_t _fd_test_lock (int fd, int type);
52
58
 
53
59
 
54
60
/*****************************************************************************
55
 
 *  Extern I/O Functions
 
61
 *  Public Functions for I/O
56
62
 *****************************************************************************/
57
63
 
58
64
ssize_t
59
65
fd_read_n (int fd, void *buf, size_t n)
60
66
{
61
 
    size_t nleft;
62
 
    ssize_t nread;
63
67
    unsigned char *p;
 
68
    size_t         nleft;
 
69
    ssize_t        nread;
64
70
 
65
71
    p = buf;
66
72
    nleft = n;
82
88
 
83
89
 
84
90
ssize_t
85
 
fd_write_n (int fd, void *buf, size_t n)
 
91
fd_write_n (int fd, const void *buf, size_t n)
86
92
{
87
 
    size_t nleft;
88
 
    ssize_t nwritten;
89
 
    unsigned char *p;
 
93
    const unsigned char *p;
 
94
    size_t               nleft;
 
95
    ssize_t              nwritten;
90
96
 
91
97
    p = buf;
92
98
    nleft = n;
105
111
 
106
112
 
107
113
ssize_t
 
114
fd_timed_read_n (int fd, void *buf, size_t n,
 
115
                 const struct timeval *when, int do_skip_first_poll)
 
116
{
 
117
    unsigned char *p;
 
118
    int            msecs;
 
119
    struct pollfd  pfd;
 
120
    int            nfd;
 
121
    size_t         nleft;
 
122
    ssize_t        nread;
 
123
 
 
124
    if ((fd < 0) || (buf == NULL)) {
 
125
        errno = EINVAL;
 
126
        return (-1);
 
127
    }
 
128
    p = buf;
 
129
    nleft = n;
 
130
    pfd.fd = fd;
 
131
    pfd.events = POLLIN;
 
132
 
 
133
    if (do_skip_first_poll && (nleft > 0)) {
 
134
        msecs = -1;
 
135
        goto read_me;
 
136
    }
 
137
    while (nleft > 0) {
 
138
 
 
139
        msecs = _fd_get_poll_timeout (when);
 
140
        nfd = poll (&pfd, 1, msecs);
 
141
 
 
142
        if (nfd < 0) {
 
143
            if ((errno == EINTR) || (errno == EAGAIN))
 
144
                continue;
 
145
            else
 
146
                return (-1);
 
147
        }
 
148
        else if (nfd == 0) {            /* timeout */
 
149
            errno = ETIMEDOUT;
 
150
            break;
 
151
        }
 
152
        else if (pfd.revents & POLLNVAL) {
 
153
            errno = EBADF;
 
154
            return (-1);
 
155
        }
 
156
        else if (pfd.revents & POLLERR) {
 
157
            errno = EIO;
 
158
            return (-1);
 
159
        }
 
160
        assert (pfd.revents & POLLIN);
 
161
 
 
162
read_me:
 
163
        nread = read (fd, p, nleft);
 
164
        if (nread < 0) {
 
165
            if ((errno == EINTR) || (errno == EAGAIN))
 
166
                continue;
 
167
            else
 
168
                return (-1);
 
169
        }
 
170
        else if (nread == 0) {          /* EOF */
 
171
            break;
 
172
        }
 
173
        nleft -= nread;
 
174
        p += nread;
 
175
 
 
176
        if (msecs == 0) {
 
177
            break;
 
178
        }
 
179
    }
 
180
    return (n - nleft);
 
181
}
 
182
 
 
183
 
 
184
ssize_t
 
185
fd_timed_write_n (int fd, const void *buf, size_t n,
 
186
                  const struct timeval *when, int do_skip_first_poll)
 
187
{
 
188
    const unsigned char *p;
 
189
    int                  msecs;
 
190
    struct pollfd        pfd;
 
191
    int                  nfd;
 
192
    size_t               nleft;
 
193
    ssize_t              nwritten;
 
194
 
 
195
    if ((fd < 0) || (buf == NULL)) {
 
196
        errno = EINVAL;
 
197
        return (-1);
 
198
    }
 
199
    p = buf;
 
200
    nleft = n;
 
201
    pfd.fd = fd;
 
202
    pfd.events = POLLOUT;
 
203
 
 
204
    if (do_skip_first_poll && (nleft > 0)) {
 
205
        msecs = -1;
 
206
        goto write_me;
 
207
    }
 
208
    while (nleft > 0) {
 
209
 
 
210
        msecs = _fd_get_poll_timeout (when);
 
211
        nfd = poll (&pfd, 1, msecs);
 
212
 
 
213
        if (nfd < 0) {
 
214
            if ((errno == EINTR) || (errno == EAGAIN))
 
215
                continue;
 
216
            else
 
217
                return (-1);
 
218
        }
 
219
        else if (nfd == 0) {            /* timeout */
 
220
            errno = ETIMEDOUT;
 
221
            break;
 
222
        }
 
223
        else if (pfd.revents & POLLHUP) {
 
224
            break;
 
225
        }
 
226
        else if (pfd.revents & POLLNVAL) {
 
227
            errno = EBADF;
 
228
            return (-1);
 
229
        }
 
230
        else if (pfd.revents & POLLERR) {
 
231
            errno = EIO;
 
232
            return (-1);
 
233
        }
 
234
        assert (pfd.revents & POLLOUT);
 
235
 
 
236
write_me:
 
237
        nwritten = write (fd, p, nleft);
 
238
        if (nwritten < 0) {
 
239
            if ((errno == EINTR) || (errno == EAGAIN))
 
240
                continue;
 
241
            else
 
242
                return (-1);
 
243
        }
 
244
        nleft -= nwritten;
 
245
        p += nwritten;
 
246
 
 
247
        if (msecs == 0) {
 
248
            break;
 
249
        }
 
250
    }
 
251
    return (n - nleft);
 
252
}
 
253
 
 
254
 
 
255
ssize_t
 
256
fd_timed_write_iov (int fd, const struct iovec *iov_orig, int iov_cnt,
 
257
                    const struct timeval *when, int do_skip_first_poll)
 
258
{
 
259
    int            iov_mem_len;
 
260
    struct iovec  *iov;
 
261
    int            i;
 
262
    size_t         n, nleft, iov_len;
 
263
    struct pollfd  pfd;
 
264
    int            nfd;
 
265
    int            msecs;
 
266
    ssize_t        nwritten;
 
267
 
 
268
    if ((fd < 0) || (iov_orig == NULL) || (iov_cnt <= 0)) {
 
269
        errno = EINVAL;
 
270
        return (-1);
 
271
    }
 
272
    /*  Create copy of iovec for modification to handle retrying short writes.
 
273
     */
 
274
    iov_mem_len = sizeof (struct iovec) * iov_cnt;
 
275
    iov = malloc (iov_mem_len);
 
276
    if (iov == NULL) {
 
277
        errno = ENOMEM;
 
278
        return (-1);
 
279
    }
 
280
    memcpy (iov, iov_orig, iov_mem_len);
 
281
 
 
282
    for (i = 0, n = 0; i < iov_cnt; i++) {
 
283
        n += iov[i].iov_len;
 
284
    }
 
285
    nleft = iov_len = n;
 
286
    pfd.fd = fd;
 
287
    pfd.events = POLLOUT;
 
288
 
 
289
    if (do_skip_first_poll && (nleft > 0)) {
 
290
        msecs = -1;
 
291
        goto writev_me;
 
292
    }
 
293
    while (nleft > 0) {
 
294
 
 
295
        msecs = _fd_get_poll_timeout (when);
 
296
        nfd = poll (&pfd, 1, msecs);
 
297
 
 
298
        if (nfd < 0) {
 
299
            if ((errno == EINTR) || (errno == EAGAIN))
 
300
                continue;
 
301
            else
 
302
                goto err;
 
303
        }
 
304
        else if (nfd == 0) {            /* timeout */
 
305
            errno = ETIMEDOUT;
 
306
            break;
 
307
        }
 
308
        else if (pfd.revents & POLLHUP) {
 
309
            break;
 
310
        }
 
311
        else if (pfd.revents & POLLNVAL) {
 
312
            errno = EBADF;
 
313
            goto err;
 
314
        }
 
315
        else if (pfd.revents & POLLERR) {
 
316
            errno = EIO;
 
317
            goto err;
 
318
        }
 
319
        assert (pfd.revents & POLLOUT);
 
320
 
 
321
writev_me:
 
322
        nwritten = writev (fd, iov, iov_cnt);
 
323
        if (nwritten < 0) {
 
324
            if ((errno == EINTR) || (errno == EAGAIN))
 
325
                continue;
 
326
            else
 
327
                goto err;
 
328
        }
 
329
        nleft -= nwritten;
 
330
 
 
331
        if (msecs == 0) {
 
332
            break;
 
333
        }
 
334
        for (i = 0; (i < iov_cnt) && (nwritten > 0); i++) {
 
335
            n = (nwritten > iov[i].iov_len) ? iov[i].iov_len : nwritten;
 
336
            if (n == 0)
 
337
                continue;
 
338
            nwritten -= n;
 
339
            iov[i].iov_len -= n;
 
340
            iov[i].iov_base = (char *) iov[i].iov_base + n;
 
341
        }
 
342
    }
 
343
    free (iov);
 
344
    return (iov_len - nleft);
 
345
 
 
346
err:
 
347
    free (iov);
 
348
    return (-1);
 
349
}
 
350
 
 
351
 
 
352
ssize_t
108
353
fd_read_line (int fd, void *buf, size_t maxlen)
109
354
{
110
355
    ssize_t n, rc;
139
384
 
140
385
 
141
386
/*****************************************************************************
142
 
 *  Extern Locking Functions
 
387
 *  Public Functions for Attributes
 
388
 *****************************************************************************/
 
389
 
 
390
int
 
391
fd_set_close_on_exec (int fd)
 
392
{
 
393
    if (fd < 0) {
 
394
        errno = EINVAL;
 
395
        return (-1);
 
396
    }
 
397
    if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0) {
 
398
        return (-1);
 
399
    }
 
400
    return (0);
 
401
}
 
402
 
 
403
 
 
404
int
 
405
fd_set_nonblocking (int fd)
 
406
{
 
407
    int fval;
 
408
 
 
409
    if (fd < 0) {
 
410
        errno = EINVAL;
 
411
        return (-1);
 
412
    }
 
413
    if ((fval = fcntl (fd, F_GETFL, 0)) < 0) {
 
414
        return (-1);
 
415
    }
 
416
    if (fcntl (fd, F_SETFL, fval | O_NONBLOCK) < 0) {
 
417
        return (-1);
 
418
    }
 
419
    return (0);
 
420
}
 
421
 
 
422
 
 
423
int
 
424
fd_is_nonblocking (int fd)
 
425
{
 
426
    int fval;
 
427
 
 
428
    if (fd < 0) {
 
429
        errno = EINVAL;
 
430
        return (-1);
 
431
    }
 
432
    if ((fval = fcntl (fd, F_GETFL, 0)) < 0) {
 
433
        return (-1);
 
434
    }
 
435
    return ((fval & O_NONBLOCK) ? 1 : 0);
 
436
}
 
437
 
 
438
 
 
439
/*****************************************************************************
 
440
 *  Public Functions for Locking
143
441
 *****************************************************************************/
144
442
 
145
443
int
192
490
 
193
491
 
194
492
/*****************************************************************************
195
 
 *  Extern Attribute Functions
196
 
 *****************************************************************************/
197
 
 
198
 
int
199
 
fd_set_close_on_exec (int fd)
200
 
{
201
 
    assert (fd >= 0);
202
 
 
203
 
    if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
204
 
        return (-1);
205
 
    return (0);
206
 
}
207
 
 
208
 
 
209
 
int
210
 
fd_set_nonblocking (int fd)
211
 
{
212
 
    int fval;
213
 
 
214
 
    assert (fd >= 0);
215
 
 
216
 
    if ((fval = fcntl (fd, F_GETFL, 0)) < 0)
217
 
        return (-1);
218
 
    if (fcntl (fd, F_SETFL, fval | O_NONBLOCK) < 0)
219
 
        return (-1);
220
 
    return (0);
221
 
}
222
 
 
223
 
 
224
 
/*****************************************************************************
225
 
 *  Static Functions
226
 
 *****************************************************************************/
 
493
 *  Private Functions
 
494
 *****************************************************************************/
 
495
 
 
496
static int
 
497
_fd_get_poll_timeout (const struct timeval *when)
 
498
{
 
499
/*  Returns the poll() timeout value for the number of milliseconds between now
 
500
 *    and [when] (which specifies an absolute time in seconds and microseconds
 
501
 *    since the Epoch), 0 if [when] is in the past, or -1 if [when] is NULL
 
502
 *    (indicating poll() should wait indefinitely).
 
503
 */
 
504
    struct timeval now;
 
505
    int            msecs;
 
506
 
 
507
    if (when == NULL) {
 
508
        return (-1);
 
509
    }
 
510
    if ((when->tv_sec == 0) && (when->tv_usec == 0)) {
 
511
        return (0);
 
512
    }
 
513
    /*  POSIX says gettimeofday() can't fail, but just in case ...
 
514
     */
 
515
    if (gettimeofday (&now, NULL) < 0) {
 
516
        return (0);
 
517
    }
 
518
    /*  Round up to the next millisecond.
 
519
     *  XXX: msecs can overflow/underflow if [when] is too far from now.
 
520
     */
 
521
    msecs = ( (when->tv_sec  - now.tv_sec)        * 1000 ) +
 
522
            ( (when->tv_usec - now.tv_usec + 999) / 1000 ) ;
 
523
    /*
 
524
     *  Return 0 if [when] is in the past to indicate poll() should not block.
 
525
     */
 
526
    return ((msecs < 0) ? 0 : msecs);
 
527
}
 
528
 
227
529
 
228
530
static int
229
531
_fd_get_lock (int fd, int cmd, int type)
253
555
    lock.l_whence = SEEK_SET;
254
556
    lock.l_len = 0;
255
557
 
256
 
    if (fcntl (fd, F_GETLK, &lock) < 0)
 
558
    if (fcntl (fd, F_GETLK, &lock) < 0) {
257
559
        return (-1);
258
 
    if (lock.l_type == F_UNLCK)
 
560
    }
 
561
    if (lock.l_type == F_UNLCK) {
259
562
        return (0);
 
563
    }
260
564
    return (lock.l_pid);
261
565
}