]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - inet/rexec.c
RISC-V: Fix `test' operand error with soft-float ABI being configured
[thirdparty/glibc.git] / inet / rexec.c
index 8f6190a83439ade6a63fe2906f9a8ff15e649a1b..bda536723bcc414485d6ad4815852eed035f426f 100644 (file)
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rexec.c    8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
 #include <sys/types.h>
 #include <sys/socket.h>
 
@@ -43,19 +39,16 @@ static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93";
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/uio.h>
 
 int    rexecoptions;
-static char    ahostbuf[NI_MAXHOST];
+libc_freeres_ptr (static char *ahostbuf);
 
 int
-rexec_af(ahost, rport, name, pass, cmd, fd2p, af)
-       char **ahost;
-       int rport;
-       const char *name, *pass, *cmd;
-       int *fd2p;
-       sa_family_t af;
+rexec_af (char **ahost, int rport, const char *name, const char *pass,
+         const char *cmd, int *fd2p, sa_family_t af)
 {
-       struct sockaddr_storage sa2, from;
+       struct sockaddr_storage from;
        struct addrinfo hints, *res0;
        const char *orig_name = name;
        const char *orig_pass = pass;
@@ -79,15 +72,21 @@ rexec_af(ahost, rport, name, pass, cmd, fd2p, af)
        }
 
        if (res0->ai_canonname){
-               strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf));
-               ahostbuf[sizeof(ahostbuf)-1] = '\0';
+               free (ahostbuf);
+               ahostbuf = __strdup (res0->ai_canonname);
+               if (ahostbuf == NULL) {
+                       perror ("rexec: strdup");
+                       return (-1);
+               }
                *ahost = ahostbuf;
-       }
-       else{
+       } else {
                *ahost = NULL;
+               __set_errno (ENOENT);
+               return -1;
        }
        ruserpass(res0->ai_canonname, &name, &pass);
 retry:
+       /* NB: No SOCK_CLOEXEC for backwards compatibility.  */
        s = __socket(res0->ai_family, res0->ai_socktype, 0);
        if (s < 0) {
                perror("rexec: socket");
@@ -108,7 +107,13 @@ retry:
                port = 0;
        } else {
                char num[32];
-               int s2, sa2len;
+               int s2;
+               union
+               {
+                 struct sockaddr_storage ss;
+                 struct sockaddr sa;
+               } sa2;
+               socklen_t sa2len;
 
                s2 = __socket(res0->ai_family, res0->ai_socktype, 0);
                if (s2 < 0) {
@@ -117,24 +122,25 @@ retry:
                }
                __listen(s2, 1);
                sa2len = sizeof (sa2);
-               if (__getsockname(s2, (struct sockaddr *)&sa2, &sa2len) < 0) {
+               if (__getsockname(s2, &sa2.sa, &sa2len) < 0) {
                        perror("getsockname");
                        (void) __close(s2);
                        goto bad;
-               } else if (sa2len != SA_LEN((struct sockaddr *)&sa2)) {
+               } else if (sa2len != SA_LEN(&sa2.sa)) {
                        __set_errno(EINVAL);
                        (void) __close(s2);
                        goto bad;
                }
                port = 0;
-               if (!getnameinfo((struct sockaddr *)&sa2, sa2len,
+               if (!getnameinfo(&sa2.sa, sa2len,
                                 NULL, 0, servbuff, sizeof(servbuff),
                                 NI_NUMERICSERV))
                        port = atoi(servbuff);
                (void) sprintf(num, "%u", port);
                (void) __write(s, num, strlen(num)+1);
-               { int len = sizeof (from);
-                 s3 = accept(s2, (struct sockaddr *)&from, &len);
+               { socklen_t len = sizeof (from);
+                 s3 = TEMP_FAILURE_RETRY (accept(s2, (struct sockaddr *)&from,
+                                                 &len));
                  __close(s2);
                  if (s3 < 0) {
                        perror("accept");
@@ -144,10 +150,15 @@ retry:
                }
                *fd2p = s3;
        }
-       (void) __write(s, name, strlen(name) + 1);
-       /* should public key encypt the password here */
-       (void) __write(s, pass, strlen(pass) + 1);
-       (void) __write(s, cmd, strlen(cmd) + 1);
+
+       struct iovec iov[3] =
+         {
+           [0] = { .iov_base = (void *) name, .iov_len = strlen (name) + 1 },
+           /* should public key encypt the password here */
+           [1] = { .iov_base = (void *) pass, .iov_len = strlen (pass) + 1 },
+           [2] = { .iov_base = (void *) cmd, .iov_len = strlen (cmd) + 1 }
+         };
+       (void) TEMP_FAILURE_RETRY (__writev (s, iov, 3));
 
        /* We don't need the memory allocated for the name and the password
           in ruserpass anymore.  */
@@ -180,11 +191,8 @@ bad:
 libc_hidden_def (rexec_af)
 
 int
-rexec(ahost, rport, name, pass, cmd, fd2p)
-       char **ahost;
-       int rport;
-       const char *name, *pass, *cmd;
-       int *fd2p;
+rexec (char **ahost, int rport, const char *name, const char *pass,
+       const char *cmd, int *fd2p)
 {
        return rexec_af(ahost, rport, name, pass, cmd, fd2p, AF_INET);
 }