109
109
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
110
110
import com .oracle .graal .python .nodes .truffle .PythonArithmeticTypes ;
111
111
import com .oracle .graal .python .nodes .util .CastToJavaLongLossyNode ;
112
- import com .oracle .graal .python .nodes .util .CastToJavaUnsignedLongNode ;
113
112
import com .oracle .graal .python .nodes .util .CastToTruffleStringNode ;
114
113
import com .oracle .graal .python .runtime .GilNode ;
115
114
import com .oracle .graal .python .runtime .PosixConstants ;
126
125
import com .oracle .graal .python .runtime .exception .PythonExitException ;
127
126
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
128
127
import com .oracle .graal .python .runtime .sequence .PSequence ;
128
+ import com .oracle .graal .python .runtime .sequence .storage .LongSequenceStorage ;
129
129
import com .oracle .graal .python .runtime .sequence .storage .ObjectSequenceStorage ;
130
130
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
131
131
import com .oracle .graal .python .util .OverflowException ;
@@ -720,6 +720,24 @@ Object setsid(VirtualFrame frame,
720
720
}
721
721
}
722
722
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
+
723
741
@ Builtin (name = "openpty" )
724
742
@ GenerateNodeFactory
725
743
public abstract static class OpenPtyNode extends PythonBuiltinNode {
@@ -2212,6 +2230,134 @@ PNone chmodFollow(VirtualFrame frame, PosixFd fd, int mode, int dirFd, @Suppress
2212
2230
}
2213
2231
}
2214
2232
2233
+ @ Builtin (name = "fchown" , parameterNames = {"fd" , "uid" , "gid" })
2234
+ @ ArgumentClinic (name = "fd" , conversion = ClinicConversion .Int )
2235
+ @ ArgumentClinic (name = "uid" , conversionClass = UidConversionNode .class )
2236
+ @ ArgumentClinic (name = "gid" , conversionClass = GidConversionNode .class )
2237
+ @ GenerateNodeFactory
2238
+ abstract static class FChownNode extends PythonTernaryClinicBuiltinNode {
2239
+ @ Specialization
2240
+ Object chown (VirtualFrame frame , int fd , long uid , long gid ,
2241
+ @ Bind ("this" ) Node inliningTarget ,
2242
+ @ Cached SysModuleBuiltins .AuditNode auditNode ,
2243
+ @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2244
+ @ Cached GilNode gil ,
2245
+ @ Cached PConstructAndRaiseNode .Lazy constructAndRaiseNode ) {
2246
+ auditNode .audit (inliningTarget , "os.chown" , fd , uid , gid , -1 );
2247
+ try {
2248
+ gil .release (true );
2249
+ try {
2250
+ posixLib .fchown (getPosixSupport (), fd , uid , gid );
2251
+ } finally {
2252
+ gil .acquire ();
2253
+ }
2254
+ } catch (PosixException e ) {
2255
+ throw constructAndRaiseNode .get (inliningTarget ).raiseOSErrorFromPosixException (frame , e , fd );
2256
+ }
2257
+ return PNone .NONE ;
2258
+ }
2259
+
2260
+ @ Override
2261
+ protected ArgumentClinicProvider getArgumentClinic () {
2262
+ return PosixModuleBuiltinsClinicProviders .FChownNodeClinicProviderGen .INSTANCE ;
2263
+ }
2264
+ }
2265
+
2266
+ @ Builtin (name = "lchown" , parameterNames = {"path" , "uid" , "gid" })
2267
+ @ ArgumentClinic (name = "path" , conversionClass = PathConversionNode .class , args = {"false" , "false" })
2268
+ @ ArgumentClinic (name = "uid" , conversionClass = UidConversionNode .class )
2269
+ @ ArgumentClinic (name = "gid" , conversionClass = GidConversionNode .class )
2270
+ @ GenerateNodeFactory
2271
+ abstract static class LChownNode extends PythonTernaryClinicBuiltinNode {
2272
+ @ Specialization
2273
+ Object chown (VirtualFrame frame , PosixPath path , long uid , long gid ,
2274
+ @ Bind ("this" ) Node inliningTarget ,
2275
+ @ Cached SysModuleBuiltins .AuditNode auditNode ,
2276
+ @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2277
+ @ Cached GilNode gil ,
2278
+ @ Cached PConstructAndRaiseNode .Lazy constructAndRaiseNode ) {
2279
+ auditNode .audit (inliningTarget , "os.chown" , path .originalObject , uid , gid , -1 );
2280
+ try {
2281
+ gil .release (true );
2282
+ try {
2283
+ posixLib .fchownat (getPosixSupport (), AT_FDCWD .value , path .value , uid , gid , false );
2284
+ } finally {
2285
+ gil .acquire ();
2286
+ }
2287
+ } catch (PosixException e ) {
2288
+ throw constructAndRaiseNode .get (inliningTarget ).raiseOSErrorFromPosixException (frame , e , path .originalObject );
2289
+ }
2290
+ return PNone .NONE ;
2291
+ }
2292
+
2293
+ @ Override
2294
+ protected ArgumentClinicProvider getArgumentClinic () {
2295
+ return PosixModuleBuiltinsClinicProviders .LChownNodeClinicProviderGen .INSTANCE ;
2296
+ }
2297
+ }
2298
+
2299
+ @ Builtin (name = "chown" , minNumOfPositionalArgs = 3 , parameterNames = {"path" , "uid" , "gid" }, keywordOnlyNames = {"dir_fd" , "follow_symlinks" })
2300
+ @ ArgumentClinic (name = "path" , conversionClass = PathConversionNode .class , args = {"false" , "true" })
2301
+ @ ArgumentClinic (name = "uid" , conversionClass = UidConversionNode .class )
2302
+ @ ArgumentClinic (name = "gid" , conversionClass = GidConversionNode .class )
2303
+ @ ArgumentClinic (name = "dir_fd" , conversionClass = DirFdConversionNode .class )
2304
+ @ ArgumentClinic (name = "follow_symlinks" , conversion = ClinicConversion .Boolean , defaultValue = "true" )
2305
+ @ GenerateNodeFactory
2306
+ abstract static class ChownNode extends PythonClinicBuiltinNode {
2307
+ @ Specialization
2308
+ Object chown (VirtualFrame frame , PosixPath path , long uid , long gid , int dirFd , boolean followSymlinks ,
2309
+ @ Bind ("this" ) Node inliningTarget ,
2310
+ @ Shared @ Cached SysModuleBuiltins .AuditNode auditNode ,
2311
+ @ Shared @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2312
+ @ Shared @ Cached GilNode gil ,
2313
+ @ Shared @ Cached PConstructAndRaiseNode .Lazy constructAndRaiseNode ) {
2314
+ auditNode .audit (inliningTarget , "os.chown" , path .originalObject , uid , gid , dirFd != AT_FDCWD .value ? dirFd : -1 );
2315
+ try {
2316
+ gil .release (true );
2317
+ try {
2318
+ posixLib .fchownat (getPosixSupport (), dirFd , path .value , uid , gid , followSymlinks );
2319
+ } finally {
2320
+ gil .acquire ();
2321
+ }
2322
+ } catch (PosixException e ) {
2323
+ throw constructAndRaiseNode .get (inliningTarget ).raiseOSErrorFromPosixException (frame , e , path .originalObject );
2324
+ }
2325
+ return PNone .NONE ;
2326
+ }
2327
+
2328
+ @ Specialization
2329
+ Object chown (VirtualFrame frame , PosixFd fd , long uid , long gid , int dirFd , boolean followSymlinks ,
2330
+ @ Bind ("this" ) Node inliningTarget ,
2331
+ @ Shared @ Cached SysModuleBuiltins .AuditNode auditNode ,
2332
+ @ Shared @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
2333
+ @ Shared @ Cached GilNode gil ,
2334
+ @ Shared @ Cached PConstructAndRaiseNode .Lazy constructAndRaiseNode ) {
2335
+ if (dirFd != AT_FDCWD .value ) {
2336
+ throw raise (ValueError , ErrorMessages .CANT_SPECIFY_BOTH_DIR_FD_AND_FD );
2337
+ }
2338
+ if (followSymlinks ) {
2339
+ throw raise (ValueError , ErrorMessages .CANNOT_USE_FD_AND_FOLLOW_SYMLINKS_TOGETHER , "chown" );
2340
+ }
2341
+ auditNode .audit (inliningTarget , "os.chown" , fd .originalObject , uid , gid , -1 );
2342
+ try {
2343
+ gil .release (true );
2344
+ try {
2345
+ posixLib .fchown (getPosixSupport (), fd .fd , uid , gid );
2346
+ } finally {
2347
+ gil .acquire ();
2348
+ }
2349
+ } catch (PosixException e ) {
2350
+ throw constructAndRaiseNode .get (inliningTarget ).raiseOSErrorFromPosixException (frame , e , fd .originalObject );
2351
+ }
2352
+ return PNone .NONE ;
2353
+ }
2354
+
2355
+ @ Override
2356
+ protected ArgumentClinicProvider getArgumentClinic () {
2357
+ return PosixModuleBuiltinsClinicProviders .ChownNodeClinicProviderGen .INSTANCE ;
2358
+ }
2359
+ }
2360
+
2215
2361
@ Builtin (name = "readlink" , minNumOfPositionalArgs = 1 , parameterNames = {"path" }, varArgsMarker = true , keywordOnlyNames = {"dir_fd" }, doc = "readlink(path, *, dir_fd=None) -> path\n " +
2216
2362
"\n Return a string representing the path to which the symbolic link points.\n " )
2217
2363
@ ArgumentClinic (name = "path" , conversionClass = PathConversionNode .class , args = {"false" , "false" })
@@ -3240,10 +3386,11 @@ public static PidtConversionNode create() {
3240
3386
}
3241
3387
}
3242
3388
3243
- /**
3244
- * Emulates CPython's {@code _Py_Uid_Converter()}. Always returns an {@code long}.
3245
- */
3246
- public abstract static class UidConversionNode extends ArgumentCastNodeWithRaise {
3389
+ @ GenerateCached (false )
3390
+ public abstract static class AbstractIdConversionNode extends ArgumentCastNodeWithRaise {
3391
+
3392
+ private static final long MAX_UINT32 = (1L << 32 ) - 1 ;
3393
+
3247
3394
public abstract long executeLong (VirtualFrame frame , Object value );
3248
3395
3249
3396
@ Specialization
@@ -3261,39 +3408,69 @@ long doLong(long value) {
3261
3408
long doGeneric (VirtualFrame frame , Object value ,
3262
3409
@ Bind ("this" ) Node inliningTarget ,
3263
3410
@ Cached PyNumberIndexNode pyNumberIndexNode ,
3264
- @ Cached PyLongAsLongAndOverflowNode asLongAndOverflowNode ,
3265
- @ Cached CastToJavaUnsignedLongNode asUnsignedLong ) {
3411
+ @ Cached PyLongAsLongNode asLongNode ) {
3266
3412
Object index ;
3267
3413
try {
3268
3414
index = pyNumberIndexNode .execute (frame , inliningTarget , value );
3269
3415
} catch (PException ex ) {
3270
- throw raise (TypeError , ErrorMessages .UID_SHOULD_BE_INTEGER_NOT_P , value );
3271
- }
3272
- try {
3273
- return checkValue (asLongAndOverflowNode .execute (frame , inliningTarget , index ));
3274
- } catch (OverflowException e ) {
3275
- // fall through
3416
+ throw raise (TypeError , ErrorMessages .S_SHOULD_BE_INTEGER_NOT_P , getIdName (), value );
3276
3417
}
3277
- return asUnsignedLong .execute (inliningTarget , index );
3278
- // We have no means to distinguish overflow/underflow so we just let any OverflowError
3279
- // from asUnsignedLong fall through. It will not have the same message as CPython, but
3280
- // still correct type.
3418
+ /*
3419
+ * We have no means to distinguish overflow/underflow, so we just let any OverflowError
3420
+ * from asLongNode fall through. It will not have the same message as CPython, but still
3421
+ * correct type.
3422
+ */
3423
+ return checkValue (asLongNode .execute (frame , inliningTarget , index ));
3281
3424
}
3282
3425
3283
3426
private long checkValue (long value ) {
3427
+ // Note that -1 is intentionally allowed
3284
3428
if (value < -1 ) {
3285
- throw raise (OverflowError , ErrorMessages .UID_IS_LESS_THAN_MINIMUM );
3429
+ throw raise (OverflowError , ErrorMessages .S_IS_LESS_THAN_MINIMUM , getIdName ());
3430
+ } else if (value > MAX_UINT32 ) {
3431
+ /* uid_t is uint32_t on Linux */
3432
+ throw raise (OverflowError , ErrorMessages .S_IS_GREATER_THAN_MAXIUMUM , getIdName ());
3286
3433
}
3287
3434
return value ;
3288
3435
}
3289
3436
3437
+ protected abstract String getIdName ();
3438
+ }
3439
+
3440
+ /**
3441
+ * Emulates CPython's {@code _Py_Uid_Converter()}. Always returns a {@code long}.
3442
+ */
3443
+ public abstract static class UidConversionNode extends AbstractIdConversionNode {
3444
+
3445
+ @ Override
3446
+ protected String getIdName () {
3447
+ return "uid" ;
3448
+ }
3449
+
3290
3450
@ ClinicConverterFactory (shortCircuitPrimitive = {PrimitiveType .Int , PrimitiveType .Long })
3291
3451
@ NeverDefault
3292
3452
public static UidConversionNode create () {
3293
3453
return PosixModuleBuiltinsFactory .UidConversionNodeGen .create ();
3294
3454
}
3295
3455
}
3296
3456
3457
+ /**
3458
+ * Emulates CPython's {@code _Py_Gid_Converter()}. Always returns a {@code long}.
3459
+ */
3460
+ public abstract static class GidConversionNode extends AbstractIdConversionNode {
3461
+
3462
+ @ Override
3463
+ protected String getIdName () {
3464
+ return "gid" ;
3465
+ }
3466
+
3467
+ @ ClinicConverterFactory (shortCircuitPrimitive = {PrimitiveType .Int , PrimitiveType .Long })
3468
+ @ NeverDefault
3469
+ public static GidConversionNode create () {
3470
+ return PosixModuleBuiltinsFactory .GidConversionNodeGen .create ();
3471
+ }
3472
+ }
3473
+
3297
3474
/**
3298
3475
* Represents the result of {@code path_t} conversion. Similar to CPython's {@code path_t}
3299
3476
* structure, but only contains the results of the conversion, not the conversion parameters.
0 commit comments