// RUN: %clangxx %s -o %t && %run %t // UNSUPPORTED: ios #include #include #include #include #include #include #include std::unique_ptr any_group; const int N = 123456; void Check(const char *str) { if (!str) return; assert(strlen(str) != N); } void Check(const passwd *result) { Check(result->pw_name); Check(result->pw_passwd); assert(result->pw_uid != N); assert(result->pw_gid != N); #if !defined(__ANDROID__) Check(result->pw_gecos); #endif Check(result->pw_dir); #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) assert(result->pw_change != N); Check(result->pw_class); assert(result->pw_expire != N); #endif #if defined(__FreeBSD__) assert(result->pw_fields != N); #endif // SunOS also has pw_age and pw_comment which are documented as unused. } void Check(const group *result) { Check(result->gr_name); Check(result->gr_passwd); assert(result->gr_gid != N); for (char **mem = result->gr_mem; *mem; ++mem) Check(*mem); if (!any_group) { auto length = strlen(result->gr_name); any_group.reset(new char[length + 1]); memcpy(any_group.get(), result->gr_name, length + 1); } } template void test(Fn f, Args... args) { T *result = f(args...); Check(result); } template void test_r(Fn f, Args... args) { T gr; T *result; char buff[10000]; assert(!f(args..., &gr, buff, sizeof(buff), &result)); Check(&gr); Check(result); } int main(int argc, const char *argv[]) { test(&getpwuid, 0); test(&getpwnam, "root"); test(&getgrgid, 0); test(&getgrnam, any_group.get()); #if !defined(__ANDROID__) setpwent(); test(&getpwent); setgrent(); test(&getgrent); #if !defined(__APPLE__) setpwent(); test_r(&getpwent_r); setgrent(); test_r(&getgrent_r); #endif test_r(&getpwuid_r, 0); test_r(&getpwnam_r, "root"); test_r(&getgrgid_r, 0); test_r(&getgrnam_r, any_group.get()); #if defined(__linux__) auto pwd_file = [] { return std::unique_ptr(fopen("/etc/passwd", "r"), &fclose); }; auto gr_file = [] { return std::unique_ptr(fopen("/etc/group", "r"), &fclose); }; test(&fgetpwent, pwd_file().get()); test(&fgetgrent, gr_file().get()); test_r(&fgetpwent_r, pwd_file().get()); test_r(&fgetgrent_r, gr_file().get()); #endif #endif // __ANDROID__ return 0; }