svn commit: r202530 - head/lib/libc/gen

Ed Schouten ed at FreeBSD.org
Sun Jan 17 21:40:06 UTC 2010


Author: ed
Date: Sun Jan 17 21:40:05 2010
New Revision: 202530
URL: http://svn.freebsd.org/changeset/base/202530

Log:
  Perform several small cleanups to the utmpx code.
  
  - Massively reduce BSS usage. Let futx_to_utx() dynamically allocate the
    structure. There is only a very small amount of applications out there
    that needs to use the utmpx database. Wasting 1 KB on unused
    structures makes little sense.
  
  - Just let getutxid() search for matching ut_id's for any *PROCESS-type.
    This makes the code a bit more future-proof.
  
  - Fix a POSIX-mistake: when reading POSIX and the OpenSolaris
    implementation, getutxline() must return USER_PROCESS and
    LOGIN_PROCESS records whose ut_lines match. When reading POSIX, it
    seems LOGIN_PROCESS should not use ut_line at the first place. I have
    reported this issue.

Modified:
  head/lib/libc/gen/getutxent.3
  head/lib/libc/gen/getutxent.c
  head/lib/libc/gen/pututxline.c
  head/lib/libc/gen/utxdb.c
  head/lib/libc/gen/utxdb.h

Modified: head/lib/libc/gen/getutxent.3
==============================================================================
--- head/lib/libc/gen/getutxent.3	Sun Jan 17 21:26:14 2010	(r202529)
+++ head/lib/libc/gen/getutxent.3	Sun Jan 17 21:40:05 2010	(r202530)
@@ -174,7 +174,9 @@ prefix, corresponding with the device us
 session.
 If no TTY character device is used, this field is left blank.
 This field is only applicable to entries of type
-.Dv USER_PROCESS .
+.Dv USER_PROCESS 
+and
+.Dv LOGIN_PROCESS .
 .It Fa ut_host
 The network hostname of the remote system, connecting to perform a user
 login.

Modified: head/lib/libc/gen/getutxent.c
==============================================================================
--- head/lib/libc/gen/getutxent.c	Sun Jan 17 21:26:14 2010	(r202529)
+++ head/lib/libc/gen/getutxent.c	Sun Jan 17 21:40:05 2010	(r202530)
@@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$");
 
 static FILE *uf = NULL;
 static int udb;
-static struct utmpx utx;
 
 int
 setutxdb(int db, const char *file)
@@ -101,70 +100,59 @@ endutxent(void)
 	}
 }
 
-static struct futx *
-getfutxent(void)
+static int
+getfutxent(struct futx *fu)
 {
-	static struct futx fu;
 
 	if (uf == NULL)
 		setutxent();
 	if (uf == NULL)
-		return (NULL);
+		return (-1);
 
 	if (udb == UTXDB_LOG) {
 		uint16_t len;
 
 		if (fread(&len, sizeof len, 1, uf) != 1)
-			return (NULL);
+			return (-1);
 		len = be16toh(len);
-		if (len > sizeof fu) {
+		if (len > sizeof *fu) {
 			/* Forward compatibility. */
-			if (fread(&fu, sizeof fu, 1, uf) != 1)
-				return (NULL);
-			fseek(uf, len - sizeof fu, SEEK_CUR);
+			if (fread(fu, sizeof *fu, 1, uf) != 1)
+				return (-1);
+			fseek(uf, len - sizeof *fu, SEEK_CUR);
 		} else {
 			/* Partial record. */
-			memset(&fu, 0, sizeof fu);
-			if (fread(&fu, len, 1, uf) != 1)
-				return (NULL);
+			memset(fu, 0, sizeof *fu);
+			if (fread(fu, len, 1, uf) != 1)
+				return (-1);
 		}
 	} else {
-		if (fread(&fu, sizeof fu, 1, uf) != 1)
-			return (NULL);
+		if (fread(fu, sizeof *fu, 1, uf) != 1)
+			return (-1);
 	}
-	return (&fu);
+	return (0);
 }
 
 struct utmpx *
 getutxent(void)
 {
-	struct futx *fu;
+	struct futx fu;
 
-	fu = getfutxent();
-	if (fu == NULL)
+	if (getfutxent(&fu) != 0)
 		return (NULL);
-	futx_to_utx(fu, &utx);
-	return (&utx);
+	return (futx_to_utx(&fu));
 }
 
 struct utmpx *
 getutxid(const struct utmpx *id)
 {
-	struct futx *fu;
+	struct futx fu;
 
 	for (;;) {
-		fu = getfutxent();
-		if (fu == NULL)
+		if (getfutxent(&fu) != 0)
 			return (NULL);
 
-		switch (fu->fu_type) {
-		case BOOT_TIME:
-		case OLD_TIME:
-		case NEW_TIME:
-		case SHUTDOWN_TIME:
-			if (fu->fu_type == id->ut_type)
-				goto found;
-			break;
+		switch (fu.fu_type) {
 		case USER_PROCESS:
 		case INIT_PROCESS:
 		case LOGIN_PROCESS:
@@ -174,61 +162,62 @@ getutxid(const struct utmpx *id)
 			case INIT_PROCESS:
 			case LOGIN_PROCESS:
 			case DEAD_PROCESS:
-				if (memcmp(fu->fu_id, id->ut_id,
-				    MIN(sizeof fu->fu_id, sizeof id->ut_id)) == 0)
+				if (memcmp(fu.fu_id, id->ut_id,
+				    MIN(sizeof fu.fu_id, sizeof id->ut_id)) == 0)
 					goto found;
 			}
 			break;
+		default:
+			if (fu.fu_type == id->ut_type)
+				goto found;
+			break;
 		}
 	}
 
 found:
-	futx_to_utx(fu, &utx);
-	return (&utx);
+	return (futx_to_utx(&fu));
 }
 
 struct utmpx *
 getutxline(const struct utmpx *line)
 {
-	struct futx *fu;
+	struct futx fu;
 
 	for (;;) {
-		fu = getfutxent();
-		if (fu == NULL)
+		if (getfutxent(&fu) != 0)
 			return (NULL);
 
-		switch (fu->fu_type) {
+		switch (fu.fu_type) {
 		case USER_PROCESS:
 		case LOGIN_PROCESS:
-			if (strncmp(fu->fu_line, line->ut_line,
-			    MIN(sizeof fu->fu_line, sizeof line->ut_line)) == 0)
+			if (strncmp(fu.fu_line, line->ut_line,
+			    MIN(sizeof fu.fu_line, sizeof line->ut_line)) == 0)
 				goto found;
+			break;
 		}
 	}
 
 found:
-	futx_to_utx(fu, &utx);
-	return (&utx);
+	return (futx_to_utx(&fu));
 }
 
 struct utmpx *
 getutxuser(const char *user)
 {
-	struct futx *fu;
+	struct futx fu;
 
 	for (;;) {
-		fu = getfutxent();
-		if (fu == NULL)
+		if (getfutxent(&fu) != 0)
 			return (NULL);
 
-		switch (fu->fu_type) {
+		switch (fu.fu_type) {
 		case USER_PROCESS:
-			if (strncmp(fu->fu_user, user, sizeof fu->fu_user) == 0)
+			if (strncmp(fu.fu_user, user, sizeof fu.fu_user) == 0)
 				goto found;
+			break;
 		}
 	}
 
 found:
-	futx_to_utx(fu, &utx);
-	return (&utx);
+	return (futx_to_utx(&fu));
 }

Modified: head/lib/libc/gen/pututxline.c
==============================================================================
--- head/lib/libc/gen/pututxline.c	Sun Jan 17 21:26:14 2010	(r202529)
+++ head/lib/libc/gen/pututxline.c	Sun Jan 17 21:40:05 2010	(r202530)
@@ -240,7 +240,6 @@ struct utmpx *
 pututxline(const struct utmpx *utmpx)
 {
 	struct futx fu;
-	static struct utmpx ut;
 
 	utx_to_futx(utmpx, &fu);
 	
@@ -272,6 +271,5 @@ pututxline(const struct utmpx *utmpx)
 	}
 
 	utx_log_add(&fu);
-	futx_to_utx(&fu, &ut);
-	return (&ut);
+	return (futx_to_utx(&fu));
 }

Modified: head/lib/libc/gen/utxdb.c
==============================================================================
--- head/lib/libc/gen/utxdb.c	Sun Jan 17 21:26:14 2010	(r202529)
+++ head/lib/libc/gen/utxdb.c	Sun Jan 17 21:40:05 2010	(r202530)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include "namespace.h"
 #include <sys/endian.h>
 #include <sys/param.h>
+#include <stdlib.h>
 #include <string.h>
 #include <utmpx.h>
 #include "utxdb.h"
@@ -82,6 +83,8 @@ utx_to_futx(const struct utmpx *ut, stru
 	case LOGIN_PROCESS:
 		UTOF_ID(ut, fu);
 		UTOF_STRING(ut, fu, user);
+		/* XXX: bug in the specification? Needed for getutxline(). */
+		UTOF_STRING(ut, fu, line);
 		UTOF_PID(ut, fu);
 		break;
 	case DEAD_PROCESS:
@@ -118,11 +121,18 @@ utx_to_futx(const struct utmpx *ut, stru
 	(ut)->ut_tv.tv_usec = t % 1000000;				\
 } while (0)
 
-void
-futx_to_utx(const struct futx *fu, struct utmpx *ut)
+struct utmpx *
+futx_to_utx(const struct futx *fu)
 {
+	static struct utmpx *ut;
 
-	memset(ut, 0, sizeof *ut);
+	if (ut == NULL) {
+		ut = calloc(1, sizeof *ut);
+		if (ut == NULL)
+			return (NULL);
+	} else {
+		memset(ut, 0, sizeof *ut);
+	}
 
 	switch (fu->fu_type) {
 	case BOOT_TIME:
@@ -146,6 +156,8 @@ futx_to_utx(const struct futx *fu, struc
 	case LOGIN_PROCESS:
 		FTOU_ID(fu, ut);
 		FTOU_STRING(fu, ut, user);
+		/* XXX: bug in the specification? Needed for getutxline(). */
+		FTOU_STRING(fu, ut, line);
 		FTOU_PID(fu, ut);
 		break;
 	case DEAD_PROCESS:
@@ -154,9 +166,10 @@ futx_to_utx(const struct futx *fu, struc
 		break;
 	default:
 		ut->ut_type = EMPTY;
-		return;
+		return (ut);
 	}
 
 	FTOU_TYPE(fu, ut);
 	FTOU_TV(fu, ut);
+	return (ut);
 }

Modified: head/lib/libc/gen/utxdb.h
==============================================================================
--- head/lib/libc/gen/utxdb.h	Sun Jan 17 21:26:14 2010	(r202529)
+++ head/lib/libc/gen/utxdb.h	Sun Jan 17 21:40:05 2010	(r202530)
@@ -56,6 +56,6 @@ struct futx {
 } __packed;
 
 void	utx_to_futx(const struct utmpx *, struct futx *);
-void	futx_to_utx(const struct futx *, struct utmpx *);
+struct utmpx *futx_to_utx(const struct futx *);
 
 #endif /* !_UTXDB_H_ */


More information about the svn-src-all mailing list