[前][次][番号順一覧][スレッド一覧]

ruby-changes:33211

From: nobu <ko1@a...>
Date: Sat, 8 Mar 2014 13:31:03 +0900 (JST)
Subject: [ruby-changes:33211] nobu:r45290 (trunk): process.c: expand buffer on ERANGE

nobu	2014-03-08 13:30:56 +0900 (Sat, 08 Mar 2014)

  New Revision: 45290

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45290

  Log:
    process.c: expand buffer on ERANGE
    
    * process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r()
      may need larger buffers than sysconf values, so retry with
      expanding the buffer when ERANGE is returned.
      [ruby-core:61325] [Bug #9600]

  Modified files:
    trunk/ChangeLog
    trunk/process.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45289)
+++ ChangeLog	(revision 45290)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Mar  8 13:30:39 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* process.c (obj2uid, obj2gid): now getpwnam_r() and getgrnam_r()
+	  may need larger buffers than sysconf values, so retry with
+	  expanding the buffer when ERANGE is returned.
+	  [ruby-core:61325] [Bug #9600]
+
 Sat Mar  8 07:35:40 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* enum.c (find_i): yield multiple values instead of a packed
Index: process.c
===================================================================
--- process.c	(revision 45289)
+++ process.c	(revision 45290)
@@ -153,6 +153,7 @@ static void check_gid_switch(void); https://github.com/ruby/ruby/blob/trunk/process.c#L153
 #  define USE_GETPWNAM_R 1
 #  define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX)
 #  define GETPW_R_SIZE_DEFAULT 0x1000
+#  define GETPW_R_SIZE_LIMIT  0x10000
 # endif
 # ifdef USE_GETPWNAM_R
 #   define PREPARE_GETPWNAM \
@@ -192,6 +193,7 @@ static rb_uid_t obj2uid(VALUE id); https://github.com/ruby/ruby/blob/trunk/process.c#L193
 #  define USE_GETGRNAM_R
 #  define GETGR_R_SIZE_INIT sysconf(_SC_GETGR_R_SIZE_MAX)
 #  define GETGR_R_SIZE_DEFAULT 0x1000
+#  define GETGR_R_SIZE_LIMIT  0x10000
 # endif
 # ifdef USE_GETGRNAM_R
 #   define PREPARE_GETGRNAM \
@@ -4741,8 +4743,17 @@ obj2uid(VALUE id https://github.com/ruby/ruby/blob/trunk/process.c#L4743
 	    getpw_buf = RSTRING_PTR(*getpw_tmp);
 	    getpw_buf_len = rb_str_capacity(*getpw_tmp);
 	}
-	if (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr))
-	    rb_sys_fail("getpwnam_r");
+	errno = ERANGE;
+	/* gepwnam_r() on MacOS X doesn't set errno if buffer size is insufficient */
+	while (getpwnam_r(usrname, &pwbuf, getpw_buf, getpw_buf_len, &pwptr)) {
+	    if (errno != ERANGE || getpw_buf_len >= GETPW_R_SIZE_LIMIT) {
+		rb_free_tmp_buffer(getpw_tmp);
+		rb_sys_fail("getpwnam_r");
+	    }
+	    rb_str_modify_expand(*getpw_tmp, getpw_buf_len);
+	    getpw_buf = RSTRING_PTR(*getpw_tmp);
+	    getpw_buf_len = rb_str_capacity(*getpw_tmp);
+	}
 #else
 	pwptr = getpwnam(usrname);
 #endif
@@ -4810,8 +4821,17 @@ obj2gid(VALUE id https://github.com/ruby/ruby/blob/trunk/process.c#L4821
 	    getgr_buf = RSTRING_PTR(*getgr_tmp);
 	    getgr_buf_len = rb_str_capacity(*getgr_tmp);
 	}
-	if (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr))
-	    rb_sys_fail("getgrnam_r");
+	errno = ERANGE;
+	/* gegrnam_r() on MacOS X doesn't set errno if buffer size is insufficient */
+	while (getgrnam_r(grpname, &grbuf, getgr_buf, getgr_buf_len, &grptr)) {
+	    if (errno != ERANGE || getgr_buf_len >= GETGR_R_SIZE_LIMIT) {
+		rb_free_tmp_buffer(getgr_tmp);
+		rb_sys_fail("getgrnam_r");
+	    }
+	    rb_str_modify_expand(*getgr_tmp, getgr_buf_len);
+	    getgr_buf = RSTRING_PTR(*getgr_tmp);
+	    getgr_buf_len = rb_str_capacity(*getgr_tmp);
+	}
 #else
 	grptr = getgrnam(grpname);
 #endif

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]