bionic: Implement getpwent and getgrent
Not efficient to iterate through given the large number of Android
ids (AID). Compile warning will result if you use these functions,
telling you as much. Not for general consumption, however for
example, some filesystem tests would like to see these to perform
all corners.
About 1/4 second for getpwent, and 1/8 second for getgrent to iterate
through all reserved Android aids.
Bug: 27999086
Change-Id: I7784273b7875c38e4954ae21d314f35e4bf8c2fc
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 29cd907..a684780 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -26,6 +26,10 @@
#include <sys/types.h>
#include <unistd.h>
+#include <bitset>
+
+#include <private/android_filesystem_config.h>
+
enum uid_type_t {
TYPE_SYSTEM,
TYPE_APP
@@ -179,6 +183,46 @@
check_get_passwd("u1_i0", 199000, TYPE_APP);
}
+TEST(getpwent, iterate) {
+ passwd* pwd;
+ std::bitset<10000> exist;
+ bool application = false;
+
+ exist.reset();
+
+ setpwent();
+ while ((pwd = getpwent()) != NULL) {
+ ASSERT_TRUE(NULL != pwd->pw_name);
+ ASSERT_EQ(pwd->pw_gid, pwd->pw_uid);
+ ASSERT_EQ(NULL, pwd->pw_passwd);
+#ifdef __LP64__
+ ASSERT_TRUE(NULL == pwd->pw_gecos);
+#endif
+ ASSERT_TRUE(NULL != pwd->pw_shell);
+ if (pwd->pw_uid >= exist.size()) {
+ ASSERT_STREQ("/data", pwd->pw_dir);
+ application = true;
+ } else {
+ ASSERT_STREQ("/", pwd->pw_dir);
+ ASSERT_FALSE(exist[pwd->pw_uid]);
+ exist[pwd->pw_uid] = true;
+ }
+ }
+ endpwent();
+
+ // Required content
+ for (size_t n = 0; n < android_id_count; ++n) {
+ ASSERT_TRUE(exist[android_ids[n].aid]);
+ }
+ for (size_t n = 2900; n < 2999; ++n) {
+ ASSERT_TRUE(exist[n]);
+ }
+ for (size_t n = 5000; n < 5999; ++n) {
+ ASSERT_TRUE(exist[n]);
+ }
+ ASSERT_TRUE(application);
+}
+
static void check_group(const group* grp, const char* group_name, gid_t gid) {
ASSERT_TRUE(grp != NULL);
ASSERT_STREQ(group_name, grp->gr_name);
@@ -373,3 +417,38 @@
ASSERT_EQ(0, getgrnam_r("root", &grp_storage, buf, size, &grp));
check_group(grp, "root", 0);
}
+
+TEST(getgrent, iterate) {
+ group* grp;
+ std::bitset<10000> exist;
+ bool application = false;
+
+ exist.reset();
+
+ setgrent();
+ while ((grp = getgrent()) != NULL) {
+ ASSERT_TRUE(grp->gr_name != NULL);
+ ASSERT_TRUE(grp->gr_mem != NULL);
+ ASSERT_STREQ(grp->gr_name, grp->gr_mem[0]);
+ ASSERT_TRUE(grp->gr_mem[1] == NULL);
+ if (grp->gr_gid >= exist.size()) {
+ application = true;
+ } else {
+ ASSERT_FALSE(exist[grp->gr_gid]);
+ exist[grp->gr_gid] = true;
+ }
+ }
+ endgrent();
+
+ // Required content
+ for (size_t n = 0; n < android_id_count; ++n) {
+ ASSERT_TRUE(exist[android_ids[n].aid]);
+ }
+ for (size_t n = 2900; n < 2999; ++n) {
+ ASSERT_TRUE(exist[n]);
+ }
+ for (size_t n = 5000; n < 5999; ++n) {
+ ASSERT_TRUE(exist[n]);
+ }
+ ASSERT_TRUE(application);
+}