PageRenderTime 30ms CodeModel.GetById 12ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/common/fd.c

https://code.google.com/
C | 273 lines | 194 code | 49 blank | 30 comment | 41 complexity | 7193be502f226542bc5f9baf93e35493 MD5 | raw file
  1/*****************************************************************************
  2 *  $Id$
  3 *****************************************************************************
  4 *  This file is part of the Munge Uid 'N' Gid Emporium (MUNGE).
  5 *  For details, see <http://www.llnl.gov/linux/munge/>.
  6 *  UCRL-CODE-2003-???.
  7 *
  8 *  Copyright (C) 2001-2003 The Regents of the University of California.
  9 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 10 *  Written by Chris Dunlap <cdunlap@llnl.gov>.
 11 *
 12 *  This is free software; you can redistribute it and/or modify it
 13 *  under the terms of the GNU General Public License as published by
 14 *  the Free Software Foundation; either version 2 of the License, or
 15 *  (at your option) any later version.
 16 *
 17 *  This is distributed in the hope that it will be useful, but WITHOUT
 18 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 19 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 20 *  for more details.
 21 *
 22 *  You should have received a copy of the GNU General Public License;
 23 *  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 24 *  Suite 330, Boston, MA  02111-1307  USA.
 25 *****************************************************************************
 26 *  Refer to "fd.h" for documentation on public functions.
 27 *****************************************************************************/
 28
 29
 30#if HAVE_CONFIG_H
 31#  include "config.h"
 32#endif /* HAVE_CONFIG_H */
 33
 34#include <assert.h>
 35#include <errno.h>
 36#include <fcntl.h>
 37#include <stdlib.h>
 38#include <string.h>
 39#include <unistd.h>
 40#include "fd.h"
 41
 42
 43static int _fd_get_lock (int fd, int cmd, int type);
 44static pid_t _fd_test_lock (int fd, int type);
 45
 46
 47int
 48fd_set_close_on_exec (int fd)
 49{
 50    assert (fd >= 0);
 51
 52    if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
 53        return (-1);
 54    return (0);
 55}
 56
 57
 58int
 59fd_set_nonblocking (int fd)
 60{
 61    int fval;
 62
 63    assert (fd >= 0);
 64
 65    if ((fval = fcntl (fd, F_GETFL, 0)) < 0)
 66        return (-1);
 67    if (fcntl (fd, F_SETFL, fval | O_NONBLOCK) < 0)
 68        return (-1);
 69    return (0);
 70}
 71
 72
 73int
 74fd_get_read_lock (int fd)
 75{
 76    return (_fd_get_lock (fd, F_SETLK, F_RDLCK));
 77}
 78
 79
 80int
 81fd_get_readw_lock (int fd)
 82{
 83    return (_fd_get_lock (fd, F_SETLKW, F_RDLCK));
 84}
 85
 86
 87int
 88fd_get_write_lock (int fd)
 89{
 90    return (_fd_get_lock (fd, F_SETLK, F_WRLCK));
 91}
 92
 93
 94int
 95fd_get_writew_lock (int fd)
 96{
 97    return (_fd_get_lock (fd, F_SETLKW, F_WRLCK));
 98}
 99
100
101int
102fd_release_lock (int fd)
103{
104    return (_fd_get_lock (fd, F_SETLK, F_UNLCK));
105}
106
107
108pid_t
109fd_is_read_lock_blocked (int fd)
110{
111    return (_fd_test_lock (fd, F_RDLCK));
112}
113
114
115pid_t
116fd_is_write_lock_blocked (int fd)
117{
118    return (_fd_test_lock (fd, F_WRLCK));
119}
120
121
122static int
123_fd_get_lock (int fd, int cmd, int type)
124{
125    struct flock lock;
126
127    assert (fd >= 0);
128
129    lock.l_type = type;
130    lock.l_start = 0;
131    lock.l_whence = SEEK_SET;
132    lock.l_len = 0;
133
134    return (fcntl (fd, cmd, &lock));
135}
136
137
138static pid_t
139_fd_test_lock (int fd, int type)
140{
141    struct flock lock;
142
143    assert (fd >= 0);
144
145    lock.l_type = type;
146    lock.l_start = 0;
147    lock.l_whence = SEEK_SET;
148    lock.l_len = 0;
149
150    if (fcntl (fd, F_GETLK, &lock) < 0)
151        return (-1);
152    if (lock.l_type == F_UNLCK)
153        return (0);
154    return (lock.l_pid);
155}
156
157
158ssize_t
159fd_read_n (int fd, void *buf, size_t n)
160{
161    size_t nleft;
162    ssize_t nread;
163    unsigned char *p;
164
165    p = buf;
166    nleft = n;
167    while (nleft > 0) {
168        if ((nread = read (fd, p, nleft)) < 0) {
169            if (errno == EINTR)
170                continue;
171            else
172                return (-1);
173        }
174        else if (nread == 0) {          /* EOF */
175            break;
176        }
177        nleft -= nread;
178        p += nread;
179    }
180    return (n - nleft);
181}
182
183
184ssize_t
185fd_write_n (int fd, void *buf, size_t n)
186{
187    size_t nleft;
188    ssize_t nwritten;
189    unsigned char *p;
190
191    p = buf;
192    nleft = n;
193    while (nleft > 0) {
194        if ((nwritten = write (fd, p, nleft)) < 0) {
195            if (errno == EINTR)
196                continue;
197            else
198                return (-1);
199        }
200        nleft -= nwritten;
201        p += nwritten;
202    }
203    return (n);
204}
205
206
207ssize_t
208fd_read_line (int fd, void *buf, size_t maxlen)
209{
210    ssize_t n, rc;
211    unsigned char c, *p;
212
213    n = 0;
214    p = buf;
215    while (n < (ssize_t) maxlen - 1) {            /* reserve space for NUL-termination */
216
217        if ((rc = read (fd, &c, 1)) == 1) {
218            n++;
219            *p++ = c;
220            if (c == '\n')
221                break;                  /* store newline, like fgets() */
222        }
223        else if (rc == 0) {
224            if (n == 0)                 /* EOF, no data read */
225                return (0);
226            else                        /* EOF, some data read */
227                break;
228        }
229        else {
230            if (errno == EINTR)
231                continue;
232            return (-1);
233        }
234    }
235
236    *p = '\0';                          /* NUL-terminate, like fgets() */
237    return (n);
238}
239
240/*
241 * Following added by Mike Haskell <mhaskell@llnl.gov>
242 */
243ssize_t
244fd_null_read_n (int fd, void *buf, size_t n)
245{
246    unsigned char *mp;
247    size_t nleft;
248    ssize_t nread;
249    unsigned char *p;
250    unsigned char *q;
251                                                                                                  
252    q = p = (unsigned char *)buf;
253    nleft = n;
254    while (nleft > 0) {
255        if ((nread = read (fd, p, nleft)) < 0) {
256            if (errno == EINTR)
257                continue;
258            else
259                return (-1);
260        }
261        else if (nread == 0) {          /* EOF */
262            break;
263        }
264        nleft -= nread;
265        p += nread;
266        mp = (unsigned char *) memchr(q, '\0', (n - nleft));
267        if (mp <=  &q[ (n - nleft - 1)]) {
268                if (mp != NULL)
269                        break;
270        }
271    }
272    return (n - nleft);
273}