Skip to content

Commit 6a81a7c

Browse files
committed
Implement os.getgroups
1 parent 68588b7 commit 6a81a7c

8 files changed

Lines changed: 93 additions & 0 deletions

File tree

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
import com.oracle.graal.python.runtime.exception.PythonExitException;
126126
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
127127
import com.oracle.graal.python.runtime.sequence.PSequence;
128+
import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage;
128129
import com.oracle.graal.python.runtime.sequence.storage.ObjectSequenceStorage;
129130
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
130131
import com.oracle.graal.python.util.OverflowException;
@@ -719,6 +720,24 @@ Object setsid(VirtualFrame frame,
719720
}
720721
}
721722

723+
@Builtin(name = "getgroups")
724+
@GenerateNodeFactory
725+
abstract static class GetGroupsNode extends PythonBuiltinNode {
726+
@Specialization
727+
Object getgroups(VirtualFrame frame,
728+
@Bind("this") Node inliningTarget,
729+
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
730+
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
731+
@Cached PythonObjectFactory factory) {
732+
try {
733+
long[] groups = posixLib.getgroups(getPosixSupport());
734+
return factory.createList(new LongSequenceStorage(groups));
735+
} catch (PosixException e) {
736+
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
737+
}
738+
}
739+
}
740+
722741
@Builtin(name = "openpty")
723742
@GenerateNodeFactory
724743
public abstract static class OpenPtyNode extends PythonBuiltinNode {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/EmulatedPosixSupport.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,19 @@ public long setsid() {
20552055
throw new UnsupportedPosixFeatureException("Emulated getsid not supported");
20562056
}
20572057

2058+
@ExportMessage
2059+
public long[] getgroups() {
2060+
if (!PythonOptions.WITHOUT_PLATFORM_ACCESS) {
2061+
switch (PythonOS.getPythonOS()) {
2062+
case PLATFORM_LINUX, PLATFORM_DARWIN -> {
2063+
return new UnixSystem().getGroups();
2064+
}
2065+
default -> throw new UnsupportedPosixFeatureException("emulated getgroups is not available on this platform");
2066+
}
2067+
}
2068+
throw new UnsupportedPosixFeatureException("getgroups was excluded");
2069+
}
2070+
20582071
@ExportMessage
20592072
@SuppressWarnings("static-method")
20602073
public OpenPtyResult openpty() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ImageBuildtimePosixSupport.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,13 @@ final long setsid(
699699
return nativeLib.setsid(nativePosixSupport);
700700
}
701701

702+
@ExportMessage
703+
final long[] getgroups(
704+
@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException {
705+
checkNotInImageBuildtime();
706+
return nativeLib.getgroups(nativePosixSupport);
707+
}
708+
702709
@ExportMessage
703710
final OpenPtyResult openpty(@CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException {
704711
checkNotInImageBuildtime();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/LoggingPosixSupport.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,17 @@ final long setsid(
903903
}
904904
}
905905

906+
@ExportMessage
907+
final long[] getgroups(
908+
@CachedLibrary("this.delegate") PosixSupportLibrary lib) throws PosixException {
909+
logEnter("getgroups", "");
910+
try {
911+
return logExit("getgroups", "%s", lib.getgroups(delegate));
912+
} catch (PosixException e) {
913+
throw logException("getgroups", e);
914+
}
915+
}
916+
906917
@ExportMessage
907918
public int mmapReadBytes(Object mmap, long index, byte[] bytes, int length,
908919
@CachedLibrary("this.delegate") PosixSupportLibrary lib) throws PosixException {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import static com.oracle.graal.python.runtime.PosixConstants._POSIX_HOST_NAME_MAX;
7676
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR;
7777
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR_BE;
78+
import static com.oracle.graal.python.util.PythonUtils.EMPTY_LONG_ARRAY;
7879
import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING;
7980
import static com.oracle.truffle.api.CompilerDirectives.SLOWPATH_PROBABILITY;
8081
import static com.oracle.truffle.api.CompilerDirectives.injectBranchProbability;
@@ -235,6 +236,7 @@ private enum PosixNativeFunction {
235236
call_getpgrp("():sint64"),
236237
call_getsid("(sint64):sint64"),
237238
call_setsid("():sint64"),
239+
call_getgroups("(sint64, [sint64]):sint32"),
238240
call_openpty("([sint32]):sint32"),
239241
call_ctermid("([sint8]):sint32"),
240242
call_setenv("([sint8], [sint8], sint32):sint32"),
@@ -1219,6 +1221,25 @@ public long setsid(
12191221
return res;
12201222
}
12211223

1224+
@ExportMessage
1225+
public long[] getgroups(
1226+
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException {
1227+
// The first call gets us the number of groups, so we can allocate the output array
1228+
int res = invokeNode.callInt(this, PosixNativeFunction.call_getgroups, 0, 0);
1229+
if (res < 0) {
1230+
throw getErrnoAndThrowPosixException(invokeNode);
1231+
}
1232+
if (res == 0) {
1233+
return EMPTY_LONG_ARRAY;
1234+
}
1235+
long[] groups = new long[res];
1236+
res = invokeNode.callInt(this, PosixNativeFunction.call_getgroups, groups.length, wrap(groups));
1237+
if (res < 0) {
1238+
throw getErrnoAndThrowPosixException(invokeNode);
1239+
}
1240+
return groups;
1241+
}
1242+
12221243
@ExportMessage
12231244
public OpenPtyResult openpty(@Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException {
12241245
int[] outvars = new int[2];

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixSupportLibrary.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ public abstract class PosixSupportLibrary extends Library {
292292

293293
public abstract long setsid(Object receiver) throws PosixException;
294294

295+
public abstract long[] getgroups(Object receiver) throws PosixException;
296+
295297
public record OpenPtyResult(int masterFd, int slaveFd) {
296298
}
297299

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ private PythonUtils() {
137137
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
138138
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
139139
public static final int[] EMPTY_INT_ARRAY = new int[0];
140+
public static final long[] EMPTY_LONG_ARRAY = new long[0];
140141
public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
141142
public static final char[] EMPTY_CHAR_ARRAY = new char[0];
142143
public static final ByteSequence EMPTY_BYTE_SEQUENCE = ByteSequence.create(EMPTY_BYTE_ARRAY);

graalpython/python-libposix/src/posix.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,25 @@ int64_t call_setsid() {
595595
return setsid();
596596
}
597597

598+
int32_t call_getgroups(int64_t size, int64_t* out) {
599+
if (size > 0) {
600+
// gid_t can be different types, we need to copy the results
601+
gid_t* tmp = calloc(size, sizeof(gid_t));
602+
if (!tmp) {
603+
return -1;
604+
}
605+
int32_t res = getgroups(size, tmp);
606+
for (int64_t i = 0; i < size; i++) {
607+
out[i] = tmp[i];
608+
}
609+
free(tmp);
610+
return res;
611+
} else {
612+
return getgroups(size, NULL);
613+
}
614+
}
615+
616+
598617
int32_t call_openpty(int32_t *outvars) {
599618
return openpty(outvars, outvars + 1, NULL, NULL, NULL);
600619
}

0 commit comments

Comments
 (0)