diff options
author | Volker Lendecke <vl@samba.org> | 2016-11-26 15:42:42 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2016-12-11 15:01:12 +0100 |
commit | 8be0a0dc76f0f1f63e29beb1ed20f46e1c8f058c (patch) | |
tree | 05a3bcdd354265f0090bd9cddc5e5c089cbbd25d /lib/util/xfile.c | |
parent | 8a0174dca503a6c290c7d565a6bf2c10363964a4 (diff) | |
download | samba-8be0a0dc76f0f1f63e29beb1ed20f46e1c8f058c.tar.gz |
lib: Remove xfile
The days of operating systems with a 255 file
descriptor limit on FILE (I'm looking at you
Solaris - Solaris 10 finally fixed this) are
long gone.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Sun Dec 11 15:01:12 CET 2016 on sn-devel-144
Diffstat (limited to 'lib/util/xfile.c')
-rw-r--r-- | lib/util/xfile.c | 524 |
1 files changed, 0 insertions, 524 deletions
diff --git a/lib/util/xfile.c b/lib/util/xfile.c deleted file mode 100644 index b22cb9871f2..00000000000 --- a/lib/util/xfile.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - Unix SMB/CIFS implementation. - stdio replacement - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -/** - * @file - * @brief scalable FILE replacement - */ - -/* - stdio is very convenient, but on some systems the file descriptor - in FILE* is 8 bits, so it fails when more than 255 files are open. - - XFILE replaces stdio. It is less efficient, but at least it works - when you have lots of files open - - The main restriction on XFILE is that it doesn't support seeking, - and doesn't support O_RDWR. That keeps the code simple. -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "memory.h" -#include "xfile.h" -#include "lib/util/debug.h" -#include "lib/util/samba_util.h" - -#define XBUFSIZE BUFSIZ - -static XFILE _x_stdin = { 0, NULL, NULL, XBUFSIZE, 0, O_RDONLY, X_IOFBF, 0 }; -static XFILE _x_stdout = { 1, NULL, NULL, XBUFSIZE, 0, O_WRONLY, X_IOLBF, 0 }; -static XFILE _x_stderr = { 2, NULL, NULL, 0, 0, O_WRONLY, X_IONBF, 0 }; - -XFILE *x_stdin = &_x_stdin; -XFILE *x_stdout = &_x_stdout; -XFILE *x_stderr = &_x_stderr; - -#define X_FLAG_EOF 1 -#define X_FLAG_ERROR 2 -#define X_FLAG_EINVAL 3 - -/** simulate setvbuf() */ -int x_setvbuf(XFILE *f, char *buf, int mode, size_t size) -{ - x_fflush(f); - if (f->bufused) return -1; - - /* on files being read full buffering is the only option */ - if ((f->open_flags & O_ACCMODE) == O_RDONLY) { - mode = X_IOFBF; - } - - /* destroy any earlier buffer */ - SAFE_FREE(f->buf); - f->buf = 0; - f->bufsize = 0; - f->next = NULL; - f->bufused = 0; - f->buftype = mode; - - if (f->buftype == X_IONBF) return 0; - - /* if buffering then we need some size */ - if (size == 0) size = XBUFSIZE; - - f->bufsize = size; - f->bufused = 0; - - return 0; -} - -/* allocate the buffer */ -static int x_allocate_buffer(XFILE *f) -{ - if (f->buf) return 1; - if (f->bufsize == 0) return 0; - f->buf = (char *)malloc(f->bufsize); - if (!f->buf) return 0; - f->next = f->buf; - return 1; -} - - -/** this looks more like open() than fopen(), but that is quite deliberate. - I want programmers to *think* about O_EXCL, O_CREAT etc not just - get them magically added -*/ -XFILE *x_fopen(const char *fname, int flags, mode_t mode) -{ - XFILE *ret; - - ret = (XFILE *)malloc_p(XFILE); - if (!ret) return NULL; - - memset(ret, 0, sizeof(XFILE)); - - if ((flags & O_ACCMODE) == O_RDWR) { - /* we don't support RDWR in XFILE - use file - descriptors instead */ - SAFE_FREE(ret); - errno = EINVAL; - return NULL; - } - - ret->open_flags = flags; - - ret->fd = open(fname, flags, mode); - if (ret->fd == -1) { - SAFE_FREE(ret); - return NULL; - } - - x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); - - return ret; -} - -/** simulate fclose() */ -int x_fclose(XFILE *f) -{ - int ret; - - /* make sure we flush any buffered data */ - x_fflush(f); - - ret = close(f->fd); - f->fd = -1; - if (f->buf) { - /* make sure data can't leak into a later malloc */ - memset(f->buf, 0, f->bufsize); - SAFE_FREE(f->buf); - } - /* check the file descriptor given to the function is NOT one of the static - * descriptor of this libreary or we will free unallocated memory - * --sss */ - if (f != x_stdin && f != x_stdout && f != x_stderr) { - SAFE_FREE(f); - } - return ret; -} - -/** simulate fwrite() */ -size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) -{ - ssize_t ret; - size_t total=0; - - /* we might be writing unbuffered */ - if (f->buftype == X_IONBF || - (!f->buf && !x_allocate_buffer(f))) { - ret = write(f->fd, p, size*nmemb); - if (ret == -1) return -1; - return ret/size; - } - - - while (total < size*nmemb) { - size_t n = f->bufsize - f->bufused; - n = MIN(n, (size*nmemb)-total); - - if (n == 0) { - /* it's full, flush it */ - x_fflush(f); - continue; - } - - memcpy(f->buf + f->bufused, total+(const char *)p, n); - f->bufused += n; - total += n; - } - - /* when line buffered we need to flush at the last linefeed. This can - flush a bit more than necessary, but that is harmless */ - if (f->buftype == X_IOLBF && f->bufused) { - int i; - for (i=(size*nmemb)-1; i>=0; i--) { - if (*(i+(const char *)p) == '\n') { - x_fflush(f); - break; - } - } - } - - return total/size; -} - -/** thank goodness for asprintf() */ - int x_vfprintf(XFILE *f, const char *format, va_list ap) -{ - char *p; - int len, ret; - va_list ap2; - - va_copy(ap2, ap); - len = vasprintf(&p, format, ap2); - va_end(ap2); - if (len <= 0) return len; - ret = x_fwrite(p, 1, len, f); - SAFE_FREE(p); - return ret; -} - - int x_fprintf(XFILE *f, const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = x_vfprintf(f, format, ap); - va_end(ap); - return ret; -} - -/* at least fileno() is simple! */ -int x_fileno(const XFILE *f) -{ - return f->fd; -} - -/** simulate fflush() */ -int x_fflush(XFILE *f) -{ - int ret; - - if (f->flags & X_FLAG_ERROR) return -1; - - if ((f->open_flags & O_ACCMODE) != O_WRONLY) { - errno = EINVAL; - return -1; - } - - if (f->bufused == 0) return 0; - - ret = write(f->fd, f->buf, f->bufused); - if (ret == -1) return -1; - - f->bufused -= ret; - if (f->bufused > 0) { - f->flags |= X_FLAG_ERROR; - memmove(f->buf, ret + (char *)f->buf, f->bufused); - return -1; - } - - return 0; -} - -/** simulate setbuffer() */ -void x_setbuffer(XFILE *f, char *buf, size_t size) -{ - x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, size); -} - -/** simulate setbuf() */ -void x_setbuf(XFILE *f, char *buf) -{ - x_setvbuf(f, buf, buf?X_IOFBF:X_IONBF, XBUFSIZE); -} - -/** simulate setlinebuf() */ -void x_setlinebuf(XFILE *f) -{ - x_setvbuf(f, NULL, X_IOLBF, 0); -} - - -/** simulate feof() */ -int x_feof(XFILE *f) -{ - if (f->flags & X_FLAG_EOF) return 1; - return 0; -} - -/** simulate ferror() */ -int x_ferror(XFILE *f) -{ - if (f->flags & X_FLAG_ERROR) return 1; - return 0; -} - -/* fill the read buffer */ -static void x_fillbuf(XFILE *f) -{ - int n; - - if (f->bufused) return; - - if (!f->buf && !x_allocate_buffer(f)) return; - - n = read(f->fd, f->buf, f->bufsize); - if (n <= 0) return; - f->bufused = n; - f->next = f->buf; -} - -/** simulate fgetc() */ -int x_fgetc(XFILE *f) -{ - int ret; - - if (f->flags & (X_FLAG_EOF | X_FLAG_ERROR)) return EOF; - - if (f->bufused == 0) x_fillbuf(f); - - if (f->bufused == 0) { - f->flags |= X_FLAG_EOF; - return EOF; - } - - ret = *(uint8_t *)(f->next); - f->next++; - f->bufused--; - return ret; -} - -/** simulate fread */ -size_t x_fread(void *p, size_t size, size_t nmemb, XFILE *f) -{ - size_t remaining = size * nmemb; - size_t total = 0; - - while (remaining > 0) { - size_t thistime; - - x_fillbuf(f); - - if (f->bufused == 0) { - f->flags |= X_FLAG_EOF; - break; - } - - thistime = MIN(f->bufused, remaining); - - memcpy((char *)p+total, f->next, thistime); - - f->next += thistime; - f->bufused -= thistime; - remaining -= thistime; - total += thistime; - } - return total/size; -} - -/** simulate fgets() */ -char *x_fgets(char *s, int size, XFILE *stream) -{ - char *s0 = s; - int l = size; - while (l>1) { - int c = x_fgetc(stream); - if (c == EOF) break; - *s++ = (char)c; - l--; - if (c == '\n') break; - } - if (l==size || x_ferror(stream)) { - return 0; - } - *s = 0; - return s0; -} - -/** - * trivial seek, works only for SEEK_SET and SEEK_END if SEEK_CUR is - * set then an error is returned */ -off_t x_tseek(XFILE *f, off_t offset, int whence) -{ - if (f->flags & X_FLAG_ERROR) - return -1; - - /* only SEEK_SET and SEEK_END are supported */ - /* SEEK_CUR needs internal offset counter */ - if (whence != SEEK_SET && whence != SEEK_END) { - f->flags |= X_FLAG_EINVAL; - errno = EINVAL; - return -1; - } - - /* empty the buffer */ - switch (f->open_flags & O_ACCMODE) { - case O_RDONLY: - f->bufused = 0; - break; - case O_WRONLY: - if (x_fflush(f) != 0) - return -1; - break; - default: - errno = EINVAL; - return -1; - } - - f->flags &= ~X_FLAG_EOF; - return lseek(f->fd, offset, whence); -} - -XFILE *x_fdup(const XFILE *f) -{ - XFILE *ret; - int fd; - - fd = dup(x_fileno(f)); - if (fd < 0) { - return NULL; - } - - ret = (XFILE *)malloc_p(XFILE); - if (!ret) { - close(fd); - return NULL; - } - memset(ret, 0, sizeof(XFILE)); - - ret->fd = fd; - ret->open_flags = f->open_flags; - x_setvbuf(ret, NULL, X_IOFBF, XBUFSIZE); - return ret; -} - -/** - * @file - * @brief File-related utility functions - */ - -/** -read a line from a file with possible \ continuation chars. -Blanks at the start or end of a line are stripped. -The string will be allocated if s2 is NULL -**/ -char *x_fgets_slash(char *s2,int maxlen,XFILE *f) -{ - char *s=s2; - int len = 0; - int c; - bool start_of_line = true; - - if (x_feof(f)) { - return(NULL); - } - - if (maxlen <2) { - return(NULL); - } - - if (!s2) { - maxlen = MIN(maxlen,8); - s = (char *)malloc(maxlen); - } - - if (!s) { - return(NULL); - } - - *s = 0; - - while (len < maxlen-1) { - c = x_getc(f); - switch (c) - { - case '\r': - break; - case '\n': - while (len > 0 && s[len-1] == ' ') { - s[--len] = 0; - } - if (len > 0 && s[len-1] == '\\') { - s[--len] = 0; - start_of_line = true; - break; - } - return(s); - case EOF: - if (len <= 0 && !s2) { - SAFE_FREE(s); - } - return(len>0?s:NULL); - case ' ': - if (start_of_line) { - break; - } - /* fall through */ - default: - start_of_line = false; - s[len++] = c; - s[len] = 0; - } - if (!s2 && len > maxlen-3) { - int m; - char *t; - - m = maxlen * 2; - if (m < maxlen) { - DBG_ERR("length overflow"); - SAFE_FREE(s); - return NULL; - } - maxlen = m; - - t = realloc_p(s, char, maxlen); - if (!t) { - DBG_ERR("failed to expand buffer!\n"); - SAFE_FREE(s); - return(NULL); - } - - s = t; - } - } - return(s); -} |