Skip to content

Commit 7831586

Browse files
committed
[Truffle] Add Process.{euid,uid}
1 parent fb73a1a commit 7831586

File tree

6 files changed

+150
-7
lines changed

6 files changed

+150
-7
lines changed
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
fails:Process.euid= raises TypeError if not passed an Integer
2-
fails:Process.euid= raises Errno::ERPERM if run by a non superuser trying to set the superuser id
31
fails:Process.euid= raises Errno::ERPERM if run by a non superuser trying to set the superuser id from username
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
fails:Process.uid also goes by Process::UID.rid
2-
fails:Process.uid also goes by Process::Sys.getuid
3-
fails:Process.uid= raises TypeError if not passed an Integer
41
fails:Process.uid= raises Errno::ERPERM if run by a non privileged user trying to set the superuser id
52
fails:Process.uid= raises Errno::ERPERM if run by a non privileged user trying to set the superuser id from username

truffle/src/main/java/org/jruby/truffle/nodes/rubinius/ExceptionPrimitiveNodes.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public abstract class ExceptionPrimitiveNodes {
2929
public static abstract class ExceptionErrnoErrorPrimitiveNode extends RubiniusPrimitiveNode {
3030

3131
// If you add a constant here, add it below in isExceptionSupported() too.
32+
protected final static int EPERM = Errno.EPERM.intValue();
3233
protected final static int ENOENT = Errno.ENOENT.intValue();
3334
protected final static int EBADF = Errno.EBADF.intValue();
3435
protected final static int EEXIST = Errno.EEXIST.intValue();
@@ -37,13 +38,23 @@ public static abstract class ExceptionErrnoErrorPrimitiveNode extends RubiniusPr
3738
protected final static int ENOTDIR = Errno.ENOTDIR.intValue();
3839

3940
public static boolean isExceptionSupported(int errno) {
40-
return errno == ENOENT || errno == EBADF || errno == EEXIST || errno == EACCES || errno == EFAULT || errno == ENOTDIR;
41+
return errno == EPERM || errno == ENOENT || errno == EBADF || errno == EEXIST || errno == EACCES || errno == EFAULT || errno == ENOTDIR;
4142
}
4243

4344
public ExceptionErrnoErrorPrimitiveNode(RubyContext context, SourceSection sourceSection) {
4445
super(context, sourceSection);
4546
}
4647

48+
@Specialization(guards = "errno == EPERM")
49+
public RubyException eperm(RubyString message, int errno) {
50+
return getContext().getCoreLibrary().operationNotPermittedError(message.toString(), this);
51+
}
52+
53+
@Specialization(guards = {"errno == EPERM", "isNil(message)"})
54+
public RubyException eperm(Object message, int errno) {
55+
return getContext().getCoreLibrary().operationNotPermittedError("nil", this);
56+
}
57+
4758
@Specialization(guards = "errno == ENOENT")
4859
public RubyException enoent(RubyString message, int errno) {
4960
return getContext().getCoreLibrary().fileNotFoundError(message.toString(), this);

truffle/src/main/java/org/jruby/truffle/nodes/rubinius/PosixNodes.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,76 @@ public int setpriority(int kind, int id, int priority) {
365365

366366
}
367367

368+
@CoreMethod(names = "setresuid", isModuleFunction = true, required = 3, lowerFixnumParameters = {0, 1, 2})
369+
public abstract static class SetResuidNode extends CoreMethodArrayArgumentsNode {
370+
371+
public SetResuidNode(RubyContext context, SourceSection sourceSection) {
372+
super(context, sourceSection);
373+
}
374+
375+
@Specialization
376+
public int setresuid(int uid, int id, int priority) {
377+
throw new RaiseException(getContext().getCoreLibrary().notImplementedError("setresuid", this));
378+
}
379+
380+
}
381+
382+
@CoreMethod(names = "seteuid", isModuleFunction = true, required = 1, lowerFixnumParameters = 0)
383+
public abstract static class SetEuidNode extends CoreMethodArrayArgumentsNode {
384+
385+
public SetEuidNode(RubyContext context, SourceSection sourceSection) {
386+
super(context, sourceSection);
387+
}
388+
389+
@Specialization
390+
public int seteuid(int uid) {
391+
return posix().seteuid(uid);
392+
}
393+
394+
}
395+
396+
@CoreMethod(names = "setreuid", isModuleFunction = true, required = 2, lowerFixnumParameters = {0, 1})
397+
public abstract static class SetReuidNode extends CoreMethodArrayArgumentsNode {
398+
399+
public SetReuidNode(RubyContext context, SourceSection sourceSection) {
400+
super(context, sourceSection);
401+
}
402+
403+
@Specialization
404+
public int setreuid(int uid, int id) {
405+
throw new RaiseException(getContext().getCoreLibrary().notImplementedError("setreuid", this));
406+
}
407+
408+
}
409+
410+
@CoreMethod(names = "setruid", isModuleFunction = true, required = 1, lowerFixnumParameters = 0)
411+
public abstract static class SetRuidNode extends CoreMethodArrayArgumentsNode {
412+
413+
public SetRuidNode(RubyContext context, SourceSection sourceSection) {
414+
super(context, sourceSection);
415+
}
416+
417+
@Specialization
418+
public int setruid(int uid) {
419+
throw new RaiseException(getContext().getCoreLibrary().notImplementedError("setruid", this));
420+
}
421+
422+
}
423+
424+
@CoreMethod(names = "setuid", isModuleFunction = true, required = 1, lowerFixnumParameters = 0)
425+
public abstract static class SetUidNode extends CoreMethodArrayArgumentsNode {
426+
427+
public SetUidNode(RubyContext context, SourceSection sourceSection) {
428+
super(context, sourceSection);
429+
}
430+
431+
@Specialization
432+
public int setuid(int uid) {
433+
return posix().setuid(uid);
434+
}
435+
436+
}
437+
368438
@CoreMethod(names = "flock", isModuleFunction = true, required = 2, lowerFixnumParameters = {0, 1})
369439
public abstract static class FlockNode extends CoreMethodArrayArgumentsNode {
370440

truffle/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public class CoreLibrary {
9494
private final RubyClass nameErrorClass;
9595
private final RubyClass nilClass;
9696
private final RubyClass noMethodErrorClass;
97+
private final RubyClass notImplementedErrorClass;
9798
private final RubyClass numericClass;
9899
private final RubyClass objectClass;
99100
private final RubyClass procClass;
@@ -270,7 +271,7 @@ public CoreLibrary(RubyContext context) {
270271
// ScriptError
271272
RubyClass scriptErrorClass = defineClass(exceptionClass, "ScriptError");
272273
loadErrorClass = defineClass(scriptErrorClass, "LoadError");
273-
defineClass(scriptErrorClass, "NotImplementedError");
274+
notImplementedErrorClass = defineClass(scriptErrorClass, "NotImplementedError");
274275
syntaxErrorClass = defineClass(scriptErrorClass, "SyntaxError");
275276

276277
// SecurityError
@@ -1014,6 +1015,11 @@ public RubyException zeroDivisionError(Node currentNode) {
10141015
return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), context.makeString("divided by 0"), RubyCallStack.getBacktrace(currentNode));
10151016
}
10161017

1018+
public RubyException notImplementedError(String message, Node currentNode) {
1019+
CompilerAsserts.neverPartOfCompilation();
1020+
return new RubyException(notImplementedErrorClass, context.makeString(String.format("Method %s not implemented", message)), RubyCallStack.getBacktrace(currentNode));
1021+
}
1022+
10171023
public RubyException syntaxError(String message, Node currentNode) {
10181024
CompilerAsserts.neverPartOfCompilation();
10191025
return new RubyException(syntaxErrorClass, context.makeString(message), RubyCallStack.getBacktrace(currentNode));
@@ -1065,6 +1071,11 @@ public RubyException dirNotEmptyError(String path, Node currentNode) {
10651071
return new RubyException(getErrnoClass(Errno.ENOTEMPTY), context.makeString(String.format("Directory not empty - %s", path)), RubyCallStack.getBacktrace(currentNode));
10661072
}
10671073

1074+
public RubyException operationNotPermittedError(String path, Node currentNode) {
1075+
CompilerAsserts.neverPartOfCompilation();
1076+
return new RubyException(getErrnoClass(Errno.EPERM), context.makeString(String.format("Operation not permitted - %s", path)), RubyCallStack.getBacktrace(currentNode));
1077+
}
1078+
10681079
public RubyException permissionDeniedError(String path, Node currentNode) {
10691080
CompilerAsserts.neverPartOfCompilation();
10701081
return new RubyException(getErrnoClass(Errno.EACCES), context.makeString(String.format("Permission denied - %s", path)), RubyCallStack.getBacktrace(currentNode));

truffle/src/main/ruby/core/rubinius/common/process.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,62 @@ def self.getpgrp
9090
ret
9191
end
9292

93+
def self.uid=(uid)
94+
# the 4 rescue clauses below are needed
95+
# until respond_to? can be used to query the implementation of methods attached via FFI
96+
# atm respond_to returns true if a method is attached but not implemented on the platform
97+
uid = Rubinius::Type.coerce_to uid, Integer, :to_int
98+
begin
99+
ret = FFI::Platform::POSIX.setresuid(uid, -1, -1)
100+
rescue NotImplementedError
101+
begin
102+
ret = FFI::Platform::POSIX.setreuid(uid, -1)
103+
rescue NotImplementedError
104+
begin
105+
ret = FFI::Platform::POSIX.setruid(uid)
106+
rescue NotImplementedError
107+
if Process.euid == uid
108+
ret = FFI::Platform::POSIX.setuid(uid)
109+
else
110+
raise NotImplementedError
111+
end
112+
end
113+
end
114+
end
115+
116+
Errno.handle if ret == -1
117+
118+
uid
119+
end
120+
121+
def self.euid=(uid)
122+
# the 4 rescue clauses below are needed
123+
# until respond_to? can be used to query the implementation of methods attached via FFI
124+
# atm respond_to returns true if a method is attached but not implemented on the platform
125+
uid = Rubinius::Type.coerce_to uid, Integer, :to_int
126+
begin
127+
ret = FFI::Platform::POSIX.setresuid(-1, uid, -1)
128+
rescue NotImplementedError
129+
begin
130+
ret = FFI::Platform::POSIX.setreuid(-1, uid)
131+
rescue NotImplementedError
132+
begin
133+
ret = FFI::Platform::POSIX.seteuid(uid)
134+
rescue NotImplementedError
135+
if Process.uid == uid
136+
ret = FFI::Platform::POSIX.setuid(uid)
137+
else
138+
raise NotImplementedError
139+
end
140+
end
141+
end
142+
end
143+
144+
Errno.handle if ret == -1
145+
146+
uid
147+
end
148+
93149
def self.uid
94150
ret = FFI::Platform::POSIX.getuid
95151
Errno.handle if ret == -1

0 commit comments

Comments
 (0)