--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/genericopenlibs/openenvcore/libc/src/grp_funcs.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,229 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name : grp_funcs.cpp
+// Part of : libc-db specific cpp file
+// This is a project specific include file for building the
+// group database related functions as part of libc library.
+// Version : 1.0
+//
+
+
+
+#include <grp.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libc_private.h"
+
+#if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
+#include "libc_wsd_defs.h"
+#endif
+
+#ifndef EMULATOR
+
+static pthread_mutex_t getgrent_mutex = PTHREAD_MUTEX_INITIALIZER;
+int isfirstgrent=1;
+#else //EMULATOR
+
+GET_STATIC_VAR_FROM_TLS(getgrent_mutex, pthread_mutex_t)
+GET_GLOBAL_VAR_FROM_TLS(isfirstgrent, int)
+
+#define getgrent_mutex (*GET_WSD_VAR_NAME(getgrent_mutex, s)())
+#define isfirstgrent (*GET_WSD_VAR_NAME(isfirstgrent, g)())
+#endif //EMULATOR
+
+extern "C" {
+
+//Returns the pointer to the filled struct group with the
+//values corresponding to the group id gid
+//We simulate only the possibility of having a single user in a single group
+//as the OS does not support the multiuser and multigroup concept as in typical
+//unix systems.Hence we set default values as in "root" mode in unix.
+EXPORT_C struct group *getgrgid(gid_t gid)
+{
+ struct group* res;
+ struct group* tempresult;
+ //The library has to return a filled pointer to struct hence we are forced to malloc
+ res = (struct group*)malloc (sizeof (struct group));
+ if(res == NULL){
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ res->gr_mem = (char**)malloc (sizeof (char**));
+ if(res->gr_mem == NULL){
+
+ errno = ENOMEM;
+ free(res);
+ return NULL;
+ }
+
+ //We call getgrgid_r to fill the result structure
+ int retval = getgrgid_r (gid, res, NULL, 0, &tempresult);
+ if(retval != 0){
+ //Since the library doesn't fill the struct group,its responsible for freeing them
+ free (res->gr_mem);
+ free (res);
+ //errno is set by getgrgid_r itself in this case
+ errno = retval;
+ return NULL;
+ }
+ return res;
+}
+
+
+//Fills a valid grp with the values corresponding to the group id gid
+//and ensures the *result points to this value
+//We simulate only the possibility of having a single user in a single group
+//as the OS does not support the multiuser and multigroup concept as in typical
+//unix systems.Hence we set default values as in "root" mode in unix.
+EXPORT_C int getgrgid_r(gid_t gid, struct group *grp, char* /*buffer*/,size_t /*bufsize*/, struct group **result)
+{
+
+ if(gid != 0){
+ errno = ENOENT;
+ *result = NULL;
+ return errno;
+ }
+
+ //Setting values corresponding to a single user systems
+ grp->gr_name = "root";
+ grp->gr_passwd = NULL;
+ grp->gr_gid = gid;
+ grp->gr_mem[0] = "root";
+
+ *result = grp;
+ errno = 0;
+ return 0;
+
+}
+
+//Returns the pointer to the filled struct group with the
+//values corresponding to the group name
+//We simulate only the possibility of having a single user in a single group
+//as the OS does not support the multiuser and multigroup concept as in typical
+//unix systems.Hence we set default values as in "root" mode in unix.
+EXPORT_C struct group *getgrnam(const char* name)
+{
+ struct group* res;
+ struct group* tempresult;
+ //The library has to return a filled pointer to struct hence we are forced to malloc
+ res = (struct group*)malloc (sizeof (struct group));
+ if(res == NULL){
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ res->gr_mem = (char**)malloc (sizeof (char**));
+ if(res->gr_mem == NULL){
+ errno = ENOMEM;
+ free(res);
+ return NULL;
+ }
+
+ //We call getgrnam_r to fill the result structure
+ int retval = getgrnam_r (name, res, NULL, 0, &tempresult);
+ if(retval != 0){
+ //Since we dont return a filled struct,we are responsible for freeing it
+ free (res->gr_mem);
+ free (res);
+ //errno is set by getgrnam_r
+ errno = retval;
+ return NULL;
+ }
+ return res;
+}
+
+
+//Fills a valid grp with the values corresponding to the group name
+//and ensures the *result points to this value
+//We simulate only the possibility of having a single user in a single group
+//as the OS does not support the multiuser and multigroup concept as in typical
+//unix systems.Hence we set default values as in "root" mode in unix.
+EXPORT_C int getgrnam_r(const char *name, struct group *grp, char* /*buffer*/,size_t /*bufsize*/, struct group **result)
+{
+
+ if(strcmp (name, "root")){
+ errno = ENOENT;
+ *result = NULL;
+ return errno;
+ }
+ //Setting values corresponding to single user system
+ grp->gr_name = "root";
+ grp->gr_passwd = NULL;
+ grp->gr_gid = 0;
+ grp->gr_mem[0] = "root";
+
+ *result = grp;
+ errno = 0;
+ return 0;
+
+}
+
+//On repeated calls returns pointer to the group struct corresponding to
+//entries in group database,but since we dont support a user group concept
+//we return a pointer to a filled struct group just the first time the application
+//calls it and subsequent calls return NULL indicating an end of the database file
+//The isfirstgrent variable is used to track the call on this api
+EXPORT_C struct group *getgrent(void){
+
+ struct group *gr;
+ pthread_mutex_lock(&getgrent_mutex);
+ if(isfirstgrent){
+ gr = getgrgid (0);
+ isfirstgrent = 0;
+ }
+ else{
+ gr = NULL;
+ }
+ pthread_mutex_unlock(&getgrent_mutex);
+
+ return gr;
+}
+
+
+//On repeated calls sets the pointer reading the group database,to the first entry
+//but since we dont support a user group concept,we return a success each time it is called
+//as if it points to the first entry in the database
+//The isfirstgrent variable is used to track the call on this api
+EXPORT_C int setgrent(void){
+
+ pthread_mutex_lock(&getgrent_mutex);
+ if(!isfirstgrent)
+ isfirstgrent = 1;
+ pthread_mutex_unlock(&getgrent_mutex);
+ return 0;
+}
+
+//On repeated calls sets the read pointer to the end of the group database,
+//but since we dont support a user group concept,we simply return
+//as if it points to the last entry in the database
+//The isfirstgrent variable is used to track the call on this api
+EXPORT_C void endgrent(void){
+
+ pthread_mutex_lock(&getgrent_mutex);
+ if(!isfirstgrent)
+ isfirstgrent = 0;
+ pthread_mutex_unlock(&getgrent_mutex);
+ return;
+}
+
+//Resets the group database with entries in ngroups for n users,
+//but since the OS doesnt support this concept,we simply return 0
+EXPORT_C int setgroups(int /*n*/, const gid_t* /*ngroups*/){
+ return 0;
+}
+
+} // extern "C"