From 54dd05b8ec2e128f2139dcd9ba24f48caefd69cd Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Mon, 8 Mar 2021 08:01:46 +0100
Subject: [PATCH] libpthread: Implement pthread_[gs]etname_np().

---
 include/pthread_np.h                 |  2 +
 lib/libc/include/namespace.h         |  4 +-
 lib/libc/include/un-namespace.h      |  4 +-
 lib/libpthread/Makefile              |  2 +
 lib/libpthread/pthread_set_name_np.3 | 56 +++++++++++++++++++++++---
 lib/libthread_xu/pthread.map         |  2 +
 lib/libthread_xu/thread/thr_info.c   | 60 +++++++++++++++++++++-------
 7 files changed, 108 insertions(+), 22 deletions(-)

diff --git a/include/pthread_np.h b/include/pthread_np.h
index 7494d632c44..197cec4109d 100644
--- a/include/pthread_np.h
+++ b/include/pthread_np.h
@@ -68,7 +68,9 @@ int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
 void pthread_resume_all_np(void);
 int pthread_resume_np(pthread_t);
 void pthread_get_name_np(pthread_t, char *, size_t);
+int pthread_getname_np(pthread_t, char *, size_t);
 void pthread_set_name_np(pthread_t, const char *);
+int pthread_setname_np(pthread_t, const char *);
 int pthread_setaffinity_np(pthread_t, size_t, const cpu_set_t *);
 int pthread_single_np(void);
 void pthread_suspend_all_np(void);
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index ec7d9483b4b..8f41a889370 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -130,10 +130,12 @@
 #define		pthread_detach			_pthread_detach
 #define		pthread_equal			_pthread_equal
 #define		pthread_exit			_pthread_exit
+#define		pthread_get_name_np		_pthread_get_name_np
 #define		pthread_getaffinity_np		_pthread_getaffinity_np
 #define		pthread_getattr_np		_pthread_getattr_np
 #define		pthread_getconcurrency		_pthread_getconcurrency
 #define		pthread_getcpuclockid		_pthread_getcpuclockid
+#define		pthread_getname_np		_pthread_getname_np
 #define		pthread_getprio			_pthread_getprio
 #define		pthread_getschedparam		_pthread_getschedparam
 #define		pthread_getspecific		_pthread_getspecific
@@ -182,12 +184,12 @@
 #define		pthread_rwlockattr_init		_pthread_rwlockattr_init
 #define		pthread_rwlockattr_setpshared	_pthread_rwlockattr_setpshared
 #define		pthread_self			_pthread_self
-#define		pthread_get_name_np		_pthread_get_name_np
 #define		pthread_set_name_np		_pthread_set_name_np
 #define		pthread_setaffinity_np		_pthread_setaffinity_np
 #define		pthread_setcancelstate		_pthread_setcancelstate
 #define		pthread_setcanceltype		_pthread_setcanceltype
 #define		pthread_setconcurrency		_pthread_setconcurrency
+#define		pthread_setname_np		_pthread_setname_np
 #define		pthread_setprio			_pthread_setprio
 #define		pthread_setschedparam		_pthread_setschedparam
 #define		pthread_setspecific		_pthread_setspecific
diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h
index 22b92b1eedf..5ea55bb91e5 100644
--- a/lib/libc/include/un-namespace.h
+++ b/lib/libc/include/un-namespace.h
@@ -111,10 +111,12 @@
 #undef		pthread_detach
 #undef		pthread_equal
 #undef		pthread_exit
+#undef		pthread_get_name_np
 #undef		pthread_getaffinity_np
 #undef		pthread_getattr_np
 #undef		pthread_getconcurrency
 #undef		pthread_getcpuclockid
+#undef		pthread_getname_np
 #undef		pthread_getprio
 #undef		pthread_getschedparam
 #undef		pthread_getspecific
@@ -163,12 +165,12 @@
 #undef		pthread_rwlockattr_init
 #undef		pthread_rwlockattr_setpshared
 #undef		pthread_self
-#undef		pthread_get_name_np
 #undef		pthread_set_name_np
 #undef		pthread_setaffinity_np
 #undef		pthread_setcancelstate
 #undef		pthread_setcanceltype
 #undef		pthread_setconcurrency
+#undef		pthread_setname_np
 #undef		pthread_setprio
 #undef		pthread_setschedparam
 #undef		pthread_setspecific
diff --git a/lib/libpthread/Makefile b/lib/libpthread/Makefile
index 55ee04fbb90..7230df2bc8e 100644
--- a/lib/libpthread/Makefile
+++ b/lib/libpthread/Makefile
@@ -140,6 +140,8 @@ MLINKS+= \
 	pthread_schedparam.3 pthread_setschedparam.3 \
 	pthread_setaffinity_np.3 pthread_getaffinity_np.3 \
 	pthread_set_name_np.3 pthread_get_name_np.3 \
+	pthread_set_name_np.3 pthread_getname_np.3 \
+	pthread_set_name_np.3 pthread_setname_np.3 \
 	pthread_spin_init.3 pthread_spin_destroy.3 \
 	pthread_spin_lock.3 pthread_spin_trylock.3 \
 	pthread_spin_lock.3 pthread_spin_unlock.3 \
diff --git a/lib/libpthread/pthread_set_name_np.3 b/lib/libpthread/pthread_set_name_np.3
index 3270576d4ad..60ae427d168 100644
--- a/lib/libpthread/pthread_set_name_np.3
+++ b/lib/libpthread/pthread_set_name_np.3
@@ -24,12 +24,14 @@
 .\"
 .\" $FreeBSD: src/share/man/man3/pthread_set_name_np.3,v 1.6 2007/10/22 10:08:01 ru Exp $
 .\"
-.Dd May 2, 2019
+.Dd March 8, 2021
 .Dt PTHREAD_SET_NAME_NP 3
 .Os
 .Sh NAME
-.Nm pthread_set_name_np
+.Nm pthread_set_name_np ,
+.Nm pthread_setname_np ,
 .Nm pthread_get_name_np
+.Nm pthread_getname_np ,
 .Nd set and get the thread name
 .Sh LIBRARY
 .Lb libpthread
@@ -38,12 +40,18 @@
 .In pthread_np.h
 .Ft void
 .Fn pthread_set_name_np "pthread_t tid" "const char *name"
+.Ft int
+.Fn pthread_setname_np "pthread_t tid" "const char *name"
 .Ft void
 .Fn pthread_get_name_np "pthread_t tid" "char *name" "size_t len"
+.Ft int
+.Fn pthread_getname_np "pthread_t tid" "char *name" "size_t len"
 .Sh DESCRIPTION
 The
 .Fn pthread_set_name_np
-function sets the internal name of the thread specified by the
+and
+.Fn pthread_setname_np
+functions set the internal name of the thread specified by the
 .Fa tid
 argument to the string value specified by the
 .Fa name
@@ -51,13 +59,49 @@ argument.
 .Pp
 The
 .Fn pthread_get_name_np
-function gets the internal name of the thread specified by the
+and
+.Fn pthread_getname_np
+functions get the internal name of the thread specified by the
 .Fa tid
-argument and stores it in the buffer.
+argument and store it in the buffer.
 If the thread does not exist, the buffer is written as an empty line.
 .Sh ERRORS
-All errors that may appear inside are silently ignored.
+The
+.Nm pthread_getname_np
+and
+.Nm pthread_setname_np
+functions will fail if
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa tid
+argment specifies an invalid thread.
+.It Bq Er ESRCH
+No thread could be found in the current process corresponding to that
+specified by the given thread ID
+.Fa thread .
+.El
+.Pp
+Because of the debugging nature of
+.Nm pthread_get_name_np
+and
+.Nm pthread_set_name_np
+functions, all errors that may appear inside are silently ignored.
 However, errno may still be set.
+.Sh SEE ALSO
+.Xr lwp_setname 2
+.Sh STANDARDS
+The
+.Fn pthread_set_name_np
+and
+.Fn pthread_get_name_np
+functions are non-standard extensions.
+While also non-standard,
+.Fn pthread_setname_np
+and
+.Fn pthread_getname_np
+are implemented by larger number of operating
+systems so they are in fact more portable.
 .Sh AUTHORS
 This manual page was written by
 .An Alexey Zelkin Aq Mt phantom@FreeBSD.org .
diff --git a/lib/libthread_xu/pthread.map b/lib/libthread_xu/pthread.map
index e43222c9bed..396a9dd8238 100644
--- a/lib/libthread_xu/pthread.map
+++ b/lib/libthread_xu/pthread.map
@@ -412,4 +412,6 @@ LIBTHREAD_1_3 {
 global:
 	_clock_nanosleep
 	clock_nanosleep
+	pthread_getname_np;
+	pthread_setname_np;
 };
diff --git a/lib/libthread_xu/thread/thr_info.c b/lib/libthread_xu/thread/thr_info.c
index 76ddce9e506..ef4f3178b6c 100644
--- a/lib/libthread_xu/thread/thr_info.c
+++ b/lib/libthread_xu/thread/thr_info.c
@@ -41,47 +41,79 @@
 #include "thr_private.h"
 
 /* Set the thread name for debug. */
-void
-_pthread_set_name_np(pthread_t thread, const char *name)
+int
+_pthread_setname_np(pthread_t thread, const char *name)
 {
 	pthread_t curthread = tls_get_curthread();
+	int error;
+	int result;
 
+	result = 0;
 	if (curthread == thread) {
-		lwp_setname(thread->tid, name);
+		if (lwp_setname(thread->tid, name) == -1)
+			result = errno;
 	} else {
-		if (_thr_ref_add(curthread, thread, 0) == 0) {
+		if ((error = _thr_ref_add(curthread, thread, 0)) == 0) {
 			THR_THREAD_LOCK(curthread, thread);
-			if (thread->state != PS_DEAD)
-				lwp_setname(thread->tid, name);
+			if (thread->state != PS_DEAD) {
+				if (lwp_setname(thread->tid, name) == -1)
+					result = errno;
+			}
 			THR_THREAD_UNLOCK(curthread, thread);
 			_thr_ref_delete(curthread, thread);
+		} else {
+			result = error;
 		}
 	}
+	return (result);
 }
 
-/* Set the thread name for debug. */
 void
-_pthread_get_name_np(pthread_t thread, char *name, size_t len)
+_pthread_set_name_np(pthread_t thread, const char *name)
+{
+	(void)_pthread_setname_np(thread, name);
+}
+
+/* Set the thread name for debug. */
+int
+_pthread_getname_np(pthread_t thread, char *name, size_t len)
 {
 	pthread_t curthread = tls_get_curthread();
+	int error;
+	int result;
 
+	result = 0;
 	if (curthread == thread) {
-		lwp_getname(thread->tid, name, len);
+		if (lwp_getname(thread->tid, name, len) == -1)
+			result = errno;
 	} else {
-		if (_thr_ref_add(curthread, thread, 0) == 0) {
+		if ((error = _thr_ref_add(curthread, thread, 0)) == 0) {
 			THR_THREAD_LOCK(curthread, thread);
-			if (thread->state != PS_DEAD)
-				lwp_getname(thread->tid, name, len);
-			else if (len)
+			if (thread->state != PS_DEAD) {
+				if (lwp_getname(thread->tid, name, len) == -1)
+					result = errno;
+			} else if (len) {
 				name[0] = 0;
+			}
 			THR_THREAD_UNLOCK(curthread, thread);
 			_thr_ref_delete(curthread, thread);
 		} else if (len) {
-			errno = EINVAL;
+			result = errno = EINVAL;
 			name[0] = 0;
+		} else {
+			result = error;
 		}
 	}
+	return (result);
+}
+
+void
+_pthread_get_name_np(pthread_t thread, char *buf, size_t len)
+{
+	(void)_pthread_getname_np(thread, buf, len);
 }
 
 __strong_reference(_pthread_get_name_np, pthread_get_name_np);
+__strong_reference(_pthread_getname_np, pthread_getname_np);
 __strong_reference(_pthread_set_name_np, pthread_set_name_np);
+__strong_reference(_pthread_setname_np, pthread_setname_np);
-- 
2.30.0

