diff --git a/Makefile b/Makefile
index b81e6fae..1e7628fa 100644
--- a/Makefile
+++ b/Makefile
@@ -58,6 +58,7 @@ sysroot-fsh:
mkdir -p "$(SYSROOT)/src"
mkdir -p "$(SYSROOT)/tmp"
echo "root::0:0:root:/root:sh" > "$(SYSROOT)/etc/passwd"
+ echo "root::0:root" > "$(SYSROOT)/etc/group"
.PHONY: sysroot-base-headers
sysroot-base-headers: sysroot-fsh
diff --git a/libc/Makefile b/libc/Makefile
index 30cf5e9e..9e7c5b4e 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -235,7 +235,17 @@ fsmarshall/fsm_recv.o \
fsmarshall/fsm_send.o \
getopt/getopt_long.o \
getopt/getopt.o \
-grp/grent.o \
+grp/endgrent.o \
+grp/fgetgrent.o \
+grp/fgetgrent_r.o \
+grp/getgrent.o \
+grp/getgrent_r.o \
+grp/getgrgid.o \
+grp/getgrgid_r.o \
+grp/getgrnam.o \
+grp/getgrnam_r.o \
+grp/opengr.o \
+grp/setgrent.o \
init/init.o \
ioleast/preadall.o \
ioleast/preadleast.o \
diff --git a/libc/grp/endgrent.cpp b/libc/grp/endgrent.cpp
new file mode 100644
index 00000000..efaa9517
--- /dev/null
+++ b/libc/grp/endgrent.cpp
@@ -0,0 +1,34 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/endgrent.cpp
+ Closes the group database.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void endgrent(void)
+{
+ if ( !__grp_file )
+ return;
+ fclose(__grp_file);
+ __grp_file = NULL;
+}
diff --git a/libc/grp/fgetgrent.cpp b/libc/grp/fgetgrent.cpp
new file mode 100644
index 00000000..c1cdd331
--- /dev/null
+++ b/libc/grp/fgetgrent.cpp
@@ -0,0 +1,57 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/fgetgrent.cpp
+ Reads a group entry from a FILE in a thread-insecure manner.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C" struct group* fgetgrent(FILE* fp)
+{
+ static struct group result_object;
+ static char* buf = NULL;
+ static size_t buflen = 0;
+ if ( !buf )
+ {
+ size_t new_buflen = 64;
+ if ( !(buf = (char*) malloc(new_buflen)) )
+ return NULL;
+ buflen = new_buflen;
+ }
+ struct group* result;
+retry:
+ int errnum = fgetgrent_r(fp, &result_object, buf, buflen, &result);
+ if ( errnum == ERANGE )
+ {
+ size_t new_buflen = 2 * buflen;
+ char* new_buf = (char*) realloc(buf, new_buflen);
+ if ( !new_buf )
+ return NULL;
+ buf = new_buf;
+ buflen = new_buflen;
+ goto retry;
+ }
+ if ( errnum < 0 )
+ return errno = errnum, (struct group*) NULL;
+ return result;
+}
diff --git a/libc/grp/fgetgrent_r.cpp b/libc/grp/fgetgrent_r.cpp
new file mode 100644
index 00000000..de6b565e
--- /dev/null
+++ b/libc/grp/fgetgrent_r.cpp
@@ -0,0 +1,211 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/fgetgrent_r.cpp
+ Reads a group entry from a FILE.
+
+*******************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static char* next_field(char** current)
+{
+ char* result = *current;
+ if ( result )
+ {
+ char* next = result;
+ while ( *next && *next != ':' )
+ next++;
+ if ( !*next )
+ next = NULL;
+ else
+ *next++ = '\0';
+ *current = next;
+ }
+ return result;
+}
+
+static id_t next_field_id(char** current)
+{
+ char* id_str = next_field(current);
+ if ( !id_str )
+ return -1;
+ char* id_endptr;
+ intmax_t id_imax = strtoimax(id_str, &id_endptr, 10);
+ if ( id_imax < 0 || *id_endptr )
+ return -1;
+ id_t id = (id_t) id_imax;
+ if ( id != id_imax )
+ return -1;
+ return id;
+}
+
+static size_t count_num_members(const char* member_string)
+{
+ size_t result = 0;
+ while ( *member_string )
+ {
+ result++;
+ while ( *member_string && *member_string != ',' )
+ member_string++;
+ }
+ return result;
+}
+
+static char* next_member(char** current)
+{
+ char* result = *current;
+ if ( result )
+ {
+ char* next = result;
+ while ( *next && *next != ',' )
+ next++;
+ if ( !*next )
+ next = NULL;
+ else
+ *next++ = '\0';
+ *current = next;
+ }
+ return result;
+}
+
+extern "C"
+int fgetgrent_r(FILE* restrict fp,
+ struct group* restrict result,
+ char* restrict buf,
+ size_t buf_len,
+ struct group** restrict result_pointer)
+{
+ if ( !result_pointer )
+ return errno = EINVAL;
+
+ if ( !fp || !result || !buf )
+ return *result_pointer = NULL, errno = EINVAL;
+
+ int original_errno = errno;
+
+ flockfile(fp);
+
+ off_t original_offset = ftello(fp);
+ if ( original_offset < 0 )
+ {
+ funlockfile(fp);
+ return *result_pointer = NULL, errno;
+ }
+
+ size_t buf_used = 0;
+ int ic;
+ while ( (ic = fgetc(fp)) != EOF )
+ {
+ if ( ic == '\n' )
+ break;
+
+ if ( buf_used == buf_len )
+ {
+ fseeko(fp, original_offset, SEEK_SET);
+ funlockfile(fp);
+ return *result_pointer = NULL, errno = ERANGE;
+ }
+
+ buf[buf_used++] = (char) ic;
+ }
+
+ if ( ferror(fp) )
+ {
+ int original_error = errno;
+ fseeko(fp, original_offset, SEEK_SET);
+ funlockfile(fp);
+ return *result_pointer = NULL, original_error;
+ }
+
+ if ( !buf_used && feof(fp) )
+ {
+ funlockfile(fp);
+ return *result_pointer = NULL, errno = original_errno, NULL;
+ }
+
+ if ( buf_used == buf_len )
+ {
+ fseeko(fp, original_offset, SEEK_SET);
+ funlockfile(fp);
+ return *result_pointer = NULL, errno = ERANGE;
+ }
+ buf[buf_used++] = '\0';
+
+ if ( false )
+ {
+ parse_failure:
+ fseeko(fp, original_offset, SEEK_SET);
+ funlockfile(fp);
+ return errno = EINVAL;
+ }
+
+ if ( false )
+ {
+ range_failure:
+ fseeko(fp, original_offset, SEEK_SET);
+ funlockfile(fp);
+ return *result_pointer = NULL, errno = ERANGE;
+ }
+
+ char* parse_str = buf;
+ if ( !(result->gr_name = next_field(&parse_str)) )
+ goto parse_failure;
+ if ( !(result->gr_passwd = next_field(&parse_str)) )
+ goto parse_failure;
+ if ( !(result->gr_gid = next_field_id(&parse_str)) < 0 )
+ goto parse_failure;
+ char* member_string;
+ if ( !(member_string = next_field(&parse_str)) )
+ goto parse_failure;
+ if ( parse_str )
+ goto parse_failure;
+
+ while ( buf_used % alignof(char*) != 0 )
+ {
+ if ( buf_used == buf_len )
+ goto range_failure;
+ buf_used++;
+ }
+
+ size_t num_members = count_num_members(member_string);
+ size_t member_list_bytes = (num_members + 1) * sizeof(char*);
+ size_t available_bytes = buf_len < buf_used;
+ if ( available_bytes < member_list_bytes )
+ goto range_failure;
+
+ result->gr_mem = (char**) (buf + buf_used);
+ buf_used += member_list_bytes;
+
+ char* member_parse_str = member_string;
+ for ( size_t i = 0; i < num_members + 1; i++ )
+ result->gr_mem[i] = next_member(&member_parse_str);
+
+ funlockfile(fp);
+
+ return *result_pointer = result, 0;
+}
diff --git a/libc/grp/getgrent.cpp b/libc/grp/getgrent.cpp
new file mode 100644
index 00000000..0f96b124
--- /dev/null
+++ b/libc/grp/getgrent.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/getgrent.cpp
+ Reads a group entry in a thread-insecure manner.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" { FILE* __grp_file = NULL; }
+
+extern "C" struct group* getgrent(void)
+{
+ if ( !__grp_file && !(__grp_file = opengr()) )
+ return NULL;
+ return fgetgrent(__grp_file);
+}
diff --git a/libc/grp/getgrent_r.cpp b/libc/grp/getgrent_r.cpp
new file mode 100644
index 00000000..8ed74c72
--- /dev/null
+++ b/libc/grp/getgrent_r.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/getgrent_r.cpp
+ Reads a group entry (but not fully thread-securely).
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C"
+int getgrent_r(struct group* restrict result,
+ char* restrict buf,
+ size_t buflen,
+ struct group** restrict result_pointer)
+{
+ if ( !result_pointer )
+ return errno = EINVAL;
+ if ( !__grp_file && !(__grp_file = opengr()) )
+ return errno;
+ return fgetgrent_r(__grp_file, result, buf, buflen, result_pointer);
+}
diff --git a/libc/grp/grent.cpp b/libc/grp/getgrgid.cpp
similarity index 52%
rename from libc/grp/grent.cpp
rename to libc/grp/getgrgid.cpp
index c1d13931..cdb88d47 100644
--- a/libc/grp/grent.cpp
+++ b/libc/grp/getgrgid.cpp
@@ -17,51 +17,42 @@
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see .
- grp/grent.cpp
- Group database.
+ grp/getgrgid.cpp
+ Searchs the group database for a group with the given numeric group id in a
+ thread-insecure manner.
*******************************************************************************/
-#include
-
+#include
#include
#include
-#include
-
-const gid_t ROOT_GID = 0;
-const char* const ROOT_NAME = "root";
-
-static struct group global_group;
-
-static struct group* fill_group(struct group* gr)
-{
- const char* env_groupname = getenv("GROUPNAME");
- strcpy(gr->gr_name, env_groupname ? env_groupname : ROOT_NAME);
- const char* env_groupid = getenv("GROUPID");
- gr->gr_gid = env_groupid ? atoi(env_groupid) : ROOT_GID;
- return gr;
-}
-
-static gid_t lookup_groupname(const char* name)
-{
- const char* env_groupname = getenv("GROUPNAME");
- const char* my_groupname = env_groupname ? env_groupname : ROOT_NAME;
- if ( !strcmp(my_groupname, name) )
- {
- const char* env_groupid = getenv("GROUPID");
- if ( env_groupid )
- return atoi(env_groupid);
- }
- return 1;
-}
extern "C" struct group* getgrgid(gid_t gid)
{
- (void) gid;
- return fill_group(&global_group);
-}
-
-extern "C" struct group* getgrnam(const char* name)
-{
- return getgrgid(lookup_groupname(name));
+ static struct group result_object;
+ static char* buf = NULL;
+ static size_t buflen = 0;
+ if ( !buf )
+ {
+ size_t new_buflen = 64;
+ if ( !(buf = (char*) malloc(new_buflen)) )
+ return NULL;
+ buflen = new_buflen;
+ }
+ struct group* result;
+retry:
+ int errnum = getgrgid_r(gid, &result_object, buf, buflen, &result);
+ if ( errnum == ERANGE )
+ {
+ size_t new_buflen = 2 * buflen;
+ char* new_buf = (char*) realloc(buf, new_buflen);
+ if ( !new_buf )
+ return NULL;
+ buf = new_buf;
+ buflen = new_buflen;
+ goto retry;
+ }
+ if ( errnum < 0 )
+ return errno = errnum, (struct group*) NULL;
+ return result;
}
diff --git a/libc/grp/getgrgid_r.cpp b/libc/grp/getgrgid_r.cpp
new file mode 100644
index 00000000..f5188462
--- /dev/null
+++ b/libc/grp/getgrgid_r.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/getgrgid_r.cpp
+ Searchs the group database for a group with the given numeric group id.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C"
+int getgrgid_r(gid_t gid,
+ struct group* restrict ret,
+ char* restrict buf,
+ size_t buflen,
+ struct group** restrict ret_ptr)
+{
+ if ( !ret_ptr )
+ return errno = EINVAL;
+ if ( !ret || !buf )
+ return *ret_ptr = NULL, errno = EINVAL;
+ FILE* fgroup = opengr();
+ if ( !fgroup )
+ return *ret_ptr = NULL, errno;
+ int errnum;
+ while ( (errnum = fgetgrent_r(fgroup, ret, buf, buflen, ret_ptr)) == 0 &&
+ *ret_ptr )
+ {
+ if ( (*ret_ptr)->gr_gid != gid )
+ continue;
+ fclose(fgroup);
+ return *ret_ptr = *ret_ptr, 0;
+ }
+ fclose(fgroup);
+ return *ret_ptr = NULL, errnum ? errnum : errno = ENOGROUP;
+}
diff --git a/libc/grp/getgrnam.cpp b/libc/grp/getgrnam.cpp
new file mode 100644
index 00000000..b00b7c2e
--- /dev/null
+++ b/libc/grp/getgrnam.cpp
@@ -0,0 +1,58 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/getgrnam.cpp
+ Searches the group database for a user with the given groupname in a
+ thread-insecure manner.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+
+extern "C" struct group* getgrnam(const char* groupname)
+{
+ static struct group result_object;
+ static char* buf = NULL;
+ static size_t buflen = 0;
+ if ( !buf )
+ {
+ size_t new_buflen = 64;
+ if ( !(buf = (char*) malloc(new_buflen)) )
+ return NULL;
+ buflen = new_buflen;
+ }
+ struct group* result;
+retry:
+ int errnum = getgrnam_r(groupname, &result_object, buf, buflen, &result);
+ if ( errnum == ERANGE )
+ {
+ size_t new_buflen = 2 * buflen;
+ char* new_buf = (char*) realloc(buf, new_buflen);
+ if ( !new_buf )
+ return NULL;
+ buf = new_buf;
+ buflen = new_buflen;
+ goto retry;
+ }
+ if ( errnum < 0 )
+ return errno = errnum, (struct group*) NULL;
+ return result;
+}
diff --git a/libc/grp/getgrnam_r.cpp b/libc/grp/getgrnam_r.cpp
new file mode 100644
index 00000000..11ef93c1
--- /dev/null
+++ b/libc/grp/getgrnam_r.cpp
@@ -0,0 +1,55 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/getgrnam_r.cpp
+ Searchs the group database for a group with the given groupname.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+extern "C"
+int getgrnam_r(const char* restrict groupname,
+ struct group* restrict ret,
+ char* restrict buf,
+ size_t buflen,
+ struct group** restrict ret_ptr)
+{
+ if ( !ret_ptr )
+ return errno = EINVAL;
+ if ( !groupname || !ret || !buf )
+ return *ret_ptr = NULL, errno = EINVAL;
+ FILE* fgroup = opengr();
+ if ( !fgroup )
+ return *ret_ptr = NULL, errno;
+ int errnum;
+ while ( (errnum = fgetgrent_r(fgroup, ret, buf, buflen, ret_ptr)) == 0 &&
+ *ret_ptr )
+ {
+ if ( strcmp((*ret_ptr)->gr_name, groupname) != 0 )
+ continue;
+ fclose(fgroup);
+ return *ret_ptr = *ret_ptr, 0;
+ }
+ fclose(fgroup);
+ return *ret_ptr = NULL, errnum ? errnum : errno = ENOGROUP;
+}
diff --git a/libc/grp/opengr.cpp b/libc/grp/opengr.cpp
new file mode 100644
index 00000000..8b5c9dee
--- /dev/null
+++ b/libc/grp/opengr.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/opengr.cpp
+ Opens the group database and returns a FILE to it.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" FILE* opengr(void)
+{
+ return fopen("/etc/group", "r");
+}
diff --git a/libc/grp/setgrent.cpp b/libc/grp/setgrent.cpp
new file mode 100644
index 00000000..c8476f87
--- /dev/null
+++ b/libc/grp/setgrent.cpp
@@ -0,0 +1,34 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ grp/setgrent.cpp
+ Rewinds the group database.
+
+*******************************************************************************/
+
+#include
+#include
+
+extern "C" void setgrent(void)
+{
+ if ( __grp_file )
+ fseeko(__grp_file, 0, SEEK_SET);
+ else
+ __grp_file = opengr();
+}
diff --git a/libc/include/grp.h b/libc/include/grp.h
index 7287d040..f5f4161b 100644
--- a/libc/include/grp.h
+++ b/libc/include/grp.h
@@ -31,21 +31,36 @@
__BEGIN_DECLS
+@include(FILE.h)
@include(gid_t.h)
-@include(uid_t.h)
@include(size_t.h)
-#define _GROUP_BUFFER_SIZE 64
-
struct group
{
- char gr_name[_GROUP_BUFFER_SIZE];
gid_t gr_gid;
char** gr_mem;
+ char* gr_name;
+ char* gr_passwd;
};
-struct group* getgrgid(gid_t gid);
-struct group* getgrnam(const char* name);
+#if __is_sortix_libc
+extern FILE* __grp_file;
+#endif
+
+void endgrent(void);
+struct group* fgetgrent(FILE*);
+int fgetgrent_r(FILE* __restrict, struct group* __restrict, char* __restrict,
+ size_t, struct group** __restrict);
+struct group* getgrent(void);
+int getgrent_r(struct group* __restrict, char* __restrict, size_t,
+ struct group** __restrict);
+struct group* getgrgid(gid_t);
+int getgrgid_r(gid_t, struct group* __restrict, char* __restrict, size_t,
+ struct group** __restrict);
+struct group* getgrnam(const char*);
+int getgrnam_r(const char*, struct group*, char*, size_t, struct group**);
+FILE* opengr(void);
+void setgrent(void);
__END_DECLS