File: xiowrite.c

package info (click to toggle)
socat 2.0.0~beta9-1
  • links: PTS
  • area: main
  • in suites: experimental
  • size: 3,740 kB
  • sloc: ansic: 30,875; sh: 11,630; makefile: 149
file content (153 lines) | stat: -rw-r--r-- 3,955 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* source: xiowrite.c */
/* Copyright Gerhard Rieger 2001-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */

/* this is the source of the extended write function */


#include "xiosysincludes.h"
#include "xioopen.h"

#include "xio-test.h"
#include "xio-readline.h"
#include "xio-openssl.h"


/* ...
   note that the write() call can block even if the select()/poll() call
   reported the FD writeable: in case the FD is not nonblocking and a lock
   defers the operation.
   on return value < 0: errno reflects the value from write() */
ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
   ssize_t writt;
   struct single *pipe;
   int fd;
   int _errno;

   if (file->tag == XIO_TAG_INVALID) {
      Error1("xiowrite(): invalid xiofile descriptor %p", file);
      errno = EINVAL;
      return -1;
   }

   if (file->tag == XIO_TAG_DUAL) {
      pipe = file->dual.stream[1];
      if (pipe->tag == XIO_TAG_INVALID) {
	 Error1("xiowrite(): invalid xiofile sub descriptor %p[1]", file);
	 errno = EINVAL;
	 return -1;
      }
   } else {
      pipe = &file->stream;
   }

#if WITH_READLINE
   /* try to extract a prompt from the write data */
   if ((pipe->dtype & XIODATA_READMASK) == XIOREAD_READLINE) {
      xioscan_readline(pipe, buff, bytes);
   }
#endif /* WITH_READLINE */

   fd = XIO_GETWRFD(file);

   switch (pipe->dtype & XIODATA_WRITEMASK) {

   case XIOWRITE_STREAM:
      writt = writefull(pipe->wfd, buff, bytes);
      if (writt < 0) {
	 _errno = errno;
	 switch (_errno) {
	 case EPIPE:
	 case ECONNRESET:
	    if (pipe->cool_write) {
	       Notice4("write(%d, %p, "F_Zu"): %s",
		       fd, buff, bytes, strerror(_errno));
	       break;
	    }
	    /*PASSTRHOUGH*/
	 default:
	    Error4("write(%d, %p, "F_Zu"): %s",
		   fd, buff, bytes, strerror(_errno));
	 }
	 errno = _errno;
	 return -1;
      }
      break;

#if _WITH_SOCKET
   case XIOWRITE_SENDTO:
      /*union {
	 char space[sizeof(struct sockaddr_un)];
	 struct sockaddr sa;
	 } from;*/
      /*socklen_t fromlen;*/

      do {
	 writt = Sendto(fd, buff, bytes, 0,
			&pipe->peersa.soa, pipe->salen);
      } while (writt < 0 && errno == EINTR);
      if (writt < 0) {
	 char infobuff[256];
	 _errno = errno;
	 Error6("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s",
		fd, buff, bytes, 
		sockaddr_info(&pipe->peersa.soa, pipe->salen,
			      infobuff, sizeof(infobuff)),
		pipe->salen, strerror(_errno));
	 errno = _errno;
	 return -1;
      }
      if ((size_t)writt < bytes) {
	 char infobuff[256];
	 Warn7("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen") only wrote "F_Zu" of "F_Zu" bytes",
	       fd, buff, bytes, 
	       sockaddr_info(&pipe->peersa.soa, pipe->salen,
			     infobuff, sizeof(infobuff)),
	       pipe->salen, writt, bytes);
      } else {
      }
      {
	 char infobuff[256];
	 union sockaddr_union us;
	 socklen_t uslen = sizeof(us);
	 Getsockname(fd, &us.soa, &uslen);
	 Notice1("local address: %s",
		 sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
      }
      break;
#endif /* _WITH_SOCKET */

   case XIOWRITE_PIPE:
   case XIOWRITE_2PIPE:
      writt = Write(pipe->wfd, buff, bytes);
      _errno = errno;
      if (writt < 0) {
	 Error4("write(%d, %p, "F_Zu"): %s",
		fd, buff, bytes, strerror(_errno));
	 errno = _errno;
	 return -1;
      }
      break;

#if WITH_TEST
   case XIOWRITE_TEST:
      /* this function prints its own error messages */
      return xiowrite_test(pipe, buff, bytes);
   case XIOWRITE_TESTREV:
      /* this function prints its own error messages */
      return xiowrite_testrev(pipe, buff, bytes);
#endif /* WITH_TEST */

#if WITH_OPENSSL
   case XIOWRITE_OPENSSL:
      /* this function prints its own error messages */
      return xiowrite_openssl(pipe, buff, bytes);
#endif /* WITH_OPENSSL */

   default:
      Error1("xiowrite(): bad data type specification %d", pipe->dtype);
      errno = EINVAL;
      return -1;
   }
   return writt;
}