changeset 39347:f9dc53a50a90

af_alg: coalesce socket creation * lib/af_alg.c (alg_socket): New function. (afalg_buffer, afalg_stream): Use it. This avoids some code duplication and gotos.
author Paul Eggert <eggert@cs.ucla.edu>
date Wed, 09 May 2018 11:16:59 -0700
parents e5a663fbaaf2
children 48c741c6c35d
files ChangeLog lib/af_alg.c
diffstat 2 files changed, 33 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed May 09 11:05:12 2018 -0700
+++ b/ChangeLog	Wed May 09 11:16:59 2018 -0700
@@ -1,5 +1,10 @@
 2018-05-09  Paul Eggert  <eggert@cs.ucla.edu>
 
+	af_alg: coalesce socket creation
+	* lib/af_alg.c (alg_socket): New function.
+	(afalg_buffer, afalg_stream): Use it.  This avoids some
+	code duplication and gotos.
+
 	af_alg: fix file descriptor leak
 	* lib/af_alg.c (afalg_stream): Close leak.
 
--- a/lib/af_alg.c	Wed May 09 11:05:12 2018 -0700
+++ b/lib/af_alg.c	Wed May 09 11:16:59 2018 -0700
@@ -35,18 +35,11 @@
 
 #define BLOCKSIZE 32768
 
-int
-afalg_buffer (const char *buffer, size_t len, const char *alg,
-              void *resblock, ssize_t hashlen)
+/* Return a newly created socket for ALG.
+   On error, return a negative error number.  */
+static int
+alg_socket (char const *alg)
 {
-  int ofd;
-
-  /* On Linux < 4.9, the value for an empty stream is wrong (all zeroes).
-     See <https://patchwork.kernel.org/patch/9308641/>.  */
-  if (len == 0)
-    return -EAFNOSUPPORT;
-
-  int result;
   struct sockaddr_alg salg = {
     .salg_family = AF_ALG,
     .salg_type = "hash",
@@ -59,19 +52,27 @@
   int cfd = socket (AF_ALG, SOCK_SEQPACKET, 0);
   if (cfd < 0)
     return -EAFNOSUPPORT;
-
-  if (bind (cfd, (struct sockaddr *) &salg, sizeof salg) != 0)
-    {
-      result = -EAFNOSUPPORT;
-      goto out_cfd;
-    }
+  int ofd = (bind (cfd, (struct sockaddr *) &salg, sizeof salg) == 0
+             ? accept (cfd, NULL, 0)
+             : -1);
+  close (cfd);
+  return ofd < 0 ? -EAFNOSUPPORT : ofd;
+}
 
-  ofd = accept (cfd, NULL, 0);
+int
+afalg_buffer (const char *buffer, size_t len, const char *alg,
+              void *resblock, ssize_t hashlen)
+{
+  /* On Linux < 4.9, the value for an empty stream is wrong (all zeroes).
+     See <https://patchwork.kernel.org/patch/9308641/>.  */
+  if (len == 0)
+    return -EAFNOSUPPORT;
+
+  int ofd = alg_socket (alg);
   if (ofd < 0)
-    {
-      result = -EAFNOSUPPORT;
-      goto out_cfd;
-    }
+    return ofd;
+
+  int result;
 
   do
     {
@@ -93,8 +94,6 @@
 
 out_ofd:
   close (ofd);
-out_cfd:
-  close (cfd);
   return result;
 }
 
@@ -102,38 +101,14 @@
 afalg_stream (FILE *stream, const char *alg,
               void *resblock, ssize_t hashlen)
 {
-  int fd, ofd;
-  struct stat st;
-
-  int result;
-  struct sockaddr_alg salg = {
-    .salg_family = AF_ALG,
-    .salg_type = "hash",
-  };
-  /* Avoid calling both strcpy and strlen.  */
-  for (int i = 0; (salg.salg_name[i] = alg[i]); i++)
-    if (i == sizeof salg.salg_name - 1)
-      return -EINVAL;
-
-  int cfd = socket (AF_ALG, SOCK_SEQPACKET, 0);
-  if (cfd < 0)
-    return -EAFNOSUPPORT;
-
-  if (bind (cfd, (struct sockaddr *) &salg, sizeof salg) != 0)
-    {
-      result = -EAFNOSUPPORT;
-      goto out_cfd;
-    }
-
-  ofd = accept (cfd, NULL, 0);
+  int ofd = alg_socket (alg);
   if (ofd < 0)
-    {
-      result = -EAFNOSUPPORT;
-      goto out_cfd;
-    }
+    return ofd;
 
   /* if file is a regular file, attempt sendfile to pipe the data.  */
-  fd = fileno (stream);
+  int fd = fileno (stream);
+  int result;
+  struct stat st;
   if (fstat (fd, &st) == 0
       && (S_ISREG (st.st_mode) || S_TYPEISSHM (&st) || S_TYPEISTMO (&st))
       && 0 < st.st_size && st.st_size <= SYS_BUFSIZE_MAX)
@@ -202,8 +177,6 @@
 
 out_ofd:
   close (ofd);
-out_cfd:
-  close (cfd);
   return result;
 }