[email protected] (Christos Zoulas) wrote:
>In article <[email protected]>,
>Robert Swindells  <[email protected]> wrote:
>>
>>What is wrong with your idea of updatesockopt(2) ? Or maybe call it
>>getsockopt2() and only use it for the "get with extra argument" case.
>
>I guess getsockopt2/updatesockopt is not that bad after all. Perhaps
>we should go with that?

This is working for me:

Index: uipc_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.191
diff -u -r1.191 uipc_syscalls.c
--- uipc_syscalls.c     12 Feb 2018 16:01:35 -0000      1.191
+++ uipc_syscalls.c     6 Mar 2018 00:47:02 -0000
@@ -1266,6 +1266,68 @@
        return error;
 }
 
+int
+sys_getsockopt2(struct lwp *l, const struct sys_getsockopt2_args *uap,
+    register_t *retval)
+{
+       /* {
+               syscallarg(int)                 s;
+               syscallarg(int)                 level;
+               syscallarg(int)                 name;
+               syscallarg(void *)              val;
+               syscallarg(unsigned int *)      avalsize;
+       } */
+       struct sockopt  sopt;
+       struct socket   *so;
+       file_t          *fp;
+       unsigned int    valsize, len;
+       int             error;
+
+       if (SCARG(uap, val) != NULL) {
+               error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize));
+               if (error)
+                       return error;
+       } else
+               valsize = 0;
+
+       if (valsize > MCLBYTES)
+               return EINVAL;
+
+       if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
+               return (error);
+
+       sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), valsize);
+       if (valsize > 0) {
+               error = copyin(SCARG(uap, val), sopt.sopt_data, valsize);
+               if (error)
+                       goto out;
+       }
+
+       if (fp->f_flag & FNOSIGPIPE)
+               so->so_options |= SO_NOSIGPIPE;
+       else
+               so->so_options &= ~SO_NOSIGPIPE;
+       error = sogetopt(so, &sopt);
+       if (error)
+               goto out;
+
+       if (valsize > 0) {
+               len = min(valsize, sopt.sopt_size);
+               error = copyout(sopt.sopt_data, SCARG(uap, val), len);
+               if (error)
+                       goto out;
+
+               error = copyout(&len, SCARG(uap, avalsize), sizeof(len));
+               if (error)
+                       goto out;
+       }
+
+ out:
+       sockopt_destroy(&sopt);
+       fd_putfile(SCARG(uap, s));
+       return error;
+}
+
 #ifdef PIPE_SOCKETPAIR
 
 int
Index: syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/kern/syscalls.master,v
retrieving revision 1.291
diff -u -r1.291 syscalls.master
--- syscalls.master     6 Jan 2018 16:41:23 -0000       1.291
+++ syscalls.master     6 Mar 2018 00:47:03 -0000
@@ -986,3 +986,5 @@
                            siginfo_t *info); }
 482    STD             { int|sys||clock_getcpuclockid2(idtype_t idtype, \
                            id_t id, clockid_t *clock_id); }
+483    STD     RUMP    { int|sys||getsockopt2(int s, int level, int name, \
+                           void *val, socklen_t *avalsize); }

Reply via email to