[PATCH 01/22] libcsupport: Use POSIX key for getgrent()

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Nov 18 14:37:07 UTC 2014


---
 cpukit/libcsupport/Makefile.am         |  1 +
 cpukit/libcsupport/src/getgrent.c      | 88 +++++++++++++++++++++++-----------
 cpukit/libcsupport/src/getgrnam.c      | 53 ++++++++++++++++++++
 testsuites/psxtests/psxpasswd01/init.c |  2 +
 testsuites/psxtests/psxpasswd02/init.c |  2 +
 5 files changed, 117 insertions(+), 29 deletions(-)
 create mode 100644 cpukit/libcsupport/src/getgrnam.c

diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 74b029c..6803fe6 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -110,6 +110,7 @@ MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \
 
 PASSWORD_GROUP_C_FILES = src/pwdgrp.c
 PASSWORD_GROUP_C_FILES += src/getgrent.c
+PASSWORD_GROUP_C_FILES += src/getgrnam.c
 PASSWORD_GROUP_C_FILES += src/getpwent.c
 
 TERMINAL_IDENTIFICATION_C_FILES = src/ctermid.c
diff --git a/cpukit/libcsupport/src/getgrent.c b/cpukit/libcsupport/src/getgrent.c
index 9b11e2e..4f27efc 100644
--- a/cpukit/libcsupport/src/getgrent.c
+++ b/cpukit/libcsupport/src/getgrent.c
@@ -24,55 +24,85 @@
 
 #include "pwdgrp.h"
 
-/*
- * Static, thread-unsafe, buffers
- */
-static FILE *group_fp;
-static char grbuf[200];
-static struct group grent;
+#include <stdlib.h>
+#include <pthread.h>
 
-struct group *getgrnam(
-  const char *name
-)
-{
-  struct group *p;
+typedef struct {
+  FILE *fp;
+  char buf[256];
+  struct group grp;
+} grp_context;
 
-  if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))
-    return NULL;
-  return p;
+static pthread_once_t grp_once = PTHREAD_ONCE_INIT;
+
+static pthread_key_t grp_key;
+
+static void grp_init(void)
+{
+  pthread_key_create(&grp_key, free);
 }
 
-struct group *getgrgid(
-  gid_t gid
-)
+static grp_context *grp_get_context(void)
 {
-  struct group *p;
+  pthread_once(&grp_once, grp_init);
 
-  if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))
-    return NULL;
-  return p;
+  return pthread_getspecific(grp_key);
 }
 
 struct group *getgrent(void)
 {
-  if (group_fp == NULL)
+  grp_context *ctx = grp_get_context();
+
+  if (ctx == NULL)
+    return NULL;
+
+  if (ctx->fp == NULL)
     return NULL;
-  if (!_libcsupport_scangr(group_fp, &grent, grbuf, sizeof grbuf))
+
+  if (!_libcsupport_scangr(ctx->fp, &ctx->grp, ctx->buf, sizeof(ctx->buf)))
     return NULL;
-  return &grent;
+
+  return &ctx->grp;
 }
 
 void setgrent(void)
 {
+  grp_context *ctx = grp_get_context();
+
+  if (ctx == NULL) {
+    int eno;
+
+    ctx = calloc(1, sizeof(*ctx));
+    if (ctx == NULL)
+      return;
+
+    eno = pthread_setspecific(grp_key, ctx);
+    if (eno != 0) {
+      free(ctx);
+
+      return;
+    }
+  }
+
   _libcsupport_pwdgrp_init();
 
-  if (group_fp != NULL)
-    fclose(group_fp);
-  group_fp = fopen("/etc/group", "r");
+  if (ctx->fp != NULL)
+    fclose(ctx->fp);
+
+  ctx->fp = fopen("/etc/group", "r");
 }
 
 void endgrent(void)
 {
-  if (group_fp != NULL)
-    fclose(group_fp);
+  grp_context *ctx = grp_get_context();
+
+  if (ctx == NULL)
+    return;
+
+  if (ctx->fp != NULL) {
+    fclose(ctx->fp);
+  }
+
+  free(ctx);
+  pthread_setspecific(grp_key, NULL);
 }
diff --git a/cpukit/libcsupport/src/getgrnam.c b/cpukit/libcsupport/src/getgrnam.c
new file mode 100644
index 0000000..505a334
--- /dev/null
+++ b/cpukit/libcsupport/src/getgrnam.c
@@ -0,0 +1,53 @@
+/**
+ *  @file
+ *
+ *  @brief User Database Access Routines
+ *  @ingroup libcsupport
+ */
+
+/*
+ *  Copyright (c) 1999-2009 Ralf Corsepius <corsepiu at faw.uni-ulm.de>
+ *  Copyright (c) 1999-2013 Joel Sherrill <joel.sherrill at OARcorp.com>
+ *  Copyright (c) 2000-2001 Fernando Ruiz Casas <fernando.ruiz at ctv.es>
+ *  Copyright (c) 2002 Eric Norum <eric.norum at usask.ca>
+ *  Copyright (c) 2003 Till Straumann <strauman at slac.stanford.edu>
+ *  Copyright (c) 2012 Alex Ivanov <alexivanov97 at gmail.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pwdgrp.h"
+
+/*
+ * Static, thread-unsafe, buffers
+ */
+static char grbuf[200];
+static struct group grent;
+
+struct group *getgrnam(
+  const char *name
+)
+{
+  struct group *p;
+
+  if(getgrnam_r(name, &grent, grbuf, sizeof grbuf, &p))
+    return NULL;
+  return p;
+}
+
+struct group *getgrgid(
+  gid_t gid
+)
+{
+  struct group *p;
+
+  if(getgrgid_r(gid, &grent, grbuf, sizeof grbuf, &p))
+    return NULL;
+  return p;
+}
diff --git a/testsuites/psxtests/psxpasswd01/init.c b/testsuites/psxtests/psxpasswd01/init.c
index 0f0f208..4553ca3 100644
--- a/testsuites/psxtests/psxpasswd01/init.c
+++ b/testsuites/psxtests/psxpasswd01/init.c
@@ -184,6 +184,8 @@ rtems_task Init(
 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 6
 
 #define CONFIGURE_MAXIMUM_TASKS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/psxtests/psxpasswd02/init.c b/testsuites/psxtests/psxpasswd02/init.c
index 7248003..da4f2b4 100644
--- a/testsuites/psxtests/psxpasswd02/init.c
+++ b/testsuites/psxtests/psxpasswd02/init.c
@@ -226,6 +226,8 @@ rtems_task Init(
 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 6
 
 #define CONFIGURE_MAXIMUM_TASKS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-- 
1.8.4.5




More information about the devel mailing list