From 395e5d4d7aa09f944bfe3aa948a39a0f925b2765 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 14 Nov 2014 15:33:57 +0100 Subject: libcsupport: Use POSIX key for getgrent() --- 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 74b029c1ad..6803fe6036 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 9b11e2ee08..4f27efc98c 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 +#include -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 0000000000..505a334f75 --- /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 + * Copyright (c) 1999-2013 Joel Sherrill + * Copyright (c) 2000-2001 Fernando Ruiz Casas + * Copyright (c) 2002 Eric Norum + * Copyright (c) 2003 Till Straumann + * Copyright (c) 2012 Alex Ivanov + * + * 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 0f0f208f2a..4553ca30d6 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 72480033bf..da4f2b4db7 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 -- cgit v1.2.3