Loading...
gen/NetBSD/utmpx.c.patch Libc-498 Libc-583
--- Libc/Libc-498/gen/NetBSD/utmpx.c.patch
+++ Libc/Libc-583/gen/NetBSD/utmpx.c.patch
@@ -1,6 +1,6 @@
---- utmpx.c.orig	2006-02-06 00:43:57.000000000 -0800
-+++ utmpx.c	2006-02-06 00:51:52.000000000 -0800
-@@ -49,34 +49,27 @@
+--- utmpx.c.orig	2009-04-01 04:01:12.000000000 -0700
++++ utmpx.c	2009-04-01 04:09:50.000000000 -0700
+@@ -49,48 +49,57 @@ __RCSID("$NetBSD: utmpx.c,v 1.21 2003/09
  #include <sys/time.h>
  #include <sys/wait.h>
  
@@ -12,9 +12,11 @@
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
++#ifdef LEGACY_UTMP_APIS
  #include <utmp.h>
 -/* don't define earlier, has side effects in fcntl.h */
 -#define __LIBC12_SOURCE__
++#endif /* LEGACY_UTMP_APIS */
  #include <utmpx.h>
 +#include <utmpx-darwin.h>
 +#include <errno.h>
@@ -32,6 +34,7 @@
  static char utfile[MAXPATHLEN] = _PATH_UTMPX;
 -static char llfile[MAXPATHLEN] = _PATH_LASTLOGX;
 +__private_extern__ int utfile_system = 1; /* are we using _PATH_UTMPX? */
++__private_extern__ pthread_mutex_t utmpx_mutex = PTHREAD_MUTEX_INITIALIZER;
  
 -static struct utmpx *utmp_update(const struct utmpx *);
 +static struct utmpx *_getutxid(const struct utmpx *);
@@ -39,9 +42,12 @@
 -static const char vers[] = "utmpx-1.00";
 +__private_extern__ const char _utmpx_vers[] = "utmpx-1.00";
  
- void
- setutxent()
-@@ -85,7 +78,11 @@
+-void
+-setutxent()
++__private_extern__ void
++_setutxent()
+ {
+ 
  	(void)memset(&ut, 0, sizeof(ut));
  	if (fp == NULL)
  		return;
@@ -53,17 +59,56 @@
  }
  
  
-@@ -105,6 +102,9 @@
- struct utmpx *
- getutxent()
- {
+ void
+-endutxent()
++setutxent()
++{
++	UTMPX_LOCK;
++	_setutxent();
++	UTMPX_UNLOCK;
++}
++
++
++__private_extern__ void
++_endutxent()
+ {
+ 
+ 	(void)memset(&ut, 0, sizeof(ut));
+@@ -102,9 +111,21 @@ endutxent()
+ }
+ 
+ 
+-struct utmpx *
+-getutxent()
++void
++endutxent()
+ {
++	UTMPX_LOCK;
++	_endutxent();
++	UTMPX_UNLOCK;
++}
++
++
++static struct utmpx *
++_getutxent()
++{
 +#ifdef __LP64__
 +	struct utmpx32 ut32;
 +#endif /* __LP64__ */
  
  	if (fp == NULL) {
  		struct stat st;
-@@ -124,42 +124,80 @@
+@@ -116,7 +137,8 @@ getutxent()
+ 				else
+ 					readonly = 1;
+ 			}
+-					
++
++		fcntl(fileno(fp), F_SETFD, 1); /* set close-on-exec flag */
+ 
+ 		/* get file size in order to check if new file */
+ 		if (fstat(fileno(fp), &st) == -1)
+@@ -124,27 +146,51 @@ getutxent()
  
  		if (st.st_size == 0) {
  			/* new file, add signature record */
@@ -117,26 +162,42 @@
  fail:
  	(void)memset(&ut, 0, sizeof(ut));
  	return NULL;
- }
- 
--
+@@ -152,14 +198,45 @@ fail:
+ 
+ 
  struct utmpx *
++getutxent()
++{
++	struct utmpx *ret;
++	UTMPX_LOCK;
++	ret = _getutxent();
++	UTMPX_UNLOCK;
++	return ret;
++}
++
++struct utmpx *
  getutxid(const struct utmpx *utx)
  {
 +	struct utmpx temp;
 +	const struct utmpx *ux;
++	struct utmpx *ret;
  
  	_DIAGASSERT(utx != NULL);
  
  	if (utx->ut_type == EMPTY)
  		return NULL;
  
++	UTMPX_LOCK;
 +	/* make a copy as needed, and auto-fill if requested */
 +	ux = _utmpx_working_copy(utx, &temp, 1);
-+	if (!ux)
++	if (!ux) {
++		UTMPX_UNLOCK;
 +		return NULL;
-+
-+	return _getutxid(ux);
++	}
++
++	ret = _getutxid(ux);
++	UTMPX_UNLOCK;
++	return ret;
 +}
 +
 +
@@ -147,7 +208,43 @@
  	do {
  		if (ut.ut_type == EMPTY)
  			continue;
-@@ -225,30 +263,68 @@
+@@ -193,7 +270,7 @@ getutxid(const struct utmpx *utx)
+ 		default:
+ 			return NULL;
+ 		}
+-	} while (getutxent() != NULL);
++	} while (_getutxent() != NULL);
+ 	return NULL;
+ }
+ 
+@@ -204,6 +281,7 @@ getutxline(const struct utmpx *utx)
+ 
+ 	_DIAGASSERT(utx != NULL);
+ 
++	UTMPX_LOCK;
+ 	do {
+ 		switch (ut.ut_type) {
+ 		case EMPTY:
+@@ -211,13 +289,16 @@ getutxline(const struct utmpx *utx)
+ 		case LOGIN_PROCESS:
+ 		case USER_PROCESS:
+ 			if (strncmp(ut.ut_line, utx->ut_line,
+-			    sizeof(ut.ut_line)) == 0)
++			    sizeof(ut.ut_line)) == 0) {
++				UTMPX_UNLOCK;
+ 				return &ut;
++			}
+ 			break;
+ 		default:
+ 			break;
+ 		}
+-	} while (getutxent() != NULL);
++	} while (_getutxent() != NULL);
++	UTMPX_UNLOCK;
+ 	return NULL;
+ }
+ 
+@@ -225,156 +306,180 @@ getutxline(const struct utmpx *utx)
  struct utmpx *
  pututxline(const struct utmpx *utx)
  {
@@ -166,15 +263,19 @@
 -	if (strcmp(_PATH_UTMPX, utfile) == 0)
 -		if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
 -			return utmp_update(utx);
+-
++	UTMPX_LOCK;
 +	if ((ux = _pututxline(utx)) != NULL && utfile_system) {
 +		_utmpx_asl(ux);	/* the equivalent of wtmpx and lastlogx */
 +#ifdef UTMP_COMPAT
 +		_write_utmp_compat(ux);
 +#endif /* UTMP_COMPAT */
 +	}
++	UTMPX_UNLOCK;
 +	return ux;
 +}
  
+-	(void)memcpy(&temp, utx, sizeof(temp));
 +__private_extern__ struct utmpx *
 +_pututxline(const struct utmpx *utx)
 +{
@@ -183,9 +284,10 @@
 +#ifdef __LP64__
 +	struct utmpx32 ut32;
 +#endif /* __LP64__ */
-+	int gotlock = 0;
- 
--	(void)memcpy(&temp, utx, sizeof(temp));
++	struct flock fl;
++#define gotlock		(fl.l_start >= 0)
++
++	fl.l_start = -1; /* also means we haven't locked */
 +	if (utfile_system)
 +		if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) {
 +			errno = EPERM;
@@ -193,8 +295,9 @@
 +		}
  
  	if (fp == NULL) {
- 		(void)getutxent();
+-		(void)getutxent();
 -		if (fp == NULL || readonly)
++		(void)_getutxent();
 +		if (fp == NULL || readonly) {
 +			errno = EPERM;
  			return NULL;
@@ -202,14 +305,16 @@
  	}
  
 -	if (getutxid(&temp) == NULL) {
+-		setutxent();
+-		if (getutxid(&temp) == NULL) {
+-			if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
 +	/* make a copy as needed, and auto-fill if requested */
 +	ux = _utmpx_working_copy(utx, &temp, 0);
 +	if (!ux)
 +		return NULL;
 +
 +	if ((x = _getutxid(ux)) == NULL) {
- 		setutxent();
--		if (getutxid(&temp) == NULL) {
++		_setutxent();
 +		if ((x = _getutxid(ux)) == NULL) {
 +			/*
 +			 * utx->ut_type has any original mask bits, while
@@ -223,10 +328,21 @@
 +				errno = EINVAL;
 +				return NULL;
 +			}
- 			if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
++			/*
++			 * Replace lockf() with fcntl() and a fixed start
++			 * value.  We should already be at EOF.
++			 */
++			if ((fl.l_start = lseek(fileno(fp), 0, SEEK_CUR)) < 0)
++				return NULL;
++			fl.l_len = 0;
++			fl.l_whence = SEEK_SET;
++			fl.l_type = F_WRLCK;
++			if (fcntl(fileno(fp), F_SETLKW, &fl) == -1)
  				return NULL;
- 			gotlock++;
-@@ -258,99 +334,66 @@
+-			gotlock++;
+ 			if (fseeko(fp, (off_t)0, SEEK_END) == -1)
+ 				goto fail;
+ 		}
  	}
  
  	if (!gotlock) {
@@ -269,8 +385,10 @@
 +	notify_post(UTMPX_CHANGE_NOTIFICATION);
  fail:
  	if (gotlock) {
+-		if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
 +		int save = errno;
- 		if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
++		fl.l_type = F_UNLCK;
++		if (fcntl(fileno(fp), F_SETLK, &fl) == -1)
  			return NULL;
 +		errno = save;
  	}
@@ -350,24 +468,41 @@
  	size_t len;
  
 -	_DIAGASSERT(fname != NULL);
++	UTMPX_LOCK;
 +	if (fname == NULL) {
 +		strcpy(utfile, _PATH_UTMPX);
 +		utfile_system = 1;
-+		endutxent();
++		_endutxent();
++		UTMPX_UNLOCK;
 +		return 1;
 +	}
  
  	len = strlen(fname);
  
-@@ -363,6 +406,7 @@
+-	if (len >= sizeof(utfile))
++	if (len >= sizeof(utfile)) {
++		UTMPX_UNLOCK;
+ 		return 0;
++	}
+ 
+ 	/* must end in x! */
+-	if (fname[len - 1] != 'x')
++	if (fname[len - 1] != 'x') {
++		UTMPX_UNLOCK;
+ 		return 0;
++	}
  
  	(void)strlcpy(utfile, fname, sizeof(utfile));
- 	endutxent();
+-	endutxent();
++	_endutxent();
 +	utfile_system = 0;
++	UTMPX_UNLOCK;
  	return 1;
  }
  
-@@ -371,10 +415,8 @@
+-
++#ifdef LEGACY_UTMP_APIS
+ void
  getutmp(const struct utmpx *ux, struct utmp *u)
  {
  
@@ -380,7 +515,7 @@
  	(void)memcpy(u->ut_line, ux->ut_line, sizeof(u->ut_line));
  	(void)memcpy(u->ut_host, ux->ut_host, sizeof(u->ut_host));
  	u->ut_time = ux->ut_tv.tv_sec;
-@@ -384,109 +426,15 @@
+@@ -384,109 +489,16 @@ void
  getutmpx(const struct utmp *u, struct utmpx *ux)
  {
  
@@ -496,3 +631,4 @@
 -	(db->close)(db);
 -	return error;
  }
++#endif /* LEGACY_UTMP_APIS */