public UnixGroupInfo (uint group)
		{
			this.group = new Group ();
			Group gr;
			int r = Syscall.getgrgid_r (group, this.group, out gr);
			if (r != 0 || gr == null)
				throw new ArgumentException (Locale.GetText ("invalid group id"), "group");
		}
		public static Group fgetgrent (IntPtr stream)
		{
			_Group group;
			int r;
			lock (grp_lock) {
				r = sys_fgetgrent (stream, out group);
			}
			if (r != 0)
				return null;
			Group gr = new Group ();
			CopyGroup (gr, ref group);
			return gr;
		}
		public static Group getgrent ()
		{
			_Group group;
			int r;
			lock (grp_lock) {
				r = sys_getgrent (out group);
			}
			if (r != 0)
				return null;
			Group gr = new Group();
			CopyGroup (gr, ref group);
			return gr;
		}
		public static int getgrgid_r (uint uid, Group grbuf, out Group grbufp)
		{
			grbufp = null;
			_Group group;
			IntPtr _grbufp;
			int r = sys_getgrgid_r (uid, out group, out _grbufp);
			if (r == 0 && _grbufp != IntPtr.Zero) {
				CopyGroup (grbuf, ref group);
				grbufp = grbuf;
			}
			return r;
		}
		public static int getgrnam_r (string name, Group grbuf, out Group grbufp)
		{
			grbufp = null;
			_Group group;
			IntPtr _grbufp;
			int r = sys_getgrnam_r (name, out group, out _grbufp);
			if (r == 0 && _grbufp != IntPtr.Zero) {
				CopyGroup (grbuf, ref group);
				grbufp = grbuf;
			}
			return r;
		}
		public static Group getgrnam (string name)
		{
			_Group group;
			int r;
			lock (grp_lock) {
				r = sys_getgrnam (name, out group);
			}
			if (r != 0)
				return null;
			Group gr = new Group ();
			CopyGroup (gr, ref group);
			return gr;
		}
		private static void CopyGroup (Group to, ref _Group from)
		{
			try {
				to.gr_gid    = from.gr_gid;
				to.gr_name   = UnixMarshal.PtrToString (from.gr_name);
				to.gr_passwd = UnixMarshal.PtrToString (from.gr_passwd);
				to.gr_mem    = UnixMarshal.PtrToStringArray (from._gr_nmem_, from.gr_mem);
			}
			finally {
				Stdlib.free (from.gr_mem);
				Stdlib.free (from._gr_buf_);
				from.gr_mem   = IntPtr.Zero;
				from._gr_buf_ = IntPtr.Zero;
			}
		}
		public void Equality ()
		{
			Group orig = new Group ();
			Group mod  = new Group ();
			mod.gr_name   = orig.gr_name   = "some name";
			mod.gr_passwd = orig.gr_passwd = "some passwd";
			mod.gr_gid    = orig.gr_gid    = 500;
			mod.gr_mem    = orig.gr_mem    = new string[]{"foo", "bar"};

			Assert.AreEqual (orig, mod, "#TE: copies should be equal");

			mod.gr_name = "another name";
			Assert.IsFalse (orig.Equals (mod), "#TE: changes should be reflected");
		}
		public UnixGroupInfo (Group group)
		{
			this.group = group;
		}