ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/c++/socket++-1.10/sockstream.C
Revision: 1.2
Committed: Thu Mar 15 20:26:47 2001 UTC (23 years, 6 months ago) by ab11
Content type: text/plain
Branch: MAIN
CVS Tags: PROJECT_COMPLETION
Changes since 1.1: +8 -3 lines
Log Message:
fixed the "UDP size no greater than 1024 bytes" with hard coding. The error is due to the definition within /usr/include/iso/stdio_iso.h which makes me think that perhaps we are breaking the normal UDP rules with anything above 1024. Currently fixed the buffer size to 8192 (current  packets run in at about 2.5 - 3k in size so we have 'some' future proofing.. This is very much something that needs to be discussed.

File Contents

# User Rev Content
1 ab11 1.1 // sockstream.C -*- C++ -*- socket library
2     // Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
3     //
4     // Permission is granted to use at your own risk and distribute this software
5     // in source and binary forms provided the above copyright
6     // notice and this paragraph are preserved on all copies.
7     // This software is provided "as is" with no express or implied warranty.
8     //
9     // Version: 17Oct95 1.10
10     //
11     // You can simultaneously read and write into
12     // a sockbuf just like you can listen and talk
13     // through a telephone. Hence, the read and the
14     // write buffers are different. That is, they do not
15     // share the same memory.
16     //
17     // Read:
18     // gptr() points to the start of the get area.
19     // The unread chars are gptr() - egptr().
20     // base() points to the read buffer
21     //
22     // eback() is set to base() so that pbackfail()
23     // is called only when there is no place to
24     // putback a char. And pbackfail() always returns EOF.
25     //
26     // Write:
27     // pptr() points to the start of the put area
28     // The unflushed chars are pbase() - pptr()
29     // pbase() points to the write buffer.
30     // epptr() points to the end of the write buffer.
31     //
32     // Output is flushed whenever one of the following conditions
33     // holds:
34     // (1) pptr() == epptr()
35     // (2) EOF is written
36     // (3) linebuffered and '\n' is written
37     //
38     // Unbuffered:
39     // Input buffer size is assumed to be of size 1 and output
40     // buffer is of size 0. That is, egptr() <= base()+1 and
41     // epptr() == pbase().
42    
43    
44     #include <config.h>
45     #include <sockstream.h>
46    
47     EXTERN_C_BEGIN
48     #include <sys/time.h>
49     #include <sys/socket.h>
50     #include <unistd.h>
51     #include <errno.h>
52     EXTERN_C_END
53    
54 ab11 1.2 // MODIFED BY ASH - Force the buffer size to 8192 for the
55     // moment. This is VERY BAD, but fixes the 1024 char limit
56     // on UDP packets. Will need to look further into the problem
57     // which exists in /usr/include/iso/stdio_iso.h
58    
59     // #ifndef BUFSIZ
60     # define BUFSIZ 8192
61     // #endif
62 ab11 1.1
63     #ifdef FD_ZERO
64     # undef FD_ZERO // bzero causes so much trouble to us
65     #endif
66     #define FD_ZERO(p) (memset ((p), 0, sizeof *(p)))
67    
68     void sock_error (const char* classname, const char* msg)
69     {
70     if (errno)
71     perror (msg);
72     cerr << classname << ' ' << msg << endl;
73     errno = 0;
74     }
75    
76     void sockAddr::error (const char* msg) const
77     {
78     sock_error ("class sockAddr ", msg);
79     }
80    
81     sockbuf::sockbuf (int soc)
82     : rep (new sockcnt (soc, 1)),
83     stmo (-1), rtmo (-1)
84     {
85     #ifdef _S_NOLIBGXX
86     xflags (0);
87     #endif
88     xsetflags (_S_LINE_BUF);
89     }
90    
91     sockbuf::sockbuf (int domain, sockbuf::type st, int proto)
92     : rep (0), stmo (-1), rtmo (-1)
93     {
94     int soc = ::socket (domain, st, proto);
95     rep = new sockcnt (soc, 1);
96     #ifdef _S_NOLIBGXX
97     xflags (0);
98     #endif
99     if (rep->sock == -1) perror ("sockbuf::sockbuf");
100     xsetflags (_S_LINE_BUF);
101     }
102    
103     sockbuf::sockbuf (const sockbuf& sb)
104     : rep (sb.rep), stmo (sb.stmo), rtmo (sb.rtmo)
105     {
106     #ifdef _S_NOLIBGXX
107     xflags (0);
108     #endif
109     rep->cnt++;
110     xsetflags (_S_LINE_BUF);
111     }
112    
113     sockbuf& sockbuf::operator = (const sockbuf& sb)
114     {
115     if (this != &sb && rep != sb.rep && rep->sock != sb.rep->sock) {
116     this->sockbuf::~sockbuf();
117     rep = sb.rep; stmo = sb.stmo; rtmo = sb.rtmo;
118     rep->cnt++;
119     #ifdef _S_NOLIBGXX
120     xflags (sb.xflags ());
121     #else
122     // xflags () is a non-const member function in libg++.
123     xflags (((sockbuf&)sb).xflags ());
124     #endif
125     }
126     return *this;
127     }
128    
129     sockbuf::~sockbuf ()
130     {
131     overflow (EOF);
132     if (rep->cnt == 1 && !(xflags () & _S_DELETE_DONT_CLOSE)) close ();
133     delete [] base ();
134     if (--rep->cnt == 0) delete rep;
135     }
136    
137     sockbuf* sockbuf::open (type, int)
138     {
139     return 0;
140     }
141    
142     sockbuf* sockbuf::close()
143     {
144     if (rep->sock >= 0) {
145     if (::close (rep->sock) == -1) return this;
146     rep->sock = -1;
147     }
148     return 0;
149     }
150    
151     _G_ssize_t sockbuf::sys_read (char* buf, _G_ssize_t len)
152     // return EOF on eof, 0 on timeout, and # of chars read on success
153     {
154     return read (buf, len);
155     }
156    
157     _G_ssize_t sockbuf::sys_write (const void* buf, long len)
158     // return written_length; < len indicates error
159     {
160     return write (buf, (int) len);
161     }
162    
163     int sockbuf::flush_output()
164     // return 0 when there is nothing to flush or when the flush is a success
165     // return EOF when it could not flush
166     {
167     if (pptr () <= pbase ()) return 0;
168     if (!(xflags () & _S_NO_WRITES)) {
169     int wlen = pptr () - pbase ();
170     int wval = sys_write (pbase (), wlen);
171     int status = (wval == wlen)? 0: EOF;
172     if (unbuffered()) setp (pbase (), pbase ());
173     else setp (pbase (), pbase () + BUFSIZ);
174     return status;
175     }
176     return EOF;
177     }
178    
179     int sockbuf::sync ()
180     {
181     return flush_output ();
182     }
183    
184     int sockbuf::doallocate ()
185     // return 1 on allocation and 0 if there is no need
186     {
187     if (!base ()) {
188     char* buf = new char[2*BUFSIZ];
189     setb (buf, buf+BUFSIZ, 0);
190     setg (buf, buf, buf);
191    
192     buf += BUFSIZ;
193     setp (buf, buf+BUFSIZ);
194     return 1;
195     }
196     return 0;
197     }
198    
199     int sockbuf::underflow ()
200     {
201     if (xflags () & _S_NO_READS) return EOF;
202    
203     if (gptr () < egptr ()) return *(unsigned char*)gptr ();
204    
205     if (base () == 0 && doallocate () == 0) return EOF;
206    
207     int bufsz = unbuffered () ? 1: BUFSIZ;
208     int rval = sys_read (base (), bufsz);
209     if (rval == EOF) {
210     xsetflags (_S_EOF_SEEN);
211     return EOF;
212     }else if (rval == 0)
213     return EOF;
214     setg (eback (), base (), base () + rval);
215     return *(unsigned char*)gptr ();
216     }
217    
218     int sockbuf::overflow (int c)
219     // if c == EOF, return flush_output();
220     // if c == '\n' and linebuffered, insert c and
221     // return (flush_output()==EOF)? EOF: c;
222     // otherwise insert c into the buffer and return c
223     {
224     if (c == EOF) return flush_output ();
225    
226     if (xflags () & _S_NO_WRITES) return EOF;
227    
228     if (pbase () == 0 && doallocate () == 0) return EOF;
229    
230     if (pptr () >= epptr() && flush_output () == EOF)
231     return EOF;
232    
233     xput_char (c);
234     if ((unbuffered () || linebuffered () && c == '\n' || pptr () >= epptr ())
235     && flush_output () == EOF)
236     return EOF;
237    
238     return c;
239     }
240    
241     int sockbuf::xsputn (const char* s, int n)
242     {
243     if (n <= 0) return 0;
244     const unsigned char* p = (const unsigned char*)s;
245    
246     for (int i=0; i<n; i++, p++) {
247     if (*p == '\n') {
248     if (overflow (*p) == EOF) return i;
249     } else
250     if (sputc (*p) == EOF) return i;
251     }
252     return n;
253     }
254    
255     int sockbuf::bind (sockAddr& sa)
256     {
257     if (::bind (rep->sock, sa.addr (), sa.size ()) == -1) {
258     // error ("sockbuf::bind");
259     return errno;
260     }
261     return 0;
262     }
263    
264     int sockbuf::connect (sockAddr& sa)
265     {
266     if (::connect(rep->sock, sa.addr (), sa.size()) == -1) {
267     // error ("sockbuf::connect");
268     return errno;
269     }
270     return 0;
271     }
272    
273     void sockbuf::listen (int num)
274     {
275     if (::listen (rep->sock, num) == -1)
276     error ("sockbuf::listen");
277     }
278    
279     sockbuf sockbuf::accept (sockAddr& sa)
280     {
281     int len = sa.size ();
282     int soc = -1;
283     while ((soc = ::accept (rep->sock, sa.addr (), &len)) == -1
284     && errno == EINTR)
285     errno = 0;
286     if (soc == -1)
287     error ("sockbuf::accept");
288     return soc;
289     }
290    
291     sockbuf sockbuf::accept ()
292     {
293     int soc = -1;
294     while ((soc = ::accept (rep->sock, 0, 0)) == -1
295     && errno == EINTR)
296     errno = 0;
297     if (soc == -1)
298     error ("sockbuf::accept");
299     return soc;
300     }
301    
302     int sockbuf::read (void* buf, int len)
303     {
304     if (rtmo != -1 && is_readready (rtmo)==0) return 0;
305    
306     int rval;
307     if ((rval = ::read (rep->sock, (char*) buf, len)) == -1)
308     error("sockbuf::read");
309     return (rval==0) ? EOF: rval;
310     }
311    
312     int sockbuf::recv (void* buf, int len, int msgf)
313     {
314     if (rtmo != -1 && is_readready (rtmo)==0) return 0;
315    
316     int rval;
317     if ((rval = ::recv (rep->sock, (char*) buf, len, msgf)) == -1)
318     error ("sockbuf::recv");
319     return (rval==0) ? EOF: rval;
320     }
321    
322     int sockbuf::recvfrom (sockAddr& sa, void* buf, int len, int msgf)
323     {
324     if (rtmo != -1 && is_readready (rtmo)==0) return 0;
325    
326     int rval;
327     int sa_len = sa.size ();
328    
329     if ((rval = ::recvfrom (rep->sock, (char*) buf, len,
330     msgf, sa.addr (), &sa_len)) == -1)
331     error ("sockbuf::recvfrom");
332     return (rval==0) ? EOF: rval;
333     }
334    
335     int sockbuf::write(const void* buf, int len)
336     {
337     if (stmo != -1 && is_writeready (stmo)==0) return 0;
338    
339     int wlen=0;
340     while(len>0) {
341     int wval;
342     if ((wval = ::write (rep->sock, (char*) buf, len)) == -1) {
343     error ("sockbuf::write");
344     return wval;
345     }
346     len -= wval;
347     wlen += wval;
348     }
349     return wlen; // == len if every thing is all right
350     }
351    
352     int sockbuf::send (const void* buf, int len, int msgf)
353     {
354     if (stmo != -1 && is_writeready (stmo)==0) return 0;
355    
356     int wlen=0;
357     while(len>0) {
358     int wval;
359     if ((wval = ::send (rep->sock, (char*) buf, len, msgf)) == -1) {
360     error ("sockbuf::send");
361     return wval;
362     }
363     len -= wval;
364     wlen += wval;
365     }
366     return wlen;
367     }
368    
369     int sockbuf::sendto (sockAddr& sa, const void* buf, int len, int msgf)
370     {
371     if (stmo != -1 && is_writeready (stmo)==0) return 0;
372    
373     int wlen=0;
374     while(len>0) {
375     int wval;
376     if ((wval = ::sendto (rep->sock, (char*) buf, len,
377     msgf, sa.addr (), sa.size())) == -1) {
378     error ("sockbuf::sendto");
379     return wval;
380     }
381     len -= wval;
382     wlen += wval;
383     }
384     return wlen;
385     }
386    
387     #ifndef __linux__
388     // linux does not have sendmsg or recvmsg
389    
390     int sockbuf::recvmsg (msghdr* msg, int msgf)
391     {
392     if (rtmo != -1 && is_readready (rtmo)==0) return 0;
393    
394     int rval;
395     if ((rval = ::recvmsg(rep->sock, msg, msgf)) == -1)
396     error ("sockbuf::recvmsg");
397     return (rval==0)? EOF: rval;
398     }
399    
400     int sockbuf::sendmsg (msghdr* msg, int msgf)
401     {
402     if (stmo != -1 && is_writeready (stmo)==0) return 0;
403    
404     int wval;
405     if ((wval = ::sendmsg (rep->sock, msg, msgf)) == -1)
406     error("sockbuf::sendmsg");
407     return wval;
408     }
409     #endif //!__linux__
410    
411     int sockbuf::sendtimeout (int wp)
412     {
413     int oldstmo = stmo;
414     stmo = (wp < 0) ? -1: wp;
415     return oldstmo;
416     }
417    
418     int sockbuf::recvtimeout (int wp)
419     {
420     int oldrtmo = rtmo;
421     rtmo = (wp < 0) ? -1: wp;
422     return oldrtmo;
423     }
424    
425     int sockbuf::is_readready (int wp_sec, int wp_usec) const
426     {
427     fd_set fds;
428     FD_ZERO (&fds);
429     FD_SET (rep->sock, &fds);
430    
431     timeval tv;
432     tv.tv_sec = wp_sec;
433     tv.tv_usec = wp_usec;
434    
435     int ret = select (rep->sock+1, &fds, 0, 0, (wp_sec == -1) ? 0: &tv);
436     if (ret == -1) {
437     error ("sockbuf::readready");
438     return 0;
439     }
440     return ret;
441     }
442    
443     int sockbuf::is_writeready (int wp_sec, int wp_usec) const
444     {
445     fd_set fds;
446     FD_ZERO (&fds);
447     FD_SET (rep->sock, &fds);
448    
449     timeval tv;
450     tv.tv_sec = wp_sec;
451     tv.tv_usec = wp_usec;
452    
453     int ret = select (rep->sock+1, 0, &fds, 0, (wp_sec == -1) ? 0: &tv);
454     if (ret == -1) {
455     error ("Select::operator ()");
456     return 0;
457     }
458     return ret;
459     }
460    
461     int sockbuf::is_exceptionpending (int wp_sec, int wp_usec) const
462     {
463     fd_set fds;
464     FD_ZERO (&fds);
465     FD_SET (rep->sock, &fds);
466    
467     timeval tv;
468     tv.tv_sec = wp_sec;
469     tv.tv_usec = wp_usec;
470    
471     int ret = select (rep->sock+1, 0, 0, &fds, (wp_sec == -1) ? 0: &tv);
472     if (ret == -1) {
473     error ("Select::operator ()");
474     return 0;
475     }
476     return ret;
477     }
478    
479     void sockbuf::shutdown (shuthow sh)
480     {
481     switch (sh) {
482     case shut_read:
483     xsetflags(_S_NO_READS);
484     break;
485     case shut_write:
486     xsetflags(_S_NO_WRITES);
487     break;
488     case shut_readwrite:
489     xsetflags(_S_NO_READS|_S_NO_WRITES);
490     break;
491     }
492     if (::shutdown(rep->sock, sh) == -1)
493     error("sockbuf::shutdown");
494     }
495    
496     int sockbuf::getopt (option op, void* buf, int len, level l) const
497     {
498     int rlen = len;
499     if (::getsockopt (rep->sock, l, op, (char*) buf, &rlen) == -1)
500     perror ("sockbuf::getopt");
501     return rlen;
502     }
503    
504     void sockbuf::setopt (option op, void* buf, int len, level l) const
505     {
506     if (::setsockopt (rep->sock, l, op, (char*) buf, len) == -1)
507     perror ("sockbuf::setopt");
508     }
509    
510     sockbuf::type sockbuf::gettype () const
511     {
512     int ty=0;
513     getopt (so_type, &ty, sizeof (ty));
514     return sockbuf::type(ty);
515     }
516    
517     int sockbuf::clearerror () const
518     {
519     int err=0;
520     getopt (so_error, &err, sizeof (err));
521     return err;
522     }
523    
524     int sockbuf::debug (int opt) const
525     {
526     int old=0;
527     getopt (so_debug, &old, sizeof (old));
528     if (opt != -1)
529     setopt (so_debug, &opt, sizeof (opt));
530     return old;
531     }
532    
533     int sockbuf::reuseaddr (int opt) const
534     {
535     int old=0;
536     getopt (so_reuseaddr, &old, sizeof (old));
537     if (opt != -1)
538     setopt (so_reuseaddr, &opt, sizeof (opt));
539     return old;
540     }
541    
542     int sockbuf::keepalive (int opt) const
543     {
544     int old=0;
545     getopt (so_keepalive, &old, sizeof (old));
546     if (opt != -1)
547     setopt (so_keepalive, &opt, sizeof (opt));
548     return old;
549     }
550    
551     int sockbuf::dontroute (int opt) const
552     {
553     int old=0;
554     getopt (so_dontroute, &old, sizeof (old));
555     if (opt != -1)
556     setopt (so_dontroute, &opt, sizeof (opt));
557     return old;
558     }
559    
560     int sockbuf::broadcast (int opt) const
561     {
562     int old=0;
563     getopt (so_broadcast, &old, sizeof (old));
564     if (opt != -1)
565     setopt (so_broadcast, &opt, sizeof (opt));
566     return old;
567     }
568    
569     int sockbuf::oobinline (int opt) const
570     {
571     int old=0;
572     getopt (so_oobinline, &old, sizeof (old));
573     if (opt != -1)
574     setopt (so_oobinline, &opt, sizeof (opt));
575     return old;
576     }
577    
578     int sockbuf::linger (int opt) const
579     {
580     socklinger old (0, 0);
581     getopt (so_linger, &old, sizeof (old));
582     if (opt > 0) {
583     socklinger nw (1, opt);
584     setopt (so_linger, &nw, sizeof (nw));
585     }else if (opt == 0) {
586     socklinger nw (0, old.l_linger);
587     setopt (so_linger, &nw, sizeof (nw));
588     }
589     return old.l_onoff ? old.l_linger: -1;
590     }
591    
592     int sockbuf::sendbufsz (int sz) const
593     {
594     int old=0;
595     getopt (so_sndbuf, &old, sizeof (old));
596     if (sz >= 0)
597     setopt (so_sndbuf, &sz, sizeof (sz));
598     return old;
599     }
600    
601     int sockbuf::recvbufsz (int sz) const
602     {
603     int old=0;
604     getopt (so_rcvbuf, &old, sizeof (old));
605     if (sz >= 0)
606     setopt (so_rcvbuf, &sz, sizeof (sz));
607     return old;
608     }
609    
610     void sockbuf::error (const char* msg) const
611     {
612     sock_error ("class sockbuf: ", msg);
613     }
614    
615     isockstream::~isockstream ()
616     {
617     delete ios::rdbuf ();
618     init (0);
619     }
620    
621     void isockstream::error (const char* msg) const
622     {
623     sock_error ("class isockstream: ", msg);
624     }
625    
626     osockstream::~osockstream ()
627     {
628     delete ios::rdbuf ();
629     init (0);
630     }
631    
632     void osockstream::error (const char* msg) const
633     {
634     sock_error ("class osockstream: ", msg);
635     }
636    
637     iosockstream::~iosockstream ()
638     {
639     delete ios::rdbuf ();
640     init (0);
641     }
642    
643     void iosockstream::error (const char* msg) const
644     {
645     sock_error ("class iosockstream: ", msg);
646     }
647