OSSP CVS Repository

ossp - Check-in [2694]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2694
Date: 2002-Oct-30 20:09:35 (local)
2002-Oct-30 19:09:35 (UTC)
User:rse
Branch:
Comment: Added a function sa_sendf(3) which is a convience wrapper to sa_send(3) for sending formatted data. This is similar to what sa_writef(3) does for sa_write(3).

The difference is just that sa_writef(3) does not need a temporary buffer (because can use the stream I/O write buffer) while sa_sendf(3) requires a temporary buffer for its operation. Nevertheless the temporary buffer is allocated only if the formatted data is large. For small formatted data a fast stack-based buffer is used for higher performance.

Tickets:
Inspections:
Files:
ossp-pkg/sa/ChangeLog      1.3 -> 1.4     10 inserted, 0 deleted
ossp-pkg/sa/sa.c      1.64 -> 1.65     40 inserted, 0 deleted
ossp-pkg/sa/sa.h      1.32 -> 1.33     1 inserted, 0 deleted
ossp-pkg/sa/sa.pod      1.35 -> 1.36     26 inserted, 5 deleted
ossp-pkg/sa/sa_test.c      1.19 -> 1.20     2 inserted, 4 deleted

ossp-pkg/sa/ChangeLog 1.3 -> 1.4

--- ChangeLog    2002/10/30 19:01:31     1.3
+++ ChangeLog    2002/10/30 19:09:35     1.4
@@ -13,6 +13,16 @@
 
   Changes between 0.9.2 and 0.9.3 (11-Oct-2002 to xx-Oct-2002)
 
+   o Added a function sa_sendf(3) which is a convience wrapper
+     to sa_send(3) for sending formatted data. This is similar to what
+     sa_writef(3) does for sa_write(3). The difference is just that
+     sa_writef(3) does not need a temporary buffer (because can use the
+     stream I/O write buffer) while sa_sendf(3) requires a temporary
+     buffer for its operation. Nevertheless the temporary buffer is
+     allocated only if the formatted data is large. For small formatted
+     data a fast stack-based buffer is used for higher performance.
+     [Ralf S. Engelschall]
+
    o Finished implementation of test suite in order to cover
      mostly all functionality of the API.
      [Ralf S. Engelschall]


ossp-pkg/sa/sa.c 1.64 -> 1.65

--- sa.c 2002/10/30 09:21:52     1.64
+++ sa.c 2002/10/30 19:09:35     1.65
@@ -2183,6 +2183,46 @@
     return SA_OK;
 }
 
+/* send formatted string to socket (convinience function) */
+sa_rc_t sa_sendf(sa_t *sa, sa_addr_t *raddr, const char *cpFmt, ...)
+{
+    va_list ap;
+    size_t nBuf;
+    char *cpBuf;
+    sa_rc_t rv;
+    char caBuf[1024];
+
+    /* argument sanity check(s) */
+    if (sa == NULL || raddr == NULL || cpFmt == NULL)
+        return SA_RC(SA_ERR_ARG);
+
+    /* format string into temporary buffer */
+    va_start(ap, cpFmt);
+    nBuf = sa_mvsnprintf(NULL, NULL, cpFmt, ap);
+    va_end(ap);
+    if ((nBuf+1) > sizeof(caBuf)) {
+        /* requires a larger buffer, so allocate dynamically */
+        if ((cpBuf = (char *)malloc(nBuf+1)) == NULL)
+            return SA_RC(SA_ERR_SYS);
+    }
+    else {
+        /* fits into small buffer, so allocate statically */
+        cpBuf = caBuf;
+    }
+    va_start(ap, cpFmt);
+    sa_mvsnprintf(cpBuf, nBuf+1, cpFmt, ap);
+    va_end(ap);
+
+    /* pass-through to sa_send() */
+    rv = sa_send(sa, cpBuf, nBuf, NULL, raddr);
+
+    /* cleanup dynamically allocated buffer */
+    if ((nBuf+1) > sizeof(caBuf))
+        free(cpBuf);
+
+    return rv;
+}
+
 /* return error string */
 char *sa_error(sa_rc_t rv)
 {


ossp-pkg/sa/sa.h 1.32 -> 1.33

--- sa.h 2002/10/30 08:42:16     1.32
+++ sa.h 2002/10/30 19:09:35     1.33
@@ -200,6 +200,7 @@
 /* socket input/output operations (datagram communication) */
 sa_rc_t sa_recv         (sa_t *sa, char *buf, size_t buflen, size_t *bufdone, sa_addr_t **raddr);
 sa_rc_t sa_send         (sa_t *sa, const char *buf, size_t buflen, size_t *bufdone, sa_addr_t *raddr);
+sa_rc_t sa_sendf        (sa_t *sa, sa_addr_t *raddr, const char *fmt, ...);
 
 /* error handling operations */
 char   *sa_error        (sa_rc_t rv);


ossp-pkg/sa/sa.pod 1.35 -> 1.36

--- sa.pod       2002/10/30 18:43:08     1.35
+++ sa.pod       2002/10/30 19:09:35     1.36
@@ -96,7 +96,8 @@
 =item B<Socket Input/Output Operations (Datagram Communication)>:
 
 sa_recv,
-sa_send.
+sa_send,
+sa_sendf.
 
 =item B<Socket Error Handling>:
 
@@ -428,10 +429,10 @@
 Possible values for I<id> are: C<SA_TIMEOUT_ACCEPT> (affecting
 sa_accept(3)), C<SA_TIMEOUT_CONNECT> (affecting sa_connect(3)),
 C<SA_TIMEOUT_READ> (affecting sa_read(3), sa_readln(3) and sa_recv(3))
-and C<SA_TIMEOUT_WRITE> (affecting sa_write(3), sa_writef(3) and
-sa_send(3)). Additionally you can set all four timeouts at once by using
-C<SA_TIMEOUT_ALL>. The default is that no communication timeouts are
-used which is equal to I<sec>=C<0>/I<usec>=C<0>.
+and C<SA_TIMEOUT_WRITE> (affecting sa_write(3), sa_writef(3),
+sa_send(3), and sa_sendf(3)). Additionally you can set all four timeouts
+at once by using C<SA_TIMEOUT_ALL>. The default is that no communication
+timeouts are used which is equal to I<sec>=C<0>/I<usec>=C<0>.
 
 Example: C<sa_timeout(sa, SA_TIMEOUT_ALL, 30, 0);>
 
@@ -774,6 +775,26 @@
 
 Example: C<sa_send(sa, buf, strlen(buf), NULL, saa);>
 
+=item sa_rc_t B<sa_sendf>(sa_t *I<sa>, sa_addr_t *I<raddr>, const char *I<fmt>, ...)
+
+Send formatted data data to remote address via socket.
+
+This formats a string according to the printf(3)-style format
+specification I<fmt> and sends the result to the socket as a single
+piece of data chunk. In case of a partial socket write, the not written
+data of the formatted string is internally discarded.
+
+The underlying string formatting engine is just a minimal one and for
+security and independence reasons intentionally not directly based on
+s[n]printf(3). It understands only the following format specifications:
+"C<%%>", "C<%c>" (C<char>), "C<%s>" (C<char *>) and "C<%d>" (C<int>)
+without any precision and padding possibilities. It is intended for
+minimal formatting only. If you need more sophisticated formatting, you
+have to format first into an own buffer via s[n]printf(3) and then send
+this to the remote address via sa_send(3) instead.
+
+Example: C<sa_sendf(sa, saa, "%s=%d\n", cp, i);>
+
 =back
 
 =head2 Socket Error Handling


ossp-pkg/sa/sa_test.c 1.19 -> 1.20

--- sa_test.c    2002/10/30 18:46:22     1.19
+++ sa_test.c    2002/10/30 19:09:35     1.20
@@ -289,8 +289,7 @@
         if (strncmp(buf_srv, MSG_UDP_CLT_REQUEST, l) != 0)
             ts_test_fail(TS_CTX, "server: got \"%s\", expected \"%s\"",
                          buf_srv, MSG_UDP_CLT_REQUEST);
-        ex(SRV, sa_send(sa_srv, MSG_UDP_SRV_RESPONSE,
-                        strlen(MSG_UDP_SRV_RESPONSE), &l, saa_clt));
+        ex(SRV, sa_sendf(sa_srv, saa_clt, "%s", MSG_UDP_SRV_RESPONSE));
         ex(SRV, sa_addr_destroy(saa_clt));
 
         /* destroy server socket and die */
@@ -311,8 +310,7 @@
         /* communicate with server */
         ex(CLT, sa_addr_create(&saa_srv));
         ex(CLT, sa_addr_u2a(saa_srv, "inet://127.0.0.1:12345#udp"));
-        ex(CLT, sa_send(sa_clt, MSG_UDP_CLT_REQUEST,
-                        strlen(MSG_UDP_CLT_REQUEST), &l, saa_srv));
+        ex(CLT, sa_sendf(sa_clt, saa_srv, "%s", MSG_UDP_CLT_REQUEST));
         ex(CLT, sa_addr_destroy(saa_srv));
         ex(CLT, sa_recv(sa_clt, buf_clt, sizeof(buf_clt), &l, &saa_srv));
         if (strncmp(buf_clt, MSG_UDP_SRV_RESPONSE, l) != 0)

CVSTrac 2.0.1