[#16732] sharing sub-regexp — Tanaka Akira <akr@...17n.org>

Oniguruma についてひとつ要望があります。

51 messages 2002/04/03
[#16744] Re: sharing sub-regexp — "K.Kosako" <kosako@...> 2002/04/04

Tanaka Akiraさんの<hvopu1hxfyd.fsf@coulee.a02.aist.go.jp>から

[#16746] Re: sharing sub-regexp — matz@... (Yukihiro Matsumoto) 2002/04/04

まつもと ゆきひろです

[#16753] Re: sharing sub-regexp — Tanaka Akira <akr@...17n.org> 2002/04/04

In article <1017890618.302241.17865.nullmailer@ev.netlab.jp>,

[#16755] Re: sharing sub-regexp — "K.Kosako" <kosako@...> 2002/04/05

Tanaka Akiraさんの<hvo7knn93ug.fsf@coulee.a02.aist.go.jp>から

[#16756] Re: sharing sub-regexp — Tanaka Akira <akr@...17n.org> 2002/04/05

In article <20020405044506.D4784349@helium.ruby-lang.org>,

[#16822] Re: sharing sub-regexp — "K.Kosako" <kosako@...> 2002/04/10

Tanaka Akiraさんの<hvopu1e4omy.fsf@coulee.a02.aist.go.jp>から

[#16831] Re: sharing sub-regexp — Tanaka Akira <akr@...17n.org> 2002/04/10

In article <20020410025054.C8DF0915@helium.ruby-lang.org>,

[#16863] Re: sharing sub-regexp — Tanaka Akira <akr@...17n.org> 2002/04/11

In article <hvor8lnchak.fsf@coulee.a02.aist.go.jp>,

[#16877] Re: sharing sub-regexp — Shugo Maeda <shugo@...> 2002/04/12

前田です。

[#16887] Re: sharing sub-regexp — Tanaka Akira <akr@...17n.org> 2002/04/12

In article <87pu15z80q.wl@studly.priv.netlab.jp>,

[#16909] Regexp#to_s — Shugo Maeda <shugo@...> 2002/04/15

前田です。

[#16912] Re: Regexp#to_s — Tanaka Akira <akr@...17n.org> 2002/04/15

In article <87g01x1e6m.wl@studly.priv.netlab.jp>,

[#16931] Re: Regexp#to_s — Kazuhiro NISHIYAMA <zn@...> 2002/04/16

西山和広です。

[#16934] Re: Regexp#to_s — Tanaka Akira <akr@...17n.org> 2002/04/16

In article <20020416180631.988E.ZN@mbf.nifty.com>,

[#16938] Re: Regexp#to_s — Shugo Maeda <shugo@...> 2002/04/17

前田です。

[#16939] Re: Regexp#to_s — Tanaka Akira <akr@...17n.org> 2002/04/17

In article <87u1qaj0xe.wl@studly.priv.netlab.jp>,

[#16947] Re: Regexp#to_s — Shugo Maeda <shugo@...> 2002/04/18

前田です。

[#16950] Re: Regexp#to_s — matz@... (Yukihiro Matsumoto) 2002/04/18

まつもと ゆきひろです

[#16951] Re: Regexp#to_s — Tanaka Akira <akr@...17n.org> 2002/04/18

In article <1019116103.420173.12691.nullmailer@picachu.netlab.jp>,

[#16960] Re: Regexp#to_s — nobu.nakada@... 2002/04/18

なかだです。

[#16761] StringIO — tadf@...

ふなばです。

43 messages 2002/04/05
[#16786] Re: StringIO — nobu.nakada@... 2002/04/08

なかだです。

[#16802] Re: StringIO — tadf@... 2002/04/09

ふなばです。

[#16803] Re: StringIO — nobu.nakada@... 2002/04/09

なかだです。

[#16804] Re: StringIO — tadf@... 2002/04/09

ふなばです。

[#17221] Re: StringIO — Wakou Aoyama <wakou@...> 2002/05/30

青山です。

[#17230] Re: StringIO — matz@... (Yukihiro Matsumoto) 2002/05/30

まつもと ゆきひろです

[#17231] Re: StringIO — Tanaka Akira <akr@...17n.org> 2002/05/30

In article <1022740594.117106.6073.nullmailer@picachu.netlab.jp>,

[#17233] IO#size — Shugo Maeda <shugo@...> 2002/05/30

前田です。

[#17239] Re: IO#size — Tanaka Akira <akr@...17n.org> 2002/05/31

In article <874rgqdt3x.wl@studly.priv.netlab.jp>,

[#17253] Re: IO#size — Wakou Aoyama <wakou@...> 2002/05/31

青山です。

[#16790] Ruby Shim — "Akinori MUSHA" <knu@...>

 1.7 early access kit という仮称で提案した構想ですが、先ほど

27 messages 2002/04/08
[#16796] Re: Ruby Shim — Koji Arai <JCA02266@...> 2002/04/08

新井です。

[#16833] math.c 1.10 — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

23 messages 2002/04/11
[#16834] Re: math.c 1.10 — matz@... (Yukihiro Matsumoto) 2002/04/11

まつもと ゆきひろです

[#16869] Makefiles dependency — nobu.nakada@...

なかだです。

17 messages 2002/04/12

[ruby-dev:16883] Re: control uid/gid

From: nagai@...
Date: 2002-04-12 09:13:13 UTC
List: ruby-dev #16883
永井@知能.九工大です.

[ruby-dev:16609] のプランに基づいて実装してみたパッチです.
追加分はすべて Process モジュール内のモジュールとなりますから,
従来のスクリプトには影響しないはずです.
試してみていただけると助かります.

# みなさん,興味なしなのかなぁ.
# ruby-talk に流れた ruby-dev digest でも省略されてたし.(^_^;


--- ../ruby/process.c	Fri Mar 29 17:49:25 2002
+++ ./process.c	Fri Apr 12 17:40:32 2002
@@ -1135,6 +1135,66 @@
 }
 
 static VALUE
+p_sys_setuid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETUID
+    if (setuid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setruid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETRUID
+    if (setruid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_seteuid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETEUID
+    if (seteuid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setreuid(obj, rid, eid)
+    VALUE obj, rid, eid;
+{
+#if defined HAVE_SETREUID
+    if (setreuid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setresuid(obj, rid, eid, sid)
+    VALUE obj, rid, eid, sid;
+{
+#if defined HAVE_SETRESUID
+    if (setresuid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
 proc_getuid(obj)
     VALUE obj;
 {
@@ -1155,7 +1215,7 @@
     if (setreuid(uid, -1) < 0) rb_sys_fail(0);
 #elif defined HAVE_SETRUID
     if (setruid(uid) < 0) rb_sys_fail(0);
-#else
+#elif defined HAVE_SETUID
     {
 	if (geteuid() == uid) {
 	    if (setuid(uid) < 0) rb_sys_fail(0);
@@ -1164,11 +1224,204 @@
 	    rb_notimplement();
 	}
     }
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(uid);
+}
+
+static int SAVED_USER_ID;
+
+static VALUE
+p_uid_set(obj, id)
+    VALUE obj, id;
+{
+    extern int errno;
+    int uid;
+
+    uid = NUM2INT(id);
+
+    if (geteuid() == 0) { /* root-user */
+#if defined(HAVE_SETRESUID)
+      if (setresuid(uid, uid, uid) < 0) rb_sys_fail(0);
+      SAVED_USER_ID = uid;
+#elif defined HAVE_SETUID
+      if (setuid(uid) < 0) rb_sys_fail(0);
+      SAVED_USER_ID = uid;
+#elif defined HAVE_SETREUID
+      if (getuid() == uid) {
+	if (SAVED_USER_ID == uid) {
+	  if (setreuid(-1, uid) < 0) rb_sys_fail(0);
+	} else {
+	  if (uid == 0) { /* (r,e,s) == (root, root, x) */
+	    if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);
+	    if (setreuid(SAVED_USER_ID, 0) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = 0; /* (r,e,s) == (x, root, root) */
+	    if (setreuid(uid, uid) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = uid;
+	  } else {
+	    if (setreuid(0, -1) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = 0;
+	    if (setreuid(uid, uid) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = uid;
+	  }
+	}
+      } else {
+	if (setreuid(uid, uid) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+      }
+#elif defined HAVE_SETRUID && defined HAVE_SETEUID
+      if (getuid() == uid) {
+	if (SAVED_USER_ID == uid) {
+	  if (seteuid(uid) < 0) rb_sys_fail(0);
+	} else {
+	  if (uid == 0) {
+	    if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = 0;
+	    if (setruid(0) < 0) rb_sys_fail(0);
+	  } else {
+	    if (setruid(0) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = 0;
+	    if (seteuid(uid) < 0) rb_sys_fail(0);
+	    if (setruid(uid) < 0) rb_sys_fail(0);
+	    SAVED_USER_ID = uid;
+	  }
+	}
+      } else {
+	if (seteuid(uid) < 0) rb_sys_fail(0);
+	if (setruid(uid) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+      }
+#else
+      rb_notimplement();
+#endif
+    } else { /* unprivileged user */
+#if defined(HAVE_SETRESUID)
+      if (setresuid((getuid() == uid)? -1: uid, 
+		    (geteuid() == uid)? -1: uid, 
+		    (SAVED_USER_ID == uid)? -1: uid) < 0) rb_sys_fail(0);
+      SAVED_USER_ID = uid;
+#elif defined HAVE_SETREUID
+      if (SAVED_USER_ID == uid) {
+	if (setreuid((getuid() == uid)? -1: uid, 
+		     (geteuid() == uid)? -1: uid) < 0) rb_sys_fail(0);
+      } else if (getuid() != uid) {
+	if (setreuid(uid, (geteuid() == uid)? -1: uid) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+      } else if (/* getuid() == uid && */ geteuid() != uid) {
+	if (setreuid(geteuid(), uid) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+	if (setreuid(uid, -1) < 0) rb_sys_fail(0);
+      } else { /* getuid() == uid && geteuid() == uid */
+	if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);
+	if (setreuid(SAVED_USER_ID, uid) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+	if (setreuid(uid, -1) < 0) rb_sys_fail(0);
+      }
+#elif defined HAVE_SETRUID && defined HAVE_SETEUID
+      if (SAVED_USER_ID == uid) {
+	if (geteuid() != uid && seteuid(uid) < 0) rb_sys_fail(0);
+	if (getuid() != uid && setruid(uid) < 0) rb_sys_fail(0);
+      } else if (/* SAVED_USER_ID != uid && */ geteuid() == uid) {
+	if (getuid() != uid) {
+	  if (setruid(uid) < 0) rb_sys_fail(0);
+	  SAVED_USER_ID = uid;
+	} else {
+	  if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
+	  SAVED_USER_ID = uid;
+	  if (setruid(uid) < 0) rb_sys_fail(0);
+	}
+      } else if (/* geteuid() != uid && */ getuid() == uid) {
+	if (seteuid(uid) < 0) rb_sys_fail(0);
+	if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
+	SAVED_USER_ID = uid;
+	if (setruid(uid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#elif defined HAVE_SETEUID
+      if (getuid() == uid && SAVED_USER_ID == uid) {
+	if (seteuid(uid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#elif defined HAVE_SETUID
+      if (getuid() == uid && SAVED_USER_ID == uid) {
+	if (setuid(uid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#else
+      rb_notimplement();
 #endif
+    }
     return INT2FIX(uid);
 }
 
 static VALUE
+p_sys_setgid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETGID
+    if (setgid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setrgid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETRGID
+    if (setrgid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setegid(obj, id)
+    VALUE obj, id;
+{
+#if defined HAVE_SETEGID
+    if (setegid(NUM2INT(id)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setregid(obj, rid, eid)
+    VALUE obj, rid, eid;
+{
+#if defined HAVE_SETREGID
+    if (setregid(NUM2INT(rid),NUM2INT(eid)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
+p_sys_setresgid(obj, rid, eid, sid)
+    VALUE obj, rid, eid, sid;
+{
+#if defined HAVE_SETRESGID
+    if (setresgid(NUM2INT(rid),NUM2INT(eid),NUM2INT(sid)) != 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return Qnil;
+}
+
+static VALUE
 proc_getgid(obj)
     VALUE obj;
 {
@@ -1187,9 +1440,9 @@
     if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0);
 #elif defined HAVE_SETREGID
     if (setregid(gid, -1) < 0) rb_sys_fail(0);
-#elif defined HAS_SETRGID
+#elif defined HAVE_SETRGID
     if (setrgid((GIDTYPE)gid) < 0) rb_sys_fail(0);
-#else
+#elif defined HAVE_SETGID
     {
 	if (getegid() == gid) {
 	    if (setgid(gid) < 0) rb_sys_fail(0);
@@ -1198,7 +1451,141 @@
 	    rb_notimplement();
 	}
     }
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(gid);
+}
+
+static int SAVED_GROUP_ID;
+
+static VALUE
+p_gid_set(obj, id)
+    VALUE obj, id;
+{
+    extern int errno;
+    int gid;
+
+    gid = NUM2INT(id);
+
+    if (geteuid() == 0) { /* root-user */
+#if defined(HAVE_SETRESGID)
+      if (setresgid(gid, gid, gid) < 0) rb_sys_fail(0);
+      SAVED_GROUP_ID = gid;
+#elif defined HAVE_SETGID
+      if (setgid(gid) < 0) rb_sys_fail(0);
+      SAVED_GROUP_ID = gid;
+#elif defined HAVE_SETREGID
+      if (getgid() == gid) {
+	if (SAVED_GROUP_ID == gid) {
+	  if (setregid(-1, gid) < 0) rb_sys_fail(0);
+	} else {
+	  if (gid == 0) { /* (r,e,s) == (root, y, x) */
+	    if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);
+	    if (setregid(SAVED_GROUP_ID, 0) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = 0; /* (r,e,s) == (x, root, root) */
+	    if (setregid(gid, gid) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = gid;
+	  } else { /* (r,e,s) == (z, y, x) */
+	    if (setregid(0, 0) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = 0;
+	    if (setregid(gid, gid) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = gid;
+	  }
+	}
+      } else {
+	if (setregid(gid, gid) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+      }
+#elif defined HAVE_SETRGID && defined HAVE_SETEGID
+      if (getgid() == gid) {
+	if (SAVED_GROUP_ID == gid) {
+	  if (setegid(gid) < 0) rb_sys_fail(0);
+	} else {
+	  if (gid == 0) {
+	    if (setegid(gid) < 0) rb_sys_fail(0);
+	    if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = 0;
+	    if (setrgid(0) < 0) rb_sys_fail(0);
+	  } else {
+	    if (setrgid(0) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = 0;
+	    if (setegid(gid) < 0) rb_sys_fail(0);
+	    if (setrgid(gid) < 0) rb_sys_fail(0);
+	    SAVED_GROUP_ID = gid;
+	  }
+	}
+      } else {
+	if (setegid(gid) < 0) rb_sys_fail(0);
+	if (setrgid(gid) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+      }
+#else
+      rb_notimplement();
+#endif
+    } else { /* unprivileged user */
+#if defined(HAVE_SETRESGID)
+      if (setresgid((getgid() == gid)? -1: gid, 
+		    (getegid() == gid)? -1: gid, 
+		    (SAVED_GROUP_ID == gid)? -1: gid) < 0) rb_sys_fail(0);
+      SAVED_GROUP_ID = gid;
+#elif defined HAVE_SETREGID
+      if (SAVED_GROUP_ID == gid) {
+	if (setregid((getgid() == gid)? -1: gid, 
+		     (getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);
+      } else if (getgid() != gid) {
+	if (setregid(gid, (getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+      } else if (/* getgid() == gid && */ getegid() != gid) {
+	if (setregid(getegid(), gid) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+	if (setregid(gid, -1) < 0) rb_sys_fail(0);
+      } else { /* getgid() == gid && getegid() == gid */
+	if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);
+	if (setregid(SAVED_GROUP_ID, gid) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+	if (setregid(gid, -1) < 0) rb_sys_fail(0);
+      }
+#elif defined HAVE_SETRGID && defined HAVE_SETEGID
+      if (SAVED_GROUP_ID == gid) {
+	if (getegid() != gid && setegid(gid) < 0) rb_sys_fail(0);
+	if (getgid() != gid && setrgid(gid) < 0) rb_sys_fail(0);
+      } else if (/* SAVED_GROUP_ID != gid && */ getegid() == gid) {
+	if (getgid() != gid) {
+	  if (setrgid(gid) < 0) rb_sys_fail(0);
+	  SAVED_GROUP_ID = gid;
+	} else {
+	  if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
+	  SAVED_GROUP_ID = gid;
+	  if (setrgid(gid) < 0) rb_sys_fail(0);
+	}
+      } else if (/* getegid() != gid && */ getgid() == gid) {
+	if (setegid(gid) < 0) rb_sys_fail(0);
+	if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
+	SAVED_GROUP_ID = gid;
+	if (setrgid(gid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#elif defined HAVE_SETEGID
+      if (getgid() == gid && SAVED_GROUP_ID == gid) {
+	if (setegid(gid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#elif defined HAVE_SETGID
+      if (getgid() == gid && SAVED_GROUP_ID == gid) {
+	if (setgid(gid) < 0) rb_sys_fail(0);
+      } else {
+	errno = EPERM;
+	rb_sys_fail(0);
+      }
+#else
+      rb_notimplement();
 #endif
+    }
     return INT2FIX(gid);
 }
 
@@ -1220,7 +1607,7 @@
     if (setreuid(-1, NUM2INT(euid)) < 0) rb_sys_fail(0);
 #elif defined HAVE_SETEUID
     if (seteuid(NUM2INT(euid)) < 0) rb_sys_fail(0);
-#else
+#elif defined HAVE_SETUID
     euid = NUM2INT(euid);
     if (euid == getuid()) {
 	if (setuid(euid) < 0) rb_sys_fail(0);
@@ -1228,11 +1615,53 @@
     else {
 	rb_notimplement();
     }
+#else
+    rb_notimplement();
 #endif
     return euid;
 }
 
 static VALUE
+rb_seteuid_core(euid)
+    int euid;
+{
+    int uid;
+
+    uid = getuid();
+
+#if defined(HAVE_SETRESUID) && !defined(__CHECKER__)
+    if (uid != euid) {
+      if (setresuid(-1,euid,euid) < 0) rb_sys_fail(0);
+      SAVED_USER_ID = euid;
+    } else {
+      if (setresuid(-1,euid,-1) < 0) rb_sys_fail(0);
+    }
+#elif defined HAVE_SETREUID && !defined(__OpenBSD__)
+    if (setreuid(-1, euid) < 0) rb_sys_fail(0);
+    if (uid != euid) {
+      if (setreuid(euid,uid) < 0) rb_sys_fail(0);
+      if (setreuid(uid,euid) < 0) rb_sys_fail(0);
+      SAVED_USER_ID = euid;
+    }
+#elif defined HAVE_SETEUID
+    if (seteuid(euid) < 0) rb_sys_fail(0);
+#elif defined HAVE_SETUID
+    if (geteuid() == 0) rb_sys_fail(0);
+    if (setuid(euid) < 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(euid);
+}
+
+static VALUE
+p_uid_set_eid(obj, id)
+    VALUE obj, id;
+{
+  return rb_seteuid_core(NUM2INT(id));
+}
+
+static VALUE
 proc_getegid(obj)
     VALUE obj;
 {
@@ -1251,7 +1680,7 @@
     if (setregid(-1, NUM2INT(egid)) < 0) rb_sys_fail(0);
 #elif defined HAVE_SETEGID
     if (setegid(NUM2INT(egid)) < 0) rb_sys_fail(0);
-#else
+#elif defined HAVE_SETGID
     egid = NUM2INT(egid);
     if (egid == getgid()) {
 	if (setgid(egid) < 0) rb_sys_fail(0);
@@ -1259,10 +1688,224 @@
     else {
 	rb_notimplement();
     }
+#else
+    rb_notimplement();
 #endif
     return egid;
 }
 
+static VALUE
+rb_setegid_core(egid)
+    int egid;
+{
+    int gid;
+
+    gid = getgid();
+
+#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
+    if (gid != egid) {
+      if (setresgid(-1,egid,egid) < 0) rb_sys_fail(0);
+      SAVED_GROUP_ID = egid;
+    } else {
+      if (setresgid(-1,egid,-1) < 0) rb_sys_fail(0);
+    }
+#elif defined HAVE_SETREGID && !defined(__OpenBSD__)
+    if (setregid(-1, egid) < 0) rb_sys_fail(0);
+    if (gid != egid) {
+      if (setregid(egid,gid) < 0) rb_sys_fail(0);
+      if (setregid(gid,egid) < 0) rb_sys_fail(0);
+      SAVED_GROUP_ID = egid;
+    }
+#elif defined HAVE_SETEGID
+    if (setegid(egid) < 0) rb_sys_fail(0);
+#elif defined HAVE_SETGID
+    if (getegid() == 0) rb_sys_fail(0);
+    if (setgid(egid) < 0) rb_sys_fail(0);
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(egid);
+}
+
+static VALUE
+p_gid_set_eid(obj, id)
+    VALUE obj, id;
+{
+  return rb_setegid_core(NUM2INT(id));
+}
+
+static VALUE
+p_uid_exchangeable()
+{
+#if defined(HAVE_SETRESUID) &&  !defined(__CHECKER__)
+  return Qtrue;
+#elif defined HAVE_SETREUID && !defined(__OpenBSD__)
+  return Qtrue;
+#else
+  return Qfalse;
+#endif
+}
+
+static VALUE
+p_uid_exchange(obj)
+    VALUE obj;
+{
+    int uid, euid;
+
+    uid = getuid();
+    euid = geteuid();
+
+#if defined(HAVE_SETRESUID) &&  !defined(__CHECKER__)
+    if (setresuid(euid, uid, uid) < 0) rb_sys_fail(0);
+    SAVED_USER_ID = uid;
+#elif defined HAVE_SETREUID && !defined(__OpenBSD__)
+    if (setreuid(euid,uid) < 0) rb_sys_fail(0);
+    SAVED_USER_ID = uid;
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(uid);
+}
+
+static VALUE
+p_gid_exchangeable()
+{
+#if defined(HAVE_SETRESGID) &&  !defined(__CHECKER__)
+  return Qtrue;
+#elif defined HAVE_SETREGID && !defined(__OpenBSD__)
+  return Qtrue;
+#else
+  return Qfalse;
+#endif
+}
+
+static VALUE
+p_gid_exchange(obj)
+    VALUE obj;
+{
+    int gid, egid;
+
+    gid = getgid();
+    egid = getegid();
+
+#if defined(HAVE_SETRESGID) &&  !defined(__CHECKER__)
+    if (setresgid(egid, gid, gid) < 0) rb_sys_fail(0);
+    SAVED_GROUP_ID = gid;
+#elif defined HAVE_SETREGID && !defined(__OpenBSD__)
+    if (setregid(egid,gid) < 0) rb_sys_fail(0);
+    SAVED_GROUP_ID = gid;
+#else
+    rb_notimplement();
+#endif
+    return INT2FIX(gid);
+}
+
+static VALUE
+p_uid_has_saved_id()
+{
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || _POSIX_SAVED_IDS
+  return Qtrue;
+#else
+  return Qfalse;
+#endif
+}
+
+static VALUE
+p_uid_switch_auth(obj)
+    VALUE obj;
+{
+    extern int errno;
+    int uid, euid;
+
+    uid = getuid();
+    euid = geteuid();
+
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || _POSIX_SAVED_IDS
+    if (uid != euid) {
+      proc_seteuid(obj, INT2FIX(uid));
+      if (rb_block_given_p()) {
+	return rb_ensure(rb_yield, Qnil, rb_seteuid_core, SAVED_USER_ID);
+      } else {
+	return INT2FIX(euid);
+      }
+    } else if (euid != SAVED_USER_ID) {
+      proc_seteuid(obj, INT2FIX(SAVED_USER_ID));
+      if (rb_block_given_p()) {
+	return rb_ensure(rb_yield, Qnil, rb_seteuid_core, euid);
+      } else {
+	return INT2FIX(uid);
+      }
+    } else {
+      errno = EPERM;
+      rb_sys_fail(0);
+    }
+#else
+    if (uid == euid) {
+      errno = EPERM;
+      rb_sys_fail(0);
+    }
+    proc_swap_uid(obj);
+    if (rb_block_given_p()) {
+      return rb_ensure(rb_yield, Qnil, proc_swap_uid, obj);
+    } else {
+      return INT2FIX(euid);
+    }
+#endif
+}
+
+static VALUE
+p_gid_has_saved_id()
+{
+#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || _POSIX_SAVED_IDS
+  return Qtrue;
+#else
+  return Qfalse;
+#endif
+}
+
+static VALUE
+p_gid_switch_auth(obj)
+    VALUE obj;
+{
+    extern int errno;
+    int gid, egid;
+
+    gid = getgid();
+    egid = getegid();
+
+#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || _POSIX_SAVED_IDS
+    if (gid != egid) {
+      proc_setegid(obj, INT2FIX(gid));
+      if (rb_block_given_p()) {
+	return rb_ensure(rb_yield, Qnil, proc_setegid, INT2FIX(SAVED_GROUP_ID));
+      } else {
+	return INT2FIX(egid);
+      }
+    } else if (egid != SAVED_GROUP_ID) {
+      proc_setegid(obj, INT2FIX(SAVED_GROUP_ID));
+      if (rb_block_given_p()) {
+	return rb_ensure(rb_yield, Qnil, proc_setegid, INT2FIX(egid));
+      } else {
+	return INT2FIX(gid);
+      }
+    } else {
+      errno = EPERM;
+      rb_sys_fail(0);
+    }
+#else
+    if (gid == egid) {
+      errno = EPERM;
+      rb_sys_fail(0);
+    }
+    proc_swap_gid(obj);
+    if (rb_block_given_p()) {
+      return rb_ensure(rb_yield, Qnil, proc_swap_gid, obj);
+    } else {
+      return INT2FIX(egid);
+    }
+#endif
+}
+
 VALUE
 rb_proc_times(obj)
     VALUE obj;
@@ -1289,6 +1932,9 @@
 }
 
 VALUE rb_mProcess;
+VALUE rb_mProcUID;
+VALUE rb_mProcGID;
+VALUE rb_mProcID_Syscall;
 
 void
 Init_process()
@@ -1378,4 +2024,60 @@
 #if defined(HAVE_TIMES) || defined(NT)
     S_Tms = rb_struct_define("Tms", "utime", "stime", "cutime", "cstime", 0);
 #endif
+
+    SAVED_USER_ID = geteuid();
+    SAVED_GROUP_ID = getegid();
+
+    rb_mProcUID = rb_define_module_under(rb_mProcess, "UserID");
+    rb_mProcGID = rb_define_module_under(rb_mProcess, "GroupID");
+
+    rb_define_module_function(rb_mProcUID, "real_id", proc_getuid, 0);
+    rb_define_module_function(rb_mProcGID, "real_id", proc_getgid, 0);
+    rb_define_module_function(rb_mProcUID, "effective_id", proc_geteuid, 0);
+    rb_define_module_function(rb_mProcGID, "effective_id", proc_getegid, 0);
+    rb_define_module_function(rb_mProcUID, "set", p_uid_set, 1);
+    rb_define_module_function(rb_mProcGID, "set", p_gid_set, 1);
+    rb_define_module_function(rb_mProcUID, "set_effective", p_uid_set_eid, 1);
+    rb_define_module_function(rb_mProcGID, "set_effective", p_gid_set_eid, 1);
+    rb_define_module_function(rb_mProcUID, "exchange_reid", p_uid_exchange, 0);
+    rb_define_module_function(rb_mProcGID, "exchange_reid", p_gid_exchange, 0);
+    rb_define_module_function(rb_mProcUID, "exchangeable?", 
+			      p_uid_exchangeable, 0);
+    rb_define_module_function(rb_mProcGID, "exchangealbe?", 
+			      p_gid_exchangeable, 0);
+    rb_define_module_function(rb_mProcUID, "has_saved_id?", 
+			      p_uid_has_saved_id, 0);
+    rb_define_module_function(rb_mProcGID, "has_saved_id?", 
+			      p_gid_has_saved_id, 0);
+    rb_define_module_function(rb_mProcUID, "switch_auth", 
+			      p_uid_switch_auth, 0);
+    rb_define_module_function(rb_mProcGID, "switch_auth", 
+			      p_uid_switch_auth, 0);
+
+    rb_mProcID_Syscall = rb_define_module_under(rb_mProcess, "ID_Syscall");
+
+    rb_define_module_function(rb_mProcID_Syscall, "getuid", proc_getuid, 0);
+    rb_define_module_function(rb_mProcID_Syscall, "geteuid", proc_geteuid, 0);
+    rb_define_module_function(rb_mProcID_Syscall, "getgid", proc_getgid, 0);
+    rb_define_module_function(rb_mProcID_Syscall, "getegid", proc_getegid, 0);
+
+    rb_define_module_function(rb_mProcID_Syscall, "setuid", p_sys_setuid, 1);
+    rb_define_module_function(rb_mProcID_Syscall, "setgid", p_sys_setgid, 1);
+
+    rb_define_module_function(rb_mProcID_Syscall, "setruid", p_sys_setruid, 1);
+    rb_define_module_function(rb_mProcID_Syscall, "setrgid", p_sys_setrgid, 1);
+
+    rb_define_module_function(rb_mProcID_Syscall, "seteuid", p_sys_seteuid, 1);
+    rb_define_module_function(rb_mProcID_Syscall, "setegid", p_sys_setegid, 1);
+
+    rb_define_module_function(rb_mProcID_Syscall, "setreuid", 
+			      p_sys_setreuid, 2);
+    rb_define_module_function(rb_mProcID_Syscall, "setregid", 
+			      p_sys_setregid, 2);
+
+    rb_define_module_function(rb_mProcID_Syscall, "setresuid", 
+			      p_sys_setresuid, 3);
+    rb_define_module_function(rb_mProcID_Syscall, "setresgid", 
+			      p_sys_setresgid, 3);
+
 }


-- 
                                         永井 秀利 (九工大 知能情報)
                                             nagai@ai.kyutech.ac.jp

In This Thread