git: e8d9d8082be3 - main - linux(4): Fix SO_LINGER l_onoff value

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Sat, 28 May 2022 20:53:18 UTC
The branch main has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=e8d9d8082be339d046826e543e8e835c61e2d4b0

commit e8d9d8082be339d046826e543e8e835c61e2d4b0
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-28 20:31:06 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-05-28 20:31:06 +0000

    linux(4): Fix SO_LINGER l_onoff value
    
    On Linux l_onoff should be 1 when linger is used.
    
    MFC after:              2 weeks
---
 sys/compat/linux/linux_socket.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 0c003cd5729f..1214c2e1fa24 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1992,6 +1992,22 @@ linux_getsockopt_so_peersec(struct thread *td,
 	    len, args));
 }
 
+static int
+linux_getsockopt_so_linger(struct thread *td,
+    struct linux_getsockopt_args *args)
+{
+	struct linger ling;
+	socklen_t len;
+	int error;
+
+	len = sizeof(ling);
+	error = kern_getsockopt(td, args->s, SOL_SOCKET,
+	    SO_LINGER, &ling, UIO_SYSSPACE, &len);
+	if (error != 0)
+		return (error);
+	ling.l_onoff = ((ling.l_onoff & SO_LINGER) != 0);
+	return (linux_sockopt_copyout(td, &ling, len, args));
+}
 
 int
 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
@@ -2075,6 +2091,9 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
 			return (linux_sockopt_copyout(td, &newval,
 			    len, args));
 			/* NOTREACHED */
+		case SO_LINGER:
+			return (linux_getsockopt_so_linger(td, args));
+			/* NOTREACHED */
 		default:
 			break;
 		}