* ext/socket/extconf.rb: check getpeereid.

* ext/socket/basicsocket.c (bsock_getpeereid): new method.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22219 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2009-02-11 01:22:08 +00:00
Родитель b8147c444b
Коммит b4e50055c3
4 изменённых файлов: 59 добавлений и 0 удалений

Просмотреть файл

@ -1,3 +1,9 @@
Wed Feb 11 10:16:34 2009 Tanaka Akira <akr@fsij.org>
* ext/socket/extconf.rb: check getpeereid.
* ext/socket/basicsocket.c (bsock_getpeereid): new method.
Wed Feb 11 09:58:59 2009 Tanaka Akira <akr@fsij.org>
* ext/socket/lib/socket.rb (Socket::UDPSource#inspect): fix variable

Просмотреть файл

@ -361,6 +361,42 @@ bsock_getpeername(VALUE sock)
return rb_str_new((char*)&buf, len);
}
/*
* call-seq:
* basicsocket.getpeereid => [euid, egid]
*
* Returns the user and group on the peer of the UNIX socket.
* The result is a two element array which contains the effective uid and the effective gid.
*
* Socket.unix_server_loop("/tmp/sock") {|s|
* p s.getpeereid #=> [1000, 1000]
* }
*
*/
static VALUE
bsock_getpeereid(VALUE self)
{
#if defined(HAVE_GETPEEREID)
rb_io_t *fptr;
uid_t euid;
gid_t egid;
GetOpenFile(self, fptr);
if (getpeereid(fptr->fd, &euid, &egid) == -1)
rb_sys_fail("getpeereid");
return rb_assoc_new(UIDT2NUM(euid), GIDT2NUM(egid));
#elif defined(SO_PEERCRED) /* GNU/Linux */
rb_io_t *fptr;
struct ucred cred;
socklen_t len = sizeof(cred);
GetOpenFile(self, fptr);
if (getsockopt(fptr->fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
rb_sys_fail("getsockopt(SO_PEERCRED)");
return rb_assoc_new(UIDT2NUM(cred.uid), GIDT2NUM(cred.gid));
#else
rb_notimplement();
#endif
}
/*
* call-seq:
* bsock.local_address => addrinfo
@ -646,6 +682,7 @@ Init_basicsocket(void)
rb_define_method(rb_cBasicSocket, "getsockopt", bsock_getsockopt, 2);
rb_define_method(rb_cBasicSocket, "getsockname", bsock_getsockname, 0);
rb_define_method(rb_cBasicSocket, "getpeername", bsock_getpeername, 0);
rb_define_method(rb_cBasicSocket, "getpeereid", bsock_getpeereid, 0);
rb_define_method(rb_cBasicSocket, "local_address", bsock_local_address, 0);
rb_define_method(rb_cBasicSocket, "remote_address", bsock_remote_address, 0);
rb_define_method(rb_cBasicSocket, "send", bsock_send, -1);

Просмотреть файл

@ -314,6 +314,8 @@ have_type("struct in6_pktinfo", headers) {|src|
have_type("struct sockcred", headers)
have_type("struct cmsgcred", headers)
have_func("getpeereid")
$distcleanfiles << "constants.h" << "constdefs.*"
if have_func(test_func)

Просмотреть файл

@ -384,4 +384,18 @@ class TestUNIXSocket < Test::Unit::TestCase
}
end
def test_getpeereid
Dir.mktmpdir {|d|
path = "#{d}/sock"
serv = Socket.unix_server_socket(path)
c = Socket.unix(path)
s, = serv.accept
begin
assert_equal([Process.euid, Process.egid], c.getpeereid)
assert_equal([Process.euid, Process.egid], s.getpeereid)
rescue NotImplementedError
end
}
end
end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM