summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2014-03-27 21:21:12 -0700
committerAnand Avati <avati@redhat.com>2014-04-21 09:30:46 -0700
commit2da51737c49f7917a974bdf9e6e566307583ad16 (patch)
treedde4377deeea90b477a118174833c2cf343eff1a
parent11473a6a10aaa5e62050e7e52115e2f8f10de124 (diff)
strfd: memory backed file descriptor
A file descriptor like interface, backed by a string, on which fprintf() like IO can be performed. Internally the backing string is grown on demand. Useful in generating virtual file content on the fly (used in meta) Change-Id: I60d8751c4c750f3f06aa454a4ccd9909b3ac8ac7 BUG: 1089216 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/7508 Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r--libglusterfs/src/Makefile.am4
-rw-r--r--libglusterfs/src/mem-types.h4
-rw-r--r--libglusterfs/src/strfd.c91
-rw-r--r--libglusterfs/src/strfd.h28
4 files changed, 124 insertions, 3 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index b1a8536..8934b35 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -26,7 +26,7 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \
event-history.c gidcache.c ctx.c client_t.c event-poll.c event-epoll.c \
$(CONTRIBDIR)/libgen/basename_r.c $(CONTRIBDIR)/libgen/dirname_r.c \
- $(CONTRIBDIR)/stdlib/gf_mkostemp.c
+ $(CONTRIBDIR)/stdlib/gf_mkostemp.c strfd.c
nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c gf-error-codes.h
@@ -43,7 +43,7 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h timespec.
$(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h \
run.h options.h lkowner.h fd-lk.h circ-buff.h event-history.h \
gidcache.h client_t.h glusterfs-acl.h glfs-message-id.h \
- template-component-messages.h
+ template-component-messages.h strfd.h
EXTRA_DIST = graph.l graph.y
diff --git a/libglusterfs/src/mem-types.h b/libglusterfs/src/mem-types.h
index c01dfa7..c07d138 100644
--- a/libglusterfs/src/mem-types.h
+++ b/libglusterfs/src/mem-types.h
@@ -122,6 +122,8 @@ enum gf_common_mem_types_ {
gf_common_mt_uuid_t = 106,
gf_common_mt_mgmt_v3_lock_obj_t = 107,
gf_common_mt_txn_opinfo_obj_t = 108,
- gf_common_mt_end = 109
+ gf_common_mt_strfd_t = 109,
+ gf_common_mt_strfd_data_t = 110,
+ gf_common_mt_end
};
#endif
diff --git a/libglusterfs/src/strfd.c b/libglusterfs/src/strfd.c
new file mode 100644
index 0000000..8c97670
--- /dev/null
+++ b/libglusterfs/src/strfd.c
@@ -0,0 +1,91 @@
+/*
+ Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdarg.h>
+
+#include "mem-types.h"
+#include "mem-pool.h"
+#include "strfd.h"
+#include "common-utils.h"
+
+
+strfd_t *
+strfd_open ()
+{
+ strfd_t *strfd = NULL;
+
+ strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t);
+
+ return strfd;
+}
+
+
+int
+strprintf (strfd_t *strfd, const char *fmt, ...)
+{
+ va_list ap;
+ char *str = NULL;
+ int size = 0;
+
+ va_start (ap, fmt);
+
+ size = vasprintf (&str, fmt, ap);
+
+ if (size < 0)
+ return size;
+
+ if (!strfd->alloc_size) {
+ strfd->data = GF_CALLOC (max(size + 1, 4096), 1,
+ gf_common_mt_strfd_data_t);
+ if (!strfd->data) {
+ free (str); /* NOT GF_FREE */
+ return -1;
+ }
+ strfd->alloc_size = max(size + 1, 4096);
+ }
+
+ if (strfd->alloc_size <= (strfd->size + size)) {
+ char *tmp_ptr = NULL;
+ int new_size = max ((strfd->alloc_size * 2),
+ gf_roundup_next_power_of_two (strfd->size + size + 1));
+ tmp_ptr = GF_REALLOC (strfd->data, new_size);
+ if (!tmp_ptr) {
+ free (str); /* NOT GF_FREE */
+ return -1;
+ }
+ strfd->alloc_size = new_size;
+ strfd->data = tmp_ptr;
+ }
+
+ // Copy the trailing '\0', but do not account for it in ->size.
+ // This allows safe use of strfd->data as a string.
+ memcpy (strfd->data + strfd->size, str, size + 1);
+ strfd->size += size;
+
+ free (str); /* NOT GF_FREE */
+
+ return size;
+}
+
+
+int
+strfd_close (strfd_t *strfd)
+{
+ GF_FREE (strfd->data);
+ GF_FREE (strfd);
+
+ return 0;
+}
+
diff --git a/libglusterfs/src/strfd.h b/libglusterfs/src/strfd.h
new file mode 100644
index 0000000..e386c84
--- /dev/null
+++ b/libglusterfs/src/strfd.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _STRFD_H
+#define _STRFD_H
+
+typedef struct {
+ void *data;
+ size_t alloc_size;
+ size_t size;
+ off_t pos;
+} strfd_t;
+
+strfd_t *strfd_open();
+
+int strprintf(strfd_t *strfd, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+
+int strfd_close(strfd_t *strfd);
+
+#endif