Skip to content

[Android] Add shims for getgrnam_r and getgrgid_r for API 23#1663

Merged
jmschonfeld merged 5 commits intoswiftlang:mainfrom
madsodgaard:main
Feb 11, 2026
Merged

[Android] Add shims for getgrnam_r and getgrgid_r for API 23#1663
jmschonfeld merged 5 commits intoswiftlang:mainfrom
madsodgaard:main

Conversation

@madsodgaard
Copy link
Contributor

@madsodgaard madsodgaard commented Dec 25, 2025

Adds simple shims for these two functions, such that swift-foundation can compile on API 23.

Motivation:

Currently, swift-foundation does not compile on Android API 23, because of getgrnam_r and getgrgid_r, which is only available on API 24.

This is the only thing that was missing to make this repo compile on API 23.

An alternative solution, was guarding the calls to these with if #available(Android 24, *), but I am not sure if we should "fail" silently in that case, and just not append the GID to the file on API 23. So, I guess this solution is at least better. Also, the shims are quite simple, since Foundation only needs the name and GID.

@finagolfin
Copy link
Member

finagolfin commented Dec 26, 2025

This isn't a polyfill, because it will be compiled in if the target API when compiling the SDK itself is 23 or earlier, regardless of the eventual Android runtime environment. These group functions seem pretty much useless on Android though, so I'd have been fine if you had just stubbed them out when compiling against such an old target API, but now that you've done this work, seems fine to include it, 👍 if the swift-foundation reviewers approve.

@finagolfin
Copy link
Member

@swift-ci test

@madsodgaard madsodgaard changed the title [Android] Add polyfill for getgrnam_r and getgrgid_r for API 23 [Android] Add shims for getgrnam_r and getgrgid_r for API 23 Dec 26, 2025
@finagolfin
Copy link
Member

@parkera, could you have someone take a look?

Copy link
Contributor

@itingliu itingliu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <string.h>
#include <errno.h>

static inline int _filemanager_shims_getgrgid_r(gid_t gid, struct group *grp,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we can't do call these code directly in Swift? Yes, there will be some boilerplates, but I'm not sure if we should be adding code to these

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, in general this patch seems ok to me, but the goal of this project is to write these implementations in Swift rather than C, so unless we have a good reason to write this in C (because Swift cannot call these functions for some reason) then writing the shim in Swift seems like a better approach to me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you propose we write this in Swift? This was written in C because these APIs are only unavailable for Android API 23 and before, so either you'd have to mimic the #if TARGET_OS_ANDROID && __ANDROID_API__ <= 23 guard above with a compile-time API version check in Swift, which the language does not provide so we'd have to pass it in manually through the Package.swift manifest and CMake config, or use the new #available(Android, ) feature, which we can't yet because it requires NDK 28 or later.

I believe Mads added these as C shims for those reasons and because he noticed these C shims here already. What we could do is get this in for now, then revisit later in Swift once #available(Android, ) is working with a new NDK on the official Android CI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to get this small pull in, let me know what you think, @itingliu.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds reasonable. Thanks

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind filing an issue for revisiting this to use #available(Android, ) when it's ready?

@itingliu itingliu requested a review from jmschonfeld January 13, 2026 22:56
@marcprux marcprux moved this to In Progress in Swift on Android Jan 14, 2026
@itingliu
Copy link
Contributor

@swift-ci please test

Comment on lines 111 to 112
grp->gr_passwd = (char *)"";
grp->gr_mem = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we don't use it right now, but should these two be copied over for consistency? Or does android define these as never set for one reason or another?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The official Bionic impl does not set these fields. For passwd, its basically a null-pointer and for the group member list, its just a "synthetic list" of the group name and a null pointer

https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/bionic/grp_pwd.cpp#83

The passwd would be simple enough to copy as well, but the group members would require a bit more complex logic to deep copy all the strings. So, since Foundation does not use these and Bionic does not, I think leaving them out, seems like the best option.

I added a comment in the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the added comment is helpful to clarify that. It looks like you changed the returned gr_passwd to an empty string "for safety" - could you elaborate on what safety you're trying to guarantee here? I know we don't use it right now, but returning the group password as an empty string seems like it would be prone to issues if we did decide to use it (I wouldn't want us to end up performing any form of string comparison against that empty string for example). It seems better to me to leave this as setting it to NULL to preserve what the OS does instead of providing a fake value that doesn't match the OS behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I've updated the shim to explicitly set gr_passwd to NULL

@madsodgaard madsodgaard requested a review from a team as a code owner February 7, 2026 10:52
@madsodgaard
Copy link
Contributor Author

@swift-ci please test

@shahmishal
Copy link
Member

@swift-ci please test macOS

@finagolfin
Copy link
Member

@swift-ci test

return 0;
}

#elif !TARGET_OS_WINDOWS && !TARGET_OS_WASI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@madsodgaard would you be able to add a __has_include(<grp.h>) to this condition (or use that instead if neither Windows nor WASI has the header)? That would be a little more robust and ensures that this doesn't trip up anything in special circumstances like WASI where the API doesn't exist and is already excluded on the calling side?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! I replaced the conditions by the _has_include. Seems neither WASM nor Windows has the header

@madsodgaard
Copy link
Contributor Author

@swift-ci test

@jmschonfeld jmschonfeld merged commit 7aae11d into swiftlang:main Feb 11, 2026
18 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Swift on Android Feb 11, 2026
madsodgaard added a commit to madsodgaard/swift-foundation that referenced this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants