diff recpt1/recpt1.c @ 28:97c820e30737

limit write length at once so that udp/stdout works well.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sun, 01 Mar 2009 22:42:09 +0900
parents 763cf84d2dc7
children 6004fe4f37f9
line wrap: on
line diff
--- a/recpt1/recpt1.c	Sat Feb 28 04:21:31 2009 +0900
+++ b/recpt1/recpt1.c	Sun Mar 01 22:42:09 2009 +0900
@@ -23,6 +23,9 @@
 #include "recpt1.h"
 #include "decoder.h"
 
+/* maximum write length at once */
+#define SIZE_CHANK 1316
+
 /* globals */
 int f_exit = FALSE;
 
@@ -204,7 +207,7 @@
     }
 
     while(1) {
-        ssize_t wc;
+        ssize_t wc = 0;
         qbuf = dequeue(p_queue);
         /* no entry in the queue */
         if(qbuf == NULL) {
@@ -217,7 +220,6 @@
         buf = sbuf; /* default */
 
         if(use_b25) {
-            /* write data to output file*/
             code = b25_decode(dec, &sbuf, &dbuf);
             if(code < 0)
                 fprintf(stderr, "b25_decode failed\n");
@@ -226,18 +228,39 @@
         }
 
         if(!fileless) {
-            wc = write(wfd, buf.data, buf.size);
-            if(wc < 0) {
-                if(errno == EPIPE)
-                    pthread_kill(signal_thread, SIGPIPE);
-                else
-                    pthread_kill(signal_thread, SIGUSR2);
+            /* write data to output file */
+            int size_remain = buf.size;
+            int offset = 0;
+            while(size_remain > 0) {
+                int ws = size_remain < SIZE_CHANK ? size_remain : SIZE_CHANK;
+                wc = write(wfd, buf.data + offset, ws);
+                if(wc < 0) {
+                    if(errno == EPIPE)
+                        pthread_kill(signal_thread, SIGPIPE);
+                    else
+                        pthread_kill(signal_thread, SIGUSR2);
+                    break;
+                }
+                size_remain -= wc;
+                offset += wc;
             }
         }
 
         if(use_udp && sfd != -1) {
-            sendto(sfd, buf.data, buf.size, 0,
-                   (struct sockaddr *)addr, sizeof(*addr));
+            /* write data to socket */
+            int size_remain = buf.size;
+            int offset = 0;
+            while(size_remain > 0) {
+                int ws = size_remain < SIZE_CHANK ? size_remain : SIZE_CHANK;
+                wc = write(sfd, buf.data + offset, ws);
+                if(wc < 0) {
+                    if(errno == EPIPE)
+                        pthread_kill(signal_thread, SIGPIPE);
+                    break;
+                }
+                size_remain -= wc;
+                offset += wc;
+            }
         }
 
         free(qbuf);
@@ -266,8 +289,11 @@
             }
 
             if(use_udp && sfd != -1) {
-                sendto(sfd, buf.data, buf.size, 0,
-                       (struct sockaddr *)addr, sizeof(*addr));
+                wc = write(sfd, buf.data, buf.size);
+                if(wc < 0) {
+                    if(errno == EPIPE)
+                        pthread_kill(signal_thread, SIGPIPE);
+                }
             }
 
             break;
@@ -662,11 +688,18 @@
             }
             ia.s_addr = *(in_addr_t*) (hoste->h_addr_list[0]);
         }
+        if((sockdata->sfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+            perror("socket");
+            return 1;
+        }
+
         sockdata->addr.sin_family = AF_INET;
         sockdata->addr.sin_port = htons (port_to);
         sockdata->addr.sin_addr.s_addr = ia.s_addr;
-        if((sockdata->sfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
-            perror("socket");
+
+        if(connect(sockdata->sfd, (struct sockaddr *)&sockdata->addr,
+                   sizeof(sockdata->addr)) < 0) {
+            perror("connect");
             return 1;
         }
     }